connection.c
上传用户:tany51
上传日期:2013-06-12
资源大小:1397k
文件大小:95k
源码类别:

MySQL数据库

开发平台:

Visual C++

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