1 /*
2 * Copyright (C) 1998 Mark Baysinger (mbaysing@ucsd.edu)
3 * Copyright (C) 1998,1999,2000,2001 Ross Combs (rocombs@cs.nmsu.edu)
4 * Copyright (C) 2000,2001 Marco Ziech (mmz@gmx.net)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20 #define CONNECTION_INTERNAL_ACCESS
21 #include "common/setup_before.h"
22 #include <stdio.h>
23 // amadeo
24 #ifdef WIN32_GUI
25 #include <win32/winmain.h>
26 #endif
27 #ifdef HAVE_STDDEF_H
28 # include <stddef.h>
29 #else
30 # ifndef NULL
31 # define NULL ((void *)0)
32 # endif
33 #endif
34 #ifdef STDC_HEADERS
35 # include <stdlib.h>
36 #else
37 # ifdef HAVE_MALLOC_H
38 # include <malloc.h>
39 # endif
40 #endif
41 #include "compat/strtoul.h"
42 #ifdef HAVE_STRING_H
43 # include <string.h>
44 #else
45 # ifdef HAVE_STRINGS_H
46 # include <strings.h>
47 # endif
48 #endif
49 #ifdef HAVE_ASSERT_H
50 # include <assert.h>
51 #endif
52 #include "compat/strchr.h"
53 #include "compat/strrchr.h"
54 #include "compat/strdup.h"
55 #include "compat/strcasecmp.h"
56 #include "compat/strncasecmp.h"
57 #include <errno.h>
58 #include "compat/strerror.h"
59 #ifdef HAVE_UNISTD_H
60 # include <unistd.h>
61 #endif
62 #ifdef TIME_WITH_SYS_TIME
63 # include <sys/time.h>
64 # include <time.h>
65 #else
66 # ifdef HAVE_SYS_TIME_H
67 # include <sys/time.h>
68 # else
69 # include <time.h>
70 # endif
71 #endif
72 #include "compat/difftime.h"
73 #ifdef HAVE_SYS_TYPES_H
74 # include <sys/types.h>
75 #endif
76 #ifdef HAVE_SYS_SOCKET_H
77 # include <sys/socket.h>
78 #endif
79 #include "compat/socket.h"
80 #include "compat/psock.h"
81 #include "common/eventlog.h"
82 #include "common/addr.h"
83 #include "account.h"
84 #include "account_wrap.h"
85 #include "realm.h"
86 #include "channel.h"
87 #include "game.h"
88 #include "common/queue.h"
89 #include "tick.h"
90 #include "common/packet.h"
91 #include "common/tag.h"
92 #include "common/bn_type.h"
93 #include "message.h"
94 #include "common/version.h"
95 #include "prefs.h"
96 #include "common/util.h"
97 #include "common/list.h"
98 #include "watch.h"
99 #include "timer.h"
100 #include "irc.h"
101 #include "ipban.h"
102 #include "game_conv.h"
103 #include "udptest_send.h"
104 #include "character.h"
105 #include "versioncheck.h"
106 #include "common/bnet_protocol.h"
107 #include "common/field_sizes.h"
108 #include "anongame.h"
109 #include "clan.h"
110 #include "connection.h"
111 #include "topic.h"
112 #include "server.h"
113 #include "handle_d2cs.h"
114 #include "command_groups.h"
115 #include "attrlayer.h"
116 #include "common/rcm.h"
117 #include "common/fdwatch.h"
118 #include "common/elist.h"
119 #include "common/xalloc.h"
120 #include "common/setup_after.h"
121
122 /* types and data structures used for the connlist array */
123 typedef struct {
124 t_connection *c;
125 t_elist freelist;
126 } t_conn_entry;
127
128 t_conn_entry *connarray = NULL;
129 t_elist arrayflist;
130
131 static int totalcount=0;
132 static t_list * conn_head=NULL;
133 static t_list * conn_dead=NULL;
134
135 static void conn_send_welcome(t_connection * c);
136 static void conn_send_issue(t_connection * c);
137
138 static int connarray_create(void);
139 static void connarray_destroy(void);
140 static t_connection *connarray_get_conn(unsigned index);
141 static unsigned connarray_add_conn(t_connection *c);
142 static void connarray_del_conn(unsigned index);
143
conn_send_welcome(t_connection * c)144 static void conn_send_welcome(t_connection * c)
145 {
146 char const * filename;
147 FILE * fp;
148
149 if (!c)
150 {
151 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
152 return;
153 }
154
155 if (c->protocol.cflags & conn_flags_welcomed)
156 return;
157 if ((conn_get_class(c)==conn_class_irc)||
158 (conn_get_class(c)==conn_class_wol))
159 {
160 c->protocol.cflags|= conn_flags_welcomed;
161 return;
162 }
163 if ((filename = prefs_get_motdfile()))
164 {
165 if ((fp = fopen(filename,"r")))
166 {
167 message_send_file(c,fp);
168 if (fclose(fp)<0)
169 { eventlog(eventlog_level_error,__FUNCTION__,"could not close MOTD file \"%s\" after reading (fopen: %s)",filename,pstrerror(errno)); }
170 }
171 else
172 { eventlog(eventlog_level_error,__FUNCTION__,"could not open MOTD file \"%s\" for reading (fopen: %s)",filename,pstrerror(errno)); }
173 }
174 c->protocol.cflags|= conn_flags_welcomed;
175 }
176
177
conn_send_issue(t_connection * c)178 static void conn_send_issue(t_connection * c)
179 {
180 char const * filename;
181 FILE * fp;
182
183 if (!c)
184 {
185 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
186 return;
187 }
188
189 if ((filename = prefs_get_issuefile()))
190 if ((fp = fopen(filename,"r")))
191 {
192 message_send_file(c,fp);
193 if (fclose(fp)<0)
194 eventlog(eventlog_level_error,__FUNCTION__,"could not close issue file \"%s\" after reading (fopen: %s)",filename,pstrerror(errno));
195 }
196 else
197 eventlog(eventlog_level_error,__FUNCTION__,"could not open issue file \"%s\" for reading (fopen: %s)",filename,pstrerror(errno));
198 else
199 eventlog(eventlog_level_debug,__FUNCTION__,"no issue file");
200 }
201
202 // [zap-zero] 20020629
conn_shutdown(t_connection * c,time_t now,t_timer_data foo)203 extern void conn_shutdown(t_connection * c, time_t now, t_timer_data foo)
204 {
205 if (!c)
206 {
207 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
208 return;
209 }
210
211 if (now==(time_t)0) /* zero means user logged out before expiration */
212 {
213 eventlog(eventlog_level_trace,__FUNCTION__,"[%d] connection allready closed",conn_get_socket(c));
214 return;
215 }
216
217 eventlog(eventlog_level_trace,__FUNCTION__,"[%d] closing connection",conn_get_socket(c));
218
219 conn_set_state(c, conn_state_destroy);
220 }
221
conn_test_latency(t_connection * c,time_t now,t_timer_data delta)222 extern void conn_test_latency(t_connection * c, time_t now, t_timer_data delta)
223 {
224 t_packet * packet;
225
226 if (!c)
227 {
228 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
229 return;
230 }
231
232
233 if (now==(time_t)0) /* zero means user logged out before expiration */
234 return;
235
236 if (conn_get_state(c)==conn_state_destroy) // [zap-zero] 20020910
237 return; // state_destroy: do nothing
238
239
240 if ((conn_get_class(c)==conn_class_irc)||
241 (conn_get_class(c)==conn_class_wol)) {
242 /* We should start pinging the client after we received the first line ... */
243 /* NOTE: RFC2812 only suggests that PINGs are being sent
244 * if no other activity is detected. However it explecitly
245 * allows PINGs to be sent if there is activity on this
246 * connection. In other words we just don't care :)
247 */
248 if (conn_get_ircping(c)!=0) {
249 eventlog(eventlog_level_warn,__FUNCTION__,"[%d] ping timeout (closing connection)",conn_get_socket(c));
250 conn_set_latency(c,0);
251 conn_set_state(c,conn_state_destroy);
252 }
253 irc_send_ping(c);
254 } else if(conn_get_class(c)==conn_class_w3route) {
255 if(!(packet = packet_create(packet_class_w3route))) {
256 eventlog(eventlog_level_error,__FUNCTION__,"[%d] packet_create failed",conn_get_socket(c));
257 } else {
258 packet_set_size(packet,sizeof(t_server_w3route_echoreq));
259 packet_set_type(packet,SERVER_W3ROUTE_ECHOREQ);
260 bn_int_set(&packet->u.server_w3route_echoreq.ticks,get_ticks());
261 conn_push_outqueue(c, packet);
262 packet_del_ref(packet);
263 }
264 } else {
265
266 /* FIXME: I think real Battle.net sends these even before login */
267 if (!conn_get_game(c))
268 {
269 if ((packet = packet_create(packet_class_bnet)))
270 {
271 packet_set_size(packet,sizeof(t_server_echoreq));
272 packet_set_type(packet,SERVER_ECHOREQ);
273 bn_int_set(&packet->u.server_echoreq.ticks,get_ticks());
274 conn_push_outqueue(c,packet);
275 packet_del_ref(packet);
276 }
277 else
278 { eventlog(eventlog_level_error,__FUNCTION__,"could not create packet"); }
279 }
280 }
281
282 if (timerlist_add_timer(c,now+(time_t)delta.n,conn_test_latency,delta)<0)
283 eventlog(eventlog_level_error,__FUNCTION__,"could not add timer");
284 }
285
286
conn_send_nullmsg(t_connection * c,time_t now,t_timer_data delta)287 static void conn_send_nullmsg(t_connection * c, time_t now, t_timer_data delta)
288 {
289 if (!c)
290 {
291 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
292 return;
293 }
294
295 if (now==(time_t)0) /* zero means user logged out before expiration */
296 return;
297
298 message_send_text(c,message_type_null,c,NULL);
299
300 if (timerlist_add_timer(c,now+(time_t)delta.n,conn_send_nullmsg,delta)<0)
301 eventlog(eventlog_level_error,__FUNCTION__,"could not add timer");
302 }
303
304
conn_class_get_str(t_conn_class class)305 extern char const * conn_class_get_str(t_conn_class class)
306 {
307 switch (class)
308 {
309 case conn_class_init:
310 return "init";
311 case conn_class_bnet:
312 return "bnet";
313 case conn_class_file:
314 return "file";
315 case conn_class_bot:
316 return "bot";
317 case conn_class_d2cs_bnetd:
318 return "d2cs_bnetd";
319 case conn_class_telnet:
320 return "telnet";
321 case conn_class_irc:
322 return "irc";
323 case conn_class_wol:
324 return "wol";
325 case conn_class_none:
326 return "none";
327 case conn_class_w3route:
328 return "w3route";
329 default:
330 return "UNKNOWN";
331 }
332 }
333
334
conn_state_get_str(t_conn_state state)335 extern char const * conn_state_get_str(t_conn_state state)
336 {
337 switch (state)
338 {
339 case conn_state_empty:
340 return "empty";
341 case conn_state_initial:
342 return "initial";
343 case conn_state_connected:
344 return "connected";
345 case conn_state_bot_username:
346 return "bot_username";
347 case conn_state_bot_password:
348 return "bot_password";
349 case conn_state_loggedin:
350 return "loggedin";
351 case conn_state_destroy:
352 return "destroy";
353 case conn_state_untrusted:
354 return "untrusted";
355 case conn_state_pending_raw:
356 return "pending_raw";
357 default:
358 return "UNKNOWN";
359 }
360 }
361
362 extern int conn_set_realm_cb(void *data, void *newref);
363
conn_create(int tsock,int usock,unsigned int real_local_addr,unsigned short real_local_port,unsigned int local_addr,unsigned short local_port,unsigned int addr,unsigned short port)364 extern t_connection * conn_create(int tsock, int usock, unsigned int real_local_addr, unsigned short real_local_port, unsigned int local_addr, unsigned short local_port, unsigned int addr, unsigned short port)
365 {
366 t_connection * temp;
367
368
369 if (tsock<0)
370 {
371 eventlog(eventlog_level_error,__FUNCTION__,"got bad TCP socket %d",tsock);
372 return NULL;
373 }
374 if (usock<-1) /* -1 is allowed for some connection classes like bot, irc, and telnet */
375 {
376 eventlog(eventlog_level_error,__FUNCTION__,"got bad UDP socket %d",usock);
377 return NULL;
378 }
379
380 temp = xmalloc(sizeof(t_connection));
381 temp->socket.tcp_sock = tsock;
382 temp->socket.tcp_addr = addr;
383 temp->socket.tcp_port = port;
384 temp->socket.udp_sock = usock;
385 temp->socket.udp_addr = addr; /* same for now but client can request it to be different */
386 temp->socket.local_addr = local_addr;
387 temp->socket.local_port = local_port;
388 temp->socket.real_local_addr = real_local_addr;
389 temp->socket.real_local_port = real_local_port;
390 temp->socket.udp_port = port;
391 temp->socket.fdw_idx = -1;
392 temp->protocol.class = conn_class_init;
393 temp->protocol.state = conn_state_initial;
394 temp->protocol.sessionkey = ((unsigned int)rand())^((unsigned int)now+(unsigned int)real_local_port);
395 temp->protocol.sessionnum = connarray_add_conn(temp);
396 temp->protocol.secret = ((unsigned int)rand())^(totalcount+((unsigned int)now));
397 temp->protocol.flags = MF_PLUG;
398 temp->protocol.latency = 0;
399 temp->protocol.chat.dnd = NULL;
400 temp->protocol.chat.away = NULL;
401 temp->protocol.chat.ignore_list = NULL;
402 temp->protocol.chat.ignore_count = 0;
403 temp->protocol.chat.quota.totcount = 0;
404 temp->protocol.chat.quota.list = list_create();
405 temp->protocol.client.versionid = 0;
406 temp->protocol.client.gameversion = 0;
407 temp->protocol.client.checksum = 0;
408 temp->protocol.client.archtag = 0;
409 temp->protocol.client.clienttag = 0;
410 temp->protocol.client.clientver = NULL;
411 temp->protocol.client.gamelang = 0;
412 temp->protocol.client.country = NULL;
413 temp->protocol.client.tzbias = 0;
414 temp->protocol.client.host = NULL;
415 temp->protocol.client.user = NULL;
416 temp->protocol.client.clientexe = NULL;
417 temp->protocol.client.owner = NULL;
418 temp->protocol.client.cdkey = NULL;
419 temp->protocol.client.versioncheck = NULL;
420 temp->protocol.account = NULL;
421 temp->protocol.chat.channel = NULL;
422 temp->protocol.chat.last_message = now;
423 temp->protocol.chat.lastsender = NULL;
424 temp->protocol.chat.irc.ircline = NULL;
425 temp->protocol.chat.irc.ircping = 0;
426 temp->protocol.chat.irc.ircpass = NULL;
427 temp->protocol.chat.tmpOP_channel = NULL;
428 temp->protocol.chat.tmpVOICE_channel = NULL;
429 temp->protocol.game = NULL;
430 temp->protocol.queues.outqueue = NULL;
431 temp->protocol.queues.outsize = 0;
432 temp->protocol.queues.outsizep = 0;
433 temp->protocol.queues.inqueue = NULL;
434 temp->protocol.queues.insize = 0;
435 temp->protocol.loggeduser = NULL;
436 temp->protocol.d2.realm = NULL;
437 rcm_regref_init(&temp->protocol.d2.realm_regref,&conn_set_realm_cb,temp);
438 temp->protocol.d2.character = NULL;
439 temp->protocol.d2.realminfo = NULL;
440 temp->protocol.d2.charname = NULL;
441 temp->protocol.w3.w3_playerinfo = NULL;
442 temp->protocol.w3.routeconn = NULL;
443 temp->protocol.w3.anongame = NULL;
444 temp->protocol.w3.anongame_search_starttime = 0;
445 temp->protocol.bound = NULL;
446 elist_init(&temp->protocol.timers);
447
448 temp->protocol.wol.ingame = 0;
449
450 temp->protocol.wol.codepage = 0;
451 temp->protocol.wol.locale = 0;
452 temp->protocol.wol.gameType = 0;
453
454 temp->protocol.wol.apgar = NULL;
455
456 temp->protocol.wol.gameOptions = NULL;
457
458
459 temp->protocol.cr_time = now;
460 temp->protocol.passfail_count = 0;
461
462
463 temp->protocol.cflags = 0;
464
465 list_prepend_data(conn_head,temp);
466
467 eventlog(eventlog_level_info,__FUNCTION__,"[%d][%d] sessionkey=0x%08x sessionnum=0x%08x",temp->socket.tcp_sock,temp->socket.udp_sock,temp->protocol.sessionkey,temp->protocol.sessionnum);
468
469 return temp;
470 }
471
472
conn_create_anongame(t_connection * c)473 extern t_anongame * conn_create_anongame(t_connection *c)
474 {
475 t_anongame * temp;
476 int i;
477
478 if(c->protocol.w3.anongame) {
479 eventlog(eventlog_level_error,__FUNCTION__,"anongame already allocated");
480 return c->protocol.w3.anongame;
481 }
482
483 temp = xmalloc(sizeof(t_anongame));
484 temp->count = 0;
485 temp->id = 0;
486 temp->tid = 0;
487
488 for (i=0; i < ANONGAME_MAX_GAMECOUNT/2; i++)
489 temp->tc[i] = NULL;
490
491 temp->race = 0;
492 temp->playernum = 0;
493 temp->handle = 0;
494 temp->addr = 0;
495 temp->loaded = 0;
496 temp->joined = 0;
497 temp->map_prefs = 0xffffffff;
498 temp->type = 0;
499 temp->gametype = 0;
500 temp->queue = 0;
501 temp->info = NULL;
502
503 c->protocol.w3.anongame = temp;
504
505 return temp;
506 }
507
conn_get_anongame(t_connection * c)508 extern t_anongame * conn_get_anongame(t_connection *c)
509 {
510 if(!c) {
511 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
512 return NULL;
513 }
514 return c->protocol.w3.anongame;
515 }
516
conn_destroy_anongame(t_connection * c)517 extern void conn_destroy_anongame(t_connection *c)
518 {
519 t_anongame * a;
520
521 if (!c)
522 {
523 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
524 return;
525 }
526
527 if (!(a = c->protocol.w3.anongame))
528 {
529 eventlog(eventlog_level_error,__FUNCTION__,"NULL anongame");
530 return;
531 }
532
533 // delete reference to this connection
534 if(a->info) {
535 a->info->player[a->playernum-1] = NULL;
536 if(--(a->info->currentplayers) == 0)
537 anongameinfo_destroy(a->info);
538 }
539
540 // [quetzal] 20020824
541 // unqueue from anongame search list,
542 // if we got AT game, unqueue entire team.
543 if (anongame_arranged(a->queue)) {
544 anongame_unqueue(a->tc[0], a->queue);
545 } else {
546 anongame_unqueue(c, a->queue);
547 }
548 xfree(c->protocol.w3.anongame);
549 c->protocol.w3.anongame = NULL;
550 }
551
conn_destroy(t_connection * c,t_elem ** elem,int conn_or_dead_list)552 extern void conn_destroy(t_connection * c, t_elem ** elem, int conn_or_dead_list)
553 {
554 char const * classstr;
555 t_elem * curr;
556
557
558 if (c == NULL) {
559 eventlog(eventlog_level_error, "conn_destroy", "got NULL connection");
560 return;
561 }
562
563 classstr = conn_class_get_str(c->protocol.class);
564
565 if (list_remove_data(conn_head,c,(conn_or_dead_list)?&curr:elem)<0)
566 {
567 eventlog(eventlog_level_error,__FUNCTION__,"could not remove item from list");
568 return;
569 }
570
571 if (c->protocol.class==conn_class_d2cs_bnetd)
572 {
573 t_realm * realm;
574
575 realm=conn_get_realm(c);
576 if (realm)
577 realm_deactive(realm);
578 else
579 {
580 eventlog(eventlog_level_error,__FUNCTION__,"could not find realm for d2cs connection");
581 }
582 }
583 else if (c->protocol.class == conn_class_w3route && c->protocol.w3.routeconn && c->protocol.w3.routeconn->protocol.w3.anongame)
584 {
585 anongame_stats(c);
586 conn_destroy_anongame(c->protocol.w3.routeconn); // [zap-zero] destroy anongame too when game connection is invalid
587 }
588
589 if (c->protocol.d2.realm) {
590 realm_add_player_number(c->protocol.d2.realm,-1);
591 realm_put(c->protocol.d2.realm,&c->protocol.d2.realm_regref);
592 }
593
594
595 /* free the memory with user quota */
596 {
597 t_qline * qline;
598
599 LIST_TRAVERSE(c->protocol.chat.quota.list,curr)
600 {
601 qline = elem_get_data(curr);
602 xfree(qline);
603 list_remove_elem(c->protocol.chat.quota.list,&curr);
604 }
605 list_destroy(c->protocol.chat.quota.list);
606 }
607
608 /* if this user in a channel, notify everyone that the user has left */
609 if (c->protocol.chat.channel)
610 channel_del_connection(c->protocol.chat.channel,c);
611
612 if ((c->protocol.game) && (c->protocol.account))
613 {
614 if (game_get_status(c->protocol.game)==game_status_started)
615 {
616 game_set_self_report(c->protocol.game,c->protocol.account,game_result_disconnect);
617 game_set_report(c->protocol.game,c->protocol.account,"disconnect","disconnect");
618 }
619 }
620
621 conn_set_game(c,NULL,NULL,NULL,game_type_none,0);
622 c->protocol.state = conn_state_empty;
623
624 watchlist_del_all_events(c);
625 timerlist_del_all_timers(c);
626
627 clanmember_set_offline(c);
628
629 if(c->protocol.account)
630 watchlist_notify_event(c->protocol.account,NULL,c->protocol.client.clienttag,watch_event_logout);
631
632 if (c->protocol.client.versioncheck)
633 versioncheck_destroy((void *)c->protocol.client.versioncheck); /* avoid warning */
634
635 if (c->protocol.chat.lastsender)
636 xfree((void *)c->protocol.chat.lastsender); /* avoid warning */
637
638 if (c->protocol.chat.away)
639 xfree((void *)c->protocol.chat.away); /* avoid warning */
640 if (c->protocol.chat.dnd)
641 xfree((void *)c->protocol.chat.dnd); /* avoid warning */
642 if (c->protocol.chat.tmpOP_channel)
643 xfree((void *)c->protocol.chat.tmpOP_channel); /* avoid warning */
644 if (c->protocol.chat.tmpVOICE_channel)
645 xfree((void *)c->protocol.chat.tmpVOICE_channel); /* avoid warning */
646
647 if (c->protocol.client.clientver)
648 xfree((void *)c->protocol.client.clientver); /* avoid warning */
649 if (c->protocol.client.country)
650 xfree((void *)c->protocol.client.country); /* avoid warning */
651 if (c->protocol.client.host)
652 xfree((void *)c->protocol.client.host); /* avoid warning */
653 if (c->protocol.client.user)
654 xfree((void *)c->protocol.client.user); /* avoid warning */
655 if (c->protocol.client.clientexe)
656 xfree((void *)c->protocol.client.clientexe); /* avoid warning */
657 if (c->protocol.client.owner)
658 xfree((void *)c->protocol.client.owner); /* avoid warning */
659 if (c->protocol.client.cdkey)
660 xfree((void *)c->protocol.client.cdkey); /* avoid warning */
661 if (c->protocol.d2.realminfo)
662 xfree((void *)c->protocol.d2.realminfo); /* avoid warning */
663 if (c->protocol.d2.charname)
664 xfree((void *)c->protocol.d2.charname); /* avoid warning */
665 if (c->protocol.chat.irc.ircline)
666 xfree((void *)c->protocol.chat.irc.ircline); /* avoid warning */
667 if (c->protocol.chat.irc.ircpass)
668 xfree((void *)c->protocol.chat.irc.ircpass); /* avoid warning */
669
670 if (c->protocol.wol.apgar)
671 xfree((void *)c->protocol.wol.apgar); /* avoid warning */
672 if (c->protocol.wol.gameOptions)
673 xfree((void *)c->protocol.wol.gameOptions); /* avoid warning */
674
675 /* ADDED BY UNDYING SOULZZ 4/8/02 */
676 if (c->protocol.w3.w3_playerinfo)
677 xfree((void *)c->protocol.w3.w3_playerinfo); /* avoid warning */
678
679 if (c->protocol.bound)
680 c->protocol.bound->protocol.bound = NULL;
681
682 if (c->protocol.chat.ignore_count>0)
683 {
684 if (!c->protocol.chat.ignore_list)
685 { eventlog(eventlog_level_error,__FUNCTION__,"found NULL ignore_list with ignore_count=%u",c->protocol.chat.ignore_count); }
686 else
687 { xfree(c->protocol.chat.ignore_list); }
688 }
689
690 if (c->protocol.account)
691 {
692 eventlog(eventlog_level_info,__FUNCTION__,"[%d] \"%s\" logged out",c->socket.tcp_sock,conn_get_loggeduser(c));
693 //amadeo
694 #ifdef WIN32_GUI
695 guiOnUpdateUserList();
696 #endif
697 if (prefs_get_sync_on_logoff()) {
698 if (account_save(conn_get_account(c),FS_FORCE) < 0)
699 eventlog(eventlog_level_error,__FUNCTION__,"cannot sync account (sync_on_logoff)");
700 }
701
702 if (account_get_conn(c->protocol.account)==c) /* make sure you don't set this when allready on new conn (relogin with same account) */
703 account_set_conn(c->protocol.account,NULL);
704 c->protocol.account = NULL; /* the account code will free the memory later */
705 }
706
707 /* logged user is no longer only for logged in users */
708 if (c->protocol.loggeduser) xfree((void*)c->protocol.loggeduser);
709
710 /* make sure the connection is closed */
711 if (c->socket.tcp_sock!=-1) { /* -1 means that the socket was already closed by conn_close() */
712 fdwatch_del_fd(c->socket.fdw_idx);
713 psock_shutdown(c->socket.tcp_sock,PSOCK_SHUT_RDWR);
714 psock_close(c->socket.tcp_sock);
715 }
716 /* clear out the packet queues */
717 if (c->protocol.queues.inqueue) packet_del_ref(c->protocol.queues.inqueue);
718 queue_clear(&c->protocol.queues.outqueue);
719
720 // [zap-zero] 20020601
721 if (c->protocol.w3.routeconn) {
722 c->protocol.w3.routeconn->protocol.w3.routeconn = NULL;
723 if(c->protocol.w3.routeconn->protocol.class == conn_class_w3route)
724 conn_set_state(c->protocol.w3.routeconn, conn_state_destroy);
725 }
726
727 if(c->protocol.w3.anongame)
728 conn_destroy_anongame(c);
729
730 /* delete the conn from the dead list if its there, we dont check for error
731 * because connections may be destroyed without first setting state to destroy */
732 if (conn_dead) list_remove_data(conn_dead, c, (conn_or_dead_list)?elem:&curr);
733 connarray_del_conn(c->protocol.sessionnum);
734
735 eventlog(eventlog_level_info,__FUNCTION__,"[%d] closed %s connection",c->socket.tcp_sock,classstr);
736
737 xfree(c);
738 }
739
740
conn_match(t_connection const * c,char const * username)741 extern int conn_match(t_connection const * c, char const * username)
742 {
743 if (!c)
744 {
745 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
746 return -1;
747 }
748 if (!username)
749 {
750 eventlog(eventlog_level_error,__FUNCTION__,"got NULL username");
751 return -1;
752 }
753
754 if (!c->protocol.account)
755 return 0;
756
757 return account_match(c->protocol.account,username);
758 }
759
760
conn_get_class(t_connection const * c)761 extern t_conn_class conn_get_class(t_connection const * c)
762 {
763 if (!c)
764 {
765 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
766 return conn_class_none;
767 }
768
769 return c->protocol.class;
770 }
771
772
conn_set_class(t_connection * c,t_conn_class class)773 extern void conn_set_class(t_connection * c, t_conn_class class)
774 {
775 t_timer_data data;
776 unsigned long delta;
777 t_conn_class oldclass;
778
779 if (!c)
780 {
781 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
782 return;
783 }
784
785 if (c->protocol.class==class)
786 return;
787
788 oldclass = c->protocol.class;
789 c->protocol.class = class;
790
791 switch(class) {
792 case conn_class_bnet:
793 if (prefs_get_udptest_port()!=0)
794 conn_set_game_port(c,(unsigned short)prefs_get_udptest_port());
795 udptest_send(c);
796
797 /* remove any init timers */
798 if (oldclass == conn_class_init) timerlist_del_all_timers(c);
799 delta = prefs_get_latency();
800 data.n = delta;
801 if (timerlist_add_timer(c,now+(time_t)delta,conn_test_latency,data)<0)
802 eventlog(eventlog_level_error,__FUNCTION__,"could not add timer");
803
804 eventlog(eventlog_level_debug,__FUNCTION__,"added latency check timer");
805 break;
806
807 case conn_class_w3route:
808 delta = prefs_get_latency();
809 data.n = delta;
810 if (timerlist_add_timer(c,now+(time_t)delta,conn_test_latency,data)<0)
811 eventlog(eventlog_level_error,__FUNCTION__,"could not add timer");
812 break;
813
814 case conn_class_bot:
815 case conn_class_telnet:
816 {
817 t_packet * rpacket;
818 if (class==conn_class_bot) {
819 if ((delta = prefs_get_nullmsg())>0) {
820 data.n = delta;
821 if (timerlist_add_timer(c,now+(time_t)delta,conn_send_nullmsg,data)<0)
822 eventlog(eventlog_level_error,__FUNCTION__,"could not add timer");
823 }
824 }
825
826 /* remove any init timers */
827 if (oldclass == conn_class_init) timerlist_del_all_timers(c);
828 conn_send_issue(c);
829
830 if (!(rpacket = packet_create(packet_class_raw)))
831 eventlog(eventlog_level_error,__FUNCTION__,"could not create rpacket");
832 else {
833 packet_append_ntstring(rpacket,"Username: ");
834 conn_push_outqueue(c,rpacket);
835 packet_del_ref(rpacket);
836 }
837
838 break;
839 }
840
841 default:
842 /* remove any init timers */
843 if (oldclass == conn_class_init)
844 timerlist_del_all_timers(c);
845 break;
846 }
847
848 }
849
850
conn_get_state(t_connection const * c)851 extern t_conn_state conn_get_state(t_connection const * c)
852 {
853 if (!c)
854 {
855 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
856 return conn_state_empty;
857 }
858
859 return c->protocol.state;
860 }
861
862
conn_set_state(t_connection * c,t_conn_state state)863 extern void conn_set_state(t_connection * c, t_conn_state state)
864 {
865 t_elem * elem;
866
867 if (!c)
868 {
869 eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
870 return;
871 }
872
873 /* special case for destroying connections, add them to conn_dead list */
874 if (state == conn_state_destroy && c->protocol.state != conn_state_destroy) {
875 if (!conn_dead)
876 conn_dead = list_create();
877 list_append_data(conn_dead, c);
878 }
879 else if (state != conn_state_destroy && c->protocol.state == conn_state_destroy)
880 if (list_remove_data(conn_dead, c, &elem)) {
881 eventlog(eventlog_level_error, __FUNCTION__, "could not remove dead connection");
882 return;
883 }
884
885 c->protocol.state = state;
886 }
887
conn_get_sessionkey(t_connection const * c)888 extern unsigned int conn_get_sessionkey(t_connection const * c)
889 {
890 if (!c)
891 {
892 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
893 return 0;
894 }
895
896 return c->protocol.sessionkey;
897 }
898
899
conn_get_sessionnum(t_connection const * c)900 extern unsigned int conn_get_sessionnum(t_connection const * c)
901 {
902 if (!c)
903 {
904 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
905 return 0;
906 }
907
908 return c->protocol.sessionnum;
909 }
910
911
conn_get_secret(t_connection const * c)912 extern unsigned int conn_get_secret(t_connection const * c)
913 {
914 if (!c)
915 {
916 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
917 return 0;
918 }
919
920 return c->protocol.secret;
921 }
922
923
conn_get_addr(t_connection const * c)924 extern unsigned int conn_get_addr(t_connection const * c)
925 {
926 if (!c)
927 {
928 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
929 return 0;
930 }
931
932 return c->socket.tcp_addr;
933 }
934
935
conn_get_port(t_connection const * c)936 extern unsigned short conn_get_port(t_connection const * c)
937 {
938 if (!c)
939 {
940 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
941 return 0;
942 }
943
944 return c->socket.tcp_port;
945 }
946
947
conn_get_local_addr(t_connection const * c)948 extern unsigned int conn_get_local_addr(t_connection const * c)
949 {
950 if (!c)
951 {
952 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
953 return 0;
954 }
955
956 return c->socket.local_addr;
957 }
958
959
conn_get_local_port(t_connection const * c)960 extern unsigned short conn_get_local_port(t_connection const * c)
961 {
962 if (!c)
963 {
964 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
965 return 0;
966 }
967
968 return c->socket.local_port;
969 }
970
971
conn_get_real_local_addr(t_connection const * c)972 extern unsigned int conn_get_real_local_addr(t_connection const * c)
973 {
974 if (!c)
975 {
976 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
977 return 0;
978 }
979
980 return c->socket.real_local_addr;
981 }
982
983
conn_get_real_local_port(t_connection const * c)984 extern unsigned short conn_get_real_local_port(t_connection const * c)
985 {
986 if (!c)
987 {
988 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
989 return 0;
990 }
991
992 return c->socket.real_local_port;
993 }
994
995
conn_get_game_addr(t_connection const * c)996 extern unsigned int conn_get_game_addr(t_connection const * c)
997 {
998 if (!c)
999 {
1000 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1001 return 0;
1002 }
1003
1004 return c->socket.udp_addr;
1005 }
1006
1007
conn_set_game_addr(t_connection * c,unsigned int game_addr)1008 extern int conn_set_game_addr(t_connection * c, unsigned int game_addr)
1009 {
1010 if (!c)
1011 {
1012 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1013 return -1;
1014 }
1015
1016 c->socket.udp_addr = game_addr;
1017 return 0;
1018 }
1019
1020
conn_get_game_port(t_connection const * c)1021 extern unsigned short conn_get_game_port(t_connection const * c)
1022 {
1023 if (!c)
1024 {
1025 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1026 return 0;
1027 }
1028
1029 return c->socket.udp_port;
1030 }
1031
1032
conn_set_game_port(t_connection * c,unsigned short game_port)1033 extern int conn_set_game_port(t_connection * c, unsigned short game_port)
1034 {
1035 if (!c)
1036 {
1037 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1038 return -1;
1039 }
1040
1041 c->socket.udp_port = game_port;
1042 return 0;
1043 }
1044
1045
conn_set_host(t_connection * c,char const * host)1046 extern void conn_set_host(t_connection * c, char const * host)
1047 {
1048 if (!c)
1049 {
1050 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1051 return;
1052 }
1053 if (!host)
1054 {
1055 eventlog(eventlog_level_error,__FUNCTION__,"got NULL host");
1056 return;
1057 }
1058
1059 if (c->protocol.client.host)
1060 xfree((void *)c->protocol.client.host); /* avoid warning */
1061 c->protocol.client.host = xstrdup(host);
1062 }
1063
1064
conn_set_user(t_connection * c,char const * user)1065 extern void conn_set_user(t_connection * c, char const * user)
1066 {
1067 if (!c)
1068 {
1069 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1070 return;
1071 }
1072 if (!user)
1073 {
1074 eventlog(eventlog_level_error,__FUNCTION__,"got NULL user");
1075 return;
1076 }
1077
1078 if (c->protocol.client.user)
1079 xfree((void *)c->protocol.client.user); /* avoid warning */
1080 c->protocol.client.user = xstrdup(user);
1081 }
1082
1083
conn_set_owner(t_connection * c,char const * owner)1084 extern void conn_set_owner(t_connection * c, char const * owner)
1085 {
1086 if (!c)
1087 {
1088 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1089 return;
1090 }
1091 if (!owner)
1092 {
1093 eventlog(eventlog_level_error,__FUNCTION__,"got NULL owner");
1094 return;
1095 }
1096
1097 if (c->protocol.client.owner)
1098 xfree((void *)c->protocol.client.owner); /* avoid warning */
1099 c->protocol.client.owner = xstrdup(owner);
1100 }
1101
conn_get_user(t_connection const * c)1102 extern const char * conn_get_user(t_connection const * c)
1103 {
1104 if (!c) {
1105 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1106 return NULL;
1107 }
1108 return c->protocol.client.user;
1109 }
1110
conn_get_owner(t_connection const * c)1111 extern const char * conn_get_owner(t_connection const * c)
1112 {
1113 if (!c) {
1114 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1115 return NULL;
1116 }
1117 return c->protocol.client.owner;
1118 }
1119
conn_set_cdkey(t_connection * c,char const * cdkey)1120 extern void conn_set_cdkey(t_connection * c, char const * cdkey)
1121 {
1122 if (!c)
1123 {
1124 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1125 return;
1126 }
1127 if (!cdkey)
1128 {
1129 eventlog(eventlog_level_error,__FUNCTION__,"got NULL cdkey");
1130 return;
1131 }
1132
1133 if (c->protocol.client.cdkey)
1134 xfree((void *)c->protocol.client.cdkey); /* avoid warning */
1135 c->protocol.client.cdkey = xstrdup(cdkey);
1136 }
1137
1138
conn_get_clientexe(t_connection const * c)1139 extern char const * conn_get_clientexe(t_connection const * c)
1140 {
1141 if (!c)
1142 {
1143 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1144 return NULL;
1145 }
1146
1147 if (!c->protocol.client.clientexe)
1148 return "";
1149 return c->protocol.client.clientexe;
1150 }
1151
1152
conn_set_clientexe(t_connection * c,char const * clientexe)1153 extern void conn_set_clientexe(t_connection * c, char const * clientexe)
1154 {
1155 char const * temp;
1156
1157 if (!c)
1158 {
1159 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1160 return;
1161 }
1162 if (!clientexe)
1163 {
1164 eventlog(eventlog_level_error,__FUNCTION__,"got NULL clientexe");
1165 return;
1166 }
1167
1168 temp = xstrdup(clientexe);
1169 if (c->protocol.client.clientexe)
1170 xfree((void *)c->protocol.client.clientexe); /* avoid warning */
1171 c->protocol.client.clientexe = temp;
1172 }
1173
1174
conn_get_clientver(t_connection const * c)1175 extern char const * conn_get_clientver(t_connection const * c)
1176 {
1177 if (!c)
1178 {
1179 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1180 return NULL;
1181 }
1182
1183 if (!c->protocol.client.clientver)
1184 return "";
1185 return c->protocol.client.clientver;
1186 }
1187
1188
conn_set_clientver(t_connection * c,char const * clientver)1189 extern void conn_set_clientver(t_connection * c, char const * clientver)
1190 {
1191 char const * temp;
1192
1193 if (!c)
1194 {
1195 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1196 return;
1197 }
1198 if (!clientver)
1199 {
1200 eventlog(eventlog_level_error,__FUNCTION__,"got NULL clientver");
1201 return;
1202 }
1203
1204 temp = xstrdup(clientver);
1205 if (c->protocol.client.clientver)
1206 xfree((void *)c->protocol.client.clientver); /* avoid warning */
1207 c->protocol.client.clientver = temp;
1208 }
1209
1210
conn_get_archtag(t_connection const * c)1211 extern t_tag conn_get_archtag(t_connection const * c)
1212 {
1213 if (!c) {
1214 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1215 return 0; /* unknown */
1216 }
1217
1218 return c->protocol.client.archtag;
1219 }
1220
1221
conn_set_archtag(t_connection * c,t_tag archtag)1222 extern void conn_set_archtag(t_connection * c, t_tag archtag)
1223 {
1224 char archtag_str[5];
1225
1226 if (!c) {
1227 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1228 return;
1229 }
1230 if (!tag_check_arch(archtag)) {
1231 eventlog(eventlog_level_error,__FUNCTION__,"got UNKNOWN archtag");
1232 return;
1233 }
1234 if (c->protocol.client.archtag!=archtag)
1235 eventlog(eventlog_level_info,__FUNCTION__,"[%d] setting client arch to \"%s\"",conn_get_socket(c),tag_uint_to_str(archtag_str,archtag));
1236
1237 c->protocol.client.archtag = archtag;
1238 }
1239
1240
conn_get_gamelang(t_connection const * c)1241 extern t_tag conn_get_gamelang(t_connection const * c)
1242 {
1243 if (!c)
1244 {
1245 eventlog(eventlog_level_error, __FUNCTION__,"got NULL connection");
1246 return 0;
1247 }
1248
1249 return c->protocol.client.gamelang;
1250 }
1251
1252
conn_set_gamelang(t_connection * c,t_tag gamelang)1253 extern void conn_set_gamelang(t_connection * c, t_tag gamelang)
1254 {
1255 char gamelang_str[5];
1256
1257 if (!c) {
1258 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1259 return;
1260 }
1261 if (!gamelang)
1262 return; /* only war3 & w3xp have gamelang */
1263
1264 if (!tag_check_gamelang(gamelang)) {
1265 eventlog(eventlog_level_error,__FUNCTION__,"got UNKNOWN gamelang");
1266 return;
1267 }
1268 if (c->protocol.client.gamelang!=gamelang)
1269 eventlog(eventlog_level_info,__FUNCTION__,"[%d] setting client gamelang to \"%s\"",conn_get_socket(c),tag_uint_to_str(gamelang_str,gamelang));
1270
1271 c->protocol.client.gamelang = gamelang;
1272 }
1273
1274
conn_get_clienttag(t_connection const * c)1275 extern t_clienttag conn_get_clienttag(t_connection const * c)
1276 {
1277 if (!c)
1278 {
1279 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1280 return CLIENTTAG_UNKNOWN_UINT;
1281 }
1282
1283 if (!c->protocol.client.clienttag)
1284 return CLIENTTAG_UNKNOWN_UINT;
1285 return c->protocol.client.clienttag;
1286 }
1287
1288
conn_get_fake_clienttag(t_connection const * c)1289 extern t_clienttag conn_get_fake_clienttag(t_connection const * c)
1290 {
1291 char const * clienttag;
1292 t_account * account;
1293
1294 if (!c)
1295 {
1296 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1297 return 0; /* unknown */
1298 }
1299
1300 account = conn_get_account(c);
1301 if (account) /* BITS remote connections don't need to have an account */
1302 if ((clienttag = account_get_strattr(account,"BNET\\fakeclienttag")))
1303 return tag_str_to_uint(clienttag);
1304 return c->protocol.client.clienttag;
1305 }
1306
1307
conn_set_clienttag(t_connection * c,t_clienttag clienttag)1308 extern void conn_set_clienttag(t_connection * c, t_clienttag clienttag)
1309 {
1310 char clienttag_str[5];
1311
1312 if (!c) {
1313 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1314 return;
1315 }
1316 if (!tag_check_client(clienttag)) {
1317 eventlog(eventlog_level_error,__FUNCTION__,"got UNKNOWN clienttag \"%s\"",tag_uint_to_str(clienttag_str,clienttag));
1318 return;
1319 }
1320 if (c->protocol.client.clienttag!=clienttag) {
1321 eventlog(eventlog_level_info,__FUNCTION__,"[%d] setting client type to \"%s\"",conn_get_socket(c),tag_uint_to_str(clienttag_str,clienttag));
1322 c->protocol.client.clienttag = clienttag;
1323 if (c->protocol.chat.channel)
1324 channel_update_userflags(c);
1325 }
1326
1327 }
1328
1329
conn_get_gameversion(t_connection const * c)1330 extern unsigned long conn_get_gameversion(t_connection const * c)
1331 {
1332 if (!c)
1333 {
1334 eventlog(eventlog_level_error, __FUNCTION__,"got NULL connection");
1335 return 0;
1336 }
1337
1338 return c->protocol.client.gameversion;
1339 }
1340
1341
conn_set_gameversion(t_connection * c,unsigned long gameversion)1342 extern int conn_set_gameversion(t_connection * c, unsigned long gameversion)
1343 {
1344 if (!c)
1345 {
1346 eventlog(eventlog_level_error, __FUNCTION__,"got NULL connection");
1347 return -1;
1348 }
1349
1350 c->protocol.client.gameversion = gameversion;
1351 return 0;
1352 }
1353
1354
conn_get_checksum(t_connection const * c)1355 extern unsigned long conn_get_checksum(t_connection const * c)
1356 {
1357 if (!c)
1358 {
1359 eventlog(eventlog_level_error, __FUNCTION__,"got NULL connection");
1360 return 0;
1361 }
1362
1363 return c->protocol.client.checksum;
1364 }
1365
1366
conn_set_checksum(t_connection * c,unsigned long checksum)1367 extern int conn_set_checksum(t_connection * c, unsigned long checksum)
1368 {
1369 if (!c)
1370 {
1371 eventlog(eventlog_level_error, __FUNCTION__,"got NULL connection");
1372 return -1;
1373 }
1374
1375 c->protocol.client.checksum = checksum;
1376 return 0;
1377 }
1378
1379
conn_get_versionid(t_connection const * c)1380 extern unsigned long conn_get_versionid(t_connection const * c)
1381 {
1382 if (!c)
1383 {
1384 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1385 return 0;
1386 }
1387
1388 return c->protocol.client.versionid;
1389 }
1390
1391
conn_set_versionid(t_connection * c,unsigned long versionid)1392 extern int conn_set_versionid(t_connection * c, unsigned long versionid)
1393 {
1394 if (!c)
1395 {
1396 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1397 return -1;
1398 }
1399
1400 c->protocol.client.versionid = versionid;
1401 return 0;
1402 }
1403
1404
conn_get_tzbias(t_connection const * c)1405 extern int conn_get_tzbias(t_connection const * c)
1406 {
1407 if (!c)
1408 {
1409 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1410 return 0;
1411 }
1412
1413 return c->protocol.client.tzbias;
1414 }
1415
1416
conn_set_tzbias(t_connection * c,int tzbias)1417 extern void conn_set_tzbias(t_connection * c, int tzbias)
1418 {
1419 if (!c)
1420 {
1421 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1422 return;
1423 }
1424
1425 c->protocol.client.tzbias = tzbias;
1426 }
1427
1428
conn_set_account(t_connection * c,t_account * account)1429 static void conn_set_account(t_connection * c, t_account * account)
1430 {
1431 t_connection * other;
1432 char const * tname;
1433
1434 if (!c)
1435 {
1436 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1437 return;
1438 }
1439 if (!account)
1440 {
1441 eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");
1442 return;
1443 }
1444
1445 if ((other = connlist_find_connection_by_accountname((tname = account_get_name(account)))))
1446 {
1447 eventlog(eventlog_level_info,__FUNCTION__,"[%d] forcing logout of previous login for \"%s\"",conn_get_socket(c),tname);
1448 conn_set_state(other, conn_state_destroy);
1449 }
1450
1451 c->protocol.account = account;
1452 c->protocol.state = conn_state_loggedin;
1453 account_set_conn(account,c);
1454 {
1455 char const * flagstr;
1456
1457 if ((flagstr = account_get_strattr(account,"BNET\\flags\\initial")))
1458 conn_add_flags(c,strtoul(flagstr,NULL,0));
1459 }
1460
1461 account_set_ll_time(c->protocol.account,(unsigned int)now);
1462 account_set_ll_owner(c->protocol.account,c->protocol.client.owner);
1463 account_set_ll_clienttag(c->protocol.account,c->protocol.client.clienttag);
1464 account_set_ll_ip(c->protocol.account,addr_num_to_ip_str(c->socket.tcp_addr));
1465
1466 if (c->protocol.client.host)
1467 {
1468 xfree((void *)c->protocol.client.host); /* avoid warning */
1469 c->protocol.client.host = NULL;
1470 }
1471 if (c->protocol.client.user)
1472 {
1473 xfree((void *)c->protocol.client.user); /* avoid warning */
1474 c->protocol.client.user = NULL;
1475 }
1476 if (c->protocol.client.clientexe)
1477 {
1478 xfree((void *)c->protocol.client.clientexe); /* avoid warning */
1479 c->protocol.client.clientexe = NULL;
1480 }
1481 if (c->protocol.client.owner)
1482 {
1483 xfree((void *)c->protocol.client.owner); /* avoid warning */
1484 c->protocol.client.owner = NULL;
1485 }
1486 if (c->protocol.client.cdkey)
1487 {
1488 xfree((void *)c->protocol.client.cdkey); /* avoid warning */
1489 c->protocol.client.cdkey = NULL;
1490 }
1491
1492 clanmember_set_online(c);
1493
1494 totalcount++;
1495
1496 watchlist_notify_event(c->protocol.account,NULL,c->protocol.client.clienttag,watch_event_login);
1497
1498 return;
1499 }
1500
1501
conn_login(t_connection * c,t_account * a,const char * loggeduser)1502 extern void conn_login(t_connection *c, t_account *a, const char *loggeduser)
1503 {
1504 assert(c != NULL);
1505 assert(a != NULL);
1506 assert(loggeduser != NULL);
1507
1508 conn_set_account(c,a);
1509 if (strcmp(conn_get_loggeduser(c),loggeduser))
1510 conn_set_loggeduser(c,loggeduser);
1511 }
1512
1513
conn_get_account(t_connection const * c)1514 extern t_account * conn_get_account(t_connection const * c)
1515 {
1516 if (!c)
1517 {
1518 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1519 return NULL;
1520 }
1521
1522 return c->protocol.account;
1523 }
1524
1525
conn_set_loggeduser(t_connection * c,char const * username)1526 extern int conn_set_loggeduser(t_connection * c, char const * username)
1527 {
1528 const char * temp;
1529
1530 assert(c != NULL);
1531 assert(username != NULL);
1532
1533 if (username[0]!='#')
1534 temp = xstrdup(username);
1535 else {
1536 unsigned int userid=0;
1537 str_to_uint(&username[1],&userid);
1538 if (userid!=0){
1539 if (prefs_get_account_force_username()){
1540 t_account* account = accountlist_find_account_by_uid(userid);
1541 temp = xstrdup(account_get_name(account));
1542 }
1543 else{
1544 char uid_string[USER_NAME_MAX];
1545 sprintf(uid_string,"#%u",userid);
1546 temp = xstrdup(uid_string);
1547 }
1548 }
1549 else{ //theoretically this should never happen...
1550 eventlog(eventlog_level_error,__FUNCTION__,"got invalid numeric uid \"%s\"",username);
1551 // set value that would have been set prior to this bugfix...
1552 temp = xstrdup(username);
1553 }
1554 }
1555 if (c->protocol.loggeduser) xfree((void*)c->protocol.loggeduser);
1556
1557 c->protocol.loggeduser = temp;
1558
1559 return 0;
1560 }
1561
1562
conn_get_loggeduser(t_connection const * c)1563 extern char const * conn_get_loggeduser(t_connection const * c)
1564 {
1565 assert(c != NULL);
1566
1567 if (!c->protocol.loggeduser && c->protocol.account)
1568 return account_get_name(c->protocol.account);
1569 return c->protocol.loggeduser;
1570 }
1571
1572
conn_get_flags(t_connection const * c)1573 extern unsigned int conn_get_flags(t_connection const * c)
1574 {
1575 if (!c)
1576 {
1577 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1578 return 0;
1579 }
1580
1581 return c->protocol.flags;
1582 }
1583
1584
conn_set_flags(t_connection * c,unsigned int flags)1585 extern int conn_set_flags(t_connection * c, unsigned int flags)
1586 {
1587 if (!c) {
1588 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1589 return -1;
1590 }
1591
1592 if (flags!=c->protocol.flags) {
1593 c->protocol.flags = flags;
1594 if (c->protocol.chat.channel) channel_update_userflags(c);
1595 }
1596
1597 return 0;
1598 }
1599
1600
conn_add_flags(t_connection * c,unsigned int flags)1601 extern void conn_add_flags(t_connection * c, unsigned int flags)
1602 {
1603 unsigned int oldflags;
1604
1605 if (!c)
1606 {
1607 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1608 return;
1609 }
1610 oldflags = c->protocol.flags;
1611 c->protocol.flags |= flags;
1612
1613 if (oldflags!=c->protocol.flags && c->protocol.chat.channel)
1614 channel_update_userflags(c);
1615 }
1616
1617
conn_del_flags(t_connection * c,unsigned int flags)1618 extern void conn_del_flags(t_connection * c, unsigned int flags)
1619 {
1620 unsigned int oldflags;
1621
1622 if (!c)
1623 {
1624 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1625 return;
1626 }
1627 oldflags = c->protocol.flags;
1628 c->protocol.flags &= ~flags;
1629
1630 if (oldflags!=c->protocol.flags && c->protocol.chat.channel)
1631 channel_update_userflags(c);
1632 }
1633
1634
conn_get_latency(t_connection const * c)1635 extern unsigned int conn_get_latency(t_connection const * c)
1636 {
1637 if (!c)
1638 {
1639 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1640 return 0;
1641 }
1642
1643 return c->protocol.latency;
1644 }
1645
1646
conn_set_latency(t_connection * c,unsigned int ms)1647 extern void conn_set_latency(t_connection * c, unsigned int ms)
1648 {
1649 if (!c)
1650 {
1651 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1652 return;
1653 }
1654
1655
1656 if (c->protocol.latency != ms)
1657 {
1658 c->protocol.latency = ms;
1659
1660 if (c->protocol.chat.channel)
1661 channel_update_latency(c);
1662 }
1663 }
1664
1665
conn_get_awaystr(t_connection const * c)1666 extern char const * conn_get_awaystr(t_connection const * c)
1667 {
1668 if (!c)
1669 {
1670 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1671 return NULL;
1672 }
1673
1674 return c->protocol.chat.away;
1675 }
1676
1677
conn_set_awaystr(t_connection * c,char const * away)1678 extern int conn_set_awaystr(t_connection * c, char const * away)
1679 {
1680 if (!c)
1681 {
1682 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1683 return -1;
1684 }
1685
1686 if (c->protocol.chat.away)
1687 xfree((void *)c->protocol.chat.away); /* avoid warning */
1688 if (!away)
1689 c->protocol.chat.away = NULL;
1690 else
1691 c->protocol.chat.away = xstrdup(away);
1692
1693 return 0;
1694 }
1695
1696
conn_get_dndstr(t_connection const * c)1697 extern char const * conn_get_dndstr(t_connection const * c)
1698 {
1699 if (!c)
1700 {
1701 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1702 return NULL;
1703 }
1704
1705 return c->protocol.chat.dnd;
1706 }
1707
1708
conn_set_dndstr(t_connection * c,char const * dnd)1709 extern int conn_set_dndstr(t_connection * c, char const * dnd)
1710 {
1711 if (!c)
1712 {
1713 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1714 return -1;
1715 }
1716
1717 if (c->protocol.chat.dnd)
1718 xfree((void *)c->protocol.chat.dnd); /* avoid warning */
1719 if (!dnd)
1720 c->protocol.chat.dnd = NULL;
1721 else
1722 c->protocol.chat.dnd = xstrdup(dnd);
1723
1724 return 0;
1725 }
1726
1727
conn_add_ignore(t_connection * c,t_account * account)1728 extern int conn_add_ignore(t_connection * c, t_account * account)
1729 {
1730 t_account * * newlist;
1731 t_connection *dest_c;
1732
1733 if (!c) {
1734 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1735 return -1;
1736 }
1737
1738 if (!account) {
1739 eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");
1740 return -1;
1741 }
1742
1743 newlist = xrealloc(c->protocol.chat.ignore_list,sizeof(t_account const *)*(c->protocol.chat.ignore_count+1));
1744 newlist[c->protocol.chat.ignore_count++] = account;
1745 c->protocol.chat.ignore_list = newlist;
1746
1747 dest_c = account_get_conn(account);
1748 if (dest_c) {
1749 t_message *message;
1750
1751 message = message_create(message_type_userflags,dest_c,NULL,NULL);
1752 if (!message) return 0;
1753 message_send(message,c);
1754 message_destroy(message);
1755 }
1756
1757 return 0;
1758 }
1759
1760
conn_del_ignore(t_connection * c,t_account const * account)1761 extern int conn_del_ignore(t_connection * c, t_account const * account)
1762 {
1763 t_account * * newlist;
1764 t_account * temp;
1765 unsigned int i;
1766
1767 if (!c)
1768 {
1769 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1770 return -1;
1771 }
1772 if (!account)
1773 {
1774 eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");
1775 return -1;
1776 }
1777
1778 for (i=0; i<c->protocol.chat.ignore_count; i++)
1779 if (c->protocol.chat.ignore_list[i]==account)
1780 break;
1781 if (i==c->protocol.chat.ignore_count)
1782 return -1; /* not in list */
1783
1784 /* swap entry to be deleted with last entry */
1785 temp = c->protocol.chat.ignore_list[c->protocol.chat.ignore_count-1];
1786 c->protocol.chat.ignore_list[c->protocol.chat.ignore_count-1] = c->protocol.chat.ignore_list[i];
1787 c->protocol.chat.ignore_list[i] = temp;
1788
1789 if (c->protocol.chat.ignore_count==1) /* some realloc()s are buggy */
1790 {
1791 xfree(c->protocol.chat.ignore_list);
1792 newlist = NULL;
1793 }
1794 else
1795 newlist = xrealloc(c->protocol.chat.ignore_list,sizeof(t_account const *)*(c->protocol.chat.ignore_count-1));
1796
1797 c->protocol.chat.ignore_count--;
1798 c->protocol.chat.ignore_list = newlist;
1799
1800 return 0;
1801 }
1802
1803
conn_add_watch(t_connection * c,t_account * account,t_clienttag clienttag)1804 extern int conn_add_watch(t_connection * c, t_account * account, t_clienttag clienttag)
1805 {
1806 if (!c)
1807 {
1808 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1809 return -1;
1810 }
1811
1812 if (watchlist_add_events(c,account,clienttag,watch_event_login|watch_event_logout|watch_event_joingame|watch_event_leavegame)<0)
1813 return -1;
1814 return 0;
1815 }
1816
1817
conn_del_watch(t_connection * c,t_account * account,t_clienttag clienttag)1818 extern int conn_del_watch(t_connection * c, t_account * account, t_clienttag clienttag)
1819 {
1820 if (!c)
1821 {
1822 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1823 return -1;
1824 }
1825
1826 if (watchlist_del_events(c,account,clienttag,watch_event_login|watch_event_logout|watch_event_joingame|watch_event_leavegame)<0)
1827 return -1;
1828 return 0;
1829 }
1830
1831
conn_check_ignoring(t_connection const * c,char const * me)1832 extern int conn_check_ignoring(t_connection const * c, char const * me)
1833 {
1834 unsigned int i;
1835 t_account * temp;
1836
1837 if (!c)
1838 {
1839 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1840 return -1;
1841 }
1842
1843 if (!me || !(temp = accountlist_find_account(me)))
1844 return -1;
1845
1846 if (c->protocol.chat.ignore_list)
1847 for (i=0; i<c->protocol.chat.ignore_count; i++)
1848 if (c->protocol.chat.ignore_list[i]==temp)
1849 return 1;
1850
1851 return 0;
1852 }
1853
1854
conn_get_channel(t_connection const * c)1855 extern t_channel * conn_get_channel(t_connection const * c)
1856 {
1857 if (!c)
1858 {
1859 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1860 return NULL;
1861 }
1862
1863 return c->protocol.chat.channel;
1864 }
1865
1866
conn_set_channel_var(t_connection * c,t_channel * channel)1867 extern int conn_set_channel_var(t_connection * c, t_channel * channel)
1868 {
1869 if (!c)
1870 {
1871 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1872 return -1;
1873 }
1874 c->protocol.chat.channel = channel;
1875 return 0;
1876 }
1877
1878
conn_set_channel(t_connection * c,char const * channelname)1879 extern int conn_set_channel(t_connection * c, char const * channelname)
1880 {
1881 t_channel * channel;
1882 t_channel * oldchannel;
1883 t_account * acc;
1884 t_elem * curr;
1885 int clantag=0;
1886 t_clan * clan = NULL;
1887 t_clanmember * member = NULL;
1888
1889 if (!c)
1890 {
1891 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1892 return -1;
1893 }
1894
1895 acc = c->protocol.account;
1896
1897 if (!acc)
1898 {
1899 eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");
1900 return -1;
1901 }
1902
1903 if (channelname)
1904 {
1905 unsigned int created;
1906
1907 oldchannel=c->protocol.chat.channel;
1908
1909 channel = channellist_find_channel_by_name(channelname,conn_get_country(c),realm_get_name(conn_get_realm(c)));
1910
1911 if(channel && (channel == oldchannel))
1912 return 0;
1913
1914 if((strncasecmp(channelname, "clan ", 5)==0)&&(strlen(channelname)<10))
1915 clantag = str_to_clantag(&channelname[5]);
1916
1917 if ((clantag) && !((account_get_auth_admin(acc,channelname) == 1) || (account_get_auth_admin(acc,NULL) == 1))) {
1918 /* PELISH: Admins should be possible to join any channel */
1919 clan = account_get_clan(acc);
1920 if ((!clan) || (clan_get_clantag(clan) != clantag)) {
1921 if (!channel)
1922 {
1923 char msgtemp[MAX_MESSAGE_LEN];
1924 snprintf(msgtemp, sizeof(msgtemp), "Unable to join channel %s, there is no member of that clan in the channel!", channelname);
1925 message_send_text(c, message_type_error, c, msgtemp);
1926
1927 if (conn_get_game(c) || c->protocol.chat.channel==NULL) {
1928 // FIXME: This is not tested to be according to battle.net!!
1929 // This is fix for empty clan channels with preventing to join CHANNEL_NAME_BANNED when is used _handle_join_command
1930 snprintf(msgtemp, sizeof(msgtemp), "You have been redirected to %s.", CHANNEL_NAME_BANNED);
1931 message_send_text(c, message_type_error, c, msgtemp);
1932 channel = channellist_find_channel_by_name(CHANNEL_NAME_BANNED,conn_get_country(c),realm_get_name(conn_get_realm(c)));
1933 } else
1934 return 0;
1935 }
1936 else
1937 {
1938 t_clan * ch_clan;
1939 if((ch_clan=clanlist_find_clan_by_clantag(clantag))&&(clan_get_channel_type(ch_clan)==1))
1940 {
1941 message_send_text(c, message_type_error, c, "This is a private clan channel, unable to join!");
1942 return 0;
1943 }
1944 }
1945 }
1946 else {
1947 if ((clan) && (clan_get_clantag(clan) == clantag) && (member = account_get_clanmember(acc))) {
1948 if (clanmember_get_status(member) >= CLAN_SHAMAN)
1949 /* PELISH: Giving tmpOP to SHAMAN and CHIEFTAIN on clanchannel */
1950 conn_set_tmpOP_channel(c,channelname);
1951 }
1952 }
1953 }
1954
1955 if (c->protocol.chat.channel)
1956 {
1957 channel_del_connection(c->protocol.chat.channel, c);
1958 c->protocol.chat.channel = NULL;
1959 }
1960
1961 if (channel)
1962 {
1963 if (channel_check_banning(channel,c))
1964 {
1965 message_send_text(c,message_type_error,c,"You are banned from that channel.");
1966 return -1;
1967 }
1968
1969 if ((account_get_auth_admin(acc,NULL)!=1) && (account_get_auth_admin(acc,channelname)!=1) &&
1970 (account_get_auth_operator(acc,NULL)!=1) && (account_get_auth_operator(acc,channelname)!=1) &&
1971 (channel_get_max(channel) == 0))
1972 {
1973 message_send_text(c,message_type_error,c,"That channel is for Admins/Operators only.");
1974 return -1;
1975 }
1976
1977 if ((account_get_auth_admin(acc,NULL)!=1) && (account_get_auth_admin(acc,channelname)!=1) &&
1978 (account_get_auth_operator(acc,NULL)!=1) && (account_get_auth_operator(acc,channelname)!=1) &&
1979 (channel_get_max(channel) != -1) && (channel_get_curr(channel)>=channel_get_max(channel)))
1980 {
1981 message_send_text(c,message_type_error,c,"The channel is currently full.");
1982 return -1;
1983 }
1984 }
1985
1986 if(conn_set_joingamewhisper_ack(c,0)<0)
1987 eventlog(eventlog_level_error,__FUNCTION__,"Unable to reset conn_set_joingamewhisper_ack flag");
1988
1989 if(conn_set_leavegamewhisper_ack(c,0)<0)
1990 eventlog(eventlog_level_error,__FUNCTION__,"Unable to reset conn_set_leavegamewhisper_ack flag");
1991
1992 /* if you're entering a channel, make sure they didn't exit a game without telling us */
1993 if (c->protocol.game)
1994 {
1995 game_del_player(conn_get_game(c),c);
1996 c->protocol.game = NULL;
1997 }
1998
1999 created = 0;
2000
2001 if (!channel)
2002 {
2003 if(clantag)
2004 channel = channel_create(channelname,channelname,NULL,0,1,1,prefs_get_chanlog(), NULL, NULL, (prefs_get_maxusers_per_channel() > 0) ? prefs_get_maxusers_per_channel() : -1, 0, 1,0);
2005 else
2006 channel = channel_create(channelname,channelname,NULL,0,1,1,prefs_get_chanlog(), NULL, NULL, (prefs_get_maxusers_per_channel() > 0) ? prefs_get_maxusers_per_channel() : -1, 0, 0,0);
2007 if (!channel)
2008 {
2009 eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create channel on join \"%s\"",conn_get_socket(c),channelname);
2010 return -1;
2011 }
2012 created = 1;
2013 }
2014
2015 c->protocol.chat.channel=channel;
2016
2017 if (channel_add_connection(channel,c)<0)
2018 {
2019 if (created)
2020 channel_destroy(channel,&curr);
2021 c->protocol.chat.channel = NULL;
2022 return -1;
2023 }
2024
2025 eventlog(eventlog_level_info,__FUNCTION__,"[%d] joined channel \"%s\"",conn_get_socket(c),channel_get_name(c->protocol.chat.channel));
2026 conn_send_welcome(c);
2027
2028 if(c->protocol.chat.channel && (channel_get_flags(c->protocol.chat.channel) & channel_flags_thevoid))
2029 message_send_text(c,message_type_info,c,"This channel does not have chat privileges.");
2030 if (clantag && clan && (clan_get_clantag(clan)==clantag))
2031 {
2032 char msgtemp[MAX_MESSAGE_LEN];
2033 sprintf(msgtemp,"%s",clan_get_motd(clan));
2034 message_send_text(c,message_type_info,c,msgtemp);
2035 }
2036
2037 if (channel_get_topic(channel_get_name(c->protocol.chat.channel)) && ((conn_get_class(c)!=conn_class_irc) ||
2038 (conn_get_class(c)!=conn_class_wol)))
2039 {
2040 char msgtemp[MAX_MESSAGE_LEN];
2041
2042 sprintf(msgtemp,"%s topic: %s",channel_get_name(c->protocol.chat.channel),channel_get_topic(channel_get_name(c->protocol.chat.channel)));
2043 message_send_text(c,message_type_info,c,msgtemp);
2044 }
2045
2046 if (c->protocol.chat.channel && (channel_get_flags(c->protocol.chat.channel) & channel_flags_moderated))
2047 message_send_text(c,message_type_error,c,"This channel is moderated.");
2048
2049 if(c->protocol.chat.channel!=oldchannel)
2050 clanmember_on_change_status_by_connection(c);
2051 }
2052 else
2053 {
2054 if (c->protocol.chat.channel)
2055 {
2056 channel_del_connection(c->protocol.chat.channel,c);
2057 c->protocol.chat.channel = NULL;
2058 }
2059 }
2060
2061 return 0;
2062 }
2063
2064
conn_get_game(t_connection const * c)2065 extern t_game * conn_get_game(t_connection const * c)
2066 {
2067 if (!c)
2068 {
2069 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2070 return NULL;
2071 }
2072
2073 return c->protocol.game;
2074 }
2075
2076
conn_set_game(t_connection * c,char const * gamename,char const * gamepass,char const * gameinfo,t_game_type type,int version)2077 extern int conn_set_game(t_connection * c, char const * gamename, char const * gamepass, char const * gameinfo, t_game_type type, int version)
2078 /*
2079 * If game not exists (create) version != 0 (called in handle_bnet.c, function _client_startgameX())
2080 * If game exists (join) version == 0 always (called in handle_bnet.c, function _client_joingame())
2081 * If game exists (join) gameinfo == "" (called in handle_bnet.c, function _client_joingame())
2082 * [KWS]
2083 */
2084 {
2085 if (!c) {
2086 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2087 return -1;
2088 }
2089
2090 if (c->protocol.game) {
2091 if (gamename) {
2092 if (strcasecmp(gamename,game_get_name(c->protocol.game)))
2093 eventlog(eventlog_level_error,__FUNCTION__,"[%d] tried to join a new game \"%s\" while already in a game \"%s\"!",conn_get_socket(c),gamename,game_get_name(c->protocol.game));
2094 else return 0;
2095 }
2096 game_del_player(conn_get_game(c),c);
2097 c->protocol.game = NULL;
2098 }
2099
2100 if (gamename) {
2101 if (!(c->protocol.game = gamelist_find_game(gamename,c->protocol.client.clienttag,type))
2102 /* do not allow creation of games with same name of same clienttag (yet) */
2103 && !gamelist_find_game(gamename,c->protocol.client.clienttag,game_type_all)) {
2104 c->protocol.game = game_create(gamename,gamepass,gameinfo,type,version,c->protocol.client.clienttag,conn_get_gameversion(c));
2105
2106 if (c->protocol.game && conn_get_realm(c) && conn_get_charname(c)) {
2107 game_set_realmname(c->protocol.game,realm_get_name(conn_get_realm(c)));
2108 realm_add_game_number(conn_get_realm(c),1);
2109 send_d2cs_gameinforeq(c);
2110 }
2111 }
2112
2113 if (c->protocol.game) {
2114 if (game_add_player(conn_get_game(c),gamepass,version,c)<0) {
2115 c->protocol.game = NULL; // bad password or version #
2116 return -1;
2117 }
2118
2119 if (game_is_ladder(c->protocol.game)) {
2120 if (c == game_get_owner(c->protocol.game))
2121 message_send_text(c,message_type_info,c,"Created ladder game");
2122 else
2123 message_send_text(c,message_type_info,c,"Joined ladder game");
2124 }
2125 }
2126 } else c->protocol.game = NULL;
2127
2128 return 0;
2129 }
2130
conn_get_tcpaddr(t_connection * c)2131 extern unsigned int conn_get_tcpaddr(t_connection * c)
2132 {
2133 if (!c)
2134 {
2135 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2136 return 0;
2137 }
2138
2139 return c->socket.tcp_addr;
2140 }
2141
2142
conn_get_in_queue(t_connection * c)2143 extern t_packet * conn_get_in_queue(t_connection * c)
2144 {
2145 assert(c);
2146
2147 return c->protocol.queues.inqueue;
2148 }
2149
2150
conn_put_in_queue(t_connection * c,t_packet * packet)2151 extern void conn_put_in_queue(t_connection * c, t_packet * packet)
2152 {
2153 assert(c);
2154
2155 c->protocol.queues.inqueue = packet;
2156 }
2157
2158
conn_get_in_size(t_connection const * c)2159 extern unsigned int conn_get_in_size(t_connection const * c)
2160 {
2161 if (!c)
2162 {
2163 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2164 return 0;
2165 }
2166
2167 return c->protocol.queues.insize;
2168 }
2169
2170
conn_set_in_size(t_connection * c,unsigned int size)2171 extern void conn_set_in_size(t_connection * c, unsigned int size)
2172 {
2173 if (!c)
2174 {
2175 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2176 return;
2177 }
2178
2179 c->protocol.queues.insize = size;
2180 }
2181
2182
conn_get_out_size(t_connection const * c)2183 extern unsigned int conn_get_out_size(t_connection const * c)
2184 {
2185 if (!c)
2186 {
2187 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2188 return 0;
2189 }
2190 return c->protocol.queues.outsize;
2191 }
2192
2193
conn_set_out_size(t_connection * c,unsigned int size)2194 extern void conn_set_out_size(t_connection * c, unsigned int size)
2195 {
2196 if (!c)
2197 {
2198 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2199 return;
2200 }
2201
2202 c->protocol.queues.outsize = size;
2203 }
2204
conn_push_outqueue(t_connection * c,t_packet * packet)2205 extern int conn_push_outqueue(t_connection * c, t_packet * packet)
2206 {
2207 if (!c)
2208 {
2209 eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
2210 return -1;
2211 }
2212
2213 if (!packet)
2214 {
2215 eventlog(eventlog_level_error, __FUNCTION__, "got NULL packet");
2216 return -1;
2217 }
2218
2219 queue_push_packet((t_queue * *)&c->protocol.queues.outqueue, packet);
2220 if (!c->protocol.queues.outsizep++) fdwatch_update_fd(c->socket.fdw_idx, fdwatch_type_read | fdwatch_type_write);
2221
2222 return 0;
2223 }
2224
conn_peek_outqueue(t_connection * c)2225 extern t_packet * conn_peek_outqueue(t_connection * c)
2226 {
2227 if (!c)
2228 {
2229 eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
2230 return NULL;
2231 }
2232
2233 return queue_peek_packet((t_queue const * const *)&c->protocol.queues.outqueue);
2234 }
2235
conn_pull_outqueue(t_connection * c)2236 extern t_packet * conn_pull_outqueue(t_connection * c)
2237 {
2238 if (!c)
2239 {
2240 eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
2241 return NULL;
2242 }
2243
2244 if (c->protocol.queues.outsizep) {
2245 if (!(--c->protocol.queues.outsizep)) fdwatch_update_fd(c->socket.fdw_idx, fdwatch_type_read);
2246 return queue_pull_packet((t_queue * *)&c->protocol.queues.outqueue);
2247 }
2248
2249 return NULL;
2250 }
2251
conn_get_username_real(t_connection const * c,char const * fn,unsigned int ln)2252 extern char const * conn_get_username_real(t_connection const * c,char const * fn,unsigned int ln)
2253 {
2254 char const * result;
2255
2256 if (!c)
2257 {
2258 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection (from %s:%u)",fn,ln);
2259 return NULL;
2260 }
2261
2262 if(!c->protocol.account)
2263 {
2264 eventlog(eventlog_level_error,__FUNCTION__,"got NULL account (from %s:%u)",fn,ln);
2265 return NULL;
2266 }
2267 result = account_get_name(c->protocol.account);
2268 if (result == NULL)
2269 eventlog(eventlog_level_error,__FUNCTION__,"returned previous error after being called by %s:%u",fn,ln);
2270
2271 return result;
2272 }
2273
2274
conn_get_chatname(t_connection const * c)2275 extern char const * conn_get_chatname(t_connection const * c)
2276 {
2277 if (!c)
2278 {
2279 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2280 return NULL;
2281 }
2282
2283 if ((c->protocol.class==conn_class_bnet) && c->protocol.bound)
2284 {
2285 if (c->protocol.d2.character)
2286 return character_get_name(c->protocol.d2.character);
2287 if (c->protocol.bound->protocol.d2.character)
2288 return character_get_name(c->protocol.bound->protocol.d2.character);
2289 eventlog(eventlog_level_error,__FUNCTION__,"[%d] got connection class %s bound to class %d without a character",conn_get_socket(c),conn_class_get_str(c->protocol.class),c->protocol.bound->protocol.class);
2290 }
2291 if (!c->protocol.account)
2292 return NULL; /* no name yet */
2293 return conn_get_loggeduser(c);
2294 }
2295
2296
conn_unget_chatname(t_connection const * c,char const * name)2297 extern int conn_unget_chatname(t_connection const * c, char const * name)
2298 {
2299 if (!c)
2300 {
2301 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2302 return -1;
2303 }
2304
2305 if ((c->protocol.class==conn_class_bnet) && c->protocol.bound)
2306 return 0;
2307 return 0;
2308 }
2309
2310
conn_get_chatcharname(t_connection const * c,t_connection const * dst)2311 extern char const * conn_get_chatcharname(t_connection const * c, t_connection const * dst)
2312 {
2313 char const * accname;
2314 char * chatcharname;
2315
2316 if (!c)
2317 {
2318 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2319 return NULL;
2320 }
2321
2322 if (!c->protocol.account)
2323 return NULL; /* no name yet */
2324
2325 /* for D2 Users */
2326 accname = conn_get_loggeduser(c);
2327 if (!accname)
2328 return NULL;
2329
2330 if (dst && dst->protocol.d2.charname)
2331 {
2332 const char *mychar;
2333
2334 if (c->protocol.d2.charname) mychar = c->protocol.d2.charname;
2335 else mychar = "";
2336 chatcharname = xmalloc(strlen(accname) + 2 + strlen(mychar));
2337 sprintf(chatcharname, "%s*%s", mychar, accname);
2338 } else chatcharname = xstrdup(accname);
2339
2340 return chatcharname;
2341 }
2342
2343
conn_unget_chatcharname(t_connection const * c,char const * name)2344 extern int conn_unget_chatcharname(t_connection const * c, char const * name)
2345 {
2346 if (!c)
2347 {
2348 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2349 return -1;
2350 }
2351 if (!name)
2352 {
2353 eventlog(eventlog_level_error,__FUNCTION__,"got NULL name");
2354 return -1;
2355 }
2356
2357 xfree((void *)name); /* avoid warning */
2358 return 0;
2359 }
2360
2361
conn_get_message_class(t_connection const * c,t_connection const * dst)2362 extern t_message_class conn_get_message_class(t_connection const * c, t_connection const * dst)
2363 {
2364 if (dst && dst->protocol.d2.charname) /* message to D2 user must be char*account */
2365 return message_class_charjoin;
2366
2367 return message_class_normal;
2368 }
2369
2370
conn_get_userid(t_connection const * c)2371 extern unsigned int conn_get_userid(t_connection const * c)
2372 {
2373 if (!c)
2374 {
2375 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2376 return 0;
2377 }
2378
2379 if(!c->protocol.account)
2380 {
2381 eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");
2382 return 0;
2383 }
2384
2385 return account_get_uid(c->protocol.account);
2386 }
2387
2388
conn_get_socket(t_connection const * c)2389 extern int conn_get_socket(t_connection const * c)
2390 {
2391 if (!c)
2392 {
2393 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2394 return -1;
2395 }
2396
2397 return c->socket.tcp_sock;
2398 }
2399
2400
conn_get_game_socket(t_connection const * c)2401 extern int conn_get_game_socket(t_connection const * c)
2402 {
2403 if (!c)
2404 {
2405 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2406 return -1;
2407 }
2408
2409 return c->socket.udp_sock;
2410 }
2411
2412
conn_set_game_socket(t_connection * c,int usock)2413 extern int conn_set_game_socket(t_connection * c, int usock)
2414 {
2415 if (!c)
2416 {
2417 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2418 return -1;
2419 }
2420
2421 c->socket.udp_sock = usock;
2422 return 0;
2423 }
2424
2425
conn_get_playerinfo(t_connection const * c)2426 extern char const * conn_get_playerinfo(t_connection const * c)
2427 {
2428 t_account * account;
2429 static char playerinfo[MAX_PLAYERINFO_STR];
2430 t_clienttag clienttag;
2431 char revtag[5];
2432
2433 if (!c)
2434 {
2435 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2436 return NULL;
2437 }
2438 if (!(account = conn_get_account(c)))
2439 {
2440 eventlog(eventlog_level_error,__FUNCTION__,"connection has no account");
2441 return NULL;
2442 }
2443
2444 if (!(clienttag = conn_get_fake_clienttag(c)))
2445 {
2446 eventlog(eventlog_level_error,__FUNCTION__,"connection has NULL fakeclienttag");
2447 return NULL;
2448 }
2449 tag_uint_to_revstr(revtag,clienttag);
2450
2451 if (clienttag==CLIENTTAG_BNCHATBOT_UINT)
2452 {
2453 strcpy(playerinfo,revtag); /* FIXME: what to return here? */
2454 }
2455 else if ((clienttag==CLIENTTAG_STARCRAFT_UINT) || (clienttag==CLIENTTAG_BROODWARS_UINT))
2456 {
2457 if (conn_get_versionid(c)<=0x000000c7)
2458 {
2459 sprintf(playerinfo,"%s %u %u %u %u %u",
2460 revtag,
2461 account_get_ladder_rating(account,clienttag,ladder_id_normal),
2462 account_get_ladder_rank(account,clienttag,ladder_id_normal),
2463 account_get_normal_wins(account,clienttag),
2464 0,0);
2465 }
2466 else
2467 {
2468 sprintf(playerinfo,"%s %u %u %u %u %u %u %u %u %s",
2469 revtag,
2470 account_get_ladder_rating(account,clienttag,ladder_id_normal),
2471 account_get_ladder_rank(account,clienttag,ladder_id_normal),
2472 account_get_normal_wins(account,clienttag),
2473 0,0,
2474 account_get_ladder_high_rating(account,clienttag,ladder_id_normal),
2475 0,0,
2476 revtag);
2477 }
2478 }
2479 else if (clienttag==CLIENTTAG_SHAREWARE_UINT)
2480 {
2481 sprintf(playerinfo,"%s %u %u %u %u %u",
2482 revtag,
2483 account_get_ladder_rating(account,clienttag,ladder_id_normal),
2484 account_get_ladder_rank(account,clienttag,ladder_id_normal),
2485 account_get_normal_wins(account,clienttag),
2486 0,0);
2487 }
2488 else if (clienttag==CLIENTTAG_DIABLORTL_UINT)
2489 {
2490 sprintf(playerinfo,"%s %u %u %u %u %u %u %u %u %u",
2491 revtag,
2492 account_get_normal_level(account,clienttag),
2493 account_get_normal_class(account,clienttag),
2494 account_get_normal_diablo_kills(account,clienttag),
2495 account_get_normal_strength(account,clienttag),
2496 account_get_normal_magic(account,clienttag),
2497 account_get_normal_dexterity(account,clienttag),
2498 account_get_normal_vitality(account,clienttag),
2499 account_get_normal_gold(account,clienttag),
2500 0);
2501 }
2502 else if (clienttag==CLIENTTAG_DIABLOSHR_UINT)
2503 {
2504 sprintf(playerinfo,"%s %u %u %u %u %u %u %u %u %u",
2505 revtag,
2506 account_get_normal_level(account,clienttag),
2507 account_get_normal_class(account,clienttag),
2508 account_get_normal_diablo_kills(account,clienttag),
2509 account_get_normal_strength(account,clienttag),
2510 account_get_normal_magic(account,clienttag),
2511 account_get_normal_dexterity(account,clienttag),
2512 account_get_normal_vitality(account,clienttag),
2513 account_get_normal_gold(account,clienttag),
2514 0);
2515 }
2516 else if (clienttag==CLIENTTAG_WARCIIBNE_UINT)
2517 {
2518 unsigned int a,b;
2519
2520 a = account_get_ladder_rating(account,clienttag,ladder_id_normal);
2521 b = account_get_ladder_rating(account,clienttag,ladder_id_ironman);
2522
2523 sprintf(playerinfo,"%s %u %u %u %u %u %u %u %u",
2524 revtag,
2525 a,
2526 account_get_ladder_rank(account,clienttag,ladder_id_normal),
2527 account_get_normal_wins(account,clienttag),
2528 0,
2529 0,
2530 (a>b) ? a : b,
2531 b,
2532 account_get_ladder_rank(account,clienttag,ladder_id_ironman));
2533 }
2534 else if (clienttag==CLIENTTAG_DIABLO2DV_UINT || clienttag==CLIENTTAG_DIABLO2XP_UINT)
2535 {
2536 /* This sets portrait of character */
2537 if (!conn_get_realm(c) || !conn_get_realminfo(c))
2538 {
2539 strcpy(playerinfo,revtag);
2540 }
2541 else
2542 {
2543 strcpy(playerinfo,conn_get_realminfo(c));
2544 }
2545 }
2546 else
2547 strcpy(playerinfo,revtag); /* open char */
2548
2549 return playerinfo;
2550 }
2551
2552
conn_set_playerinfo(t_connection const * c,char const * playerinfo)2553 extern int conn_set_playerinfo(t_connection const * c, char const * playerinfo)
2554 {
2555 t_clienttag clienttag;
2556 char clienttag_str[5];
2557
2558 if (!c)
2559 {
2560 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2561 return -1;
2562 }
2563 if (!playerinfo)
2564 {
2565 eventlog(eventlog_level_error,__FUNCTION__,"got NULL playerinfo");
2566 return -1;
2567 }
2568 clienttag = c->protocol.client.clienttag;
2569
2570 if (clienttag==CLIENTTAG_DIABLORTL_UINT)
2571 {
2572 unsigned int level;
2573 unsigned int class;
2574 unsigned int diablo_kills;
2575 unsigned int strength;
2576 unsigned int magic;
2577 unsigned int dexterity;
2578 unsigned int vitality;
2579 unsigned int gold;
2580
2581 if (sscanf(playerinfo,"LTRD %u %u %u %u %u %u %u %u %*u",
2582 &level,
2583 &class,
2584 &diablo_kills,
2585 &strength,
2586 &magic,
2587 &dexterity,
2588 &vitality,
2589 &gold)!=8)
2590 {
2591 eventlog(eventlog_level_error,__FUNCTION__,"got bad playerinfo");
2592 return -1;
2593 }
2594
2595 account_set_normal_level(conn_get_account(c),clienttag,level);
2596 account_set_normal_class(conn_get_account(c),clienttag,class);
2597 account_set_normal_diablo_kills(conn_get_account(c),clienttag,diablo_kills);
2598 account_set_normal_strength(conn_get_account(c),clienttag,strength);
2599 account_set_normal_magic(conn_get_account(c),clienttag,magic);
2600 account_set_normal_dexterity(conn_get_account(c),clienttag,dexterity);
2601 account_set_normal_vitality(conn_get_account(c),clienttag,vitality);
2602 account_set_normal_gold(conn_get_account(c),clienttag,gold);
2603 }
2604 else if (clienttag==CLIENTTAG_DIABLOSHR_UINT)
2605 {
2606 unsigned int level;
2607 unsigned int class;
2608 unsigned int diablo_kills;
2609 unsigned int strength;
2610 unsigned int magic;
2611 unsigned int dexterity;
2612 unsigned int vitality;
2613 unsigned int gold;
2614
2615 if (sscanf(playerinfo,"RHSD %u %u %u %u %u %u %u %u %*u",
2616 &level,
2617 &class,
2618 &diablo_kills,
2619 &strength,
2620 &magic,
2621 &dexterity,
2622 &vitality,
2623 &gold)!=8)
2624 {
2625 eventlog(eventlog_level_error,__FUNCTION__,"got bad playerinfo");
2626 return -1;
2627 }
2628
2629 account_set_normal_level(conn_get_account(c),clienttag,level);
2630 account_set_normal_class(conn_get_account(c),clienttag,class);
2631 account_set_normal_diablo_kills(conn_get_account(c),clienttag,diablo_kills);
2632 account_set_normal_strength(conn_get_account(c),clienttag,strength);
2633 account_set_normal_magic(conn_get_account(c),clienttag,magic);
2634 account_set_normal_dexterity(conn_get_account(c),clienttag,dexterity);
2635 account_set_normal_vitality(conn_get_account(c),clienttag,vitality);
2636 account_set_normal_gold(conn_get_account(c),clienttag,gold);
2637 }
2638 else if (clienttag==CLIENTTAG_DIABLO2DV_UINT)
2639 {
2640 /* not much to do */ /* FIXME: get char name here? */
2641 eventlog(eventlog_level_trace,__FUNCTION__,"[%d] playerinfo request for client \"%s\" playerinfo=\"%s\"",conn_get_socket(c),tag_uint_to_str(clienttag_str,clienttag),playerinfo);
2642 }
2643 else if (clienttag==CLIENTTAG_DIABLO2XP_UINT)
2644 {
2645 /* in playerinfo we get strings of the form "Realmname,charname" */
2646 eventlog(eventlog_level_trace,__FUNCTION__,"[%d] playerinfo request for client \"%s\" playerinfo=\"%s\"",conn_get_socket(c),tag_uint_to_str(clienttag_str,clienttag),playerinfo);
2647 }
2648 else
2649 {
2650 eventlog(eventlog_level_warn,__FUNCTION__,"setting playerinfo for client \"%s\" not supported (playerinfo=\"%s\")",tag_uint_to_str(clienttag_str,clienttag),playerinfo);
2651 return -1;
2652 }
2653
2654 return 0;
2655 }
2656
2657
conn_get_realminfo(t_connection const * c)2658 extern char const * conn_get_realminfo(t_connection const * c)
2659 {
2660 if (!c)
2661 {
2662 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2663 return NULL;
2664 }
2665 return c->protocol.d2.realminfo;
2666 }
2667
2668
conn_set_realminfo(t_connection * c,char const * realminfo)2669 extern int conn_set_realminfo(t_connection * c, char const * realminfo)
2670 {
2671 char const * temp;
2672
2673 if (!c)
2674 {
2675 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2676 return -1;
2677 }
2678
2679 if (realminfo)
2680 temp = xstrdup(realminfo);
2681 else
2682 temp = NULL;
2683
2684 if (c->protocol.d2.realminfo) /* if it was set before, free it now */
2685 xfree((void *)c->protocol.d2.realminfo); /* avoid warning */
2686 c->protocol.d2.realminfo = temp;
2687 return 0;
2688 }
2689
2690
conn_get_charname(t_connection const * c)2691 extern char const * conn_get_charname(t_connection const * c)
2692 {
2693 if (!c)
2694 {
2695 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2696 return NULL;
2697 }
2698 return c->protocol.d2.charname;
2699 }
2700
2701
conn_set_charname(t_connection * c,char const * charname)2702 extern int conn_set_charname(t_connection * c, char const * charname)
2703 {
2704 char const * temp;
2705
2706 if (!c)
2707 {
2708 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2709 return -1;
2710 }
2711
2712 if (charname)
2713 temp = xstrdup(charname);
2714 else
2715 temp = charname;
2716
2717 if (c->protocol.d2.charname) /* free it, if it was previously set */
2718 xfree((void *)c->protocol.d2.charname); /* avoid warning */
2719 c->protocol.d2.charname = temp;
2720 return 0;
2721 }
2722
2723
conn_set_idletime(t_connection * c)2724 extern int conn_set_idletime(t_connection * c)
2725 {
2726 if (!c)
2727 {
2728 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2729 return -1;
2730 }
2731
2732 c->protocol.chat.last_message = now;
2733 return 0;
2734 }
2735
2736
conn_get_idletime(t_connection const * c)2737 extern unsigned int conn_get_idletime(t_connection const * c)
2738 {
2739 if (!c)
2740 {
2741 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2742 return 0;
2743 }
2744
2745 return (unsigned int)difftime(now,c->protocol.chat.last_message);
2746 }
2747
2748
conn_get_realm(t_connection const * c)2749 extern t_realm * conn_get_realm(t_connection const * c)
2750 {
2751 if (!c)
2752 {
2753 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2754 return NULL;
2755 }
2756
2757 return c->protocol.d2.realm;
2758 }
2759
2760
conn_set_realm(t_connection * c,t_realm * realm)2761 extern int conn_set_realm(t_connection * c, t_realm * realm)
2762 {
2763 if (!c)
2764 {
2765 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2766 return -1;
2767 }
2768
2769 if (c->protocol.d2.realm)
2770 realm_put(c->protocol.d2.realm,&c->protocol.d2.realm_regref);
2771
2772 if (!realm)
2773 c->protocol.d2.realm = NULL;
2774 else
2775 {
2776 c->protocol.d2.realm = realm_get(realm,&c->protocol.d2.realm_regref);
2777 eventlog(eventlog_level_debug,__FUNCTION__,"[%d] set to \"%s\"",conn_get_socket(c),realm_get_name(realm));
2778 }
2779
2780 return 0;
2781 }
2782
conn_set_realm_cb(void * data,void * newref)2783 extern int conn_set_realm_cb(void *data, void *newref)
2784 {
2785 t_connection *c = (t_connection*)data;
2786 t_realm *newrealm = (t_realm*)newref;
2787
2788 assert(c->protocol.d2.realm); /* this should never be NULL here */
2789
2790 /* we are removing a reference */
2791 realm_put(c->protocol.d2.realm,&c->protocol.d2.realm_regref);
2792
2793 if (newrealm)
2794 c->protocol.d2.realm = realm_get(newrealm,&c->protocol.d2.realm_regref);
2795 else {
2796 /* close the connection for players on unconfigured realms */
2797 conn_set_state(c,conn_state_destroy);
2798 c->protocol.d2.realm = NULL;
2799 }
2800
2801 return 0;
2802 }
2803
2804
conn_set_character(t_connection * c,t_character * character)2805 extern int conn_set_character(t_connection * c, t_character * character)
2806 {
2807 if (!c)
2808 {
2809 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2810 return -1;
2811 }
2812 if (!character)
2813 {
2814 eventlog(eventlog_level_error,__FUNCTION__,"got NULL character");
2815 return -1;
2816 }
2817
2818 c->protocol.d2.character = character;
2819
2820 return 0;
2821 }
2822
2823
conn_set_country(t_connection * c,char const * country)2824 extern void conn_set_country(t_connection * c, char const * country)
2825 {
2826 if (!c)
2827 {
2828 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2829 return;
2830 }
2831 if (!country)
2832 {
2833 eventlog(eventlog_level_error,__FUNCTION__,"got NULL country");
2834 return;
2835 }
2836
2837 if (c->protocol.client.country)
2838 xfree((void *)c->protocol.client.country); /* avoid warning */
2839 c->protocol.client.country = xstrdup(country);
2840 }
2841
2842
conn_get_country(t_connection const * c)2843 extern char const * conn_get_country(t_connection const * c)
2844 {
2845 if (!c)
2846 {
2847 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2848 return NULL;
2849 }
2850
2851 return c->protocol.client.country;
2852 }
2853
2854
conn_bind(t_connection * c1,t_connection * c2)2855 extern int conn_bind(t_connection * c1, t_connection * c2)
2856 {
2857 if (!c1)
2858 {
2859 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2860 return -1;
2861 }
2862 if (!c2)
2863 {
2864 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2865 return -1;
2866 }
2867
2868 c1->protocol.bound = c2;
2869 c2->protocol.bound = c1;
2870
2871 return 0;
2872 }
2873
2874
conn_set_ircline(t_connection * c,char const * line)2875 extern int conn_set_ircline(t_connection * c, char const * line)
2876 {
2877 if (!c) {
2878 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2879 return -1;
2880 }
2881 if (!line) {
2882 eventlog(eventlog_level_error,__FUNCTION__,"got NULL line");
2883 return -1;
2884 }
2885 if (c->protocol.chat.irc.ircline)
2886 xfree((void *)c->protocol.chat.irc.ircline); /* avoid warning */
2887 c->protocol.chat.irc.ircline = xstrdup(line);
2888 return 0;
2889 }
2890
2891
conn_get_ircline(t_connection const * c)2892 extern char const * conn_get_ircline(t_connection const * c)
2893 {
2894 if (!c) {
2895 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2896 return NULL;
2897 }
2898 return c->protocol.chat.irc.ircline;
2899 }
2900
2901
conn_set_ircpass(t_connection * c,char const * pass)2902 extern int conn_set_ircpass(t_connection * c, char const * pass)
2903 {
2904 if (!c) {
2905 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2906 return -1;
2907 }
2908 if (c->protocol.chat.irc.ircpass)
2909 xfree((void *)c->protocol.chat.irc.ircpass); /* avoid warning */
2910 if (!pass)
2911 c->protocol.chat.irc.ircpass = NULL;
2912 else
2913 c->protocol.chat.irc.ircpass = xstrdup(pass);
2914
2915 return 0;
2916 }
2917
2918
conn_get_ircpass(t_connection const * c)2919 extern char const * conn_get_ircpass(t_connection const * c)
2920 {
2921 if (!c) {
2922 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2923 return NULL;
2924 }
2925 return c->protocol.chat.irc.ircpass;
2926 }
2927
2928
conn_set_ircping(t_connection * c,unsigned int ping)2929 extern int conn_set_ircping(t_connection * c, unsigned int ping)
2930 {
2931 if (!c) {
2932 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2933 return -1;
2934 }
2935 c->protocol.chat.irc.ircping = ping;
2936 return 0;
2937 }
2938
2939
conn_get_ircping(t_connection const * c)2940 extern unsigned int conn_get_ircping(t_connection const * c)
2941 {
2942 if (!c) {
2943 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2944 return 0;
2945 }
2946 return c->protocol.chat.irc.ircping;
2947 }
2948
2949 // NonReal
conn_get_welcomed(t_connection const * c)2950 extern int conn_get_welcomed(t_connection const * c)
2951 {
2952 if (!c)
2953 {
2954 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2955 return 0;
2956 }
2957
2958 return (c->protocol.cflags & conn_flags_welcomed);
2959 }
2960
2961 // NonReal
conn_set_welcomed(t_connection * c,int welcomed)2962 extern void conn_set_welcomed(t_connection * c, int welcomed)
2963 {
2964
2965 if (!c)
2966 {
2967 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2968 return;
2969 }
2970 c->protocol.cflags |= conn_flags_welcomed;
2971 }
2972
2973 /* ADDED BY UNDYING SOULZZ 4/7/02 */
conn_set_w3_playerinfo(t_connection * c,const char * w3_playerinfo)2974 extern int conn_set_w3_playerinfo( t_connection * c, const char * w3_playerinfo )
2975 {
2976 const char * temp;
2977
2978 if (!c)
2979 {
2980 eventlog(eventlog_level_error,__FUNCTION__, "got NULL connection");
2981 return -1;
2982 }
2983
2984 temp = xstrdup( w3_playerinfo );
2985
2986 if ( c->protocol.w3.w3_playerinfo )
2987 xfree((void *)c->protocol.w3.w3_playerinfo);
2988
2989 c->protocol.w3.w3_playerinfo = temp;
2990
2991 return 1;
2992 }
2993
conn_get_w3_playerinfo(t_connection * c)2994 extern const char * conn_get_w3_playerinfo( t_connection * c )
2995 {
2996 if (!c)
2997 {
2998 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
2999 return NULL;
3000 }
3001 return c->protocol.w3.w3_playerinfo;
3002 }
3003
3004
conn_quota_exceeded(t_connection * con,char const * text)3005 extern int conn_quota_exceeded(t_connection * con, char const * text)
3006 {
3007 t_qline * qline;
3008 t_elem * curr;
3009
3010 if (!prefs_get_quota() ||
3011 !conn_get_account(con) ||
3012 (account_get_command_groups(conn_get_account(con)) & command_get_group("/admin-con"))) return 0;
3013
3014 if (strlen(text)>prefs_get_quota_maxline())
3015 {
3016 message_send_text(con,message_type_error,con,"Your line length quota has been exceeded!");
3017 return 1;
3018 }
3019
3020 LIST_TRAVERSE(con->protocol.chat.quota.list,curr)
3021 {
3022 qline = elem_get_data(curr);
3023 if (now>=qline->inf+(time_t)prefs_get_quota_time())
3024 {
3025 /* these lines are at least quota_time old */
3026 list_remove_elem(con->protocol.chat.quota.list,&curr);
3027 if (qline->count>con->protocol.chat.quota.totcount)
3028 eventlog(eventlog_level_error,__FUNCTION__,"qline->count=%u but con->protocol.chat.quota.totcount=%u",qline->count,con->protocol.chat.quota.totcount);
3029 con->protocol.chat.quota.totcount -= qline->count;
3030 xfree(qline);
3031 }
3032 else
3033 break; /* old items are first, so we know nothing else will match */
3034 }
3035
3036 qline = xmalloc(sizeof(t_qline));
3037 qline->inf = now; /* set the moment */
3038 if (strlen(text)>prefs_get_quota_wrapline()) /* round up on the divide */
3039 qline->count = (strlen(text)+prefs_get_quota_wrapline()-1)/prefs_get_quota_wrapline();
3040 else
3041 qline->count = 1;
3042
3043 list_append_data(con->protocol.chat.quota.list,qline);
3044
3045 con->protocol.chat.quota.totcount += qline->count;
3046
3047 if (con->protocol.chat.quota.totcount>=prefs_get_quota_lines())
3048 {
3049 message_send_text(con,message_type_error,con,"Your message quota has been exceeded!");
3050 if (con->protocol.chat.quota.totcount>=prefs_get_quota_dobae())
3051 {
3052 /* kick out the dobae user for violation of the quota rule */
3053 conn_set_state(con,conn_state_destroy);
3054 if (con->protocol.chat.channel)
3055 channel_message_log(con->protocol.chat.channel,con,0,"DISCONNECTED FOR DOBAE ABUSE");
3056 return 2;
3057 }
3058 return 1;
3059 }
3060
3061 return 0;
3062 }
3063
3064
conn_set_lastsender(t_connection * c,char const * sender)3065 extern int conn_set_lastsender(t_connection * c, char const * sender)
3066 {
3067 if (!c)
3068 {
3069 eventlog(eventlog_level_error,__FUNCTION__,"got NULL conection");
3070 return -1;
3071 }
3072 if (c->protocol.chat.lastsender)
3073 xfree((void *)c->protocol.chat.lastsender); /* avoid warning */
3074 if (!sender)
3075 {
3076 c->protocol.chat.lastsender = NULL;
3077 return 0;
3078 }
3079 c->protocol.chat.lastsender = xstrdup(sender);
3080
3081 return 0;
3082 }
3083
3084
conn_get_lastsender(t_connection const * c)3085 extern char const * conn_get_lastsender(t_connection const * c)
3086 {
3087 if (!c)
3088 {
3089 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3090 return NULL;
3091 }
3092 return c->protocol.chat.lastsender;
3093 }
3094
3095
conn_get_versioncheck(t_connection * c)3096 extern t_versioncheck * conn_get_versioncheck(t_connection * c)
3097 {
3098 if (!c)
3099 {
3100 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3101 return NULL;
3102 }
3103
3104 return c->protocol.client.versioncheck;
3105 }
3106
3107
conn_set_versioncheck(t_connection * c,t_versioncheck * versioncheck)3108 extern int conn_set_versioncheck(t_connection * c, t_versioncheck * versioncheck)
3109 {
3110 if (!c)
3111 {
3112 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3113 return -1;
3114 }
3115 if (!versioncheck)
3116 {
3117 eventlog(eventlog_level_error,__FUNCTION__,"got NULL versioncheck");
3118 return -1;
3119 }
3120
3121 c->protocol.client.versioncheck = versioncheck;
3122
3123 return 0;
3124 }
3125
conn_get_echoback(t_connection * c)3126 extern int conn_get_echoback(t_connection * c)
3127 {
3128 if (!c)
3129 {
3130 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3131 return 0;
3132 }
3133
3134 return (c->protocol.cflags & conn_flags_echoback);
3135 }
3136
conn_set_echoback(t_connection * c,int echoback)3137 extern void conn_set_echoback(t_connection * c, int echoback)
3138 {
3139 if (!c)
3140 {
3141 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3142 return;
3143 }
3144 if (echoback)
3145 c->protocol.cflags |= conn_flags_echoback;
3146 else
3147 c->protocol.cflags &= ~conn_flags_echoback;
3148 }
3149
conn_set_udpok(t_connection * c)3150 extern int conn_set_udpok(t_connection * c)
3151 {
3152 if (!c)
3153 {
3154 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3155 return -1;
3156 }
3157
3158 if (!(c->protocol.cflags & conn_flags_udpok))
3159 {
3160 c->protocol.cflags|= conn_flags_udpok;
3161 c->protocol.flags &= ~MF_PLUG;
3162 }
3163
3164 return 0;
3165 }
3166
3167
conn_get_routeconn(t_connection const * c)3168 extern t_connection * conn_get_routeconn(t_connection const * c)
3169 {
3170 if (!c)
3171 {
3172 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3173 return NULL;
3174 }
3175
3176 return c->protocol.w3.routeconn;
3177 }
3178
3179
conn_set_routeconn(t_connection * c,t_connection * rc)3180 extern int conn_set_routeconn(t_connection * c, t_connection * rc)
3181 {
3182 if (!c) {
3183 eventlog(eventlog_level_error,__FUNCTION__,"got NULL conection");
3184 return -1;
3185 }
3186 c->protocol.w3.routeconn = rc;
3187
3188 return 0;
3189 }
3190
conn_get_crtime(t_connection * c)3191 extern int conn_get_crtime(t_connection *c)
3192 {
3193 if (!c)
3194 {
3195 eventlog(eventlog_level_error, "conn_get_crtime", "got NULL connection");
3196 return -1;
3197 }
3198 return c->protocol.cr_time;
3199 }
3200
conn_set_joingamewhisper_ack(t_connection * c,unsigned int value)3201 extern int conn_set_joingamewhisper_ack(t_connection * c, unsigned int value)
3202 {
3203 if (!c)
3204 {
3205 eventlog(eventlog_level_error,__FUNCTION__, "got NULL connection");
3206 return -1;
3207 }
3208 if (value)
3209 c->protocol.cflags |= conn_flags_joingamewhisper;
3210 else
3211 c->protocol.cflags &= ~conn_flags_joingamewhisper;
3212 return 0;
3213 }
conn_get_joingamewhisper_ack(t_connection * c)3214 extern int conn_get_joingamewhisper_ack(t_connection * c)
3215 {
3216 if (!c)
3217 {
3218 eventlog(eventlog_level_error,__FUNCTION__, "got NULL connection");
3219 return -1;
3220 }
3221 return (c->protocol.cflags & conn_flags_joingamewhisper);
3222 }
3223
conn_set_leavegamewhisper_ack(t_connection * c,unsigned int value)3224 extern int conn_set_leavegamewhisper_ack(t_connection * c, unsigned int value)
3225 {
3226 if (!c)
3227 {
3228 eventlog(eventlog_level_error,__FUNCTION__, "got NULL connection");
3229 return -1;
3230 }
3231 if (value)
3232 c->protocol.cflags |= conn_flags_leavegamewhisper;
3233 else
3234 c->protocol.cflags &= ~conn_flags_leavegamewhisper;
3235 return 0;
3236 }
conn_get_leavegamewhisper_ack(t_connection * c)3237 extern int conn_get_leavegamewhisper_ack(t_connection * c)
3238 {
3239 if (!c)
3240 {
3241 eventlog(eventlog_level_error,__FUNCTION__, "got NULL connection");
3242 return -1;
3243 }
3244 return (c->protocol.cflags & conn_flags_leavegamewhisper);
3245 }
3246
conn_set_anongame_search_starttime(t_connection * c,time_t t)3247 extern int conn_set_anongame_search_starttime(t_connection * c, time_t t)
3248 {
3249 if (c == NULL) {
3250 eventlog(eventlog_level_error, "conn_set_anongame_search_starttime", "got NULL connection");
3251 return -1;
3252 }
3253 c->protocol.w3.anongame_search_starttime = t;
3254 return 0;
3255 }
3256
conn_get_anongame_search_starttime(t_connection * c)3257 extern time_t conn_get_anongame_search_starttime(t_connection * c)
3258 {
3259 if (c == NULL) {
3260 eventlog(eventlog_level_error, "conn_set_anongame_search_starttime", "got NULL connection");
3261 return ((time_t) 0);
3262 }
3263 return c->protocol.w3.anongame_search_starttime;
3264 }
3265
3266
conn_get_timer(t_connection * c)3267 extern t_elist * conn_get_timer(t_connection *c)
3268 {
3269 if (!c) {
3270 eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
3271 return NULL;
3272 }
3273
3274 return &c->protocol.timers;
3275 }
3276
3277
conn_add_fdwatch(t_connection * c,fdwatch_handler handle)3278 extern int conn_add_fdwatch(t_connection *c, fdwatch_handler handle)
3279 {
3280 assert(c);
3281 c->socket.fdw_idx = fdwatch_add_fd(c->socket.tcp_sock, fdwatch_type_read, handle, c);
3282 return c->socket.fdw_idx;
3283 }
3284
3285
conn_get_user_count_by_clienttag(t_clienttag ct)3286 extern int conn_get_user_count_by_clienttag(t_clienttag ct)
3287 {
3288 t_connection * conn;
3289 t_elem const * curr;
3290 int clienttagusers = 0;
3291
3292 /* Get Number of Users for client tag specific */
3293 LIST_TRAVERSE_CONST(connlist(),curr)
3294 {
3295 conn = elem_get_data(curr);
3296 if ( ( ct == conn->protocol.client.clienttag )
3297 && ( conn->protocol.state == conn_state_loggedin ) ) clienttagusers++;
3298 }
3299
3300 return clienttagusers;
3301 }
3302
connlist_create(void)3303 extern int connlist_create(void)
3304 {
3305 conn_head = list_create();
3306 connarray_create();
3307 return 0;
3308 }
3309
connlist_destroy(void)3310 extern int connlist_destroy(void)
3311 {
3312 if (conn_dead) list_destroy(conn_dead);
3313 conn_dead = NULL;
3314 connarray_destroy();
3315 /* FIXME: if called with active connection, connection are not freed */
3316 if (list_destroy(conn_head)<0)
3317 return -1;
3318 conn_head = NULL;
3319 return 0;
3320 }
3321
connlist_reap(void)3322 extern void connlist_reap(void)
3323 {
3324 t_elem *curr;
3325 t_connection *c;
3326
3327 if (!conn_dead || !conn_head) return;
3328
3329 LIST_TRAVERSE(conn_dead, curr)
3330 {
3331 c = (t_connection *)elem_get_data(curr);
3332
3333 if (!c)
3334 eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in conn_dead list");
3335 else conn_destroy(c,&curr,DESTROY_FROM_DEADLIST); /* also removes from conn_dead list and fdwatch */
3336 }
3337 }
3338
connlist(void)3339 extern t_list * connlist(void)
3340 {
3341 return conn_head;
3342 }
3343
3344
connlist_find_connection_by_accountname(char const * accountname)3345 extern t_connection * connlist_find_connection_by_accountname(char const * accountname)
3346 {
3347 t_account * temp;
3348
3349 if (!accountname)
3350 {
3351 eventlog(eventlog_level_error,__FUNCTION__,"got NULL accountname");
3352 return NULL;
3353 }
3354
3355 if (!(temp = accountlist_find_account(accountname)))
3356 return NULL;
3357
3358 return account_get_conn(temp);
3359 }
3360
connlist_find_connection_by_account(t_account * account)3361 extern t_connection * connlist_find_connection_by_account(t_account * account)
3362 {
3363 if (!account) {
3364 eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");
3365 return NULL;
3366 }
3367 return account_get_conn(account);
3368 }
3369
3370
connlist_find_connection_by_sessionkey(unsigned int sessionkey)3371 extern t_connection * connlist_find_connection_by_sessionkey(unsigned int sessionkey)
3372 {
3373 t_connection * c;
3374 t_elem const * curr;
3375
3376 LIST_TRAVERSE_CONST(conn_head,curr)
3377 {
3378 c = elem_get_data(curr);
3379 if (c->protocol.sessionkey==sessionkey)
3380 return c;
3381 }
3382
3383 return NULL;
3384 }
3385
3386
connlist_find_connection_by_sessionnum(unsigned int sessionnum)3387 extern t_connection * connlist_find_connection_by_sessionnum(unsigned int sessionnum)
3388 {
3389 return connarray_get_conn(sessionnum);
3390 }
3391
3392
connlist_find_connection_by_socket(int socket)3393 extern t_connection * connlist_find_connection_by_socket(int socket)
3394 {
3395 t_connection * c;
3396 t_elem const * curr;
3397
3398 LIST_TRAVERSE_CONST(conn_head,curr)
3399 {
3400 c = elem_get_data(curr);
3401 if (c->socket.tcp_sock==socket)
3402 return c;
3403 }
3404
3405 return NULL;
3406 }
3407
3408
connlist_find_connection_by_name(char const * name,t_realm * realm)3409 extern t_connection * connlist_find_connection_by_name(char const * name, t_realm * realm)
3410 {
3411 char charname[CHAR_NAME_LEN];
3412 char const * temp;
3413
3414 if (!name)
3415 {
3416 eventlog(eventlog_level_error,__FUNCTION__,"got NULL name");
3417 return NULL;
3418 }
3419 if (name[0]=='\0')
3420 {
3421 eventlog(eventlog_level_error,__FUNCTION__,"got empty name");
3422 return NULL;
3423 }
3424
3425 /* format: *username */
3426 if (name[0]=='*')
3427 {
3428 name++;
3429 return connlist_find_connection_by_accountname(name);
3430 }
3431
3432 /* If is charname@otherrealm or ch@rname@realm */
3433 if ((temp=strrchr(name,'@'))) /* search from the right */
3434 {
3435 unsigned int n;
3436
3437 n = temp - name;
3438 if (n>=CHAR_NAME_LEN)
3439 {
3440 eventlog(eventlog_level_info,__FUNCTION__,"character name too long in \"%s\" (charname@otherrealm format)",name);
3441 return NULL;
3442 }
3443 strncpy(charname,name,n);
3444 charname[n] = '\0';
3445 return connlist_find_connection_by_charname(name,temp + 1);
3446 }
3447
3448 /* format: charname*username */
3449 if ((temp=strchr(name,'*')))
3450 {
3451 unsigned int n;
3452
3453 n = temp - name;
3454 if (n>=CHAR_NAME_LEN)
3455 {
3456 eventlog(eventlog_level_info,__FUNCTION__,"character name too long in \"%s\" (charname*username format)",name);
3457 return NULL;
3458 }
3459 name = temp + 1;
3460 return connlist_find_connection_by_accountname(name);
3461 }
3462
3463 /* format: charname (realm must be not NULL) */
3464 if (realm)
3465 return connlist_find_connection_by_charname(name,realm_get_name(realm));
3466
3467 /* format: Simple username, clients with no realm, like starcraft or d2 open,
3468 * the format is the same of charname but is matched if realmname is NULL */
3469 return connlist_find_connection_by_accountname(name);
3470 }
3471
3472
connlist_find_connection_by_charname(char const * charname,char const * realmname)3473 extern t_connection * connlist_find_connection_by_charname(char const * charname, char const * realmname)
3474 {
3475 t_connection * c;
3476 t_elem const * curr;
3477
3478 if (!realmname) {
3479 eventlog(eventlog_level_error,__FUNCTION__,"got NULL realmname");
3480 return NULL;
3481 }
3482 LIST_TRAVERSE_CONST(conn_head, curr)
3483 {
3484 c = elem_get_data(curr);
3485 if (!c)
3486 continue;
3487 if (!c->protocol.d2.charname)
3488 continue;
3489 if (!c->protocol.d2.realm)
3490 continue;
3491 if ((strcasecmp(c->protocol.d2.charname, charname)==0)&&(strcasecmp(realm_get_name(c->protocol.d2.realm),realmname)==0))
3492 return c;
3493 }
3494 return NULL;
3495 }
3496
3497
connlist_find_connection_by_uid(unsigned int uid)3498 extern t_connection * connlist_find_connection_by_uid(unsigned int uid)
3499 {
3500 t_account * temp;
3501
3502 if (!(temp = accountlist_find_account_by_uid(uid)))
3503 {
3504 return NULL;
3505 }
3506 return account_get_conn(temp);
3507 }
3508
connlist_get_length(void)3509 extern int connlist_get_length(void)
3510 {
3511 return list_get_length(conn_head);
3512 }
3513
3514
connlist_login_get_length(void)3515 extern unsigned int connlist_login_get_length(void)
3516 {
3517 t_connection const * c;
3518 unsigned int count;
3519 t_elem const * curr;
3520
3521 count = 0;
3522 LIST_TRAVERSE_CONST(conn_head,curr)
3523 {
3524 c = elem_get_data(curr);
3525 if ((c->protocol.state==conn_state_loggedin)&&
3526 ((c->protocol.class==conn_class_bnet)||(c->protocol.class==conn_class_bot)||(c->protocol.class==conn_class_telnet)||(c->protocol.class==conn_class_irc)||(c->protocol.class==conn_class_wol)))
3527 count++;
3528 }
3529
3530 return count;
3531 }
3532
3533
connlist_total_logins(void)3534 extern int connlist_total_logins(void)
3535 {
3536 return totalcount;
3537 }
3538
3539
connlist_count_connections(unsigned int addr)3540 extern unsigned int connlist_count_connections(unsigned int addr)
3541 {
3542 t_connection * c;
3543 t_elem const * curr;
3544 unsigned int count;
3545
3546 count = 0;
3547
3548 LIST_TRAVERSE_CONST(conn_head,curr)
3549 {
3550 c = (t_connection *)elem_get_data(curr);
3551 if (c->socket.tcp_addr == addr)
3552 count++;
3553 }
3554
3555 return count;
3556 }
3557
conn_update_w3_playerinfo(t_connection * c)3558 extern int conn_update_w3_playerinfo(t_connection * c)
3559 {
3560 t_account * account;
3561 t_clienttag clienttag;
3562 t_clan * user_clan;
3563 int clantag=0;
3564 unsigned int acctlevel;
3565 char tempplayerinfo[40];
3566 char raceicon; /* appeared in 1.03 */
3567 unsigned int raceiconnumber;
3568 unsigned int wins;
3569 char const * usericon;
3570 char clantag_str_tmp[5];
3571 const char * clantag_str = NULL;
3572 char revtag[5];
3573 char clienttag_str[5];
3574
3575 if (c == NULL) {
3576 eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
3577 return -1;
3578 }
3579
3580 account = conn_get_account(c);
3581
3582 if (account == NULL) {
3583 eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
3584 return -1;
3585 }
3586
3587 strncpy(revtag, tag_uint_to_str(clienttag_str,conn_get_fake_clienttag(c)),5); revtag[4] = '\0';
3588 strreverse(revtag);
3589
3590 clienttag = c->protocol.client.clienttag;
3591
3592 acctlevel = account_get_highestladderlevel(account,clienttag);
3593 account_get_raceicon(account, &raceicon, &raceiconnumber, &wins, clienttag);
3594
3595 if((user_clan = account_get_clan(account)) != NULL)
3596 clantag = clan_get_clantag(user_clan);
3597
3598 if(clantag) {
3599 sprintf(clantag_str_tmp, "%c%c%c%c", clantag&0xff, (clantag>>8)&0xff, (clantag>>16)&0xff, clantag>>24);
3600 clantag_str=clantag_str_tmp;
3601 while((* clantag_str) == 0) clantag_str++;
3602 }
3603
3604 if(acctlevel == 0) {
3605 if(clantag)
3606 sprintf(tempplayerinfo, "%s %s 0 %s", revtag, revtag, clantag_str);
3607 else
3608 strcpy(tempplayerinfo, revtag);
3609 eventlog(eventlog_level_info,__FUNCTION__,"[%d] %s",conn_get_socket(c), revtag);
3610 } else {
3611 usericon = account_get_user_icon(account,clienttag);
3612 if (!usericon) {
3613 if(clantag)
3614 sprintf(tempplayerinfo, "%s %1u%c3W %u %s", revtag, raceiconnumber, raceicon, acctlevel, clantag_str);
3615 else
3616 sprintf(tempplayerinfo, "%s %1u%c3W %u", revtag, raceiconnumber, raceicon, acctlevel);
3617 eventlog(eventlog_level_info,__FUNCTION__,"[%d] %s using generated icon [%1u%c3W]",conn_get_socket(c), revtag, raceiconnumber, raceicon);
3618 } else {
3619 if(clantag)
3620 sprintf(tempplayerinfo, "%s %s %u %s",revtag, usericon, acctlevel, clantag_str);
3621 else
3622 sprintf(tempplayerinfo, "%s %s %u",revtag, usericon, acctlevel);
3623 eventlog(eventlog_level_info,__FUNCTION__,"[%d] %s using user-selected icon [%s]",conn_get_socket(c),revtag,usericon);
3624 }
3625 }
3626
3627 conn_set_w3_playerinfo( c, tempplayerinfo );
3628
3629 return 0;
3630 }
3631
3632
conn_get_passfail_count(t_connection * c)3633 extern int conn_get_passfail_count (t_connection * c)
3634 {
3635 if (!c)
3636 {
3637 eventlog(eventlog_level_error, "conn_get_passfail_count", "got NULL connection");
3638 return -1;
3639 }
3640 return c->protocol.passfail_count;
3641 }
3642
3643
conn_set_passfail_count(t_connection * c,unsigned int n)3644 extern int conn_set_passfail_count (t_connection * c, unsigned int n)
3645 {
3646 if (c == NULL)
3647 {
3648 eventlog(eventlog_level_error, "conn_set_passfail_count", "got NULL connection");
3649 return -1;
3650 }
3651 c->protocol.passfail_count = n;
3652 return 0;
3653 }
3654
3655
conn_increment_passfail_count(t_connection * c)3656 extern int conn_increment_passfail_count (t_connection * c)
3657 {
3658 unsigned int count;
3659
3660 if (prefs_get_passfail_count() > 0)
3661 {
3662 count = conn_get_passfail_count(c) + 1;
3663 if (count == prefs_get_passfail_count())
3664 {
3665 ipbanlist_add(NULL, addr_num_to_ip_str(conn_get_addr(c)), now+(time_t)prefs_get_passfail_bantime());
3666 eventlog(eventlog_level_info,__FUNCTION__,"[%d] failed password tries: %d (banned ip)",conn_get_socket(c), count);
3667 conn_set_state(c, conn_state_destroy);
3668 return -1;
3669 }
3670 else conn_set_passfail_count(c, count);
3671 }
3672 return 0;
3673 }
3674
conn_set_tmpOP_channel(t_connection * c,char const * tmpOP_channel)3675 extern int conn_set_tmpOP_channel(t_connection * c, char const * tmpOP_channel)
3676 {
3677 if (!c)
3678 {
3679 eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
3680 return -1;
3681 }
3682
3683 if (c->protocol.chat.tmpOP_channel)
3684 {
3685 xfree((void *)c->protocol.chat.tmpOP_channel);
3686 c->protocol.chat.tmpOP_channel = NULL;
3687 }
3688
3689 if (tmpOP_channel)
3690 c->protocol.chat.tmpOP_channel = xstrdup(tmpOP_channel);
3691
3692 return 0;
3693 }
3694
conn_get_tmpOP_channel(t_connection * c)3695 extern char const * conn_get_tmpOP_channel(t_connection * c)
3696 {
3697 if (!c)
3698 {
3699 eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
3700 return NULL;
3701 }
3702
3703 return c->protocol.chat.tmpOP_channel;
3704 }
3705
conn_set_tmpVOICE_channel(t_connection * c,char const * tmpVOICE_channel)3706 extern int conn_set_tmpVOICE_channel(t_connection * c, char const * tmpVOICE_channel)
3707 {
3708 if (!c)
3709 {
3710 eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
3711 return -1;
3712 }
3713
3714 if (c->protocol.chat.tmpVOICE_channel)
3715 {
3716 xfree((void *)c->protocol.chat.tmpVOICE_channel);
3717 c->protocol.chat.tmpVOICE_channel = NULL;
3718 }
3719
3720 if (tmpVOICE_channel)
3721 c->protocol.chat.tmpVOICE_channel = xstrdup(tmpVOICE_channel);
3722
3723 return 0;
3724 }
3725
conn_get_tmpVOICE_channel(t_connection * c)3726 extern char const * conn_get_tmpVOICE_channel(t_connection * c)
3727 {
3728 if (!c)
3729 {
3730 eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
3731 return NULL;
3732 }
3733
3734 return c->protocol.chat.tmpVOICE_channel;
3735 }
3736
connarray_create(void)3737 static int connarray_create(void)
3738 {
3739 int i;
3740 t_conn_entry *curr;
3741
3742 if (connarray) connarray_destroy();
3743 connarray = xmalloc(sizeof(t_conn_entry) * fdw_maxcons);
3744
3745 elist_init(&arrayflist);
3746 /* put all elements as free */
3747 for(i = 0, curr = connarray; i < fdw_maxcons; i++, curr++) {
3748 elist_add_tail(&arrayflist,&curr->freelist);
3749 curr->c = NULL;
3750 }
3751
3752 return 0;
3753 }
3754
3755
connarray_destroy(void)3756 static void connarray_destroy(void)
3757 {
3758 if (connarray) xfree((void*)connarray);
3759 connarray = NULL;
3760 }
3761
connarray_get_conn(unsigned index)3762 static t_connection *connarray_get_conn(unsigned index)
3763 {
3764 if (index >= fdw_maxcons) return NULL;
3765 return connarray[index].c;
3766 }
3767
connarray_add_conn(t_connection * c)3768 static unsigned connarray_add_conn(t_connection *c)
3769 {
3770 t_conn_entry *curr;
3771
3772 assert(c);
3773 assert(!elist_empty(&arrayflist));
3774
3775 curr = elist_entry(elist_next(&arrayflist),t_conn_entry,freelist);
3776 assert(curr->c == NULL); /* it should never be free and != NULL */
3777 curr->c = c;
3778 elist_del(&curr->freelist);
3779 return (curr - connarray); /* return the array index */
3780 }
3781
connarray_del_conn(unsigned index)3782 static void connarray_del_conn(unsigned index)
3783 {
3784 t_conn_entry *curr;
3785
3786 if (index >= fdw_maxcons) return;
3787 curr = connarray + index;
3788 curr->c = NULL;
3789 elist_add_tail(&arrayflist,&curr->freelist);
3790 }
3791
3792 /**
3793 * Westwood Online Extensions
3794 */
conn_get_wol(t_connection * c)3795 extern int conn_get_wol(t_connection * c)
3796 {
3797 if (!c)
3798 {
3799 eventlog(eventlog_level_error,__FUNCTION__,"get NULL conn");
3800 return -1;
3801 }
3802
3803 if (c->protocol.class==conn_class_wol)
3804 return 1;
3805
3806 return 0;
3807 }
3808
conn_wol_set_ingame(t_connection * c,int ingame)3809 extern void conn_wol_set_ingame(t_connection * c, int ingame)
3810 {
3811 if (!c)
3812 {
3813 eventlog(eventlog_level_error,__FUNCTION__,"get NULL conn");
3814 return;
3815 }
3816
3817 if (ingame)
3818 c->protocol.wol.ingame = ingame;
3819 }
3820
conn_wol_get_ingame(t_connection * c)3821 extern int conn_wol_get_ingame(t_connection * c)
3822 {
3823 if (!c)
3824 {
3825 eventlog(eventlog_level_error,__FUNCTION__,"get NULL conn");
3826 return -1;
3827 }
3828
3829 return c->protocol.wol.ingame;
3830 }
3831
conn_wol_set_apgar(t_connection * c,char const * apgar)3832 extern void conn_wol_set_apgar(t_connection * c, char const * apgar)
3833 {
3834 if (!c)
3835 {
3836 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3837 return;
3838 }
3839 if (!apgar)
3840 {
3841 eventlog(eventlog_level_error,__FUNCTION__,"got NULL WOL apgar");
3842 return;
3843 }
3844
3845 if (c->protocol.wol.apgar)
3846 xfree((void *)c->protocol.wol.apgar); /* avoid warning */
3847 c->protocol.wol.apgar = xstrdup(apgar);
3848 }
3849
conn_wol_get_apgar(t_connection * c)3850 extern char const * conn_wol_get_apgar(t_connection * c)
3851 {
3852 if (!c)
3853 {
3854 eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
3855 return NULL;
3856 }
3857
3858 return c->protocol.wol.apgar;
3859 }
3860
conn_wol_set_codepage(t_connection * c,int codepage)3861 extern void conn_wol_set_codepage(t_connection * c, int codepage)
3862 {
3863 if (!c)
3864 {
3865 eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
3866 return;
3867 }
3868
3869 if (codepage)
3870 c->protocol.wol.codepage = codepage;
3871 }
3872
conn_wol_get_codepage(t_connection * c)3873 extern int conn_wol_get_codepage(t_connection * c)
3874 {
3875 if (!c)
3876 {
3877 eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
3878 return -1;
3879 }
3880
3881 return c->protocol.wol.codepage;
3882 }
3883
conn_wol_set_locale(t_connection * c,int locale)3884 extern void conn_wol_set_locale(t_connection * c, int locale)
3885 {
3886 if (!c)
3887 {
3888 eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
3889 return;
3890 }
3891
3892 if (locale)
3893 c->protocol.wol.locale = locale;
3894 }
3895
conn_wol_get_locale(t_connection * c)3896 extern int conn_wol_get_locale(t_connection * c)
3897 {
3898 if (!c)
3899 {
3900 eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
3901 return -1;
3902 }
3903
3904 return c->protocol.wol.locale;
3905 }
3906
conn_wol_set_game_type(t_connection * c,int gameType)3907 extern void conn_wol_set_game_type(t_connection * c, int gameType)
3908 {
3909 if (!c)
3910 {
3911 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3912 return;
3913 }
3914
3915 if (gameType)
3916 c->protocol.wol.gameType = gameType;
3917 }
3918
conn_wol_get_game_type(t_connection * c)3919 extern int conn_wol_get_game_type(t_connection * c)
3920 {
3921 if (!c)
3922 {
3923 eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
3924 return -1;
3925 }
3926
3927 return c->protocol.wol.gameType;
3928 }
3929
conn_wol_set_game_options(t_connection * c,char const * gameOptions)3930 extern void conn_wol_set_game_options(t_connection * c, char const * gameOptions)
3931 {
3932 if (!c)
3933 {
3934 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
3935 return;
3936 }
3937 if (!gameOptions)
3938 {
3939 eventlog(eventlog_level_error,__FUNCTION__,"got NULL game options");
3940 return;
3941 }
3942
3943 if (c->protocol.wol.gameOptions)
3944 xfree((void *)c->protocol.wol.gameOptions); /* avoid warning */
3945 c->protocol.wol.gameOptions = xstrdup(gameOptions);
3946 }
3947
conn_wol_get_game_options(t_connection * c)3948 extern char const * conn_wol_get_game_options(t_connection * c)
3949 {
3950 if (!c)
3951 {
3952 eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
3953 return NULL;
3954 }
3955
3956 return c->protocol.wol.gameOptions;
3957 }
3958