/[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.2 - (show annotations)
Sat Jun 10 16:20:06 2006 UTC (19 years, 9 months ago) by sysadm
Branch: MAIN
CVS Tags: pvpgn_1-7-4-0_MIL, HEAD
Changes since 1.1: +42 -0 lines
Content type: text/x-csrc
Error occurred while calculating annotation data.
Antibot

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

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