1 /*
2 * Copyright (C) 1999,2000,2001 Ross Combs (rocombs@cs.nmsu.edu)
3 * Copyright (C) 1999,2000 Rob Crittenden (rcrit@greyoak.com)
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19 #define GAME_INTERNAL_ACCESS
20 #include "common/setup_before.h"
21 #ifdef HAVE_STDDEF_H
22 # include <stddef.h>
23 #else
24 # ifndef NULL
25 # define NULL ((void *)0)
26 # endif
27 #endif
28 #ifdef STDC_HEADERS
29 # include <stdlib.h>
30 #else
31 # ifdef HAVE_MALLOC_H
32 # include <malloc.h>
33 # endif
34 #endif
35 #ifdef HAVE_STRING_H
36 # include <string.h>
37 #else
38 # ifdef HAVE_STRINGS_H
39 # include <strings.h>
40 # endif
41 #endif
42 #include "compat/strdup.h"
43 #include "compat/strsep.h"
44 #include "common/tag.h"
45 #include "common/eventlog.h"
46 #include "game.h"
47 #include "common/bnet_protocol.h"
48 #include "common/util.h"
49 #include "common/bn_type.h"
50 #include "common/xalloc.h"
51 #include "game_conv.h"
52 #include "common/setup_after.h"
53
54
bngreqtype_to_gtype(t_clienttag clienttag,unsigned short bngtype)55 extern t_game_type bngreqtype_to_gtype(t_clienttag clienttag, unsigned short bngtype)
56 {
57 char clienttag_str[5];
58
59 if (!clienttag)
60 {
61 eventlog(eventlog_level_error,__FUNCTION__,"got NULL clienttag");
62 return game_type_none;
63 }
64
65 if (clienttag==CLIENTTAG_WARCIIBNE_UINT)
66 {
67 switch (bngtype)
68 {
69 case CLIENT_GAMELISTREQ_ALL:
70 return game_type_all;
71 case CLIENT_GAMELISTREQ_TOPVBOT:
72 return game_type_topvbot;
73 case CLIENT_GAMELISTREQ_MELEE:
74 return game_type_melee;
75 case CLIENT_GAMELISTREQ_FFA:
76 return game_type_ffa;
77 case CLIENT_GAMELISTREQ_ONEONONE:
78 return game_type_oneonone;
79 case CLIENT_GAMELISTREQ_LADDER:
80 return game_type_ladder;
81 case CLIENT_GAMELISTREQ_IRONMAN:
82 return game_type_ironman;
83 case CLIENT_GAMELISTREQ_MAPSET:
84 return game_type_mapset;
85 default:
86 eventlog(eventlog_level_error,__FUNCTION__,"unknown Warcraft bnet game type \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),bngtype);
87 return game_type_none;
88 }
89 }
90 else if (clienttag==CLIENTTAG_DIABLO2DV_UINT ||
91 clienttag==CLIENTTAG_DIABLO2XP_UINT)
92 {
93 switch (bngtype)
94 {
95 case CLIENT_GAMELISTREQ_ALL:
96 return game_type_diablo2open;
97 default:
98 eventlog(eventlog_level_error,__FUNCTION__,"unknown Diablo II bnet game type \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),bngtype);
99 return game_type_none;
100 }
101 }
102 else if (clienttag==CLIENTTAG_DIABLORTL_UINT ||
103 clienttag==CLIENTTAG_DIABLOSHR_UINT)
104 {
105 switch (bngtype)
106 {
107 case CLIENT_GAMETYPE_DIABLO_0:
108 case CLIENT_GAMETYPE_DIABLO_1:
109 case CLIENT_GAMETYPE_DIABLO_2:
110 case CLIENT_GAMETYPE_DIABLO_3:
111 case CLIENT_GAMETYPE_DIABLO_4:
112 case CLIENT_GAMETYPE_DIABLO_5:
113 case CLIENT_GAMETYPE_DIABLO_6:
114 case CLIENT_GAMETYPE_DIABLO_7:
115 case CLIENT_GAMETYPE_DIABLO_8:
116 case CLIENT_GAMETYPE_DIABLO_9:
117 case CLIENT_GAMETYPE_DIABLO_a:
118 case CLIENT_GAMETYPE_DIABLO_b:
119 case CLIENT_GAMETYPE_DIABLO_c:
120 case CLIENT_GAMETYPE_DIABLO_d:
121 return game_type_diablo;
122 default:
123 eventlog(eventlog_level_error,__FUNCTION__,"unknown Diablo bnet game type \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),bngtype);
124 return game_type_none;
125 }
126 }
127 else if (clienttag==CLIENTTAG_STARCRAFT_UINT ||
128 clienttag==CLIENTTAG_BROODWARS_UINT ||
129 clienttag==CLIENTTAG_SHAREWARE_UINT)
130 {
131 switch (bngtype)
132 {
133 case CLIENT_GAMELISTREQ_ALL:
134 return game_type_all;
135 case CLIENT_GAMELISTREQ_MELEE:
136 return game_type_melee;
137 case CLIENT_GAMELISTREQ_FFA:
138 return game_type_ffa;
139 case CLIENT_GAMELISTREQ_ONEONONE:
140 return game_type_oneonone;
141 case CLIENT_GAMELISTREQ_CTF:
142 return game_type_ctf;
143 case CLIENT_GAMELISTREQ_GREED:
144 return game_type_greed;
145 case CLIENT_GAMELISTREQ_SLAUGHTER:
146 return game_type_slaughter;
147 case CLIENT_GAMELISTREQ_SDEATH:
148 return game_type_sdeath;
149 case CLIENT_GAMELISTREQ_LADDER:
150 return game_type_ladder;
151 case CLIENT_GAMELISTREQ_MAPSET:
152 return game_type_mapset;
153 case CLIENT_GAMELISTREQ_TEAMMELEE:
154 return game_type_teammelee;
155 case CLIENT_GAMELISTREQ_TEAMFFA:
156 return game_type_teamffa;
157 case CLIENT_GAMELISTREQ_TEAMCTF:
158 return game_type_teamctf;
159 case CLIENT_GAMELISTREQ_PGL:
160 return game_type_pgl;
161 case CLIENT_GAMELISTREQ_TOPVBOT:
162 return game_type_topvbot;
163 default:
164 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game type \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),bngtype);
165 return game_type_none;
166 }
167 }
168 else if (clienttag==CLIENTTAG_WARCRAFT3_UINT ||
169 clienttag==CLIENTTAG_WAR3XP_UINT)
170 {
171 return game_type_all;
172 }
173 else
174 {
175 eventlog(eventlog_level_error,__FUNCTION__,"unknown game clienttag \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),bngtype);
176 return game_type_none;
177 }
178 }
179
180
bngtype_to_gtype(t_clienttag clienttag,unsigned short bngtype)181 extern t_game_type bngtype_to_gtype(t_clienttag clienttag, unsigned short bngtype)
182 {
183 char clienttag_str[5];
184 if (!clienttag)
185 {
186 eventlog(eventlog_level_error,__FUNCTION__,"got NULL clienttag");
187 return game_type_none;
188 }
189
190 if (clienttag==CLIENTTAG_WARCIIBNE_UINT)
191 {
192 switch (bngtype)
193 {
194 case CLIENT_GAMELISTREQ_TOPVBOT:
195 return game_type_topvbot;
196 case CLIENT_GAMELISTREQ_MELEE:
197 return game_type_melee;
198 case CLIENT_GAMELISTREQ_FFA:
199 return game_type_ffa;
200 case CLIENT_GAMELISTREQ_ONEONONE:
201 return game_type_oneonone;
202 case CLIENT_GAMELISTREQ_LADDER:
203 return game_type_ladder;
204 case CLIENT_GAMELISTREQ_IRONMAN:
205 return game_type_ironman;
206 case CLIENT_GAMELISTREQ_MAPSET:
207 return game_type_mapset;
208 default:
209 eventlog(eventlog_level_error,__FUNCTION__,"unknown Warcraft bnet game type \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),bngtype);
210 return game_type_none;
211 }
212 }
213 else if (clienttag==CLIENTTAG_DIABLO2DV_UINT ||
214 clienttag==CLIENTTAG_DIABLO2XP_UINT)
215 {
216 switch (bngtype)
217 {
218 case CLIENT_GAMETYPE_DIABLO2_OPEN_NORMAL:
219 case CLIENT_GAMETYPE_DIABLO2_OPEN_NIGHTMARE:
220 case CLIENT_GAMETYPE_DIABLO2_OPEN_HELL:
221 return game_type_diablo2open;
222 case CLIENT_GAMETYPE_DIABLO2_CLOSE:
223 return game_type_diablo2closed;
224 default:
225 eventlog(eventlog_level_error,__FUNCTION__,"unknown Diablo II bnet game type \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),bngtype);
226 return game_type_none;
227 }
228 }
229 else if (clienttag==CLIENTTAG_DIABLORTL_UINT ||
230 clienttag==CLIENTTAG_DIABLOSHR_UINT)
231 {
232 switch (bngtype)
233 {
234 case CLIENT_GAMETYPE_DIABLO_0:
235 case CLIENT_GAMETYPE_DIABLO_1:
236 case CLIENT_GAMETYPE_DIABLO_2:
237 case CLIENT_GAMETYPE_DIABLO_3:
238 case CLIENT_GAMETYPE_DIABLO_4:
239 case CLIENT_GAMETYPE_DIABLO_5:
240 case CLIENT_GAMETYPE_DIABLO_6:
241 case CLIENT_GAMETYPE_DIABLO_7:
242 case CLIENT_GAMETYPE_DIABLO_8:
243 case CLIENT_GAMETYPE_DIABLO_9:
244 case CLIENT_GAMETYPE_DIABLO_a:
245 case CLIENT_GAMETYPE_DIABLO_b:
246 case CLIENT_GAMETYPE_DIABLO_c:
247 return game_type_diablo;
248 default:
249 eventlog(eventlog_level_error,__FUNCTION__,"unknown Diablo bnet game type \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),bngtype);
250 return game_type_none;
251 }
252 }
253 else if (clienttag==CLIENTTAG_STARCRAFT_UINT ||
254 clienttag==CLIENTTAG_BROODWARS_UINT ||
255 clienttag==CLIENTTAG_SHAREWARE_UINT)
256 {
257 switch (bngtype)
258 {
259 case CLIENT_GAMELISTREQ_ALL:
260 return game_type_all;
261 case CLIENT_GAMELISTREQ_MELEE:
262 return game_type_melee;
263 case CLIENT_GAMELISTREQ_FFA:
264 return game_type_ffa;
265 case CLIENT_GAMELISTREQ_ONEONONE:
266 return game_type_oneonone;
267 case CLIENT_GAMELISTREQ_CTF:
268 return game_type_ctf;
269 case CLIENT_GAMELISTREQ_GREED:
270 return game_type_greed;
271 case CLIENT_GAMELISTREQ_SLAUGHTER:
272 return game_type_slaughter;
273 case CLIENT_GAMELISTREQ_SDEATH:
274 return game_type_sdeath;
275 case CLIENT_GAMELISTREQ_LADDER:
276 return game_type_ladder;
277 case CLIENT_GAMELISTREQ_MAPSET:
278 return game_type_mapset;
279 case CLIENT_GAMELISTREQ_TEAMMELEE:
280 return game_type_teammelee;
281 case CLIENT_GAMELISTREQ_TEAMFFA:
282 return game_type_teamffa;
283 case CLIENT_GAMELISTREQ_TEAMCTF:
284 return game_type_teamctf;
285 case CLIENT_GAMELISTREQ_PGL:
286 return game_type_pgl;
287 case CLIENT_GAMELISTREQ_TOPVBOT:
288 return game_type_topvbot;
289 default:
290 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game type \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),bngtype);
291 return game_type_none;
292 }
293 }
294 else if (clienttag==CLIENTTAG_WARCRAFT3_UINT ||
295 clienttag==CLIENTTAG_WAR3XP_UINT)
296 {
297 return game_type_all;
298 }
299 else
300 {
301 eventlog(eventlog_level_error,__FUNCTION__,"unknown game clienttag \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),bngtype);
302 return game_type_none;
303 }
304 }
305
306
gtype_to_bngtype(t_game_type gtype)307 extern unsigned short gtype_to_bngtype(t_game_type gtype)
308 {
309 switch (gtype)
310 {
311 case game_type_all:
312 return CLIENT_GAMELISTREQ_ALL;
313 case game_type_melee:
314 return CLIENT_GAMELISTREQ_MELEE;
315 case game_type_ffa:
316 return CLIENT_GAMELISTREQ_FFA;
317 case game_type_oneonone:
318 return CLIENT_GAMELISTREQ_ONEONONE;
319 case game_type_ctf:
320 return CLIENT_GAMELISTREQ_CTF;
321 case game_type_greed:
322 return CLIENT_GAMELISTREQ_GREED;
323 case game_type_slaughter:
324 return CLIENT_GAMELISTREQ_SLAUGHTER;
325 case game_type_sdeath:
326 return CLIENT_GAMELISTREQ_SDEATH;
327 case game_type_ladder:
328 return CLIENT_GAMELISTREQ_LADDER;
329 case game_type_mapset:
330 return CLIENT_GAMELISTREQ_MAPSET;
331 case game_type_teammelee:
332 return CLIENT_GAMELISTREQ_TEAMMELEE;
333 case game_type_teamffa:
334 return CLIENT_GAMELISTREQ_TEAMFFA;
335 case game_type_teamctf:
336 return CLIENT_GAMELISTREQ_TEAMCTF;
337 case game_type_pgl:
338 return CLIENT_GAMELISTREQ_PGL;
339 case game_type_topvbot:
340 return CLIENT_GAMELISTREQ_TOPVBOT;
341 case game_type_diablo:
342 return CLIENT_GAMELISTREQ_DIABLO;
343 case game_type_diablo2open:
344 return SERVER_GAMELISTREPLY_TYPE_DIABLO2_OPEN;
345 case game_type_diablo2closed:
346 eventlog(eventlog_level_error,__FUNCTION__,"don't know how to list Diablo II");
347 return 0;
348 case game_type_anongame:
349 return 0;
350 case game_type_none:
351 default:
352 eventlog(eventlog_level_error,__FUNCTION__,"unknown game type %u",(unsigned int)gtype);
353 return 0xffff;
354 }
355 }
356
357
bngoption_to_goption(t_clienttag clienttag,t_game_type gtype,unsigned short bngoption)358 extern t_game_option bngoption_to_goption(t_clienttag clienttag, t_game_type gtype, unsigned short bngoption)
359 {
360 char clienttag_str[5];
361
362 if (!clienttag)
363 {
364 eventlog(eventlog_level_error,__FUNCTION__,"got NULL clienttag");
365 return game_option_none;
366 }
367
368 if (clienttag==CLIENTTAG_WARCIIBNE_UINT)
369 {
370 switch (gtype)
371 {
372 case game_type_topvbot:
373 switch (bngoption)
374 {
375 case CLIENT_STARTGAME4_OPTION_TOPVBOT_1:
376 return game_option_topvbot_1;
377 case CLIENT_STARTGAME4_OPTION_TOPVBOT_2:
378 return game_option_topvbot_2;
379 case CLIENT_STARTGAME4_OPTION_TOPVBOT_3:
380 return game_option_topvbot_3;
381 case CLIENT_STARTGAME4_OPTION_TOPVBOT_4:
382 return game_option_topvbot_4;
383 case CLIENT_STARTGAME4_OPTION_TOPVBOT_5:
384 return game_option_topvbot_5;
385 case CLIENT_STARTGAME4_OPTION_TOPVBOT_6:
386 return game_option_topvbot_6;
387 case CLIENT_STARTGAME4_OPTION_TOPVBOT_7:
388 return game_option_topvbot_7;
389 default:
390 eventlog(eventlog_level_error,__FUNCTION__,"unknown Warcraft II bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
391 return game_option_none;
392 }
393 case game_type_melee:
394 switch (bngoption)
395 {
396 case CLIENT_STARTGAME4_OPTION_MELEE_NORMAL:
397 return game_option_melee_normal;
398 default:
399 eventlog(eventlog_level_error,__FUNCTION__,"unknown Warcraft II bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
400 return game_option_none;
401 }
402 case game_type_ffa:
403 switch (bngoption)
404 {
405 case CLIENT_STARTGAME4_OPTION_FFA_NORMAL:
406 return game_option_ffa_normal;
407 default:
408 eventlog(eventlog_level_error,__FUNCTION__,"unknown Warcraft II bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
409 return game_option_none;
410 }
411 case game_type_oneonone:
412 switch (bngoption)
413 {
414 case CLIENT_STARTGAME4_OPTION_ONEONONE_NORMAL:
415 return game_option_oneonone_normal;
416 default:
417 eventlog(eventlog_level_error,__FUNCTION__,"unknown Warcraft II bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
418 return game_option_none;
419 }
420 case game_type_ladder:
421 switch (bngoption)
422 {
423 case CLIENT_STARTGAME4_OPTION_LADDER_COUNTASLOSS:
424 return game_option_ladder_countasloss;
425 case CLIENT_STARTGAME4_OPTION_LADDER_NOPENALTY:
426 return game_option_ladder_nopenalty;
427 default:
428 eventlog(eventlog_level_error,__FUNCTION__,"unknown Warcraft II bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
429 return game_option_none;
430 }
431 case game_type_ironman:
432 switch (bngoption)
433 {
434 default:
435 eventlog(eventlog_level_error,__FUNCTION__,"unknown Warcraft II bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
436 return game_option_none;
437 }
438 case game_type_mapset:
439 switch (bngoption)
440 {
441 case CLIENT_STARTGAME4_OPTION_MAPSET_NORMAL:
442 return game_option_mapset_normal;
443 default:
444 eventlog(eventlog_level_error,__FUNCTION__,"unknown Warcraft II bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
445 return game_option_none;
446 }
447 default:
448 eventlog(eventlog_level_error,__FUNCTION__,"unknown Warcraft II game type \"%s\" %u",tag_uint_to_str(clienttag_str,clienttag),(unsigned int)gtype);
449 return game_option_none;
450 }
451 }
452 else if (clienttag==CLIENTTAG_DIABLO2DV_UINT ||
453 clienttag==CLIENTTAG_DIABLO2XP_UINT)
454 {
455 switch (gtype)
456 {
457 case game_type_diablo2open:
458 switch (bngoption)
459 {
460 case CLIENT_STARTGAME4_OPTION_NONE: /* FIXME: really? */
461 return game_option_none;
462 default:
463 eventlog(eventlog_level_error,__FUNCTION__,"unknown Diablo II bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
464 return game_option_none;
465 }
466 case game_type_diablo2closed:
467 switch (bngoption)
468 {
469 case CLIENT_STARTGAME4_OPTION_NONE: /* FIXME: really? */
470 return game_option_none;
471 default:
472 eventlog(eventlog_level_error,__FUNCTION__,"unknown Diablo II bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
473 return game_option_none;
474 }
475 default:
476 eventlog(eventlog_level_error,__FUNCTION__,"unknown Diablo II game type \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),(unsigned int)gtype);
477 return game_option_none;
478 }
479 }
480 else if (clienttag==CLIENTTAG_DIABLORTL_UINT ||
481 clienttag==CLIENTTAG_DIABLOSHR_UINT)
482 {
483 switch (gtype)
484 {
485 case game_type_diablo:
486 switch (bngoption)
487 {
488 default:
489 /* diablo doesn't use any options */
490 return game_option_none;
491 }
492 default:
493 eventlog(eventlog_level_error,__FUNCTION__,"unknown Diablo game type \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),(unsigned int)gtype);
494 return game_option_none;
495 }
496 }
497 else if (clienttag==CLIENTTAG_STARCRAFT_UINT ||
498 clienttag==CLIENTTAG_BROODWARS_UINT ||
499 clienttag==CLIENTTAG_SHAREWARE_UINT)
500 {
501 switch (gtype)
502 {
503 case game_type_melee:
504 switch (bngoption)
505 {
506 case CLIENT_STARTGAME4_OPTION_MELEE_NORMAL:
507 return game_option_melee_normal;
508 default:
509 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
510 return game_option_none;
511 }
512 case game_type_ffa:
513 switch (bngoption)
514 {
515 case CLIENT_STARTGAME4_OPTION_FFA_NORMAL:
516 return game_option_ffa_normal;
517 default:
518 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
519 return game_option_none;
520 }
521 case game_type_oneonone:
522 switch (bngoption)
523 {
524 case CLIENT_STARTGAME4_OPTION_ONEONONE_NORMAL:
525 return game_option_oneonone_normal;
526 default:
527 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
528 return game_option_none;
529 }
530 case game_type_ctf:
531 switch (bngoption)
532 {
533 case CLIENT_STARTGAME4_OPTION_CTF_NORMAL:
534 return game_option_ctf_normal;
535 default:
536 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
537 return game_option_none;
538 }
539 case game_type_greed:
540 switch (bngoption)
541 {
542 case CLIENT_STARTGAME4_OPTION_GREED_10000:
543 return game_option_greed_10000;
544 case CLIENT_STARTGAME4_OPTION_GREED_7500:
545 return game_option_greed_7500;
546 case CLIENT_STARTGAME4_OPTION_GREED_5000:
547 return game_option_greed_5000;
548 case CLIENT_STARTGAME4_OPTION_GREED_2500:
549 return game_option_greed_2500;
550 default:
551 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
552 return game_option_none;
553 }
554 case game_type_slaughter:
555 switch (bngoption)
556 {
557 case CLIENT_STARTGAME4_OPTION_SLAUGHTER_60:
558 return game_option_slaughter_60;
559 case CLIENT_STARTGAME4_OPTION_SLAUGHTER_45:
560 return game_option_slaughter_45;
561 case CLIENT_STARTGAME4_OPTION_SLAUGHTER_30:
562 return game_option_slaughter_30;
563 case CLIENT_STARTGAME4_OPTION_SLAUGHTER_15:
564 return game_option_slaughter_15;
565 default:
566 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
567 return game_option_none;
568 }
569 case game_type_sdeath:
570 switch (bngoption)
571 {
572 case CLIENT_STARTGAME4_OPTION_SDEATH_NORMAL:
573 return game_option_sdeath_normal;
574 default:
575 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
576 return game_option_none;
577 }
578 case game_type_ladder:
579 switch (bngoption)
580 {
581 case CLIENT_STARTGAME4_OPTION_LADDER_COUNTASLOSS:
582 return game_option_ladder_countasloss;
583 case CLIENT_STARTGAME4_OPTION_LADDER_NOPENALTY:
584 return game_option_ladder_nopenalty;
585 default:
586 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
587 return game_option_none;
588 }
589 case game_type_mapset:
590 switch (bngoption)
591 {
592 case CLIENT_STARTGAME4_OPTION_MAPSET_NORMAL:
593 return game_option_mapset_normal;
594 default:
595 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
596 return game_option_none;
597 }
598 case game_type_teammelee:
599 switch (bngoption)
600 {
601 case CLIENT_STARTGAME4_OPTION_TEAMMELEE_4:
602 return game_option_teammelee_4;
603 case CLIENT_STARTGAME4_OPTION_TEAMMELEE_3:
604 return game_option_teammelee_3;
605 case CLIENT_STARTGAME4_OPTION_TEAMMELEE_2:
606 return game_option_teammelee_2;
607 default:
608 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
609 return game_option_none;
610 }
611 case game_type_teamffa:
612 switch (bngoption)
613 {
614 case CLIENT_STARTGAME4_OPTION_TEAMFFA_4:
615 return game_option_teamffa_4;
616 case CLIENT_STARTGAME4_OPTION_TEAMFFA_3:
617 return game_option_teamffa_3;
618 case CLIENT_STARTGAME4_OPTION_TEAMFFA_2:
619 return game_option_teamffa_2;
620 default:
621 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
622 return game_option_none;
623 }
624 case game_type_teamctf:
625 switch (bngoption)
626 {
627 case CLIENT_STARTGAME4_OPTION_TEAMCTF_4:
628 return game_option_teamctf_4;
629 case CLIENT_STARTGAME4_OPTION_TEAMCTF_3:
630 return game_option_teamctf_3;
631 case CLIENT_STARTGAME4_OPTION_TEAMCTF_2:
632 return game_option_teamctf_2;
633 default:
634 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
635 return game_option_none;
636 }
637 case game_type_pgl:
638 switch (bngoption)
639 {
640 default:
641 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
642 return game_option_none;
643 }
644 case game_type_topvbot:
645 switch (bngoption)
646 {
647 case CLIENT_STARTGAME4_OPTION_TOPVBOT_1:
648 return game_option_topvbot_1;
649 case CLIENT_STARTGAME4_OPTION_TOPVBOT_2:
650 return game_option_topvbot_2;
651 case CLIENT_STARTGAME4_OPTION_TOPVBOT_3:
652 return game_option_topvbot_3;
653 case CLIENT_STARTGAME4_OPTION_TOPVBOT_4:
654 return game_option_topvbot_4;
655 case CLIENT_STARTGAME4_OPTION_TOPVBOT_5:
656 return game_option_topvbot_5;
657 case CLIENT_STARTGAME4_OPTION_TOPVBOT_6:
658 return game_option_topvbot_6;
659 case CLIENT_STARTGAME4_OPTION_TOPVBOT_7:
660 return game_option_topvbot_7;
661 default:
662 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft bnet game option for \"%s\" game \"%s\" %hu",tag_uint_to_str(clienttag_str,clienttag),game_type_get_str(gtype),bngoption);
663 return game_option_none;
664 }
665 case game_type_none:
666 default:
667 eventlog(eventlog_level_error,__FUNCTION__,"unknown Starcraft game type \"%s\" %u(%s)",tag_uint_to_str(clienttag_str,clienttag),(unsigned int)gtype,game_type_get_str(gtype));
668 return game_option_none;
669 }
670 }
671 else if (clienttag==CLIENTTAG_WARCRAFT3_UINT ||
672 clienttag==CLIENTTAG_WAR3XP_UINT)
673 {
674 return game_option_none;
675 }
676 else
677 {
678 eventlog(eventlog_level_error,__FUNCTION__,"unknown game clienttag \"%s\" %u",tag_uint_to_str(clienttag_str,clienttag),(unsigned int)gtype);
679 return game_option_none;
680 }
681 }
682
683
bngresult_to_gresult(unsigned int bngresult)684 extern t_game_result bngresult_to_gresult(unsigned int bngresult)
685 {
686 switch (bngresult)
687 {
688 case CLIENT_GAME_REPORT_RESULT_PLAYING:
689 return game_result_playing;
690 case CLIENT_GAME_REPORT_RESULT_WIN:
691 return game_result_win;
692 case CLIENT_GAME_REPORT_RESULT_LOSS:
693 return game_result_loss;
694 case CLIENT_GAME_REPORT_RESULT_DRAW:
695 return game_result_draw;
696 case CLIENT_GAME_REPORT_RESULT_DISCONNECT:
697 return game_result_disconnect;
698 case CLIENT_GAME_REPORT_RESULT_OBSERVER:
699 return game_result_observer;
700 default:
701 eventlog(eventlog_level_error,__FUNCTION__,"unknown bnet game result %u",bngresult);
702 return game_result_disconnect; /* bad packet? */
703 }
704 }
705
706
bngmaptype_to_gmaptype(unsigned int bngmaptype)707 extern t_game_maptype bngmaptype_to_gmaptype(unsigned int bngmaptype)
708 {
709 switch (bngmaptype)
710 {
711 case CLIENT_MAPTYPE_SELFMADE:
712 return game_maptype_selfmade;
713 case CLIENT_MAPTYPE_BLIZZARD:
714 return game_maptype_blizzard;
715 case CLIENT_MAPTYPE_LADDER:
716 return game_maptype_ladder;
717 case CLIENT_MAPTYPE_PGL:
718 return game_maptype_pgl;
719 case CLIENT_MAPTYPE_KBK:
720 return game_maptype_kbk;
721 case CLIENT_MAPTYPE_CompUSA:
722 return game_maptype_compusa;
723 default:
724 return game_maptype_none;
725 }
726 }
727
728
bngtileset_to_gtileset(unsigned int bngtileset)729 extern t_game_tileset bngtileset_to_gtileset(unsigned int bngtileset)
730 {
731 switch (bngtileset)
732 {
733 case CLIENT_TILESET_BADLANDS:
734 return game_tileset_badlands;
735 case CLIENT_TILESET_SPACE:
736 return game_tileset_space;
737 case CLIENT_TILESET_INSTALLATION:
738 return game_tileset_installation;
739 case CLIENT_TILESET_ASHWORLD:
740 return game_tileset_ashworld;
741 case CLIENT_TILESET_JUNGLE:
742 return game_tileset_jungle;
743 case CLIENT_TILESET_DESERT:
744 return game_tileset_desert;
745 case CLIENT_TILESET_ICE:
746 return game_tileset_ice;
747 case CLIENT_TILESET_TWILIGHT:
748 return game_tileset_twilight;
749 default:
750 return game_tileset_none;
751 }
752 }
753
754
bngspeed_to_gspeed(unsigned int bngspeed)755 extern t_game_speed bngspeed_to_gspeed(unsigned int bngspeed)
756 {
757 switch (bngspeed)
758 {
759 case CLIENT_GAMESPEED_SLOWEST:
760 return game_speed_slowest;
761 case CLIENT_GAMESPEED_SLOWER:
762 return game_speed_slower;
763 case CLIENT_GAMESPEED_SLOW:
764 return game_speed_slow;
765 case CLIENT_GAMESPEED_NORMAL:
766 return game_speed_normal;
767 case CLIENT_GAMESPEED_FAST:
768 return game_speed_fast;
769 case CLIENT_GAMESPEED_FASTER:
770 return game_speed_faster;
771 case CLIENT_GAMESPEED_FASTEST:
772 return game_speed_fastest;
773 default:
774 return game_speed_none;
775 }
776 }
777
w3speed_to_gspeed(unsigned int w3speed)778 t_game_speed w3speed_to_gspeed(unsigned int w3speed)
779 {
780 switch (w3speed)
781 {
782 case 0: return game_speed_slow;
783 case 1: return game_speed_normal;
784 case 2: return game_speed_fast;
785 default: return game_speed_none;
786 }
787 }
788
789
bngdifficulty_to_gdifficulty(unsigned int bngdifficulty)790 extern t_game_difficulty bngdifficulty_to_gdifficulty(unsigned int bngdifficulty)
791 {
792 switch (bngdifficulty)
793 {
794 case CLIENT_DIFFICULTY_NORMAL:
795 return game_difficulty_normal;
796 case CLIENT_DIFFICULTY_NIGHTMARE:
797 return game_difficulty_nightmare;
798 case CLIENT_DIFFICULTY_HELL:
799 return game_difficulty_hell;
800 case CLIENT_DIFFICULTY_HARDCORE_NORMAL:
801 return game_difficulty_hardcore_normal;
802 case CLIENT_DIFFICULTY_HARDCORE_NIGHTMARE:
803 return game_difficulty_hardcore_nightmare;
804 case CLIENT_DIFFICULTY_HARDCORE_HELL:
805 return game_difficulty_hardcore_hell;
806 default:
807 return game_difficulty_none;
808 }
809 }
810
811
_w3_decrypt_mapinfo(const char * enc)812 static const char * _w3_decrypt_mapinfo(const char *enc)
813 {
814 char *mapinfo;
815 char *dec;
816 unsigned pos;
817 unsigned char bitmask;
818
819 if (!(mapinfo = xstrdup(enc))) {
820 eventlog(eventlog_level_error, __FUNCTION__, "not enough memory to setup temporary buffer");
821 return NULL;
822 }
823
824 dec = mapinfo;
825 pos = 0;
826 bitmask = 0; /* stupid gcc warning */
827 while(*enc)
828 {
829 if (pos % 8)
830 {
831 *dec = *enc;
832 if (!(bitmask & 0x1)) (*dec)--;
833 dec++;
834 bitmask >>= 1;
835 } else
836 bitmask = *enc >> 1;
837 enc++;
838 pos++;
839 }
840 *dec = '\0';
841
842 return mapinfo;
843 }
844
845
game_parse_info(t_game * game,char const * gameinfo)846 extern int game_parse_info(t_game * game, char const * gameinfo)
847 {
848 t_clienttag clienttag;
849 char * save;
850 char * line1;
851 char * line2;
852 char * currtok;
853 char const * unknown;
854 char const * mapsize;
855 char const * maxplayers;
856 char const * speed;
857 char const * maptype;
858 char const * gametype;
859 char const * option;
860 char const * checksum;
861 char const * tileset;
862 char const * player;
863 char const * mapname;
864 unsigned int bngmapsize;
865 unsigned int bngmaxplayers;
866 unsigned int bngspeed;
867 unsigned int bngmaptype;
868 unsigned int bngtileset;
869
870 if (!game)
871 {
872 eventlog(eventlog_level_error,__FUNCTION__,"got NULL game");
873 return -1;
874 }
875 if (!gameinfo)
876 {
877 eventlog(eventlog_level_error,__FUNCTION__,"got NULL gameinfo");
878 return -1;
879 }
880
881 /*
882
883 BW 104:
884 9: recv class=bnet[0x01] type=CLIENT_STARTGAME4[0x1cff] length=74
885 0000: FF 1C 4A 00 00 00 00 00 00 00 00 00 09 00 01 00 ..J.............
886 0010: 00 00 00 00 01 00 00 00 4E 4F 50 45 4E 41 4C 54 ........NOPENALT
887 0020: 59 00 00 2C 34 34 2C 31 34 2C 2C 32 2C 39 2C 31 Y..,44,14,,2,9,1
888 0030: 2C 33 65 33 37 61 38 34 63 2C 33 2C 52 6F 73 73 ,3e37a84c,3,Ross
889 0040: 0D 41 73 68 72 69 67 6F 0D 00 .Ashrigo..
890
891 Diablo:
892 7: cli class=bnet[0x01] type=CLIENT_STARTGAME3[0x1aff] length=105
893 0000: FF 1A 69 00 01 00 00 00 00 00 00 00 00 00 00 00 ..i.............
894 0010: 0F 00 00 00 00 00 00 00 E0 17 00 00 61 73 64 66 ............asdf
895 0020: 61 73 64 66 61 73 64 66 61 73 64 66 32 00 61 73 asdfasdfasdf2.as
896 0030: 64 66 61 73 64 66 73 61 64 66 61 73 64 66 32 00 dfasdfsadfasdf2.
897 0040: 30 0D 7A 62 6E 7A 62 6E 7A 62 6E 0D 4C 54 52 44 0.zbnzbnzbn.LTRD
898 0050: 20 31 20 30 20 30 20 33 30 20 31 30 20 32 30 20 1 0 0 30 10 20
899 0060: 32 35 20 31 30 30 20 30 00 25 100 0.
900
901 10: recv class=bnet[0x01] type=CLIENT_STARTGAME3[0x1aff] length=72
902 0000: FF 1A 48 00 00 00 00 00 00 00 00 00 00 00 00 00 ..H.............
903 0010: 0F 00 00 00 00 00 00 00 E0 17 00 00 61 6E 73 00 ............ans.
904 0020: 00 30 0D 77 61 72 72 69 6F 72 0D 4C 54 52 44 20 .0.warrior.LTRD
905 0030: 31 20 30 20 30 20 33 30 20 31 30 20 32 30 20 32 1 0 0 30 10 20 2
906 0040: 35 20 31 30 30 20 30 00 5 100 0.
907
908
909 Warcraft:
910 4: srv class=bnet[0x01] type=SERVER_GAMELISTREPLY[0x09ff] length=524
911 0000: FF 09 0C 02 05 00 00 00 02 00 01 00 09 04 00 00 ................
912 0010: 02 00 17 E0 D0 C6 66 F0 00 00 00 00 00 00 00 00 ......f.........
913 0020: 04 00 00 00 74 00 00 00 48 65 79 77 6F 6F 64 73 ....t...Heywoods
914 0030: 20 47 4F 57 32 76 32 00 00 2C 2C 2C 36 2C 32 2C GOW2v2..,,,6,2,
915 0040: 32 2C 31 2C 31 39 37 33 64 35 66 32 2C 33 30 30 2,1,1973d5f2,300
916 0050: 30 2C 48 65 79 77 6F 6F 64 0D 47 61 72 64 65 6E 0,Heywood.Garden
917 0060: 20 6F 66 20 77 61 72 20 42 4E 45 2E 70 75 64 0D of war BNE.pud.
918 0070: 00 09 00 02 00 09 04 00 00 02 00 17 E0 CF 45 3E ..............E>
919 0080: 65 00 00 00 00 00 00 00 00 10 00 00 00 11 00 00 e...............
920 0090: 00 67 6F 77 20 6C 61 64 64 65 72 20 31 76 31 00 .gow ladder 1v1.
921 00A0: 00 2C 2C 2C 36 2C 32 2C 39 2C 32 2C 65 66 38 34 .,,,6,2,9,2,ef84
922 00B0: 33 61 35 33 2C 2C 77 63 73 63 6D 61 73 74 65 72 3a53,,wcscmaster
923 00C0: 0D 47 61 72 64 65 6E 20 6F 66 20 77 61 72 20 42 .Garden of war B
924 00D0: 4E 45 2E 70 75 64 0D 00 09 00 01 00 09 04 00 00 NE.pud..........
925 00E0: 02 00 17 E0 98 CE 7C E2 00 00 00 00 00 00 00 00 ......|.........
926 00F0: 04 00 00 00 4D 00 00 00 4C 61 64 64 65 72 20 46 ....M...Ladder F
927 0100: 46 41 20 6F 6E 6C 79 00 00 2C 2C 2C 36 2C 32 2C FA only..,,,6,2,
928 0110: 39 2C 31 2C 61 65 32 66 61 61 62 37 2C 2C 6B 69 9,1,ae2faab7,,ki
929 0120: 6C 6F 67 72 61 6D 0D 50 6C 61 69 6E 73 20 6F 66 logram.Plains of
930 0130: 20 73 6E 6F 77 20 42 4E 45 2E 70 75 64 0D 00 0F snow BNE.pud...
931 0140: 00 04 00 09 04 00 00 02 00 17 E0 C6 0B 13 3C 00 ..............<.
932 0150: 00 00 00 00 00 00 00 04 00 00 00 BE 00 00 00 4C ...............L
933 0160: 61 64 64 65 72 20 31 20 6F 6E 20 31 00 00 2C 2C adder 1 on 1..,,
934 0170: 2C 36 2C 32 2C 66 2C 34 2C 66 63 63 35 38 65 34 ,6,2,f,4,fcc58e4
935 0180: 61 2C 37 32 30 30 2C 49 63 65 36 39 62 75 72 67 a,7200,Ice69burg
936 0190: 0D 46 6F 72 65 73 74 20 54 72 61 69 6C 20 42 4E .Forest Trail BN
937 01A0: 45 2E 70 75 64 0D 00 0F 00 04 00 09 04 00 00 02 E.pud...........
938 01B0: 00 04 15 D1 F4 B6 6A 00 00 00 00 00 00 00 00 04 ......j.........
939 01C0: 00 00 00 C8 03 00 00 52 6F 63 6B 20 49 74 21 21 .......Rock It!!
940 01D0: 20 32 76 32 2B 00 00 2C 2C 2C 38 2C 31 2C 66 2C 2v2+..,,,8,1,f,
941 01E0: 34 2C 62 30 36 38 63 62 34 62 2C 66 30 30 30 2C 4,b068cb4b,f000,
942 01F0: 6E 75 66 74 63 72 6F 77 0D 43 72 6F 73 73 68 61 nuftcrow.Crossha
943 0200: 69 72 20 42 4E 45 2E 70 75 64 0D 00 ir BNE.pud..
944
945 FIXME:
946 Note the map size and max players fields are empty. Does WCII have different
947 map sizes and starting positions? If so, are they reported here?
948 Also note the map tileset is "3000". Maybe this isn't the tileset for WCII
949 but instead the starting gold or something.
950
951 FIXME:
952 Also, what is the upper player limit on WCII... 8 like on Starcraft?
953 */
954
955 if (!(clienttag = game_get_clienttag(game)))
956 {
957 eventlog(eventlog_level_error,__FUNCTION__,"NULL clienttag for game?");
958 return -1;
959 }
960
961 if (clienttag==CLIENTTAG_DIABLORTL_UINT ||
962 clienttag==CLIENTTAG_DIABLOSHR_UINT)
963 {
964 game_set_maxplayers(game,4);
965 eventlog(eventlog_level_debug,__FUNCTION__,"no gameinfo for Diablo");
966 return 0;
967 }
968 else if (clienttag==CLIENTTAG_DIABLO2DV_UINT ||
969 clienttag==CLIENTTAG_DIABLO2XP_UINT)
970 {
971 if ((game->type == game_type_diablo2closed) &&
972 (!strlen(gameinfo)))
973
974 {
975 /* D2 closed games are handled by d2cs so we can have only have a generic startgame4
976 without any info :(, this fix also a memory leak for description allocation */
977 game_set_difficulty(game,game_difficulty_none);
978 game_set_description(game, "");
979 }
980 else
981 {
982 char difficulty[2];
983 unsigned int bngdifficulty;
984
985 if (!strlen(gameinfo))
986 {
987 eventlog(eventlog_level_info,__FUNCTION__, "got empty gameinfo (from D2 client)");
988 return -1;
989 }
990
991 difficulty[0] = gameinfo[0];
992 difficulty[1] = '\0';
993 if (str_to_uint(difficulty,&bngdifficulty)<0)
994 {
995 eventlog(eventlog_level_error,__FUNCTION__,"bad gameinfo format (missing difficulty) \"%s\"",gameinfo);
996 return -1;
997 }
998 game_set_difficulty(game,bngdifficulty);
999 game_set_description(game,&gameinfo[1]);
1000
1001 if ((game->type == game_type_diablo2closed))
1002 {
1003 eventlog(eventlog_level_debug,__FUNCTION__,"D2 bug workarround needed (open games tagged as closed)");
1004 game->type = game_type_diablo2open;
1005 }
1006 }
1007 return 0;
1008 }
1009 else if (clienttag==CLIENTTAG_WARCRAFT3_UINT ||
1010 clienttag==CLIENTTAG_WAR3XP_UINT)
1011 {
1012 /* Warcraft 3 game info format -- by Soar
1013 0x00 -- 1 byte (char, Empty slots)
1014 0x01 -- 8 bytes (char[8], Count of games created)
1015
1016 From offset 0x11 there is a bitmask byte before every 7 bytes, offset 0x09 to 0x10 also has bitmask 0.
1017 Bit 0 corresponds to byte 0, bit 1 to byte 1, and so on.
1018 Except offset 0x09, only Byte 1-7 contribute to the info data, bit 0 seems to be always 1;
1019 Decoding these bytes works as follows:
1020 If the corresponding bit is a '1' then the character is moved over directly.
1021 If the corresponding bit is a '0' then subtract 1 from the character.
1022 (We decode info data and remove the bitmask bytes from info data in following description)
1023 0x09 -- 5 bytes (char[5], map options)
1024 0x0e -- 1 bytes (0, seems to be a seperate sign)
1025 0x0f -- 2 bytes (short, mapsize x)
1026 0x11 -- 2 bytes (short, mapsize y)
1027 0x13 -- 4 bytes (long, unknown, map checksum ?)
1028 0x17 -- n bytes (string, mapname \0 terminated)
1029 0x17+n -- m bytes (string, game creator \0 terminated, but we already set this to game before, :P)
1030 0x17+n+m -- 2 bytes: \0 \0 (first \0 might be a reserved string for password, but blizzard didn't implement it, second \0 is the info string end sign)
1031 */
1032 const char *pstr;
1033
1034 if (!strlen(gameinfo))
1035 {
1036 eventlog(eventlog_level_info,__FUNCTION__, "got empty gameinfo (from W3 client)");
1037 return -1;
1038 }
1039
1040 if (strlen(gameinfo) < 0xf + 2 + 1 + 2 + 4) {
1041 eventlog(eventlog_level_error, __FUNCTION__, "got too short W3 mapinfo");
1042 return -1;
1043 }
1044 pstr = gameinfo + 9;
1045 pstr = _w3_decrypt_mapinfo(pstr);
1046 if (!pstr) return -1;
1047 /* after decryption we dont have the mask bytes anymore so offsets need
1048 * to be adjusted acordingly */
1049 game_set_speed(game,w3speed_to_gspeed(bn_byte_get(*((bn_byte*)(pstr)))));
1050 game_set_mapsize_x(game, bn_short_get(*((bn_short*)(pstr + 5))));
1051 game_set_mapsize_y(game, bn_short_get(*((bn_short*)(pstr + 7))));
1052 game_set_mapname(game, pstr + 13);
1053 xfree((void*)pstr);
1054
1055 return 0;
1056 }
1057
1058 /* otherwise it's Starcraft, Brood War, or Warcraft II */
1059 if (!(save = xstrdup(gameinfo)))
1060 {
1061 eventlog(eventlog_level_error,__FUNCTION__,"could not allocate memory for save");
1062 return -1;
1063 }
1064
1065 if (!(line1 = strtok(save,"\r"))) /* actual game info fields */
1066 {
1067 eventlog(eventlog_level_error,__FUNCTION__,"bad gameinfo format (missing line1) \"%s\"",gameinfo);
1068 xfree(save);
1069 return -1;
1070 }
1071 if (!(line2 = strtok(NULL,"\r")))
1072 {
1073 eventlog(eventlog_level_error,__FUNCTION__,"bad gameinfo format (missing player) \"%s\"",gameinfo);
1074 xfree(save);
1075 return -1;
1076 }
1077 /* is there room for another field after that? */
1078
1079 /*
1080 * This is the same as the normal strtok() function but it doesn't skip over
1081 * empty entries. The C-library strtok() will skip past entries like 12,,3
1082 * and rather than you being able to get "12", "", "3" you get "12", "3".
1083 * Since some values returned by the client contain these empty entries we
1084 * need this. Unlike strtok() all state is recorded in the first argument.
1085 */
1086 currtok = line1;
1087 if (!(unknown = strsep(&currtok,","))) /* skip past first field (always empty?) */
1088 {
1089 eventlog(eventlog_level_error,__FUNCTION__,"bad gameinfo format (missing unknown)");
1090 xfree(save);
1091 return -1;
1092 }
1093 if (!(mapsize = strsep(&currtok,",")))
1094 {
1095 eventlog(eventlog_level_error,__FUNCTION__,"bad gameinfo format (missing mapsize)");
1096 xfree(save);
1097 return -1;
1098 }
1099 if (!(maxplayers = strsep(&currtok,","))) /* for later use (FIXME: what is upper field, max observers?) */
1100 {
1101 eventlog(eventlog_level_error,__FUNCTION__,"bad gameinfo format (missing maxplayers)");
1102 xfree(save);
1103 return -1;
1104 }
1105 if (!(speed = strsep(&currtok,",")))
1106 {
1107 eventlog(eventlog_level_error,__FUNCTION__,"bad gameinfo format (missing speed)");
1108 xfree(save);
1109 return -1;
1110 }
1111 if (!(maptype = strsep(&currtok,",")))
1112 {
1113 eventlog(eventlog_level_error,__FUNCTION__,"bad gameinfo format (missing maptype)");
1114 xfree(save);
1115 return -1;
1116 }
1117 if (!(gametype = strsep(&currtok,","))) /* this is set from another field */
1118 {
1119 eventlog(eventlog_level_error,__FUNCTION__,"bad gameinfo format (missing gametype)");
1120 xfree(save);
1121 return -1;
1122 }
1123 if (!(option = strsep(&currtok,","))) /* this is set from another field */
1124 {
1125 eventlog(eventlog_level_error,__FUNCTION__,"bad gameinfo format (missing option)");
1126 xfree(save);
1127 return -1;
1128 }
1129 if (!(checksum = strsep(&currtok,","))) /* FIXME */
1130 {
1131 eventlog(eventlog_level_error,__FUNCTION__,"bad gameinfo format (missing checksum)");
1132 xfree(save);
1133 return -1;
1134 }
1135 if (!(tileset = strsep(&currtok,",")))
1136 {
1137 eventlog(eventlog_level_error,__FUNCTION__,"bad gameinfo format (missing tileset)");
1138 xfree(save);
1139 return -1;
1140 }
1141 if (!(player = strsep(&currtok,",")))
1142 {
1143 eventlog(eventlog_level_error,__FUNCTION__,"bad gameinfo format (missing player)");
1144 xfree(save);
1145 return -1;
1146 }
1147
1148 mapname = line2; /* only one item on this line */
1149
1150 eventlog(eventlog_level_debug,__FUNCTION__,"got info \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"", mapsize, maxplayers, speed, maptype, gametype, option, checksum, tileset, player, mapname);
1151
1152 /* The map size is determined by breaking the number into two pieces and
1153 * multiplying each piece by 32.
1154 * for example, 34 = (32*3) x (32*4) = 96 x 128
1155 */
1156 /* special handling for mapsize. empty is 256x256 */
1157 if ((mapsize[0]=='\0') || (str_to_uint(mapsize,&bngmapsize)<0))
1158 bngmapsize = 88; /* 256x256 */
1159 game_set_mapsize_x(game,(bngmapsize/10)*32);
1160 game_set_mapsize_y(game,(bngmapsize%10)*32);
1161
1162 /* special handling for maxplayers, empty is 8 */
1163 if ((maxplayers[0]=='\0') || (str_to_uint(maxplayers,&bngmaxplayers)<0))
1164 bngmaxplayers = 8;
1165 game_set_maxplayers(game,(bngmaxplayers%10));
1166
1167 /* special handling for gamespeed. empty is fast */
1168 if ((speed[0]=='\0') || ( str_to_uint(speed,&bngspeed)<0))
1169 bngspeed = CLIENT_GAMESPEED_FAST;
1170 game_set_speed(game,bngspeed_to_gspeed(bngspeed));
1171
1172 /* special handling for maptype. empty is self-made */
1173 if ((maptype[0]=='\0') || (str_to_uint(maptype,&bngmaptype)<0))
1174 bngmaptype = CLIENT_MAPTYPE_SELFMADE;
1175 game_set_maptype(game,bngmaptype_to_gmaptype(bngmaptype));
1176
1177 /* special handling for tileset. empty is badlands */
1178 if ((tileset[0]=='\0') || (str_to_uint(tileset,&bngtileset)<0))
1179 bngtileset = CLIENT_TILESET_BADLANDS;
1180 game_set_tileset(game,bngtileset_to_gtileset(bngtileset));
1181
1182 game_set_mapname(game,mapname);
1183
1184 xfree(save);
1185
1186 return 0;
1187 }
1188