handle_d2gs.c
上传用户:tany51
上传日期:2013-06-12
资源大小:1397k
文件大小:20k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.  * Copyright (C) 2000,2001 Onlyer (onlyer@263.net)
  3.  *
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  */
  18. #include "common/setup_before.h"
  19. #include "setup.h"
  20. #ifdef STDC_HEADERS
  21. # include <stdlib.h>
  22. #else
  23. # ifdef HAVE_MALLOC_H
  24. #  include <malloc.h>
  25. # endif
  26. #endif
  27. #ifdef HAVE_SYS_TYPES_H
  28. # include <sys/types.h> /* needed to include netinet/in.h */
  29. #endif
  30. #ifdef HAVE_SYS_SOCKET_H
  31. # include <sys/socket.h>
  32. #endif
  33. #include "compat/socket.h"
  34. #ifdef HAVE_NETINET_IN_H
  35. # include <netinet/in.h>
  36. #endif
  37. #include "compat/netinet_in.h"
  38. #ifdef HAVE_ARPA_INET_H
  39. # include <arpa/inet.h> /* FIXME: probably not needed... do some systems put types in here or something? */
  40. #endif
  41. #include "compat/psock.h"
  42. #include "d2gs.h"
  43. #include "handle_d2gs.h"
  44. #include "serverqueue.h"
  45. #include "game.h"
  46. #include "connection.h"
  47. #include "prefs.h"
  48. #include "d2cs_d2gs_protocol.h"
  49. #include "d2gstrans.h"
  50. #include "common/addr.h"
  51. #include "common/eventlog.h"
  52. #include "common/queue.h"
  53. #include "common/bn_type.h"
  54. #include "common/packet.h"
  55. #include "common/setup_after.h"
  56. DECLARE_PACKET_HANDLER(on_d2gs_authreply)
  57. DECLARE_PACKET_HANDLER(on_d2gs_setgsinfo)
  58. DECLARE_PACKET_HANDLER(on_d2gs_echoreply)
  59. DECLARE_PACKET_HANDLER(on_d2gs_creategamereply)
  60. DECLARE_PACKET_HANDLER(on_d2gs_joingamereply)
  61. DECLARE_PACKET_HANDLER(on_d2gs_updategameinfo)
  62. DECLARE_PACKET_HANDLER(on_d2gs_closegame)
  63. static t_packet_handle_table d2gs_packet_handle_table[]={
  64. /* 0x00 */ { 0,                                  conn_state_none,       NULL                    },
  65. /* 0x01 */ { 0,                                  conn_state_none,       NULL                    },
  66. /* 0x02 */ { 0,                                  conn_state_none,       NULL                    },
  67. /* 0x03 */ { 0,                                  conn_state_none,       NULL                    },
  68. /* 0x04 */ { 0,                                  conn_state_none,       NULL                    },
  69. /* 0x05 */ { 0,                                  conn_state_none,       NULL                    },
  70. /* 0x06 */ { 0,                                  conn_state_none,       NULL                    },
  71. /* 0x07 */ { 0,                                  conn_state_none,       NULL                    },
  72. /* 0x08 */ { 0,                                  conn_state_none,       NULL                    },
  73. /* 0x09 */ { 0,                                  conn_state_none,       NULL                    },
  74. /* 0x0a */ { 0,                                  conn_state_none,       NULL                    },
  75. /* 0x0b */ { 0,                                  conn_state_none,       NULL                    },
  76. /* 0x0c */ { 0,                                  conn_state_none,       NULL                    },
  77. /* 0x0d */ { 0,                                  conn_state_none,       NULL                    },
  78. /* 0x0e */ { 0,                                  conn_state_none,       NULL                    },
  79. /* 0x0f */ { 0,                                  conn_state_none,       NULL                    },
  80. /* 0x10 */ { 0,                                  conn_state_none,       NULL                    },
  81. /* FIXME: shouldn't these three be at 0x10-0x12? (But I'm pretty sure I preserved the padding) */
  82. /* 0x11 */ { sizeof(t_d2gs_d2cs_authreply),      conn_state_connected,  on_d2gs_authreply       },
  83. /* 0x12 */ { sizeof(t_d2gs_d2cs_setgsinfo),      conn_state_authed,     on_d2gs_setgsinfo       },
  84. /* 0x13 */ { sizeof(t_d2gs_d2cs_echoreply),      conn_state_any,        on_d2gs_echoreply       },
  85. /* 0x14 */ { 0,                                  conn_state_none,       NULL                    },
  86. /* 0x15 */ { 0,                                  conn_state_none,       NULL                    },
  87. /* 0x16 */ { 0,                                  conn_state_none,       NULL                    },
  88. /* 0x17 */ { 0,                                  conn_state_none,       NULL                    },
  89. /* 0x18 */ { 0,                                  conn_state_none,       NULL                    },
  90. /* 0x19 */ { 0,                                  conn_state_none,       NULL                    },
  91. /* 0x1a */ { 0,                                  conn_state_none,       NULL                    },
  92. /* 0x1b */ { 0,                                  conn_state_none,       NULL                    },
  93. /* 0x1c */ { 0,                                  conn_state_none,       NULL                    },
  94. /* 0x1d */ { 0,                                  conn_state_none,       NULL                    },
  95. /* 0x1e */ { 0,                                  conn_state_none,       NULL                    },
  96. /* 0x1f */ { 0,                                  conn_state_none,       NULL                    },
  97. /* 0x20 */ { sizeof(t_d2gs_d2cs_creategamereply),conn_state_authed,     on_d2gs_creategamereply },
  98. /* 0x21 */ { sizeof(t_d2gs_d2cs_joingamereply),  conn_state_authed,     on_d2gs_joingamereply   },
  99. /* 0x22 */ { sizeof(t_d2gs_d2cs_updategameinfo), conn_state_authed,     on_d2gs_updategameinfo  },
  100. /* 0x23 */ { sizeof(t_d2gs_d2cs_closegame),      conn_state_authed,     on_d2gs_closegame       },
  101. };
  102. static void d2gs_send_init_info(t_d2gs * gs, t_connection * c)
  103. {
  104. t_packet * rpacket;
  105. if ((rpacket=packet_create(packet_class_d2gs))) {
  106. packet_set_size(rpacket,sizeof(t_d2cs_d2gs_setinitinfo));
  107. packet_set_type(rpacket,D2CS_D2GS_SETINITINFO);
  108. bn_int_set(&rpacket->u.d2cs_d2gs_setinitinfo.h.seqno,0);
  109. bn_int_set(&rpacket->u.d2cs_d2gs_setinitinfo.time, time(NULL));
  110. bn_int_set(&rpacket->u.d2cs_d2gs_setinitinfo.gs_id, d2gs_get_id(gs));
  111. bn_int_set(&rpacket->u.d2cs_d2gs_setinitinfo.ac_version, 0);
  112. // packet_append_string(rpacket,prefs_get_d2gs_ac_checksum());
  113. packet_append_string(rpacket,"bogus_ac_checksum");
  114. // packet_append_string(rpacket,prefs_get_d2gs_ac_string());
  115. packet_append_string(rpacket,"bogus_ac_string");
  116. conn_push_outqueue(c,rpacket);
  117. packet_del_ref(rpacket);
  118. }
  119. return;
  120. }
  121. static void d2gs_send_server_conffile(t_d2gs *gs, t_connection *c)
  122. {
  123. t_packet *rpacket;
  124. FILE *fp;
  125. char *confs;
  126. long size;
  127. /* open d2gs server config file */
  128. if ((fp=fopen(prefs_get_d2gsconffile(), "r"))==NULL)
  129. return;
  130. /* get file size */
  131. if (fseek(fp, 0L, SEEK_END)) {
  132. fclose(fp);
  133. eventlog(eventlog_level_debug,__FUNCTION__,"failed fseek()");
  134. return;
  135. }
  136. if ((size = ftell(fp)) <= 0) {
  137. fclose(fp);
  138. eventlog(eventlog_level_error,__FUNCTION__,"failed ftell()");
  139. return;
  140. }
  141. fseek(fp, 0L, SEEK_SET);
  142. /* read config file content */
  143. confs = malloc(size+8);
  144. if (confs==NULL) {
  145. fclose(fp);
  146. eventlog(eventlog_level_error,__FUNCTION__,"not enough memory");
  147. return;
  148. }
  149. if (fread(confs, size, 1, fp) != 1) {
  150. fclose(fp);
  151. free(confs);
  152. eventlog(eventlog_level_error,__FUNCTION__,"failed fread()");
  153. return;
  154. }
  155. confs[size]='';
  156. fclose(fp);
  157. /* send the config within a packet */
  158. if ((rpacket=packet_create(packet_class_d2gs))) {
  159. packet_set_size(rpacket,sizeof(t_d2cs_d2gs_setconffile));
  160. packet_set_type(rpacket,D2CS_D2GS_SETCONFFILE);
  161. bn_int_set(&rpacket->u.d2cs_d2gs_setconffile.h.seqno,0);
  162. bn_int_set(&rpacket->u.d2cs_d2gs_setconffile.size, size);
  163. bn_int_set(&rpacket->u.d2cs_d2gs_setconffile.reserved1, time(NULL));
  164. packet_append_string(rpacket,confs);
  165. queue_push_packet(d2cs_conn_get_out_queue(c),rpacket);
  166. packet_del_ref(rpacket);
  167. eventlog(eventlog_level_info,__FUNCTION__,"send config file to d2gs %s", addr_num_to_ip_str(d2cs_conn_get_addr(c)));
  168. }
  169. free(confs);
  170. return;
  171. }
  172. static int on_d2gs_authreply(t_connection * c, t_packet * packet)
  173. {
  174. t_d2gs * gs;
  175. t_packet * rpacket;
  176. unsigned int reply;
  177. unsigned int try_checksum, checksum;
  178. unsigned int version, conf_version;
  179. unsigned int randnum, signlen;
  180. unsigned char *sign;
  181. if (!(gs=d2gslist_find_gs(conn_get_d2gs_id(c)))) {
  182. eventlog(eventlog_level_error,__FUNCTION__,"game server %d not found",conn_get_d2gs_id(c));
  183. return -1;
  184. }
  185. version=bn_int_get(packet->u.d2gs_d2cs_authreply.version);
  186. try_checksum=bn_int_get(packet->u.d2gs_d2cs_authreply.checksum);
  187. checksum=d2gs_calc_checksum(c);
  188. conf_version = prefs_get_d2gs_version();
  189. randnum = bn_int_get(packet->u.d2gs_d2cs_authreply.randnum);
  190. signlen = bn_int_get(packet->u.d2gs_d2cs_authreply.signlen);
  191. sign    = packet->u.d2gs_d2cs_authreply.sign;
  192. if (conf_version && conf_version != version) {
  193. eventlog(eventlog_level_warn,__FUNCTION__,"game server %d version mismatch 0x%X - 0x%X",conn_get_d2gs_id(c),
  194. version,conf_version);
  195. }
  196. if (conf_version && !MAJOR_VERSION_EQUAL(version, conf_version, D2GS_MAJOR_VERSION_MASK)) {
  197. eventlog(eventlog_level_error,__FUNCTION__,"game server %d major version mismatch 0x%X - 0x%X",conn_get_d2gs_id(c),
  198. version,conf_version);
  199. reply=D2CS_D2GS_AUTHREPLY_BAD_VERSION;
  200. } else if (prefs_get_d2gs_checksum() && try_checksum != checksum) {
  201. eventlog(eventlog_level_error,__FUNCTION__,"game server %d checksum mismach 0x%X - 0x%X",conn_get_d2gs_id(c),try_checksum,checksum);
  202. reply=D2CS_D2GS_AUTHREPLY_BAD_CHECKSUM;
  203. // } else if (license_verify_reply(c, randnum, sign, signlen)) {
  204. // eventlog(eventlog_level_error,__FUNCTION__,"game server %d signal mismach", conn_get_d2gs_id(c));
  205. // reply=D2CS_D2GS_AUTHREPLY_BAD_CHECKSUM;
  206. } else {
  207. reply=D2CS_D2GS_AUTHREPLY_SUCCEED;
  208. }
  209. if (reply==D2CS_D2GS_AUTHREPLY_SUCCEED) {
  210. eventlog(eventlog_level_info,__FUNCTION__,"game server %s authed",addr_num_to_ip_str(d2cs_conn_get_addr(c)));
  211. d2cs_conn_set_state(c,conn_state_authed);
  212. d2gs_send_server_conffile(gs, c);
  213. d2gs_send_init_info(gs, c);
  214. d2gs_active(gs,c);
  215. } else {
  216. eventlog(eventlog_level_error,__FUNCTION__,"game server %s failed to auth",addr_num_to_ip_str(d2cs_conn_get_addr(c)));
  217. /* 
  218. d2cs_conn_set_state(c,conn_state_destroy); 
  219. */
  220. }
  221. if ((rpacket=packet_create(packet_class_d2gs))) {
  222. packet_set_size(rpacket,sizeof(t_d2cs_d2gs_authreply));
  223. packet_set_type(rpacket,D2CS_D2GS_AUTHREPLY);
  224. bn_int_set(&rpacket->u.d2cs_d2gs_authreply.h.seqno,0);
  225. bn_int_set(&rpacket->u.d2cs_d2gs_authreply.reply,reply);
  226. conn_push_outqueue(c,rpacket);
  227. packet_del_ref(rpacket);
  228. }
  229. return 0;
  230. }
  231. static int on_d2gs_setgsinfo(t_connection * c, t_packet * packet)
  232. {
  233. t_d2gs * gs;
  234. t_packet * rpacket;
  235. unsigned int maxgame, prev_maxgame;
  236. unsigned int currgame, gameflag;
  237. if (!(gs=d2gslist_find_gs(conn_get_d2gs_id(c)))) {
  238. eventlog(eventlog_level_error,__FUNCTION__,"game server %d not found",conn_get_d2gs_id(c));
  239. return -1;
  240. }
  241. maxgame=bn_int_get(packet->u.d2gs_d2cs_setgsinfo.maxgame);
  242. gameflag=bn_int_get(packet->u.d2gs_d2cs_setgsinfo.gameflag);
  243. prev_maxgame=d2gs_get_maxgame(gs);
  244. currgame = d2gs_get_gamenum(gs);
  245. eventlog(eventlog_level_info, __FUNCTION__, "change game server %s max game from %d to %d (%d current)",addr_num_to_ip_str(d2cs_conn_get_addr(c)),prev_maxgame, maxgame, currgame);
  246. d2gs_set_maxgame(gs,maxgame);
  247.         if ((rpacket=packet_create(packet_class_d2gs))) {
  248.     packet_set_size(rpacket,sizeof(t_d2cs_d2gs_setgsinfo));
  249.     packet_set_type(rpacket,D2CS_D2GS_SETGSINFO);
  250.     bn_int_set(&rpacket->u.d2cs_d2gs_setgsinfo.h.seqno,0);
  251.     bn_int_set(&rpacket->u.d2cs_d2gs_setgsinfo.maxgame,maxgame);
  252.     bn_int_set(&rpacket->u.d2cs_d2gs_setgsinfo.gameflag,gameflag);
  253.     conn_push_outqueue(c,rpacket);
  254.     packet_del_ref(rpacket);
  255.         }
  256. gqlist_check_creategame(maxgame - currgame);
  257. return 0;
  258. }
  259. static int on_d2gs_echoreply(t_connection * c, t_packet * packet)
  260. {
  261. if (!c || !packet)
  262.     return 0;
  263. return 0;
  264. }
  265. static int on_d2gs_creategamereply(t_connection * c, t_packet * packet)
  266. {
  267. t_packet * opacket, * rpacket;
  268. t_sq * sq;
  269. t_connection * client;
  270. t_game * game;
  271. int result;
  272. int reply;
  273. int seqno;
  274. seqno=bn_int_get(packet->u.d2cs_d2gs.h.seqno);
  275. if (!(sq=sqlist_find_sq(seqno))) {
  276. eventlog(eventlog_level_error,__FUNCTION__,"seqno %d not found",seqno);
  277. return 0;
  278. }
  279. if (!(client=d2cs_connlist_find_connection_by_sessionnum(sq_get_clientid(sq)))) {
  280. eventlog(eventlog_level_error,__FUNCTION__,"client %d not found",sq_get_clientid(sq));
  281. sq_destroy(sq);
  282. return 0;
  283. }
  284. if (!(game=gamelist_find_game_by_id(sq_get_gameid(sq)))) {
  285. eventlog(eventlog_level_error,__FUNCTION__,"game %d not found",sq_get_gameid(sq));
  286. sq_destroy(sq);
  287. return 0;
  288. }
  289. if (!(opacket=sq_get_packet(sq))) {
  290. eventlog(eventlog_level_error,__FUNCTION__,"previous packet not found (seqno: %d)",seqno);
  291. sq_destroy(sq);
  292. return 0;
  293. }
  294. result=bn_int_get(packet->u.d2gs_d2cs_creategamereply.result);
  295. if (result==D2GS_D2CS_CREATEGAME_SUCCEED) {
  296. game_set_d2gs_gameid(game,bn_int_get(packet->u.d2gs_d2cs_creategamereply.gameid));
  297. game_set_created(game,1);
  298. eventlog(eventlog_level_info,__FUNCTION__,"game %s created on gs %d",d2cs_game_get_name(game),conn_get_d2gs_id(c));
  299. reply=D2CS_CLIENT_CREATEGAMEREPLY_SUCCEED;
  300. } else {
  301. eventlog(eventlog_level_warn,__FUNCTION__,"failed to create game %s on gs %d",d2cs_game_get_name(game),conn_get_d2gs_id(c));
  302. game_destroy(game);
  303. reply=D2CS_CLIENT_CREATEGAMEREPLY_FAILED;
  304. }
  305. if ((rpacket=packet_create(packet_class_d2cs))) {
  306. packet_set_size(rpacket,sizeof(t_d2cs_client_creategamereply));
  307. packet_set_type(rpacket,D2CS_CLIENT_CREATEGAMEREPLY);
  308. bn_short_set(&rpacket->u.d2cs_client_creategamereply.seqno,
  309. bn_short_get(opacket->u.client_d2cs_creategamereq.seqno));
  310. bn_short_set(&rpacket->u.d2cs_client_creategamereply.gameid,1);
  311. bn_short_set(&rpacket->u.d2cs_client_creategamereply.u1,1);
  312. bn_int_set(&rpacket->u.d2cs_client_creategamereply.reply,reply);
  313. conn_push_outqueue(client,rpacket);
  314. packet_del_ref(rpacket);
  315. }
  316. sq_destroy(sq);
  317. return 0;
  318. }
  319. static int on_d2gs_joingamereply(t_connection * c, t_packet * packet)
  320. {
  321. t_sq * sq;
  322. t_d2gs * gs;
  323. t_connection * client;
  324. t_game * game;
  325. t_packet * opacket, * rpacket;
  326. int result;
  327. int reply;
  328. int seqno;
  329. unsigned int gsaddr;
  330. seqno=bn_int_get(packet->u.d2cs_d2gs.h.seqno);
  331. if (!(sq=sqlist_find_sq(seqno))) {
  332. eventlog(eventlog_level_error,__FUNCTION__,"seqno %d not found",seqno);
  333. return 0;
  334. }
  335. if (!(client=d2cs_connlist_find_connection_by_sessionnum(sq_get_clientid(sq)))) {
  336. eventlog(eventlog_level_error,__FUNCTION__,"client %d not found",sq_get_clientid(sq));
  337. sq_destroy(sq);
  338. return 0;
  339. }
  340. if (!(game=gamelist_find_game_by_id(sq_get_gameid(sq)))) {
  341. eventlog(eventlog_level_error,__FUNCTION__,"game %d not found",sq_get_gameid(sq));
  342. sq_destroy(sq);
  343. return 0;
  344. }
  345. if (!(gs=game_get_d2gs(game))) {
  346. eventlog(eventlog_level_error,__FUNCTION__,"try join game without game server set");
  347. sq_destroy(sq);
  348. return 0;
  349. }
  350. if (!(opacket=sq_get_packet(sq))) {
  351. eventlog(eventlog_level_error,__FUNCTION__,"previous packet not found (seqno: %d)",seqno);
  352. sq_destroy(sq);
  353. return 0;
  354. }
  355. result=bn_int_get(packet->u.d2gs_d2cs_joingamereply.result);
  356. switch (result) {
  357. case D2GS_D2CS_JOINGAME_SUCCEED:
  358. eventlog(eventlog_level_info,__FUNCTION__,"added %s to game %s on gs %d",d2cs_conn_get_charname(client),
  359. d2cs_game_get_name(game),conn_get_d2gs_id(c));
  360. reply=D2CS_CLIENT_JOINGAMEREPLY_SUCCEED;
  361. break;
  362. case D2GS_D2CS_JOINGAME_GAME_FULL:
  363. eventlog(eventlog_level_info,__FUNCTION__,"failed to add %s to game %s on gs %d (game full)",d2cs_conn_get_charname(client),
  364. d2cs_game_get_name(game),conn_get_d2gs_id(c));
  365. reply=D2CS_CLIENT_JOINGAMEREPLY_GAME_FULL;
  366. break;
  367. default:
  368. eventlog(eventlog_level_info,__FUNCTION__,"failed to add %s to game %s on gs %d",d2cs_conn_get_charname(client),
  369. d2cs_game_get_name(game),conn_get_d2gs_id(c));
  370. reply=D2CS_CLIENT_JOINGAMEREPLY_FAILED;
  371. }
  372. if ((rpacket=packet_create(packet_class_d2cs))) {
  373. packet_set_size(rpacket,sizeof(t_d2cs_client_joingamereply));
  374. packet_set_type(rpacket,D2CS_CLIENT_JOINGAMEREPLY);
  375. bn_short_set(&rpacket->u.d2cs_client_joingamereply.seqno,
  376. bn_short_get(opacket->u.client_d2cs_joingamereq.seqno));
  377. /* specific flag for anti-cheating support */
  378. /*
  379. bn_short_set(&rpacket->u.d2cs_client_joingamereply.gameid,(unsigned short)game_get_d2gs_gameid(game)|0x8000);
  380. */
  381. bn_short_set(&rpacket->u.d2cs_client_joingamereply.gameid,(unsigned short)game_get_d2gs_gameid(game));
  382. bn_short_set(&rpacket->u.d2cs_client_joingamereply.u1,0);
  383. bn_int_set(&rpacket->u.d2cs_client_joingamereply.reply,reply);
  384. // if (reply == SERVER_JOINGAMEREPLY2_REPLY_OK) {
  385. if (reply == D2CS_CLIENT_JOINGAMEREPLY_SUCCEED) {
  386. bn_int_set(&rpacket->u.d2cs_client_joingamereply.token,sq_get_gametoken(sq));
  387. gsaddr = d2gs_get_ip(gs);
  388. d2gstrans_net(d2cs_conn_get_addr(client),&gsaddr);
  389. if(d2gs_get_ip(gs)!=gsaddr)
  390. {
  391.     eventlog(eventlog_level_info,__FUNCTION__,"translated gameserver %s -> %s",addr_num_to_ip_str(d2gs_get_ip(gs)),addr_num_to_ip_str(gsaddr));
  392. } else {
  393.     eventlog(eventlog_level_info,__FUNCTION__,"no translation required for gamserver %s",addr_num_to_ip_str(gsaddr));
  394. }
  395. bn_int_nset(&rpacket->u.d2cs_client_joingamereply.addr,gsaddr);
  396. } else {
  397. bn_int_set(&rpacket->u.d2cs_client_joingamereply.token,0);
  398. bn_int_set(&rpacket->u.d2cs_client_joingamereply.addr,0);
  399. }
  400. conn_push_outqueue(client,rpacket);
  401. packet_del_ref(rpacket);
  402. }
  403. sq_destroy(sq);
  404. return 0;
  405. }
  406. static int on_d2gs_updategameinfo(t_connection * c, t_packet * packet)
  407. {
  408. unsigned int flag;
  409. char const * charname;
  410. t_game * game;
  411. unsigned int charclass;
  412. unsigned int charlevel;
  413. unsigned int d2gs_gameid;
  414. unsigned int d2gs_id;
  415. if (!(charname=packet_get_str_const(packet,sizeof(t_d2gs_d2cs_updategameinfo),MAX_CHARNAME_LEN))) {
  416. eventlog(eventlog_level_error,__FUNCTION__,"got bad charname");
  417. return 0;
  418. }
  419. d2gs_id=conn_get_d2gs_id(c);
  420. d2gs_gameid=bn_int_get(packet->u.d2gs_d2cs_updategameinfo.gameid);
  421. charclass=bn_int_get(packet->u.d2gs_d2cs_updategameinfo.charclass);
  422. charlevel=bn_int_get(packet->u.d2gs_d2cs_updategameinfo.charlevel);
  423. flag=bn_int_get(packet->u.d2gs_d2cs_updategameinfo.flag);
  424. if (!(game=gamelist_find_game_by_d2gs_and_id(d2gs_id,d2gs_gameid))) {
  425. eventlog(eventlog_level_error,__FUNCTION__,"game %d not found on gs %d",d2gs_gameid,d2gs_id);
  426. return -1;
  427. }
  428. if (flag==D2GS_D2CS_UPDATEGAMEINFO_FLAG_ENTER) {
  429. game_add_character(game,charname,charclass,charlevel);
  430. } else if (flag==D2GS_D2CS_UPDATEGAMEINFO_FLAG_LEAVE) {
  431. game_del_character(game,charname);
  432. } else if (flag==D2GS_D2CS_UPDATEGAMEINFO_FLAG_UPDATE) {
  433. game_add_character(game,charname,charclass,charlevel);
  434. } else {
  435. eventlog(eventlog_level_error,__FUNCTION__,"got bad updategameinfo flag %d",flag);
  436. }
  437. return 0;
  438. }
  439. static int on_d2gs_closegame(t_connection * c, t_packet * packet)
  440. {
  441. t_game * game;
  442. if (!(game=gamelist_find_game_by_d2gs_and_id(conn_get_d2gs_id(c),
  443. bn_int_get(packet->u.d2gs_d2cs_closegame.gameid)))) {
  444. return 0;
  445. }
  446. game_destroy(game);
  447. return 0;
  448. }
  449. extern int handle_d2gs_packet(t_connection * c, t_packet * packet)
  450. {
  451. conn_process_packet(c,packet,d2gs_packet_handle_table,NELEMS(d2gs_packet_handle_table));
  452. return 0;
  453. }
  454. extern int handle_d2gs_init(t_connection * c)
  455. {
  456. t_packet * packet;
  457. if ((packet=packet_create(packet_class_d2gs))) {
  458. packet_set_size(packet,sizeof(t_d2cs_d2gs_authreq));
  459. packet_set_type(packet,D2CS_D2GS_AUTHREQ);
  460. bn_int_set(&packet->u.d2cs_d2gs_authreq.h.seqno,0);
  461. bn_int_set(&packet->u.d2cs_d2gs_authreq.sessionnum,d2cs_conn_get_sessionnum(c));
  462. bn_int_set(&packet->u.d2cs_d2gs_authreq.signlen, 0);
  463. packet_append_string(packet,prefs_get_realmname());
  464. // packet_append_data(packet, sign, signlen);
  465. conn_push_outqueue(c,packet);
  466. packet_del_ref(packet);
  467. }
  468. eventlog(eventlog_level_info,__FUNCTION__,"sent init packet to d2gs %d (sessionnum=%d)",conn_get_d2gs_id(c),d2cs_conn_get_sessionnum(c));
  469. return 0;
  470. }