/[LeafOK_CVS]/pvpgn-1.7.4/src/d2cs/handle_bnetd.c
ViewVC logotype

Contents of /pvpgn-1.7.4/src/d2cs/handle_bnetd.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Tue Jun 6 03:41:38 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU, MAIN
CVS Tags: pvpgn_1-7-4-0_MIL, arelease, HEAD
Changes since 1.1: +0 -0 lines
Content type: text/x-csrc
no message

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

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1