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

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. #include "connection.h"
  28. #include "handle_bnetd.h"
  29. #include "serverqueue.h"
  30. #include "d2cs_bnetd_protocol.h"
  31. #include "d2cs_protocol.h"
  32. #include "version.h"
  33. #include "prefs.h"
  34. #include "common/init_protocol.h"
  35. #include "common/packet.h"
  36. #include "common/eventlog.h"
  37. #include "common/setup_after.h"
  38. DECLARE_PACKET_HANDLER(on_bnetd_accountloginreply)
  39. DECLARE_PACKET_HANDLER(on_bnetd_charloginreply)
  40. DECLARE_PACKET_HANDLER(on_bnetd_authreq)
  41. DECLARE_PACKET_HANDLER(on_bnetd_authreply)
  42. static t_packet_handle_table bnetd_packet_handle_table[]={
  43. /* 0x00 */ { 0,                                      conn_state_none,      NULL                       },
  44. /* 0x01 */ { sizeof(t_bnetd_d2cs_authreq),           conn_state_connected, on_bnetd_authreq           },
  45. /* 0x02 */ { sizeof(t_bnetd_d2cs_authreply),         conn_state_connected, on_bnetd_authreply         },
  46. /* 0x03 */ { 0,                                      conn_state_none,      NULL                       },
  47. /* 0x04 */ { 0,                                      conn_state_none,      NULL                       },
  48. /* 0x05 */ { 0,                                      conn_state_none,      NULL                       },
  49. /* 0x06 */ { 0,                                      conn_state_none,      NULL                       },
  50. /* 0x07 */ { 0,                                      conn_state_none,      NULL                       },
  51. /* 0x08 */ { 0,                                      conn_state_none,      NULL                       },
  52. /* 0x09 */ { 0,                                      conn_state_none,      NULL                       },
  53. /* 0x0a */ { 0,                                      conn_state_none,      NULL                       },
  54. /* 0x0b */ { 0,                                      conn_state_none,      NULL                       },
  55. /* 0x0c */ { 0,                                      conn_state_none,      NULL                       },
  56. /* 0x0d */ { 0,                                      conn_state_none,      NULL                       },
  57. /* 0x03 */ { 0,                                      conn_state_none,      NULL                       },
  58. /* 0x0f */ { 0,                                      conn_state_none,      NULL                       },
  59. /* 0x10 */ { sizeof(t_bnetd_d2cs_accountloginreply), conn_state_authed,    on_bnetd_accountloginreply },
  60. /* 0x11 */ { sizeof(t_bnetd_d2cs_charloginreply),    conn_state_authed,    on_bnetd_charloginreply    }
  61. };
  62. extern int handle_bnetd_packet(t_connection * c, t_packet * packet)
  63. {
  64.         conn_process_packet(c,packet,bnetd_packet_handle_table,NELEMS(bnetd_packet_handle_table));
  65. return 0;
  66. }
  67. extern int handle_bnetd_init(t_connection * c)
  68. {
  69. t_packet * packet;
  70. packet=packet_create(packet_class_init);
  71. packet_set_size(packet,sizeof(t_client_initconn));
  72. bn_byte_set(&packet->u.client_initconn.class, CLIENT_INITCONN_CLASS_D2CS_BNETD);
  73. conn_push_outqueue(c,packet);
  74. packet_del_ref(packet);
  75. d2cs_conn_set_state(c,conn_state_connected);
  76. eventlog(eventlog_level_info,__FUNCTION__,"sent init class packet to bnetd");
  77. return 0;
  78. }
  79. static int on_bnetd_authreq(t_connection * c, t_packet * packet)
  80. {
  81. t_packet * rpacket;
  82. unsigned int sessionnum;
  83. sessionnum=bn_int_get(packet->u.bnetd_d2cs_authreq.sessionnum);
  84. eventlog(eventlog_level_info,__FUNCTION__,"received bnetd sessionnum %d",sessionnum);
  85. if ((rpacket=packet_create(packet_class_d2cs_bnetd))) {
  86. packet_set_size(rpacket,sizeof(t_d2cs_bnetd_authreply));
  87. packet_set_type(rpacket,D2CS_BNETD_AUTHREPLY);
  88. bn_int_set(&rpacket->u.d2cs_bnetd_authreply.h.seqno,1);
  89. bn_int_set(&rpacket->u.d2cs_bnetd_authreply.version,D2CS_VERSION_NUMBER);
  90. packet_append_string(rpacket,prefs_get_realmname());
  91. conn_push_outqueue(c,rpacket);
  92. packet_del_ref(rpacket);
  93. }
  94. return 0;
  95. }
  96. static int on_bnetd_authreply(t_connection * c, t_packet * packet)
  97. {
  98. unsigned int reply;
  99. reply=bn_int_get(packet->u.bnetd_d2cs_authreply.reply);
  100. if (reply == BNETD_D2CS_AUTHREPLY_SUCCEED) {
  101. eventlog(eventlog_level_info,__FUNCTION__,"authed by bnetd");
  102. d2cs_conn_set_state(c,conn_state_authed);
  103. } else {
  104. eventlog(eventlog_level_error,__FUNCTION__,"failed to auth by bnetd (error=%d)",reply);
  105. d2cs_conn_set_state(c,conn_state_destroy);
  106. }
  107. return 0;
  108. }
  109. static int on_bnetd_accountloginreply(t_connection * c, t_packet * packet)
  110. {
  111. unsigned int seqno;
  112. t_sq * sq;
  113. t_packet * opacket, * rpacket;
  114. t_connection * client;
  115. int result, reply;
  116. char const * account;
  117. if (!packet || !c)
  118.     return -1;
  119. seqno=bn_int_get(packet->u.d2cs_bnetd.h.seqno);
  120. if (!(sq=sqlist_find_sq(seqno))) {
  121. eventlog(eventlog_level_error,__FUNCTION__,"seqno %d not found",seqno);
  122. return -1;
  123. }
  124. if (!(client=d2cs_connlist_find_connection_by_sessionnum(sq_get_clientid(sq)))) {
  125. eventlog(eventlog_level_error,__FUNCTION__,"client %d not found",sq_get_clientid(sq));
  126. sq_destroy(sq);
  127. return -1;
  128. }
  129. if (!(opacket=sq_get_packet(sq))) {
  130. eventlog(eventlog_level_error,__FUNCTION__,"previous packet missing (seqno: %d)",seqno);
  131. sq_destroy(sq);
  132. return -1;
  133. }
  134. result=bn_int_get(packet->u.bnetd_d2cs_accountloginreply.reply);
  135. if (result==BNETD_D2CS_CHARLOGINREPLY_SUCCEED) {
  136. reply=D2CS_CLIENT_LOGINREPLY_SUCCEED;
  137. account=packet_get_str_const(opacket,sizeof(t_client_d2cs_loginreq),MAX_CHARNAME_LEN);
  138. d2cs_conn_set_account(client,account);
  139. d2cs_conn_set_state(client,conn_state_authed);
  140. eventlog(eventlog_level_info,__FUNCTION__,"account %s authed",account);
  141. } else {
  142. eventlog(eventlog_level_warn,__FUNCTION__,"client %d login request was rejected by bnetd",sq_get_clientid(sq));
  143. reply=D2CS_CLIENT_LOGINREPLY_BADPASS;
  144. }
  145. if ((rpacket=packet_create(packet_class_d2cs))) {
  146. packet_set_size(rpacket,sizeof(t_d2cs_client_loginreply));
  147. packet_set_type(rpacket,D2CS_CLIENT_LOGINREPLY);
  148. bn_int_set(&rpacket->u.d2cs_client_loginreply.reply,reply);
  149. conn_push_outqueue(client,rpacket);
  150. packet_del_ref(rpacket);
  151. }
  152. sq_destroy(sq);
  153. return 0;
  154. }
  155. static int on_bnetd_charloginreply(t_connection * c, t_packet * packet)
  156. {
  157. unsigned int seqno;
  158. t_sq * sq;
  159. t_connection * client;
  160. t_packet * opacket, * rpacket;
  161. int result, reply, type;
  162. char const * charname;
  163. if (!packet || !c)
  164.     return -1;
  165. seqno=bn_int_get(packet->u.d2cs_bnetd.h.seqno);
  166. if (!(sq=sqlist_find_sq(seqno))) {
  167. eventlog(eventlog_level_error,__FUNCTION__,"seqno %d not found",seqno);
  168. return -1;
  169. }
  170. if (!(client=d2cs_connlist_find_connection_by_sessionnum(sq_get_clientid(sq)))) {
  171. eventlog(eventlog_level_error,__FUNCTION__,"client %d not found",sq_get_clientid(sq));
  172. sq_destroy(sq);
  173. return -1;
  174. }
  175. if (!(opacket=sq_get_packet(sq))) {
  176. eventlog(eventlog_level_error,__FUNCTION__,"previous packet missing (seqno: %d)",seqno);
  177. sq_destroy(sq);
  178. return -1;
  179. }
  180. type=packet_get_type(opacket);
  181. result=bn_int_get(packet->u.bnetd_d2cs_charloginreply.reply);
  182. if (type==CLIENT_D2CS_CREATECHARREQ) {
  183. charname=packet_get_str_const(opacket,sizeof(t_client_d2cs_createcharreq),MAX_CHARNAME_LEN);
  184. if (result==BNETD_D2CS_CHARLOGINREPLY_SUCCEED) {
  185. if (conn_check_multilogin(client,charname)<0) {
  186. eventlog(eventlog_level_error,__FUNCTION__,"character %s is already logged in",charname);
  187. reply = D2CS_CLIENT_CHARLOGINREPLY_FAILED;
  188. } else {
  189. reply= D2CS_CLIENT_CREATECHARREPLY_SUCCEED;
  190. eventlog(eventlog_level_info,__FUNCTION__,"character %s authed",charname);
  191. d2cs_conn_set_charname(client,charname);
  192. d2cs_conn_set_state(client,conn_state_char_authed);
  193. }
  194. } else {
  195. reply = D2CS_CLIENT_CREATECHARREPLY_FAILED;
  196. eventlog(eventlog_level_error,__FUNCTION__,"failed to auth character %s",charname);
  197. }
  198. if ((rpacket=packet_create(packet_class_d2cs))) {
  199. packet_set_size(rpacket,sizeof(t_d2cs_client_createcharreply));
  200. packet_set_type(rpacket,D2CS_CLIENT_CREATECHARREPLY);
  201. bn_int_set(&rpacket->u.d2cs_client_createcharreply.reply,reply);
  202. conn_push_outqueue(client,rpacket);
  203. packet_del_ref(rpacket);
  204. }
  205. } else if (type==CLIENT_D2CS_CHARLOGINREQ) {
  206. charname=packet_get_str_const(opacket,sizeof(t_client_d2cs_charloginreq),MAX_CHARNAME_LEN);
  207. if (result==BNETD_D2CS_CHARLOGINREPLY_SUCCEED) {
  208. if (conn_check_multilogin(client,charname)<0) {
  209. eventlog(eventlog_level_error,__FUNCTION__,"character %s is already logged in",charname);
  210. reply = D2CS_CLIENT_CHARLOGINREPLY_FAILED;
  211. } else {
  212. reply = D2CS_CLIENT_CHARLOGINREPLY_SUCCEED;
  213. eventlog(eventlog_level_info,__FUNCTION__,"character %s authed",charname);
  214. d2cs_conn_set_charname(client,charname);
  215. d2cs_conn_set_state(client,conn_state_char_authed);
  216. }
  217. } else {
  218. reply = D2CS_CLIENT_CHARLOGINREPLY_FAILED;
  219. eventlog(eventlog_level_error,__FUNCTION__,"failed to auth character %s",charname);
  220. }
  221. if ((rpacket=packet_create(packet_class_d2cs))) {
  222. packet_set_size(rpacket,sizeof(t_d2cs_client_charloginreply));
  223. packet_set_type(rpacket,D2CS_CLIENT_CHARLOGINREPLY);
  224. bn_int_set(&rpacket->u.d2cs_client_charloginreply.reply,reply);
  225. conn_push_outqueue(client,rpacket);
  226. packet_del_ref(rpacket);
  227. }
  228. } else {
  229. eventlog(eventlog_level_error,__FUNCTION__,"got bad packet type %d",type);
  230. sq_destroy(sq);
  231. return -1;
  232. }
  233. sq_destroy(sq);
  234. return 0;
  235. }