/[LeafOK_CVS]/pvpgn-1.7.4/src/bnetd/connection.c
ViewVC logotype

Contents of /pvpgn-1.7.4/src/bnetd/connection.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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

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