1 /*
2  * Copyright (C) 2004 CreepLord (creeplord@pvpgn.org)
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 #ifdef HAVE_STRING_H
20 # include <string.h>
21 #else
22 # ifdef HAVE_STRINGS_H
23 #  include <strings.h>
24 # endif
25 #endif
26 #include <errno.h>
27 #ifdef STDC_HEADERS
28 # include <stdlib.h>
29 #else
30 # ifdef HAVE_MALLOC_H
31 #  include <malloc.h>
32 # endif
33 #endif
34 #include "common/bn_type.h"
35 #include "common/eventlog.h"
36 #include "common/packet.h"
37 #include "common/queue.h"
38 #include "common/tag.h"
39 #include "common/list.h"
40 #include "common/util.h"
41 #include "common/xalloc.h"
42 #include "common/bnettime.h"
43 #include "connection.h"
44 #include "team.h"
45 #include "account.h"
46 #include "account_wrap.h"
47 #include "channel.h"
48 #include "anongame.h"
49 #include "anongame_infos.h"
50 #include "anongame_maplists.h"
51 #include "handle_anongame.h"
52 #include "tournament.h"
53 #include "server.h"
54 #include "clan.h"
55 #include "common/setup_after.h"
56 
57 /* option - handling function */
58 
59 /* 0x00 */ /* PG style search - handle_anongame_search() in anongame.c */
60 /* 0x01 */ /* server side packet sent from handle_anongame_search() in anongame.c */
61 /* 0x02 */ static int _client_anongame_infos(t_connection * c, t_packet const * const packet);
62 /* 0x03 */ static int _client_anongame_cancel(t_connection * c);
63 /* 0x04 */ static int _client_anongame_profile(t_connection * c, t_packet const * const packet);
64 /* 0x05 */ /* AT style search - handle_anongame_search() in anongame.c */
65 /* 0x06 */ /* AT style search (Inviter) handle_anongame_search() in anongame.c */
66 /* 0x07 */ static int _client_anongame_tournament(t_connection * c, t_packet const * const packet);
67 /* 0x08 */ static int _client_anongame_profile_clan(t_connection * c, t_packet const * const packet);
68 /* 0x09 */ static int _client_anongame_get_icon(t_connection * c, t_packet const * const packet);
69 /* 0x0A */ static int _client_anongame_set_icon(t_connection * c, t_packet const * const packet);
70 
71 /* misc functions used by _client_anongame_tournament() */
72 static unsigned int _tournament_time_convert(unsigned int time);
73 
74 /* and now the functions */
75 
_client_anongame_profile_clan(t_connection * c,t_packet const * const packet)76 static int _client_anongame_profile_clan(t_connection * c, t_packet const * const packet)
77 {
78     t_packet * rpacket;
79     int clantag;
80     int clienttag;
81     int count;
82     int temp;
83     t_clan * clan;
84     unsigned char rescount;
85 
86     if (packet_get_size(packet)<sizeof(t_client_findanongame_profile_clan))
87     {
88 	eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad ANONGAME_PROFILE_CLAN packet (expected %u bytes, got %u)",conn_get_socket(c), sizeof(t_client_findanongame_profile_clan), packet_get_size(packet));
89 	return -1;
90     }
91 
92     clantag = bn_int_get(packet->u.client_findanongame_profile_clan.clantag);
93     clienttag = bn_int_get(packet->u.client_findanongame_profile_clan.clienttag);
94     count = bn_int_get(packet->u.server_findanongame_profile_clan.count);
95     clan = clanlist_find_clan_by_clantag(clantag);
96 
97     if ((rpacket = packet_create(packet_class_bnet)))
98     {
99 	packet_set_size(rpacket,sizeof(t_server_findanongame_profile_clan));
100 	packet_set_type(rpacket,SERVER_FINDANONGAME_PROFILE_CLAN);
101 	bn_byte_set(&rpacket->u.server_findanongame_profile_clan.option,CLIENT_FINDANONGAME_PROFILE_CLAN);
102 	bn_int_set(&rpacket->u.server_findanongame_profile_clan.count,count);
103 	rescount = 0;
104 
105 	if (!(clan))
106 	{
107 	   temp = 0;
108 	   packet_append_data(rpacket,&temp,1);
109 	}
110 	else
111 	{
112 	   temp = 0;
113 	   packet_append_data(rpacket,&temp,1);
114 
115 	   /* need to add clan stuff here:
116 	   	format:
117 		bn_int	ladder_tag (SNLC, 2NLC, 3NLC, 4NLC)
118 		bn_int	wins
119 		bn_int	losses
120 		bn_byte rank
121 		bn_byte progess bar
122 		bn_int	xp
123 		bn_int	rank
124 		bn_byte 0x06 <-- random + 5 races
125 		6 times:
126 		bn_int  wins
127 		bn_int	losses
128 	    */
129 	}
130 
131 	bn_byte_set(&rpacket->u.server_findanongame_profile_clan.rescount,rescount);
132 
133 
134 	conn_push_outqueue(c,rpacket);
135 	packet_del_ref(rpacket);
136     }
137 
138    return 0;
139 }
140 
_client_anongame_profile(t_connection * c,t_packet const * const packet)141 static int _client_anongame_profile(t_connection * c, t_packet const * const packet)
142 {
143     t_packet * rpacket;
144     char const * username;
145     int Count, i;
146     int temp;
147     t_account * account;
148     t_connection * dest_c;
149     t_clienttag ctag;
150     char clienttag_str[5];
151     t_list * teamlist;
152     unsigned char teamcount;
153     unsigned char *atcountp;
154     t_elem * curr;
155     t_team * team;
156     t_bnettime bn_time;
157     bn_long ltime;
158 
159 
160     Count = bn_int_get(packet->u.client_findanongame.count);
161     eventlog(eventlog_level_info,__FUNCTION__,"[%d] got a FINDANONGAME PROFILE packet",conn_get_socket(c));
162 
163     if (!(username = packet_get_str_const(packet,sizeof(t_client_findanongame_profile),USER_NAME_MAX)))
164     {
165 	eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad FINDANONGAME_PROFILE (missing or too long username)",conn_get_socket(c));
166 	return -1;
167     }
168 
169     //If no account is found then break
170     if (!(account = accountlist_find_account(username)))
171     {
172 	eventlog(eventlog_level_error, __FUNCTION__, "Could not get account - PROFILE");
173 	return -1;
174     }
175 
176     if (!(dest_c = connlist_find_connection_by_accountname(username))) {
177 	eventlog(eventlog_level_debug, __FUNCTION__, "account is offline -  try ll_clienttag");
178 	if (!(ctag = account_get_ll_clienttag(account))) return -1;
179     }
180     else
181     ctag = conn_get_clienttag(dest_c);
182 
183     eventlog(eventlog_level_info,__FUNCTION__,"Looking up %s's %s Stats.",username,tag_uint_to_str(clienttag_str,ctag));
184 
185     if (account_get_ladder_level(account,ctag,ladder_id_solo)<=0 &&
186         account_get_ladder_level(account,ctag,ladder_id_team)<=0 &&
187         account_get_ladder_level(account,ctag,ladder_id_ffa)<=0 &&
188 	account_get_teams(account)==NULL)
189     {
190 	eventlog(eventlog_level_info,__FUNCTION__,"%s does not have WAR3 Stats.",username);
191 	if (!(rpacket = packet_create(packet_class_bnet)))
192 	    return -1;
193 	packet_set_size(rpacket,sizeof(t_server_findanongame_profile2));
194 	packet_set_type(rpacket,SERVER_FINDANONGAME_PROFILE);
195 	bn_byte_set(&rpacket->u.server_findanongame_profile2.option,CLIENT_FINDANONGAME_PROFILE);
196 	bn_int_set(&rpacket->u.server_findanongame_profile2.count,Count);
197 	bn_int_set(&rpacket->u.server_findanongame_profile2.icon,account_icon_to_profile_icon(account_get_user_icon(account,ctag),account,ctag));
198 	bn_byte_set(&rpacket->u.server_findanongame_profile2.rescount,0);
199 	temp=0;
200 	packet_append_data(rpacket,&temp,2);
201 	conn_push_outqueue(c,rpacket);
202 	packet_del_ref(rpacket);
203     }
204     else // If they do have a profile then:
205     {
206 	int solowins=account_get_ladder_wins(account,ctag,ladder_id_solo);
207 	int sololoss=account_get_ladder_losses(account,ctag,ladder_id_solo);
208 	int soloxp=account_get_ladder_xp(account,ctag,ladder_id_solo);
209 	int sololevel=account_get_ladder_level(account,ctag,ladder_id_solo);
210 	int solorank=account_get_ladder_rank(account,ctag,ladder_id_solo);
211 
212 	int teamwins=account_get_ladder_wins(account,ctag,ladder_id_team);
213 	int teamloss=account_get_ladder_losses(account,ctag,ladder_id_team);
214 	int teamxp=account_get_ladder_xp(account,ctag,ladder_id_team);
215 	int teamlevel=account_get_ladder_level(account,ctag,ladder_id_team);
216 	int teamrank=account_get_ladder_rank(account,ctag,ladder_id_team);
217 
218 	int ffawins=account_get_ladder_wins(account,ctag,ladder_id_ffa);
219 	int ffaloss=account_get_ladder_losses(account,ctag,ladder_id_ffa);
220 	int ffaxp=account_get_ladder_xp(account,ctag,ladder_id_ffa);
221 	int ffalevel=account_get_ladder_level(account,ctag,ladder_id_ffa);
222 	int ffarank=account_get_ladder_rank(account,ctag,ladder_id_ffa);
223 
224 	int humanwins=account_get_racewins(account,W3_RACE_HUMANS,ctag);
225 	int humanlosses=account_get_racelosses(account,W3_RACE_HUMANS,ctag);
226 	int orcwins=account_get_racewins(account,W3_RACE_ORCS,ctag);
227 	int orclosses=account_get_racelosses(account,W3_RACE_ORCS,ctag);
228 	int undeadwins=account_get_racewins(account,W3_RACE_UNDEAD,ctag);
229 	int undeadlosses=account_get_racelosses(account,W3_RACE_UNDEAD,ctag);
230 	int nightelfwins=account_get_racewins(account,W3_RACE_NIGHTELVES,ctag);
231 	int nightelflosses=account_get_racelosses(account,W3_RACE_NIGHTELVES,ctag);
232 	int randomwins=account_get_racewins(account,W3_RACE_RANDOM,ctag);
233 	int randomlosses=account_get_racelosses(account,W3_RACE_RANDOM,ctag);
234 	int tourneywins=account_get_racewins(account,W3_RACE_DEMONS,ctag);
235 	int tourneylosses=account_get_racelosses(account,W3_RACE_DEMONS,ctag);
236 
237 	unsigned char rescount;
238 
239 	if (!(rpacket = packet_create(packet_class_bnet)))
240 	    return -1;
241 	packet_set_size(rpacket,sizeof(t_server_findanongame_profile2));
242 	packet_set_type(rpacket,SERVER_FINDANONGAME_PROFILE);
243 	bn_byte_set(&rpacket->u.server_findanongame_profile2.option,CLIENT_FINDANONGAME_PROFILE);
244 	bn_int_set(&rpacket->u.server_findanongame_profile2.count,Count); //job count
245 	bn_int_set(&rpacket->u.server_findanongame_profile2.icon,account_icon_to_profile_icon(account_get_user_icon(account,ctag),account,ctag));
246 
247 	rescount = 0;
248 	if (sololevel > 0) {
249 	    bn_int_set((bn_int*)&temp,0x534F4C4F); // SOLO backwards
250 	    packet_append_data(rpacket,&temp,4);
251 	    temp=0;
252 	    bn_int_set((bn_int*)&temp,solowins);
253 	    packet_append_data(rpacket,&temp,2); //SOLO WINS
254 	    bn_int_set((bn_int*)&temp,sololoss);
255 	    packet_append_data(rpacket,&temp,2); // SOLO LOSSES
256 	    bn_int_set((bn_int*)&temp,sololevel);
257 	    packet_append_data(rpacket,&temp,1); // SOLO LEVEL
258 	    bn_int_set((bn_int*)&temp,account_get_profile_calcs(account,soloxp,sololevel));
259 	    packet_append_data(rpacket,&temp,1); // SOLO PROFILE CALC
260 	    bn_int_set((bn_int *)&temp,soloxp);
261 	    packet_append_data(rpacket,&temp,2); // SOLO XP
262 	    bn_int_set((bn_int *)&temp,solorank);
263 	    packet_append_data(rpacket,&temp,4); // SOLO LADDER RANK
264 	    rescount++;
265 	}
266 
267 	if (teamlevel > 0) {
268 	    //below is for team records. Add this after 2v2,3v3,4v4 are done
269 	    bn_int_set((bn_int*)&temp,0x5445414D);
270 	    packet_append_data(rpacket,&temp,4);
271 	    bn_int_set((bn_int*)&temp,teamwins);
272 	    packet_append_data(rpacket,&temp,2);
273 	    bn_int_set((bn_int*)&temp,teamloss);
274 	    packet_append_data(rpacket,&temp,2);
275 	    bn_int_set((bn_int*)&temp,teamlevel);
276 	    packet_append_data(rpacket,&temp,1);
277 	    bn_int_set((bn_int*)&temp,account_get_profile_calcs(account,teamxp,teamlevel));
278 
279 	    packet_append_data(rpacket,&temp,1);
280 	    bn_int_set((bn_int*)&temp,teamxp);
281 	    packet_append_data(rpacket,&temp,2);
282 	    bn_int_set((bn_int*)&temp,teamrank);
283 	    packet_append_data(rpacket,&temp,4);
284 	    //done of team game stats
285 	    rescount++;
286 	}
287 
288 	if (ffalevel > 0) {
289 	    bn_int_set((bn_int*)&temp,0x46464120);
290 	    packet_append_data(rpacket,&temp,4);
291 	    bn_int_set((bn_int*)&temp,ffawins);
292 	    packet_append_data(rpacket,&temp,2);
293 	    bn_int_set((bn_int*)&temp,ffaloss);
294 	    packet_append_data(rpacket,&temp,2);
295 	    bn_int_set((bn_int*)&temp,ffalevel);
296 	    packet_append_data(rpacket,&temp,1);
297 	    bn_int_set((bn_int*)&temp,account_get_profile_calcs(account,ffaxp,ffalevel));
298 	    packet_append_data(rpacket,&temp,1);
299 	    bn_int_set((bn_int*)&temp,ffaxp);
300 	    packet_append_data(rpacket,&temp,2);
301 	    bn_int_set((bn_int*)&temp,ffarank);
302 	    packet_append_data(rpacket,&temp,4);
303 	    //End of FFA Stats
304 	    rescount++;
305 	}
306 	/* set result count */
307 	bn_byte_set(&rpacket->u.server_findanongame_profile2.rescount,rescount);
308 
309 	bn_int_set((bn_int*)&temp,0x06); //start of race stats
310 	packet_append_data(rpacket,&temp,1);
311 	bn_int_set((bn_int*)&temp,randomwins);
312 	packet_append_data(rpacket,&temp,2); //random wins
313 	bn_int_set((bn_int*)&temp,randomlosses);
314 	packet_append_data(rpacket,&temp,2); //random losses
315 	bn_int_set((bn_int*)&temp,humanwins);
316 	packet_append_data(rpacket,&temp,2); //human wins
317 	bn_int_set((bn_int*)&temp,humanlosses);
318 	packet_append_data(rpacket,&temp,2); //human losses
319 	bn_int_set((bn_int*)&temp,orcwins);
320 	packet_append_data(rpacket,&temp,2); //orc wins
321 	bn_int_set((bn_int*)&temp,orclosses);
322 	packet_append_data(rpacket,&temp,2); //orc losses
323 	bn_int_set((bn_int*)&temp,undeadwins);
324 	packet_append_data(rpacket,&temp,2); //undead wins
325 	bn_int_set((bn_int*)&temp,undeadlosses);
326 	packet_append_data(rpacket,&temp,2); //undead losses
327 	bn_int_set((bn_int*)&temp,nightelfwins);
328 	packet_append_data(rpacket,&temp,2); //elf wins
329 	bn_int_set((bn_int*)&temp,nightelflosses);
330 	packet_append_data(rpacket,&temp,2); //elf losses
331 	bn_int_set((bn_int*)&temp,tourneywins);
332 	packet_append_data(rpacket,&temp,2); //tourney wins
333 	bn_int_set((bn_int*)&temp,tourneylosses);
334 	packet_append_data(rpacket,&temp,2); //tourney losses
335 	//end of normal stats - Start of AT stats
336 
337 	/* 1 byte team count place holder, set later */
338 	packet_append_data(rpacket, &temp, 1);
339 
340 	/* we need to store the AT team count but we dont know yet the no
341 	 * of stored teams so we cache the pointer for later use
342 	 */
343 	atcountp = (unsigned char *)packet_get_raw_data(rpacket, packet_get_size(rpacket) - 1);
344 
345 	teamlist = account_get_teams(account);
346 	teamcount = 0;
347 	if (teamlist)
348 	{
349 	  int teamtype[] = {0, 0x32565332, 0x33565333, 0x34565334, 0x35565335, 0x36565336};
350 
351 	  LIST_TRAVERSE(teamlist,curr)
352 	  {
353 	    if (!(team = elem_get_data(curr)))
354 	    {
355 	      eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
356 	      continue;
357 	    }
358 
359 	    if (team_get_clienttag(team) != ctag)
360 	      continue;
361 
362 	    bn_int_set((bn_int*)&temp,teamtype[team_get_size(team)-1]);
363 	    packet_append_data(rpacket,&temp,4);
364 
365 	    bn_int_set((bn_int*)&temp,team_get_wins(team)); //at team wins
366 	    packet_append_data(rpacket,&temp,2);
367 	    bn_int_set((bn_int*)&temp,team_get_losses(team)); //at team losses
368 	    packet_append_data(rpacket,&temp,2);
369 	    bn_int_set((bn_int*)&temp,team_get_level(team));
370 	    packet_append_data(rpacket,&temp,1);
371 	    bn_int_set((bn_int*)&temp,account_get_profile_calcs(account,team_get_xp(team),team_get_level(team))); // xp bar calc
372 	    packet_append_data(rpacket,&temp,1);
373 	    bn_int_set((bn_int*)&temp,team_get_xp(team));
374 	    packet_append_data(rpacket,&temp,2);
375 	    bn_int_set((bn_int*)&temp,team_get_rank(team)); //rank on AT ladder
376 	    packet_append_data(rpacket,&temp,4);
377 
378 	    bn_time = time_to_bnettime(temp,team_get_lastgame(team));
379 	    bnettime_to_bn_long(bn_time,&ltime);
380 	    packet_append_data(rpacket,&ltime,8);
381 
382 	    bn_int_set((bn_int*)&temp,team_get_size(team)-1);
383 	    packet_append_data(rpacket,&temp,1);
384 
385 	    for (i=0; i<team_get_size(team);i++)
386 	    {
387 	    	if ((team_get_memberuid(team,i)!=account_get_uid(account)))
388 		  packet_append_string(rpacket,account_get_name(team_get_member(team,i)));
389 		//now attach the names to the packet - not including yourself
390 		// [quetzal] 20020826
391 
392 	    }
393 	    teamcount++;
394 
395 	    if ((teamcount>=16)) break;
396 	  }
397 	}
398 
399 	*atcountp = (unsigned char)teamcount;
400 
401 	conn_push_outqueue(c,rpacket);
402 	packet_del_ref(rpacket);
403 
404 	eventlog(eventlog_level_info,__FUNCTION__,"Sent %s's WAR3 Stats (including %d teams) to requestor.",username,teamcount);
405     }
406     return 0;
407 }
408 
_client_anongame_cancel(t_connection * c)409 static int _client_anongame_cancel(t_connection * c)
410 {
411     t_packet * rpacket;
412     t_connection * tc[ANONGAME_MAX_GAMECOUNT/2];
413 
414     // [quetzal] 20020809 - added a_count, so we dont refer to already destroyed anongame
415     t_anongame *a = conn_get_anongame(c);
416     int a_count, i;
417 
418     eventlog(eventlog_level_info,__FUNCTION__,"[%d] got FINDANONGAME CANCEL packet", conn_get_socket(c));
419 
420     if(!a)
421 	return -1;
422 
423     a_count = anongame_get_count(a);
424 
425     // anongame_unqueue(c, anongame_get_queue(a));
426     // -- already doing unqueue in conn_destroy_anongame
427     for (i=0; i < ANONGAME_MAX_GAMECOUNT/2; i++)
428 	tc[i] = anongame_get_tc(a, i);
429 
430     for (i=0; i < ANONGAME_MAX_GAMECOUNT/2; i++) {
431 	if (tc[i] == NULL)
432 	    continue;
433 
434 	conn_set_routeconn(tc[i], NULL);
435 	conn_destroy_anongame(tc[i]);
436     }
437 
438     if (!(rpacket = packet_create(packet_class_bnet)))
439 	return -1;
440 
441     packet_set_size(rpacket,sizeof(t_server_findanongame_playgame_cancel));
442     packet_set_type(rpacket,SERVER_FINDANONGAME_PLAYGAME_CANCEL);
443     bn_byte_set(&rpacket->u.server_findanongame_playgame_cancel.cancel,SERVER_FINDANONGAME_CANCEL);
444     bn_int_set(&rpacket->u.server_findanongame_playgame_cancel.count, a_count);
445     conn_push_outqueue(c,rpacket);
446     packet_del_ref(rpacket);
447     return 0;
448 }
449 
_client_anongame_get_icon(t_connection * c,t_packet const * const packet)450 static int _client_anongame_get_icon(t_connection * c, t_packet const * const packet)
451 {
452     t_packet * rpacket;
453 
454     //BlacKDicK 04/20/2003 Need some huge re-work on this.
455     {
456 	struct
457 	{
458 	    char	 icon_code[4];
459 	    unsigned int portrait_code;
460 	    char	 race;
461 	    bn_short	 required_wins;
462 	    char	 client_enabled;
463         } tempicon;
464 
465 	//FIXME: Add those to the prefs and also merge them on accoun_wrap;
466 	// FIXED BY DJP 07/16/2003 FOR 110 CHANGE ( TOURNEY & RACE WINS ) + Table_witdh
467 	short icon_req_race_wins;
468 	short icon_req_tourney_wins;
469         int race[]={W3_RACE_RANDOM,W3_RACE_HUMANS,W3_RACE_ORCS,W3_RACE_UNDEAD,W3_RACE_NIGHTELVES,W3_RACE_DEMONS};
470         char race_char[6] ={'R','H','O','U','N','D'};
471         char icon_pos[5] ={'2','3','4','5','6',};
472         char table_width = 6;
473         char table_height= 5;
474         int i,j;
475         char rico;
476         unsigned int rlvl,rwins;
477 	t_clienttag clienttag;
478 	t_account * acc;
479 
480         char user_icon[5];
481         char const * uicon;
482 
483 	clienttag = conn_get_clienttag(c);
484 	acc = conn_get_account(c);
485 	/* WAR3 uses a different table size, might change if blizzard add tournament support to RoC */
486 	if (clienttag==CLIENTTAG_WARCRAFT3_UINT) {
487     	    table_width = 5;
488 	    table_height= 4;
489 	}
490 
491         eventlog(eventlog_level_info,__FUNCTION__,"[%d] got FINDANONGAME Get Icons packet",conn_get_socket(c));
492 
493 	if ((rpacket = packet_create(packet_class_bnet)) == NULL) {
494 	    eventlog(eventlog_level_error, __FUNCTION__, "could not create new packet");
495 	    return -1;
496 	}
497 
498 	packet_set_size(rpacket, sizeof(t_server_findanongame_iconreply));
499         packet_set_type(rpacket, SERVER_FINDANONGAME_ICONREPLY);
500         bn_int_set(&rpacket->u.server_findanongame_iconreply.count, bn_int_get(packet->u.client_findanongame_inforeq.count));
501         bn_byte_set(&rpacket->u.server_findanongame_iconreply.option, CLIENT_FINDANONGAME_GET_ICON);
502         if ((uicon = account_get_user_icon(acc,clienttag)))
503         {
504 	    memcpy(&rpacket->u.server_findanongame_iconreply.curricon, uicon,4);
505         }
506         else
507         {
508 	    account_get_raceicon(acc,&rico,&rlvl,&rwins,clienttag);
509 	    sprintf(user_icon,"%1d%c3W",rlvl,rico);
510             memcpy(&rpacket->u.server_findanongame_iconreply.curricon,user_icon,4);
511         }
512 
513 	bn_byte_set(&rpacket->u.server_findanongame_iconreply.table_width, table_width);
514         bn_byte_set(&rpacket->u.server_findanongame_iconreply.table_size, table_width*table_height);
515         for (j=0;j<table_height;j++){
516 	    icon_req_race_wins = anongame_infos_get_ICON_REQ(j+1,clienttag);
517 	    for (i=0;i<table_width;i++){
518 		tempicon.race=i;
519 	        tempicon.icon_code[0] = icon_pos[j];
520 	        tempicon.icon_code[1] = race_char[i];
521 	        tempicon.icon_code[2] = '3';
522 	        tempicon.icon_code[3] = 'W';
523 	        tempicon.portrait_code = (account_icon_to_profile_icon(tempicon.icon_code,acc,clienttag));
524 	        if (i<=4){
525 	    	    //Building the icon for the races
526 	    	    bn_short_set(&tempicon.required_wins,icon_req_race_wins);
527 	    	    if (account_get_racewins(acc,race[i],clienttag)>=icon_req_race_wins) {
528 			tempicon.client_enabled=1;
529 	    	    }else{
530 			tempicon.client_enabled=0;
531 		    }
532 	    	}else{
533 	        //Building the icon for the tourney
534 		icon_req_tourney_wins = anongame_infos_get_ICON_REQ_TOURNEY(j+1);
535 	        bn_short_set(&tempicon.required_wins,icon_req_tourney_wins);
536 	        if (account_get_racewins(acc,race[i],clienttag)>=icon_req_tourney_wins) {
537 		    tempicon.client_enabled=1;
538 	        }else{
539 		    tempicon.client_enabled=0;}
540 	        }
541 	        packet_append_data(rpacket, &tempicon, sizeof(tempicon));
542 	    }
543 	}
544         //Go,go,go
545         conn_push_outqueue(c,rpacket);
546         packet_del_ref(rpacket);
547     }
548     return 0;
549 }
550 
_client_anongame_set_icon(t_connection * c,t_packet const * const packet)551 static int _client_anongame_set_icon(t_connection * c, t_packet const * const packet)
552 {
553     //BlacKDicK 04/20/2003
554     unsigned int desired_icon;
555     char user_icon[5];
556 
557     /*FIXME: In this case we do not get a 'count' but insted of it we get the icon
558     that the client wants to set.'W3H2' for an example. For now it is ok, since they share
559     the same position	on the packet*/
560     desired_icon=bn_int_get(packet->u.client_findanongame.count);
561     user_icon[4]=0;
562     if (desired_icon==0){
563 	strcpy(user_icon,"NULL");
564 	eventlog(eventlog_level_info,__FUNCTION__,"[%d] Set icon packet to DEFAULT ICON [%4.4s]",conn_get_socket(c),user_icon);
565     }else{
566 	memcpy(user_icon,&desired_icon,4);
567 	eventlog(eventlog_level_info,__FUNCTION__,"[%d] Set icon packet to ICON [%s]",conn_get_socket(c),user_icon);
568     }
569 
570     account_set_user_icon(conn_get_account(c),conn_get_clienttag(c),user_icon);
571     //FIXME: Still need a way to 'refresh the user/channel'
572     //_handle_rejoin_command(conn_get_account(c),"");
573     /* ??? channel_update_userflags() */
574 	conn_update_w3_playerinfo(c);
575 
576     channel_rejoin(c);
577     return 0;
578 }
579 
_client_anongame_infos(t_connection * c,t_packet const * const packet)580 static int _client_anongame_infos(t_connection * c, t_packet const * const packet)
581 {
582     t_packet * rpacket;
583 
584     if (bn_int_get(packet->u.client_findanongame_inforeq.count) > 1) {
585 	/* reply with 0 entries found */
586 	int	temp = 0;
587 
588 	if ((rpacket = packet_create(packet_class_bnet)) == NULL) {
589 	    eventlog(eventlog_level_error, __FUNCTION__, "could not create new packet");
590 	    return -1;
591 	}
592 
593 	packet_set_size(rpacket, sizeof(t_server_findanongame_inforeply));
594 	packet_set_type(rpacket, SERVER_FINDANONGAME_INFOREPLY);
595 	bn_byte_set(&rpacket->u.server_findanongame_inforeply.option, CLIENT_FINDANONGAME_INFOS);
596 	bn_int_set(&rpacket->u.server_findanongame_inforeply.count, bn_int_get(packet->u.client_findanongame_inforeq.count));
597 	bn_byte_set(&rpacket->u.server_findanongame_inforeply.noitems, 0);
598 	packet_append_data(rpacket, &temp, 1);
599 
600 	conn_push_outqueue(c,rpacket);
601 	packet_del_ref(rpacket);
602     } else {
603 	int i;
604 	int client_tag;
605 	int server_tag_count	= 0;
606 	int client_tag_unk;
607 	int server_tag_unk;
608 	bn_int temp;
609 	char noitems;
610 	char * tmpdata;
611 	int tmplen;
612 	t_clienttag clienttag	= conn_get_clienttag(c);
613 	char last_packet	= 0x00;
614 	char other_packet	= 0x01;
615 	char langstr[5];
616 	t_gamelang gamelang = conn_get_gamelang(c);
617 	bn_int_tag_get((bn_int const *)&gamelang, langstr, 5);
618 
619 	/* Send seperate packet for each item requested
620 	 * sending all at once overloaded w3xp
621 	 * [Omega] */
622 	for (i=0;i<bn_byte_get(packet->u.client_findanongame_inforeq.noitems);i++){
623 	    noitems = 0;
624 
625 	    if ((rpacket = packet_create(packet_class_bnet)) == NULL) {
626 		eventlog(eventlog_level_error, __FUNCTION__, "could not create new packet");
627 		return -1;
628 	    }
629 
630 	    /* Starting the packet stuff */
631 	    packet_set_size(rpacket, sizeof(t_server_findanongame_inforeply));
632 	    packet_set_type(rpacket, SERVER_FINDANONGAME_INFOREPLY);
633 	    bn_byte_set(&rpacket->u.server_findanongame_inforeply.option, CLIENT_FINDANONGAME_INFOS);
634 	    bn_int_set(&rpacket->u.server_findanongame_inforeply.count, 1);
635 
636 	    memcpy(&temp,(packet_get_data_const(packet,10+(i*8),4)),sizeof(int));
637 	    client_tag=bn_int_get(temp);
638 	    memcpy(&temp,packet_get_data_const(packet,14+(i*8),4),sizeof(int));
639 	    client_tag_unk=bn_int_get(temp);
640 
641 	    switch (client_tag){
642 		case CLIENT_FINDANONGAME_INFOTAG_URL:
643 		    bn_int_set((bn_int*)&server_tag_unk,0xBF1F1047);
644 		    packet_append_data(rpacket, "LRU\0" , 4);
645 		    packet_append_data(rpacket, &server_tag_unk , 4);
646 		    // FIXME: Maybe need do do some checks to avoid prefs empty strings.
647 			tmpdata = anongame_infos_data_get_url(clienttag, conn_get_versionid(c), &tmplen);
648 		    packet_append_data(rpacket, tmpdata, tmplen);
649 		    noitems++;
650 		    server_tag_count++;
651 		    eventlog(eventlog_level_debug,__FUNCTION__,"client_tag request tagid=(0x%01x) tag=(%s)  tag_unk=(0x%04x)",i,"CLIENT_FINDANONGAME_INFOTAG_URL",client_tag_unk);
652 		    break;
653 		case CLIENT_FINDANONGAME_INFOTAG_MAP:
654 		    bn_int_set((bn_int*)&server_tag_unk,0x70E2E0D5);
655 		    packet_append_data(rpacket, "PAM\0" , 4);
656 		    packet_append_data(rpacket, &server_tag_unk , 4);
657 			tmpdata = anongame_infos_data_get_map(clienttag, conn_get_versionid(c), &tmplen);
658 		    packet_append_data(rpacket, tmpdata, tmplen);
659 		    noitems++;
660 		    server_tag_count++;
661 		    eventlog(eventlog_level_debug,__FUNCTION__,"client_tag request tagid=(0x%01x) tag=(%s)  tag_unk=(0x%04x)",i,"CLIENT_FINDANONGAME_INFOTAG_MAP",client_tag_unk);
662 		    break;
663 		case CLIENT_FINDANONGAME_INFOTAG_TYPE:
664 		    bn_int_set((bn_int*)&server_tag_unk,0x7C87DEEE);
665 		    packet_append_data(rpacket, "EPYT" , 4);
666 		    packet_append_data(rpacket, &server_tag_unk , 4);
667 			tmpdata = anongame_infos_data_get_type(clienttag, conn_get_versionid(c), &tmplen);
668 		    packet_append_data(rpacket, tmpdata, tmplen);
669 		    noitems++;
670 		    server_tag_count++;
671 		    eventlog(eventlog_level_debug,__FUNCTION__,"client_tag request tagid=(0x%01x) tag=(%s) tag_unk=(0x%04x)",i,"CLIENT_FINDANONGAME_INFOTAG_TYPE",client_tag_unk);
672 		    break;
673 		case CLIENT_FINDANONGAME_INFOTAG_DESC:
674 		    bn_int_set((bn_int*)&server_tag_unk,0xA4F0A22F);
675 		    packet_append_data(rpacket, "CSED" , 4);
676 		    packet_append_data(rpacket,&server_tag_unk,4);
677 			tmpdata = anongame_infos_data_get_desc(langstr, clienttag, conn_get_versionid(c), &tmplen);
678 		    packet_append_data(rpacket, tmpdata, tmplen);
679 		    eventlog(eventlog_level_debug,__FUNCTION__,"client_tag request tagid=(0x%01x) tag=(%s) tag_unk=(0x%04x)",i,"CLIENT_FINDANONGAME_INFOTAG_DESC",client_tag_unk);
680 		    noitems++;
681 		    server_tag_count++;
682 		    break;
683 		case CLIENT_FINDANONGAME_INFOTAG_LADR:
684 		    bn_int_set((bn_int*)&server_tag_unk,0x3BADE25A);
685 		    packet_append_data(rpacket, "RDAL" , 4);
686 		    packet_append_data(rpacket, &server_tag_unk , 4);
687 			tmpdata = anongame_infos_data_get_ladr(langstr, clienttag, conn_get_versionid(c), &tmplen);
688 		    packet_append_data(rpacket, tmpdata, tmplen);
689 		    noitems++;
690 		    server_tag_count++;
691 		    eventlog(eventlog_level_debug,__FUNCTION__,"client_tag request tagid=(0x%01x) tag=(%s) tag_unk=(0x%04x)",i,"CLIENT_FINDANONGAME_INFOTAG_LADR",client_tag_unk);
692 		    break;
693 		default:
694 		     eventlog(eventlog_level_debug,__FUNCTION__,"unrec client_tag request tagid=(0x%01x) tag=(0x%04x)",i,client_tag);
695 
696 	    }
697 	    //Adding a last padding null-byte
698 	    if (server_tag_count == bn_byte_get(packet->u.client_findanongame_inforeq.noitems))
699 		packet_append_data(rpacket, &last_packet, 1); /* only last packet in group gets 0x00 */
700 	    else
701 		packet_append_data(rpacket, &other_packet, 1); /* the rest get 0x01 */
702 
703 	    //Go,go,go
704 	    bn_byte_set(&rpacket->u.server_findanongame_inforeply.noitems, noitems);
705 	    conn_push_outqueue(c,rpacket);
706 	    packet_del_ref(rpacket);
707 	}
708     }
709     return 0;
710 }
711 
712 /* tournament notice disabled at this time, but responce is sent to cleint */
_client_anongame_tournament(t_connection * c,t_packet const * const packet)713 static int _client_anongame_tournament(t_connection * c, t_packet const * const packet)
714 {
715     t_packet * rpacket;
716 
717     t_account * account = conn_get_account(c);
718     t_clienttag clienttag = conn_get_clienttag(c);
719 
720     unsigned int start_prelim	= tournament_get_start_preliminary();
721     unsigned int end_signup	= tournament_get_end_signup();
722     unsigned int end_prelim	= tournament_get_end_preliminary();
723     unsigned int start_r1	= tournament_get_start_round_1();
724 
725     if ((rpacket = packet_create(packet_class_bnet)) == NULL) {
726 	eventlog(eventlog_level_error, __FUNCTION__, "could not create new packet");
727 	return -1;
728     }
729 
730     packet_set_size(rpacket, sizeof(t_server_anongame_tournament_reply));
731     packet_set_type(rpacket, SERVER_FINDANONGAME_TOURNAMENT_REPLY);
732     bn_byte_set(&rpacket->u.server_anongame_tournament_reply.option, 7);
733     bn_int_set(&rpacket->u.server_anongame_tournament_reply.count,
734     bn_int_get(packet->u.client_anongame_tournament_request.count));
735 
736     if ( !start_prelim || (end_signup <= now && tournament_user_signed_up(account) < 0) ||
737 	    tournament_check_client(clienttag) < 0) { /* No Tournament Notice */
738 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		0);
739 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
740 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0);
741 	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		0);
742 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0);
743 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		0);
744 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0);
745 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		0);
746 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		0);
747 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		0);
748 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0);
749 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		0);
750 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
751 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
752     }
753     else if (start_prelim>=now) { /* Tournament Notice */
754 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		1);
755 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
756 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0x0000); /* random */
757 	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		_tournament_time_convert(start_prelim));
758 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0x01);
759 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		start_prelim-now);
760 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0);
761 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		0);
762 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		0);
763 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		0);
764 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0x00);
765 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		2);
766 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
767 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
768     }
769     else if (end_signup>=now) { /* Tournament Signup Notice - Play Game Active */
770 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		2);
771 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
772 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0x0828); /* random */
773 	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		_tournament_time_convert(end_signup));
774 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0x01);
775 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		end_signup-now);
776 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0);
777 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		tournament_get_stat(account, 1));
778 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		tournament_get_stat(account, 2));
779 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		tournament_get_stat(account, 3));
780 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0x08);
781 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		2);
782 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
783 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
784     }
785     else if (end_prelim>=now) { /* Tournament Prelim Period - Play Game Active */
786 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		3);
787 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
788 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0x0828); /* random */
789 	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		_tournament_time_convert(end_prelim));
790 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0x01);
791 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		end_prelim-now);
792 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0);
793 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		tournament_get_stat(account, 1));
794 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		tournament_get_stat(account, 2));
795 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		tournament_get_stat(account, 3));
796 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0x08);
797 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		2);
798 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
799 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
800     }
801     else if (start_r1>=now && (tournament_get_game_in_progress()) ) { /* Prelim Period Over - Shows user stats (not all prelim games finished) */
802 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		4);
803 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
804 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0x0000); /* random */
805 	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		_tournament_time_convert(start_r1));
806 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0x01);
807 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		start_r1-now);
808 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0); /* 00 00 */
809 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		tournament_get_stat(account, 1));
810 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		tournament_get_stat(account, 2));
811 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		tournament_get_stat(account, 3));
812 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0x08);
813 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		2);
814 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
815 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
816     }
817     else if (!(tournament_get_in_finals_status(account))) { /* Prelim Period Over - user did not make finals - Shows user stats */
818 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		5);
819 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
820 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0);
821 	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		0);
822 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0);
823 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		0);
824 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0);
825 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		tournament_get_stat(account, 1));
826 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		tournament_get_stat(account, 2));
827 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		tournament_get_stat(account, 3));
828 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0x04);
829 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		2);
830 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
831 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
832     }
833     /* cycle through [type-6] & [type-7] packets
834      *
835      * use [type-6] to show client "eliminated" or "continue"
836      *     timestamp , countdown & round number (of next round) must be set if clinet continues
837      *
838      * use [type-7] to make cleint wait for 44FF packet option 1 to start game (A guess, not tested)
839      *
840      * not sure if there is overall winner packet sent at end of last final round
841      */
842 
843     else if ( (0) ) { /* User in finals - Shows user stats and start of next round*/
844 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		6);
845 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
846 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0x0000);
847 	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		_tournament_time_convert(start_r1));
848 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0x01);
849 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		start_r1-now);
850 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0x0000); /* 00 00 */
851 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		4); /* round number */
852 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		0); /* 0 = continue , 1= eliminated */
853 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		0);
854 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0x04); /* number of rounds in finals */
855 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		2);
856 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
857 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
858     }
859     else if ( (0) ) { /* user waiting for match to be made */
860 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		7);
861 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
862 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0);
863 	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		0);
864 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0);
865 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		0);
866 	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0);
867 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		1); /* round number */
868 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		0);
869 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		0);
870 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0x04); /* number of finals */
871 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		2);
872 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
873 	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
874     }
875 
876     conn_push_outqueue(c,rpacket);
877     packet_del_ref(rpacket);
878     return 0;
879 }
880 
_tournament_time_convert(unsigned int time)881 static unsigned int _tournament_time_convert(unsigned int time)
882 {
883     /* it works, don't ask me how */ /* some time drift reportd by testers */
884     unsigned int tmp1, tmp2, tmp3;
885 
886     tmp1 = time-1059179400;	/* 0x3F21CB88  */
887     tmp2 = tmp1*0.59604645;
888     tmp3 = tmp2+3276999960U;
889     /*eventlog(eventlog_level_trace,__FUNCTION__,"time: 0x%08x, tmp1: 0x%08x, tmp2 0x%08x, tmp3 0x%08x",time,tmp1,tmp2,tmp3);*/
890 
891     return tmp3;
892 }
893 
handle_anongame_packet(t_connection * c,t_packet const * const packet)894 extern int handle_anongame_packet(t_connection * c, t_packet const * const packet)
895 {
896     switch (bn_byte_get(packet->u.client_anongame.option))
897     {
898 	case CLIENT_FINDANONGAME_PROFILE:
899 	  return _client_anongame_profile(c, packet);
900 
901 	case CLIENT_FINDANONGAME_CANCEL:
902 	  return _client_anongame_cancel(c);
903 
904 	case CLIENT_FINDANONGAME_SEARCH:
905 	case CLIENT_FINDANONGAME_AT_INVITER_SEARCH:
906 	case CLIENT_FINDANONGAME_AT_SEARCH:
907 	  return handle_anongame_search(c, packet); /* located in anongame.c */
908 
909 	case CLIENT_FINDANONGAME_GET_ICON:
910 	  return _client_anongame_get_icon(c, packet);
911 
912 	case CLIENT_FINDANONGAME_SET_ICON:
913 	  return _client_anongame_set_icon(c, packet);
914 
915 	case CLIENT_FINDANONGAME_INFOS:
916 	  return _client_anongame_infos(c, packet);
917 
918 	case CLIENT_ANONGAME_TOURNAMENT:
919 	  return _client_anongame_tournament(c, packet);
920 
921 	case CLIENT_FINDANONGAME_PROFILE_CLAN:
922 	  return _client_anongame_profile_clan(c, packet);
923 
924 	default:
925           eventlog(eventlog_level_error,__FUNCTION__,"got unhandled option %d",bn_byte_get(packet->u.client_findanongame.option));
926 	  return -1;
927     }
928 }
929