serversession.cpp
上传用户:zslianheng
上传日期:2013-04-03
资源大小:946k
文件大小:10k
源码类别:

Linux/Unix编程

开发平台:

Visual C++

  1. /***************************************************************************
  2.  *                                                                         *
  3.  *   This program is free software; you can redistribute it and/or modify  *
  4.  *   it under the terms of the GNU General Public License as published by  *
  5.  *   the Free Software Foundation; either version 2 of the License, or     *
  6.  *   (at your option) any later version.                                   *
  7.  *                                                                         *
  8.  *   copyright            : (C) 2002 by Zhang Yong                         *
  9.  *   email                : z-yong163@163.com                              *
  10.  ***************************************************************************/
  11. #include <iostream>
  12. #include "serversession.h"
  13. #include "icqlink.h"
  14. #include "udppacket.h"
  15. #include "ndes.h"
  16. #define MAX_SEARCH_PER_PAGE 25
  17. ServerSession::ServerSession(IcqLink *link)
  18. : UdpSession(link, ICQ_SESSION_SERVER, 0)
  19. {
  20. ackseq = 0;
  21. sessionCount = 0;
  22. realIP = 0;
  23. memset(&proxyAddr, 0, sizeof(proxyAddr));
  24. udpSock = IcqSocket::createSocket(SOCK_DGRAM, this);
  25. socksSession.setListener(this);
  26. httpSession.setListener(this);
  27. }
  28. ServerSession::~ServerSession()
  29. {
  30. if (udpSock >= 0)
  31. IcqSocket::closeSocket(udpSock);
  32. }
  33. void ServerSession::sendDirect(UdpOutPacket *p)
  34. {
  35. if (icqLink->isProxyType(PROXY_HTTP)) {
  36. uint16 n = p->getSize() - sizeof(uint16);
  37. int old = p->setCursor(0);
  38. *p << n;
  39. p->setCursor(old);
  40. UdpSession::sendDirect(p, httpSession.sock);
  41. } else
  42. UdpSession::sendDirect(p);
  43. }
  44. void ServerSession::onSendError(UdpOutPacket *p)
  45. {
  46. if (p->cmd == UDP_KEEPALIVE)
  47. icqLink->onConnect(false);
  48. else
  49. UdpSession::onSendError(p);
  50. }
  51. void ServerSession::connect(const char *host, uint16 port)
  52. {
  53. destHost = host;
  54. UdpSession::connect(ntohl(inet_addr(host)), port);
  55. IcqOption &options = icqLink->options;
  56. if (options.flags.test(UF_USE_PROXY)) {
  57. if (options.proxyType == PROXY_SOCKS) {
  58. sockaddr_in addr;
  59. socklen_t addrlen = sizeof(addr);
  60. getsockname(udpSock, (sockaddr *) &addr, &addrlen);
  61. socksSession.start(options.proxy[PROXY_SOCKS], addr.sin_port);
  62. } else if (options.proxyType == PROXY_HTTP)
  63. httpSession.start(host, options.proxy[PROXY_HTTP]);
  64. } else
  65. icqLink->onConnect(true);
  66. }
  67. void ServerSession::sendKeepAlive()
  68. {
  69. UdpOutPacket *out = createPacket(UDP_KEEPALIVE);
  70. sendPacket(out);
  71. }
  72. uint16 ServerSession::sendPacket(UdpOutPacket *p)
  73. {
  74. if (p->cmd != UDP_NEW_UIN && p->cmd != UDP_LOGIN)
  75. p->encrypt();
  76. return UdpSession::sendPacket(p);
  77. }
  78. void ServerSession::getInfo(IcqInfo &info, UdpInPacket &in)
  79. {
  80. in >> info.face >> info.nick >> info.age >> info.gender;
  81. in >> info.country >> info.province >> info.city;
  82. in >> info.email >> info.address >> info.zipcode >> info.tel;
  83. in >> info.name >> info.blood >> info.college;
  84. in >> info.profession >> info.homepage >> info.intro;
  85. }
  86. uint16 ServerSession::regNewUIN(const char *passwd)
  87. {
  88. initSession();
  89. uin = 0;
  90. UdpOutPacket *out = createPacket(UDP_NEW_UIN);
  91. *out << passwd;
  92. return sendPacket(out);
  93. }
  94. uint16 ServerSession::getContactList()
  95. {
  96. UdpOutPacket *out = createPacket(UDP_GET_CONTACTLIST);
  97. return sendPacket(out);
  98. }
  99. uint16 ServerSession::login(const char *passwd, uint32 status)
  100. {
  101. initSession();
  102. char pass[8];
  103. strncpy(pass, passwd, sizeof(pass));
  104. setkey(pass);
  105. UdpOutPacket *out = createPacket(UDP_LOGIN);
  106. *out << passwd << status << (uint16) MYICQ_TCP_VER << realIP;
  107. return sendPacket(out);
  108. }
  109. void ServerSession::logout()
  110. {
  111. UdpOutPacket *out = createPacket(UDP_LOGOUT);
  112. sendPacket(out);
  113. clearSendQueue();
  114. }
  115. void ServerSession::changeStatus(uint32 status)
  116. {
  117. UdpOutPacket *out = createPacket(UDP_CHANGE_STATUS);
  118. *out << status;
  119. sendPacket(out);
  120. }
  121. uint16 ServerSession::updateContact(uint32 uin)
  122. {
  123. UdpOutPacket *out = createPacket(UDP_UPDATE_CONTACT);
  124. *out << uin;
  125. return sendPacket(out);
  126. }
  127. void ServerSession::updateUser()
  128. {
  129. UdpOutPacket *out = createPacket(UDP_UPDATE_USER);
  130. sendPacket(out);
  131. }
  132. uint16 ServerSession::modifyUser(IcqUser *info, uint8 modifyPasswd)
  133. {
  134. UdpOutPacket *out = createPacket(UDP_MODIFY_USER);
  135. *out << info->face << info->nick << info->age << info->gender;
  136. *out << info->country << info->province << info->city;
  137. *out << info->email << info->address << info->zipcode << info->tel;
  138.     *out << info->name << info->blood << info->college;
  139.     *out << info->profession << info->homepage << info->intro;
  140. *out << info->auth << modifyPasswd;
  141. if (modifyPasswd)
  142. *out << info->passwd;
  143. return sendPacket(out);
  144. }
  145. uint16 ServerSession::sendMessage(uint8 type, uint32 to, const char *text)
  146. {
  147. time_t when = time(NULL);
  148. UdpOutPacket *out = createPacket(UDP_SEND_MSG);
  149. *out << type << to << (uint32) when << text;
  150. return sendPacket(out);
  151. }
  152. uint16 ServerSession::groupSendMessage(uint8 type, UinList &uinList, const char *text)
  153. {
  154. time_t when = time(NULL);
  155. UdpOutPacket *out = createPacket(UDP_GROUP_SEND_MSG);
  156. *out << type << (uint32) when << text;
  157. *out << (uint16) uinList.size();
  158. UinList::iterator it;
  159. for (it = uinList.begin(); it != uinList.end(); ++it)
  160. *out << *it;
  161. return sendPacket(out);
  162. }
  163. uint16 ServerSession::broadcastMsg(uint8 type, uint32 expire, const char *text)
  164. {
  165. time_t when = time(NULL);
  166. UdpOutPacket *out = createPacket(UDP_BROADCAST_MSG);
  167. *out << type << (uint32) when << expire << text;
  168. return sendPacket(out);
  169. }
  170. uint16 ServerSession::searchRandom()
  171. {
  172. UdpOutPacket *out = createPacket(UDP_SEARCH_RANDOM);
  173. return sendPacket(out);
  174. }
  175. uint16 ServerSession::searchCustom(uint32 uin, const char *nick, const char *email, uint32 startUIN)
  176. {
  177. UdpOutPacket *out = createPacket(UDP_SEARCH_CUSTOM);
  178. *out << uin << nick << email << startUIN;
  179. return sendPacket(out);
  180. }
  181. uint16 ServerSession::addFriend(uint32 uin)
  182. {
  183. UdpOutPacket *out = createPacket(UDP_ADD_FRIEND);
  184. *out << uin;
  185. return sendPacket(out);
  186. }
  187. uint16 ServerSession::delFriend(uint32 uin)
  188. {
  189. UdpOutPacket *out = createPacket(UDP_DEL_FRIEND);
  190. *out << uin;
  191. return sendPacket(out);
  192. }
  193. bool ServerSession::onPacketReceived(UdpInPacket &in)
  194. {
  195. if (!UdpSession::onPacketReceived(in))
  196. return false;
  197. uint16 seq = in.getSeq();
  198. ackseq = in.getAckSeq();
  199. if (ackseq && !seq)
  200. icqLink->onAck(ackseq);
  201. uint16 cmd = in.getCmd();
  202. switch (cmd) {
  203. case UDP_NEW_UIN:
  204. onNewUINReply(in);
  205. break;
  206. case UDP_GET_CONTACTLIST:
  207. onContactListReply(in);
  208. break;
  209. case UDP_LOGIN:
  210. onLoginReply(in);
  211. break;
  212. case UDP_KEEPALIVE:
  213. in >> sessionCount;
  214. return true;
  215. case UDP_SRV_MULTI_ONLINE:
  216. onMultiOnline(in);
  217. break;
  218. case UDP_SRV_USER_ONLINE:
  219. onUserOnline(in);
  220. break;
  221. case UDP_SRV_USER_OFFLINE:
  222. onUserOffline(in);
  223. break;
  224. case UDP_SRV_STATUS_CHANGED:
  225. onStatusChanged(in);
  226. break;
  227. case UDP_UPDATE_CONTACT:
  228. onUpdateContactReply(in);
  229. break;
  230. case UDP_UPDATE_USER:
  231. onUpdateUserReply(in);
  232. break;
  233. case UDP_SRV_MESSAGE:
  234. onRecvMessage(in);
  235. break;
  236. case UDP_SRV_SEARCH:
  237. onSearchReply(in);
  238. break;
  239. case UDP_ADD_FRIEND:
  240. onAddFriendReply(in);
  241. break;
  242. default:
  243. cerr << "unknown cmd " << cmd << endl;
  244. return false;
  245. }
  246. sendAckPacket(in.getSeq());
  247. return true;
  248. }
  249. void ServerSession::onLoginReply(UdpInPacket &in)
  250. {
  251. uint8 error;
  252. in >> error;
  253. icqLink->onLoginReply(error);
  254. }
  255. void ServerSession::onMultiOnline(UdpInPacket &in)
  256. {
  257. uint16 num;
  258. in >> num;
  259. int n = num;
  260. while (--n >= 0) {
  261. uint32 uin, status, ip, realIP;
  262. uint16 port;
  263. in >> uin >> status >> ip >> port >> realIP;
  264. icqLink->onUserOnline(uin, status, ip, port, realIP, true);
  265. }
  266. }
  267. void ServerSession::onUserOnline(UdpInPacket &in)
  268. {
  269. uint32 uin, status, ip, realIP;
  270. uint16 port;
  271. in >> uin >> status >> ip >> port >> realIP;
  272. icqLink->onUserOnline(uin, status, ip, port, realIP);
  273. }
  274. void ServerSession::onUserOffline(UdpInPacket &in)
  275. {
  276. uint32 uin;
  277. in >> uin;
  278. icqLink->onUserOffline(uin);
  279. }
  280. void ServerSession::onStatusChanged(UdpInPacket &in)
  281. {
  282. uint32 uin, status;
  283. in >> uin >> status;
  284. icqLink->onStatusChanged(uin, status);
  285. }
  286. void ServerSession::onNewUINReply(UdpInPacket &in)
  287. {
  288. in >> uin;
  289. icqLink->onNewUINReply(uin);
  290. }
  291. void ServerSession::onContactListReply(UdpInPacket &in)
  292. {
  293. uint16 num;
  294. in >> num;
  295. UinList l;
  296. while (num-- > 0) {
  297. uint32 uin;
  298. in >> uin;
  299. l.push_back(uin);
  300. }
  301. icqLink->onContactListReply(l);
  302. }
  303. void ServerSession::onUpdateContactReply(UdpInPacket &in)
  304. {
  305. IcqContact info;
  306. in >> info.uin;
  307. getInfo(info, in);
  308. icqLink->onUpdateContactReply(&info);
  309. }
  310. void ServerSession::onUpdateUserReply(UdpInPacket &in)
  311. {
  312. IcqUser &info = icqLink->myInfo;
  313. getInfo(info, in);
  314. in >> info.auth;
  315. icqLink->onUpdateUserReply();
  316. }
  317. void ServerSession::onRecvMessage(UdpInPacket &in)
  318. {
  319. uint8 type;
  320. uint32 from, when;
  321. const char *text;
  322. in >> type >> from >> when >> text;
  323. cout << "received message from " << from << endl;
  324. icqLink->onRecvMessage(type, from, when, text, true);
  325. }
  326. void ServerSession::onSearchReply(UdpInPacket &in)
  327. {
  328. PtrList *l = new PtrList;
  329. uint16 num;
  330. in >> num;
  331. int n = num;
  332. while (n-- > 0) {
  333. SEARCH_RESULT *p = new SEARCH_RESULT;
  334. in >> p->uin >> p->online >> p->face >> p->nick >> p->province;
  335. l->push_back(p);
  336. }
  337. icqLink->onUserFound(l);
  338. }
  339. void ServerSession::onAddFriendReply(UdpInPacket &in)
  340. {
  341. uint32 uin;
  342. uint8 result;
  343. in >> uin >> result;
  344. icqLink->onAddFriendReply(uin, result);
  345. }
  346. void ServerSession::sessionFinished(bool success)
  347. {
  348. if (success && icqLink->options.proxyType == PROXY_SOCKS) {
  349. sockaddr_in addr;
  350. socklen_t addrlen = sizeof(addr);
  351. getsockname(socksSession.sock, (sockaddr *) &addr, &addrlen);
  352. realIP = ntohl(addr.sin_addr.s_addr);
  353. memset(&proxyAddr, 0, sizeof(proxyAddr));
  354. proxyAddr.sin_family = AF_INET;
  355. proxyAddr.sin_addr.s_addr = socksSession.socksIP;
  356. proxyAddr.sin_port = socksSession.socksPort;
  357. icqLink->socksIP = ntohl(socksSession.socksIP);
  358. }
  359. icqLink->onConnect(success);
  360. }