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