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

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) 1999  Gediminas (gediminas_lt@mailexcite.com)
  5.  * Copyright (C) 1999  Rob Crittenden (rcrit@greyoak.com)
  6.  * Copyright (C) 2000,2001  Marco Ziech (mmz@gmx.net)
  7.  * Copyright (C) 2000  Dizzy (dizzy@roedu.net)
  8.  * Copyright (C) 2000  Onlyer (onlyer@263.net)
  9.  *
  10.  * This program is free software; you can redistribute it and/or
  11.  * modify it under the terms of the GNU General Public License
  12.  * as published by the Free Software Foundation; either version 2
  13.  * of the License, or (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  23.  */
  24. #include "common/setup_before.h"
  25. #include <stdio.h>
  26. #ifdef HAVE_STDDEF_H
  27. # include <stddef.h>
  28. #else
  29. # ifndef NULL
  30. #  define NULL ((void *)0)
  31. # endif
  32. #endif
  33. #ifdef STDC_HEADERS
  34. # include <stdlib.h>
  35. #else
  36. # ifdef HAVE_MALLOC_H
  37. #  include <malloc.h>
  38. # endif
  39. #endif
  40. #include "compat/strtoul.h"
  41. #ifdef HAVE_STRING_H
  42. # include <string.h>
  43. #else
  44. # ifdef HAVE_STRINGS_H
  45. #  include <strings.h>
  46. # endif
  47. #endif
  48. #include "compat/strdup.h"
  49. #include "compat/strcasecmp.h"
  50. #include <ctype.h>
  51. #include <errno.h>
  52. #include "compat/strerror.h"
  53. #ifdef TIME_WITH_SYS_TIME
  54. # include <sys/time.h>
  55. # include <time.h>
  56. #else
  57. # ifdef HAVE_SYS_TIME_H
  58. #  include <sys/time.h>
  59. # else
  60. #  include <time.h>
  61. # endif
  62. #endif
  63. #ifdef HAVE_SYS_TYPES
  64. # include <sys/types.h>
  65. #endif
  66. #include "compat/strftime.h"
  67. #include "message.h"
  68. #include "common/tag.h"
  69. #include "connection.h"
  70. #include "channel.h"
  71. #include "game.h"
  72. #include "common/util.h"
  73. #include "common/version.h"
  74. #include "account.h"
  75. #include "server.h"
  76. #include "prefs.h"
  77. #include "common/eventlog.h"
  78. #include "ladder.h"
  79. #include "timer.h"
  80. #include "common/bnettime.h"
  81. #include "common/addr.h"
  82. #include "common/packet.h"
  83. #include "gametrans.h"
  84. #include "helpfile.h"
  85. #include "mail.h"
  86. #include "common/bnethash.h"
  87. #include "runprog.h"
  88. #include "common/list.h"
  89. #include "common/proginfo.h"
  90. #include "alias_command.h"
  91. #include "realm.h"
  92. #include "ipban.h"
  93. #include "command_groups.h"
  94. #include "common/queue.h"
  95. #include "common/bn_type.h"
  96. #include "command.h"
  97. #include "news.h"
  98. #include "common/setup_after.h"
  99. // aaron
  100. #include "topic.h"
  101. #include "friends.h"
  102. #include "clan.h"
  103. static char const * bnclass_get_str(unsigned int class);
  104. static void do_whisper(t_connection * user_c, char const * dest, char const * text);
  105. static void do_whois(t_connection * c, char const * dest);
  106. static void user_timer_cb(t_connection * c, time_t now, t_timer_data str);
  107. char msgtemp[MAX_MESSAGE_LEN];
  108. static char const * bnclass_get_str(unsigned int class)
  109. {
  110.     switch (class)
  111.     {
  112.     case PLAYERINFO_DRTL_CLASS_WARRIOR:
  113. return "warrior";
  114.     case PLAYERINFO_DRTL_CLASS_ROGUE:
  115. return "rogue";
  116.     case PLAYERINFO_DRTL_CLASS_SORCERER:
  117. return "sorcerer";
  118.     default:
  119. return "unknown";
  120.     }
  121. }
  122. static void do_whisper(t_connection * user_c, char const * dest, char const * text)
  123. {
  124.     t_connection * dest_c;
  125.     char const *   tname;
  126.     
  127.     if (!(dest_c = connlist_find_connection_by_name(dest,conn_get_realmname(user_c))))
  128.     {
  129. message_send_text(user_c,message_type_error,user_c,"That user is not logged on.");
  130. return;
  131.     }
  132.     
  133.     if (conn_get_dndstr(dest_c))
  134.     {
  135.         sprintf(msgtemp,"%.64s is unavailable (%.128s)",(tname = conn_get_username(dest_c)),conn_get_dndstr(dest_c));
  136. conn_unget_username(dest_c,tname);
  137.         message_send_text(user_c,message_type_info,user_c,msgtemp);
  138.         return;
  139.     }
  140.     
  141.     message_send_text(user_c,message_type_whisperack,dest_c,text);
  142.     
  143.     if (conn_get_awaystr(dest_c))
  144.     {
  145.         sprintf(msgtemp,"%.64s is away (%.128s)",(tname = conn_get_username(dest_c)),conn_get_awaystr(dest_c));
  146. conn_unget_username(dest_c,tname);
  147.         message_send_text(user_c,message_type_info,user_c,msgtemp);
  148.     }
  149.     
  150.     message_send_text(dest_c,message_type_whisper,user_c,text);
  151.     
  152.     if ((tname = conn_get_username(user_c)))
  153.     {
  154.         char username[1+USER_NAME_MAX]; /* '*' + username (including NUL) */
  155. if (strlen(tname)<USER_NAME_MAX)
  156. {
  157.             sprintf(username,"*%s",tname);
  158.     conn_set_lastsender(dest_c,username);
  159. }
  160. conn_unget_username(dest_c,tname);
  161.     }
  162. }
  163. static void do_whois(t_connection * c, char const * dest)
  164. {
  165.     t_connection *    dest_c;
  166.     char              namepart[136]; /* 64 + " (" + 64 + ")" + NUL */
  167.     char const *      verb;
  168.     t_game const *    game;
  169.     t_channel const * channel;
  170.     
  171.     if (!(dest_c = connlist_find_connection_by_accountname(dest)))
  172.     {
  173. t_account * dest_a;
  174. t_bnettime btlogin;
  175. time_t ulogin;
  176. struct tm * tmlogin;
  177. if (!(dest_a = accountlist_find_account(dest))) {
  178.     message_send_text(c,message_type_error,c,"Unknown user.");
  179.     return;
  180. }
  181. if (conn_get_class(c) == conn_class_bnet) {
  182.     btlogin = time_to_bnettime((time_t)account_get_ll_time(dest_a),0);
  183.     btlogin = bnettime_add_tzbias(btlogin, conn_get_tzbias(c));
  184.     ulogin = bnettime_to_time(btlogin);
  185.     if (!(tmlogin = gmtime(&ulogin)))
  186. strcpy(msgtemp, "User was last seen on ?");
  187.     else
  188. strftime(msgtemp, sizeof(msgtemp), "User was last seen on : %a %b %d %H:%M:%S",tmlogin);
  189. } else strcpy(msgtemp, "User is offline");
  190. message_send_text(c, message_type_info, c, msgtemp);
  191. return;
  192.     }
  193.     
  194.     if (c==dest_c)
  195.     {
  196. strcpy(namepart,"You");
  197. verb = "are";
  198.     }
  199.     else
  200.     {
  201. char const * tname;
  202. sprintf(namepart,"%.64s",(tname = conn_get_username(dest_c)));
  203. conn_unget_username(dest_c,tname);
  204. verb = "is";
  205.     }
  206.     
  207.     if ((game = conn_get_game(dest_c)))
  208.     {
  209. sprintf(msgtemp,"%s %s logged on from account "UID_FORMAT", and %s currently in %s game "%.64s".",
  210. namepart,
  211. verb,
  212. conn_get_userid(dest_c),
  213. verb,
  214. game_get_flag(game) == game_flag_private ? "private" : "",
  215. game_get_name(game));
  216.     }
  217.     else if ((channel = conn_get_channel(dest_c)))
  218.     {
  219.         sprintf(msgtemp,"%s %s logged on from account "UID_FORMAT", and %s currently in channel "%.64s".",
  220. namepart,
  221. verb,
  222. conn_get_userid(dest_c),
  223. verb,
  224. channel_get_name(channel));
  225.     }
  226.     else
  227. sprintf(msgtemp,"%s %s logged on from account "UID_FORMAT".",
  228. namepart,
  229. verb,
  230. conn_get_userid(dest_c));
  231.     message_send_text(c,message_type_info,c,msgtemp);
  232.     
  233.     if (conn_get_dndstr(dest_c))
  234.     {
  235.         sprintf(msgtemp,"%s %s refusing messages (%.128s)",
  236. namepart,
  237. verb,
  238. conn_get_dndstr(dest_c));
  239. message_send_text(c,message_type_info,c,msgtemp);
  240.     }
  241.     else
  242.         if (conn_get_awaystr(dest_c))
  243.         {
  244.             sprintf(msgtemp,"%s away (%.128s)",
  245.     namepart,
  246.     conn_get_awaystr(dest_c));
  247.     message_send_text(c,message_type_info,c,msgtemp);
  248.         }
  249. }
  250. static void user_timer_cb(t_connection * c, time_t now, t_timer_data str)
  251. {
  252.     if (!c)
  253.     {
  254. eventlog(eventlog_level_error,"user_timer_cb","got NULL connection");
  255. return;
  256.     }
  257.     if (!str.p)
  258.     {
  259. eventlog(eventlog_level_error,"user_timer_cb","got NULL str");
  260. return;
  261.     }
  262.     
  263.     if (now!=(time_t)0) /* zero means user logged out before expiration */
  264. message_send_text(c,message_type_info,c,str.p);
  265.     free(str.p);
  266. }
  267. typedef int (* t_command)(t_connection * c, char const * text);
  268. typedef struct {
  269. const char * command_string;
  270. t_command    command_handler;
  271. } t_command_table_row;
  272. static int command_set_flags(t_connection * c); // [Omega]
  273. // command handler prototypes
  274. static int _handle_clan_command(t_connection * c, char const * text);
  275. static int _handle_admin_command(t_connection * c, char const * text);
  276. static int _handle_aop_command(t_connection * c, char const * text);
  277. static int _handle_op_command(t_connection * c, char const * text);
  278. static int _handle_tmpop_command(t_connection * c, char const * text);
  279. static int _handle_deop_command(t_connection * c, char const * text);
  280. static int _handle_voice_command(t_connection * c, char const * text);
  281. static int _handle_devoice_command(t_connection * c, char const * text);
  282. static int _handle_vop_command(t_connection * c, char const * text);
  283. static int _handle_friends_command(t_connection * c, char const * text);
  284. static int _handle_me_command(t_connection * c, char const * text);
  285. static int _handle_whisper_command(t_connection * c, char const * text);
  286. static int _handle_status_command(t_connection * c, char const * text);
  287. static int _handle_who_command(t_connection * c, char const * text);
  288. static int _handle_whois_command(t_connection * c, char const * text);
  289. static int _handle_whoami_command(t_connection * c, char const * text);
  290. static int _handle_announce_command(t_connection * c, char const * text);
  291. static int _handle_beep_command(t_connection * c, char const * text);
  292. static int _handle_nobeep_command(t_connection * c, char const * text);
  293. static int _handle_version_command(t_connection * c, char const * text);
  294. static int _handle_copyright_command(t_connection * c, char const * text);
  295. static int _handle_uptime_command(t_connection * c, char const * text);
  296. static int _handle_stats_command(t_connection * c, char const * text);
  297. static int _handle_time_command(t_connection * c, char const * text);
  298. static int _handle_channel_command(t_connection * c, char const * text);
  299. static int _handle_rejoin_command(t_connection * c, char const * text);
  300. static int _handle_away_command(t_connection * c, char const * text);
  301. static int _handle_dnd_command(t_connection * c, char const * text);
  302. static int _handle_squelch_command(t_connection * c, char const * text);
  303. static int _handle_unsquelch_command(t_connection * c, char const * text);
  304. //static int _handle_designate_command(t_connection * c, char const * text); Obsolete function [Omega]
  305. //static int _handle_resign_command(t_connection * c, char const * text); Obsolete function [Omega]
  306. static int _handle_kick_command(t_connection * c, char const * text);
  307. static int _handle_ban_command(t_connection * c, char const * text);
  308. static int _handle_unban_command(t_connection * c, char const * text);
  309. static int _handle_reply_command(t_connection * c, char const * text);
  310. static int _handle_realmann_command(t_connection * c, char const * text);
  311. static int _handle_watch_command(t_connection * c, char const * text);
  312. static int _handle_unwatch_command(t_connection * c, char const * text);
  313. static int _handle_watchall_command(t_connection * c, char const * text);
  314. static int _handle_unwatchall_command(t_connection * c, char const * text);
  315. static int _handle_lusers_command(t_connection * c, char const * text);
  316. static int _handle_news_command(t_connection * c, char const * text);
  317. static int _handle_games_command(t_connection * c, char const * text);
  318. static int _handle_channels_command(t_connection * c, char const * text);
  319. static int _handle_addacct_command(t_connection * c, char const * text);
  320. static int _handle_chpass_command(t_connection * c, char const * text);
  321. static int _handle_connections_command(t_connection * c, char const * text);
  322. static int _handle_finger_command(t_connection * c, char const * text);
  323. static int _handle_operator_command(t_connection * c, char const * text);
  324. static int _handle_admins_command(t_connection * c, char const * text);
  325. static int _handle_quit_command(t_connection * c, char const * text);
  326. static int _handle_kill_command(t_connection * c, char const * text);
  327. static int _handle_killsession_command(t_connection * c, char const * text);
  328. static int _handle_gameinfo_command(t_connection * c, char const * text);
  329. static int _handle_ladderactivate_command(t_connection * c, char const * text);
  330. static int _handle_rehash_command(t_connection * c, char const * text);
  331. //static int _handle_rank_all_accounts_command(t_connection * c, char const * text);
  332. static int _handle_shutdown_command(t_connection * c, char const * text);
  333. static int _handle_ladderinfo_command(t_connection * c, char const * text);
  334. static int _handle_timer_command(t_connection * c, char const * text);
  335. static int _handle_serverban_command(t_connection * c, char const * text);
  336. static int _handle_netinfo_command(t_connection * c, char const * text);
  337. static int _handle_quota_command(t_connection * c, char const * text);
  338. static int _handle_lockacct_command(t_connection * c, char const * text);
  339. static int _handle_unlockacct_command(t_connection * c, char const * text);
  340. static int _handle_flag_command(t_connection * c, char const * text);
  341. static int _handle_tag_command(t_connection * c, char const * text);
  342. //static int _handle_ipban_command(t_connection * c, char const * text); Redirected to handle_ipban_command() in ipban.c [Omega]
  343. static int _handle_set_command(t_connection * c, char const * text);
  344. static int _handle_motd_command(t_connection * c, char const * text);
  345. static int _handle_ping_command(t_connection * c, char const * text);
  346. static int _handle_commandgroups_command(t_connection * c, char const * text);
  347. static int _handle_topic_command(t_connection * c, char const * text);
  348. static const t_command_table_row standard_command_table[] =
  349. {
  350. { "/clan" , _handle_clan_command },
  351. { "/c" , _handle_clan_command },
  352. { "/admin" , _handle_admin_command },
  353. { "/f"                  , _handle_friends_command },
  354. { "/friends"            , _handle_friends_command },
  355. { "/me"                 , _handle_me_command },
  356. { "/msg"                , _handle_whisper_command },
  357. { "/whisper"            , _handle_whisper_command },
  358. { "/w"                  , _handle_whisper_command },
  359. { "/m"                  , _handle_whisper_command },
  360. { "/status"             , _handle_status_command },
  361. { "/users"              , _handle_status_command },
  362. { "/who"                , _handle_who_command },
  363. { "/whois"              , _handle_whois_command },
  364. { "/whereis"            , _handle_whois_command },
  365. { "/where"              , _handle_whois_command },
  366. { "/whoami"             , _handle_whoami_command },
  367. { "/announce"           , _handle_announce_command },
  368. { "/beep"               , _handle_beep_command },
  369. { "/nobeep"             , _handle_nobeep_command },
  370. { "/version"            , _handle_version_command },
  371. { "/copyright"          , _handle_copyright_command },
  372. { "/warrenty"           , _handle_copyright_command },
  373. { "/license"            , _handle_copyright_command },
  374. { "/uptime"             , _handle_uptime_command },
  375. { "/stats"              , _handle_stats_command },
  376. { "/astat"              , _handle_stats_command },
  377. { "/time"               , _handle_time_command },
  378.         { "/channel"            , _handle_channel_command },
  379. { "/join"               , _handle_channel_command },
  380. { "/rejoin"             , _handle_rejoin_command },
  381. { "/away"               , _handle_away_command },
  382. { "/dnd"                , _handle_dnd_command },
  383. { "/ignore"             , _handle_squelch_command },
  384. { "/squelch"            , _handle_squelch_command },
  385. { "/unignore"           , _handle_unsquelch_command },
  386. { "/unsquelch"          , _handle_unsquelch_command },
  387. // { "/designate"          , _handle_designate_command }, Obsotele command [Omega]
  388. // { "/resign"             , _handle_resign_command }, Obsolete command [Omega]
  389. { "/kick"               , _handle_kick_command },
  390. { "/ban"                , _handle_ban_command },
  391. { "/unban"              , _handle_unban_command },
  392. { NULL                  , NULL }
  393. };
  394. static const t_command_table_row extended_command_table[] =
  395. {
  396. { "/ann"                , _handle_announce_command },
  397. { "/r"                  , _handle_reply_command },
  398. { "/reply"              , _handle_reply_command },
  399. { "/realmann"           , _handle_realmann_command },
  400. { "/watch"              , _handle_watch_command },
  401. { "/unwatch"            , _handle_unwatch_command },
  402. { "/watchall"           , _handle_watchall_command },
  403. { "/unwatchall"         , _handle_unwatchall_command },
  404. { "/lusers"             , _handle_lusers_command },
  405. { "/news"               , _handle_news_command },
  406. { "/games"              , _handle_games_command },
  407. { "/channels"           , _handle_channels_command },
  408. { "/chs"                , _handle_channels_command },
  409. { "/addacct"            , _handle_addacct_command },
  410. { "/chpass"             , _handle_chpass_command },
  411. { "/connections"        , _handle_connections_command },
  412. { "/con"                , _handle_connections_command },
  413. { "/finger"             , _handle_finger_command },
  414. { "/operator"           , _handle_operator_command },
  415. { "/aop" , _handle_aop_command },
  416. { "/op"            , _handle_op_command },
  417. { "/tmpop"            , _handle_tmpop_command },
  418. { "/deop"            , _handle_deop_command },
  419. { "/voice" , _handle_voice_command },
  420. { "/devoice" , _handle_devoice_command },
  421. { "/vop" , _handle_vop_command },
  422. { "/admins"             , _handle_admins_command },
  423. { "/logout"             , _handle_quit_command },
  424. { "/quit"               , _handle_quit_command },
  425. { "/exit"               , _handle_quit_command },
  426. { "/kill"               , _handle_kill_command },
  427. { "/killsession"        , _handle_killsession_command },
  428. { "/gameinfo"           , _handle_gameinfo_command },
  429. { "/ladderactivate"     , _handle_ladderactivate_command },
  430. { "/rehash"             , _handle_rehash_command },
  431. // { "/rank_all_accounts"  , _handle_rank_all_accounts_command },
  432. { "/shutdown"           , _handle_shutdown_command },
  433. { "/ladderinfo"         , _handle_ladderinfo_command },
  434. { "/timer"              , _handle_timer_command },
  435. { "/serverban"          , _handle_serverban_command },
  436. { "/netinfo"            , _handle_netinfo_command },
  437. { "/quota"              , _handle_quota_command },
  438. { "/lockacct"           , _handle_lockacct_command },
  439. { "/unlockacct"         , _handle_unlockacct_command },
  440. { "/flag"               , _handle_flag_command },
  441. { "/tag"                , _handle_tag_command },
  442. { "/help"               , handle_help_command },
  443. { "/mail"               , handle_mail_command },
  444. { "/ipban"              , handle_ipban_command }, // in ipban.c
  445. { "/set"                , _handle_set_command },
  446. { "/motd"               , _handle_motd_command },
  447. { "/latency"            , _handle_ping_command },
  448. { "/ping"               , _handle_ping_command },
  449. { "/p"                  , _handle_ping_command },
  450. { "/commandgroups" , _handle_commandgroups_command },
  451. { "/cg" , _handle_commandgroups_command },
  452. { "/topic" , _handle_topic_command },
  453.         { NULL                  , NULL } 
  454. };
  455. char const * skip_command(char const * org_text)
  456. {
  457.    unsigned int i;
  458.    char * text = (char *)org_text;
  459.    for (i=0; text[i]!=' ' && text[i]!=''; i++); /* skip command */
  460.    if (text[i]!='') text[i++]='';             /* -terminate command */
  461.    for (; text[i]==' '; i++);  
  462.    return &text[i];
  463. }
  464. extern int handle_command(t_connection * c,  char const * text)
  465. {
  466.   t_command_table_row const *p;
  467.   for (p = standard_command_table; p->command_string != NULL; p++)
  468.     {
  469.       if (strstart(text, p->command_string)==0)
  470.         {
  471.   if (!(command_get_group(p->command_string)))
  472.     {
  473.       message_send_text(c,message_type_error,c,"This command has been deactivated");
  474.       return 0;
  475.     }
  476.   if (!((command_get_group(p->command_string) & account_get_command_groups(conn_get_account(c)))))
  477.     {
  478.       message_send_text(c,message_type_error,c,"This command is reserved for admins.");
  479.       return 0;
  480.     }
  481. if (p->command_handler != NULL) return ((p->command_handler)(c,text));
  482. }
  483.     }
  484.        
  485.     if (prefs_get_extra_commands()==0)
  486.     {
  487. message_send_text(c,message_type_error,c,"Unknown command.");
  488. eventlog(eventlog_level_debug,"handle_command","got unknown standard command "%s"",text);
  489. return 0;
  490.     }
  491.     
  492.     for (p = extended_command_table; p->command_string != NULL; p++)
  493.       {
  494.       if (strstart(text, p->command_string)==0)
  495.         {
  496.   if (!(command_get_group(p->command_string)))
  497.     {
  498.       message_send_text(c,message_type_error,c,"This command has been deactivated");
  499.       return 0;
  500.     }
  501.   if (!((command_get_group(p->command_string) & account_get_command_groups(conn_get_account(c)))))
  502.     {
  503.       message_send_text(c,message_type_error,c,"This command is reserved for admins.");
  504.       return 0;
  505.     }
  506. if (p->command_handler != NULL) return ((p->command_handler)(c,text));
  507. }
  508.     }
  509.      
  510.     if (strlen(text)>=2 && strncmp(text,"//",2)==0)
  511.     {
  512. handle_alias_command(c,text);
  513. return 0;
  514.     }
  515.     message_send_text(c,message_type_error,c,"Unknown command.");
  516.     eventlog(eventlog_level_debug,"handle_command","got unknown command "%s"",text);
  517.     return 0;
  518. }
  519. // +++++++++++++++++++++++++++++++++ command implementations +++++++++++++++++++++++++++++++++++++++
  520. static int _handle_clan_command(t_connection * c, char const * text)
  521. {
  522.   t_account * acc;
  523.   t_clanmember * member;
  524.   t_clan * clan;
  525.   text = skip_command(text);
  526.   if ( text[0] == '' )
  527.     {
  528.       message_send_text(c,message_type_info,c,"usage:");
  529.       message_send_text(c,message_type_info,c,"/clan public  /clan pub");
  530.       message_send_text(c,message_type_info,c,"Opens the clan channel up to the public so that anyone may enter.");
  531.       message_send_text(c,message_type_info,c,"/clan private  /clan priv");
  532.       message_send_text(c,message_type_info,c,"Closes the clan channel such that only members of the clan may enter.");
  533.       message_send_text(c,message_type_info,c,"/clan motd MESSAGE");
  534.       message_send_text(c,message_type_info,c,"Update the clan message of the day to MESSAGE.");
  535.       return 0;
  536.     }
  537.   if((acc = conn_get_account(c)) && (member = account_get_clanmember(acc)) && (clan = clanmember_get_clan(member)))
  538.   {
  539.     if(clanmember_get_status(member)>=CLAN_SHAMAN)
  540.     {
  541.       if (strstart(text,"public")==0 || strstart(text,"pub")==0) {
  542.         if(clan_get_channel_type(clan)!=0)
  543.         {
  544.           clan_set_channel_type(clan,0);
  545.           message_send_text(c,message_type_info,c,"Clan channel is opened up!");
  546.         }
  547.         else
  548.           message_send_text(c,message_type_error,c,"Clan channel has already been opened up!");
  549.       }
  550.       else
  551.       if (strstart(text,"private")==0 || strstart(text,"priv")==0) {
  552.         if(clan_get_channel_type(clan)!=1)
  553.         {
  554.           clan_set_channel_type(clan,1);
  555.           message_send_text(c,message_type_info,c,"Clan channel is closed!");
  556.         }
  557.         else
  558.           message_send_text(c,message_type_error,c,"Clan channel has already been closed!");
  559.       }
  560.       else
  561.       if (strstart(text,"motd")==0) {
  562.         const char * msg=skip_command(text);
  563.         if(msg[0]=='')
  564.         {
  565.           message_send_text(c,message_type_info,c,"usage:");
  566.           message_send_text(c,message_type_info,c,"/clan motd MESSAGE");
  567.           message_send_text(c,message_type_info,c,"Update the clan message of the day to MESSAGE.");
  568.         }
  569.         else
  570.         {
  571.           clan_set_motd(clan, msg);
  572.           message_send_text(c,message_type_info,c,"Clan message of day is updated!");
  573.         }
  574.       }
  575.     }
  576.     else
  577.       message_send_text(c,message_type_error,c,"You are not the chieftain or shaman of clan!");
  578.   }
  579.   else
  580.     message_send_text(c,message_type_error,c,"You are not in a clan!");
  581.   return 0;
  582. }
  583. /*
  584. static int _handle_clan_command(t_connection * c, char const * text)
  585. {
  586.   t_channel const * channel;
  587.   char const      * oldclanname;
  588.   
  589.   if (!(channel = conn_get_channel(c)))
  590.     {
  591.       message_send_text(c,message_type_error,c,"You are not in a channel. Join a channel to set a account password!");
  592.       return 0;
  593.     }
  594.   
  595.   text = skip_command(text);
  596.   
  597.   if ( text[0] == '' )
  598.     {
  599.       message_send_text(c,message_type_info,c,"usage: /clan <clanname>");
  600.       message_send_text(c,message_type_info,c,"Using this option will allow you to join a clan which displays in your profile.  ");
  601.       return 0;
  602.     }
  603.   if (strlen(text) > MAX_CLANNAME_LEN)
  604.   {
  605.     message_send_text(c,message_type_error,c,"the length of your clanname is limited to 64 characters.");
  606.     return 0;
  607.   }
  608.   
  609.   oldclanname = strdup(account_get_w3_clanname(conn_get_account(c)));
  610.   account_set_w3_clanname(conn_get_account(c),text);
  611.   if(!oldclanname || !(*oldclanname))
  612.     {
  613.       sprintf( msgtemp, "Joined Clan %s", text );
  614.     }
  615.   else
  616.     {
  617.       sprintf( msgtemp, "Left Clan %s and Joined Clan %s", oldclanname, text );
  618.     }
  619.   message_send_text(c,message_type_info,c,msgtemp);
  620.   free((void *)oldclanname);
  621.   return 0;
  622. }
  623. */
  624. static int command_set_flags(t_connection * c)
  625. {
  626.   return channel_set_flags(c);
  627. }
  628. static int _handle_admin_command(t_connection * c, char const * text)
  629. {
  630.     char const * username;
  631.     char command;
  632.     t_account * acc;
  633.     
  634.     text = skip_command(text);
  635.     
  636.     if ((text[0]=='') || ((text[0] != '+') && (text[0] != '-'))) {
  637. message_send_text(c,message_type_info,c,"usage: /admin +username to promote user to Server Admin.");
  638. message_send_text(c,message_type_info,c,"       /admin -username to demote user from Aerver Admin.");
  639. return -1;
  640.     }
  641.     
  642.     command = text[0];
  643.     username = &text[1];
  644.     
  645.     if(!*username) {
  646. message_send_text(c,message_type_info,c,"You need to supply a username.");
  647.       return -1;
  648.     }
  649.     
  650.     if(!(acc = accountlist_find_account(username))) {
  651. sprintf(msgtemp, "There's no account with username %.64s.", username);
  652. message_send_text(c, message_type_info, c, msgtemp);
  653. return -1;
  654.     }
  655.     
  656.     if (command == '+') {
  657. if (account_get_auth_admin(acc,NULL) == 1) {
  658.     sprintf(msgtemp,"%s is already a Server Admin",username);
  659. } else {
  660.     account_set_auth_admin(acc,NULL,1);
  661.     sprintf(msgtemp,"%s has been promoted to a Server Admin",username);
  662. }
  663.     } else {
  664. if (account_get_auth_admin(acc,NULL) != 1)
  665.          sprintf(msgtemp,"%s is no Server Admin, so you can't demote him",username);
  666. else {
  667.     account_set_auth_admin(acc,NULL,0);
  668.     sprintf(msgtemp,"%s has been demoted from a Server Admin",username);
  669. }
  670.     }
  671.     
  672.     message_send_text(c, message_type_info, c, msgtemp);
  673.     command_set_flags(connlist_find_connection_by_accountname(username));
  674.     return 0;
  675. }
  676. static int _handle_operator_command(t_connection * c, char const * text)
  677. {
  678.     char const * username;
  679.     char command;
  680.     t_account * acc;
  681.     
  682.     text = skip_command(text);
  683.     
  684.     if ((text[0]=='') || ((text[0] != '+') && (text[0] != '-'))) {
  685. message_send_text(c,message_type_info,c,"usage: /operator +username to promote user to Server Operator.");
  686. message_send_text(c,message_type_info,c,"       /operator -username to demote user from Server Operator.");
  687. return -1;
  688.     }
  689.     
  690.     command = text[0];
  691.     username = &text[1];
  692.     
  693.     if(!*username) {
  694. message_send_text(c,message_type_info,c,"You need to supply a username.");
  695.       return -1;
  696.     }
  697.     
  698.     if(!(acc = accountlist_find_account(username))) {
  699. sprintf(msgtemp, "There's no account with username %.64s.", username);
  700. message_send_text(c, message_type_info, c, msgtemp);
  701. return -1;
  702.     }
  703.     
  704.     if (command == '+') {
  705. if (account_get_auth_operator(acc,NULL) == 1)
  706.     sprintf(msgtemp,"%s is already a Server Operator",username);
  707. else {
  708.     account_set_auth_operator(acc,NULL,1);
  709.     sprintf(msgtemp,"%s has been promoted to a Server Operator",username);
  710. }
  711.     } else {
  712. if (account_get_auth_operator(acc,NULL) != 1)
  713.          sprintf(msgtemp,"%s is no Server Operator, so you can't demote him",username);
  714. else {
  715.     account_set_auth_operator(acc,NULL,0);
  716.     sprintf(msgtemp,"%s has been demoted from a Server Operator",username);
  717. }
  718.     }
  719.     
  720.     message_send_text(c, message_type_info, c, msgtemp);
  721.     command_set_flags(connlist_find_connection_by_accountname(username));
  722.     return 0;
  723. }
  724. static int _handle_aop_command(t_connection * c, char const * text)
  725. {
  726.     char const * username;
  727.     char const * channel;
  728.     t_account * acc;
  729.     
  730.     if (!(channel = channel_get_name(conn_get_channel(c)))) {
  731. message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
  732. return -1;
  733.     }
  734.     
  735.     if (account_get_auth_admin(conn_get_account(c),NULL)!=1 && account_get_auth_admin(conn_get_account(c),channel)!=1) {
  736. message_send_text(c,message_type_error,c,"You must be at least a Channel Admin to use this command.");
  737. return -1;
  738.     }
  739.     
  740.     text = skip_command(text);
  741.     
  742.     if (!(username = &text[0])) {
  743. message_send_text(c, message_type_info, c, "You need to supply a username.");
  744. return -1;
  745.     }
  746.     
  747.     if(!(acc = accountlist_find_account(username))) {
  748. sprintf(msgtemp, "There's no account with username %.64s.", username);
  749. message_send_text(c, message_type_info, c, msgtemp);
  750. return -1;
  751.     }
  752.     
  753.     if (account_get_auth_admin(acc,channel) == 1)
  754. sprintf(msgtemp,"%s is already a Channel Admin",username);
  755.     else {
  756. account_set_auth_admin(acc,channel,1);
  757. sprintf(msgtemp,"%s has been promoted to a Channel Admin",username);
  758.     }
  759.     
  760.     message_send_text(c, message_type_info, c, msgtemp);
  761.     command_set_flags(connlist_find_connection_by_accountname(username));
  762.     return 0;
  763. }
  764. static int _handle_vop_command(t_connection * c, char const * text)
  765. {
  766.     char const * username;
  767.     char const * channel;
  768.     t_account * acc;
  769.     
  770.     if (!(channel = channel_get_name(conn_get_channel(c)))) {
  771. message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
  772. return -1;
  773.     }
  774.     
  775.     if (account_get_auth_admin(conn_get_account(c),NULL)!=1 && account_get_auth_admin(conn_get_account(c),channel)!=1) {
  776. message_send_text(c,message_type_error,c,"You must be at least a Channel Admin to use this command.");
  777. return -1;
  778.     }
  779.     
  780.     text = skip_command(text);
  781.     
  782.     if (!(username = &text[0])) {
  783. message_send_text(c, message_type_info, c, "You need to supply a username.");
  784. return -1;
  785.     }
  786.     
  787.     if(!(acc = accountlist_find_account(username))) {
  788. sprintf(msgtemp, "There's no account with username %.64s.", username);
  789. message_send_text(c, message_type_info, c, msgtemp);
  790. return -1;
  791.     }
  792.     
  793.     if (account_get_auth_voice(acc,channel) == 1)
  794. sprintf(msgtemp,"%s is already on VOP list",username);
  795.     else {
  796. account_set_auth_voice(acc,channel,1);
  797. sprintf(msgtemp,"%s has been added to the VOP list",username);
  798.     }
  799.     
  800.     message_send_text(c, message_type_info, c, msgtemp);
  801.     command_set_flags(connlist_find_connection_by_accountname(username));
  802.     return 0;
  803. }
  804. static int _handle_voice_command(t_connection * c, char const * text)
  805. {
  806.     char const * username;
  807.     char const * channel;
  808.     t_account * acc;
  809.     
  810.     if (!(channel = channel_get_name(conn_get_channel(c)))) {
  811. message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
  812. return -1;
  813.     }
  814.         
  815.     if (!(account_is_operator_or_admin(conn_get_account(c),channel_get_name(conn_get_channel(c))))) {
  816. message_send_text(c,message_type_error,c,"You must be at least a Channel Operator to use this command.");
  817. return -1;
  818.     }
  819.  
  820.     text = skip_command(text);
  821.     
  822.     if (!(username = &text[0])) {
  823. message_send_text(c, message_type_info, c, "You need to supply a username.");
  824. return -1;
  825.     }
  826.     
  827.     if(!(acc = accountlist_find_account(username))) {
  828. sprintf(msgtemp, "There's no account with username %.64s.", username);
  829. message_send_text(c, message_type_info, c, msgtemp);
  830. return -1;
  831.     }
  832.     if (account_get_auth_voice(acc,channel)==1)
  833. sprintf(msgtemp,"%s is already on VOP list, no need to Voice him", username);
  834.     else
  835.     {
  836.       if (channel_account_has_tmpVOICE(conn_get_channel(c),acc))
  837.   sprintf(msgtemp,"%s has already Voice in this channel",username);
  838.       else {
  839.   account_set_tmpVOICE_channel(acc,channel);
  840.   sprintf(msgtemp,"%s has been granted Voice in this channel",username);
  841.       }
  842.     }
  843.     
  844.     message_send_text(c, message_type_info, c, msgtemp);
  845.     command_set_flags(connlist_find_connection_by_accountname(username));
  846.     return 0;
  847. }
  848. static int _handle_devoice_command(t_connection * c, char const * text)
  849. {
  850.     char const * username;
  851.     char const * channel;
  852.     t_account * acc;
  853.     
  854.     if (!(channel = channel_get_name(conn_get_channel(c)))) {
  855. message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
  856. return -1;
  857.     }
  858.     
  859.     if (!(account_is_operator_or_admin(conn_get_account(c),channel_get_name(conn_get_channel(c))))) {
  860. message_send_text(c,message_type_error,c,"You must be at least a Channel Operator to use this command.");
  861. return -1;
  862.     }
  863.     
  864.     text = skip_command(text);
  865.     
  866.     if (!(username = &text[0])) {
  867. message_send_text(c, message_type_info, c, "You need to supply a username.");
  868. return -1;
  869.     }
  870.     
  871.     if(!(acc = accountlist_find_account(username))) {
  872. sprintf(msgtemp, "There's no account with username %.64s.", username);
  873. message_send_text(c, message_type_info, c, msgtemp);
  874. return -1;
  875.     }
  876.     
  877.     if (account_get_auth_voice(acc,channel)==1)
  878.     {
  879. if ((account_get_auth_admin(conn_get_account(c),channel)==1) || (account_get_auth_admin(conn_get_account(c),NULL)==1))
  880. {
  881.     account_set_auth_voice(acc,channel,0);
  882.     account_set_tmpVOICE_channel(acc,NULL);
  883.     sprintf(msgtemp,"%s has been removed from VOP list.",username);
  884. }
  885. else
  886. {
  887.     account_set_tmpVOICE_channel(acc,NULL);
  888.     sprintf(msgtemp,"You must be at least Channel Admin to remove %s from the VOP list",username);
  889. }
  890.     }
  891.     else
  892.     {
  893.       if (channel_account_has_tmpVOICE(conn_get_channel(c),acc))
  894.   {
  895.     account_set_tmpVOICE_channel(acc,NULL);
  896.     sprintf(msgtemp,"Voice has been taken from %s in this channel",username);
  897.   }
  898.       else {
  899.   sprintf(msgtemp,"%s has no Voice, so it can't be taken away",username);
  900.       }
  901.     }
  902.     
  903.     message_send_text(c, message_type_info, c, msgtemp);
  904.     command_set_flags(connlist_find_connection_by_accountname(username));
  905.     return 0;
  906. }
  907. static int _handle_op_command(t_connection * c, char const * text)
  908. {
  909.     char const * username;
  910.     char const * channel;
  911.     t_account * acc;
  912.     int OP_lvl;
  913.     
  914.     if (!(channel = channel_get_name(conn_get_channel(c)))) {
  915. message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
  916. return -1;
  917.     }
  918.     acc = conn_get_account(c);
  919.     OP_lvl = 0;
  920.     
  921.     if (account_is_operator_or_admin(acc,channel))
  922.       OP_lvl = 1;
  923.     else if (channel_account_is_tmpOP(conn_get_channel(c),acc))
  924.       OP_lvl = 2;
  925.     if (OP_lvl==0)
  926.     {
  927. message_send_text(c,message_type_error,c,"You must be at least a Channel Operator or tempOP to use this command.");
  928. return -1;
  929.     }
  930.     
  931.     text = skip_command(text);
  932.     
  933.     if (!(username = &text[0])) {
  934. message_send_text(c, message_type_info, c, "You need to supply a username.");
  935. return -1;
  936.     }
  937.     
  938.     if(!(acc = accountlist_find_account(username))) {
  939. sprintf(msgtemp, "There's no account with username %.64s.", username);
  940. message_send_text(c, message_type_info, c, msgtemp);
  941. return -1;
  942.     }
  943.     
  944.     
  945.     if (OP_lvl==1) // user is full op so he may fully op others
  946.     {
  947.       if (account_get_auth_operator(acc,channel) == 1)
  948.   sprintf(msgtemp,"%s is allready a Channel Operator",username);
  949.       else {
  950.   account_set_auth_operator(acc,channel,1);
  951.   sprintf(msgtemp,"%s has been promoted to a Channel Operator",username);
  952.       }
  953.     }
  954.     else { // user is only tempOP so he may only tempOP others
  955.          t_connection * con;
  956.          if ((!(con = connlist_find_connection_by_account(acc))) || 
  957.              (conn_get_channel(c) != conn_get_channel(con)))
  958.           sprintf(msgtemp,"%s must be on the same channel to tempOP him",username);
  959.          else
  960.          {
  961.            account_set_tmpOP_channel(acc,channel);
  962.    sprintf(msgtemp,"%s has been promoted to a tempOP",username);
  963.          }
  964.     }
  965.     
  966.     message_send_text(c, message_type_info, c, msgtemp);
  967.     command_set_flags(connlist_find_connection_by_accountname(username));
  968.     return 0;
  969. }
  970. static int _handle_tmpop_command(t_connection * c, char const * text)
  971. {
  972.     char const * username;
  973.     char const * channel;
  974.     t_account * acc;
  975.     
  976.     if (!(channel = channel_get_name(conn_get_channel(c)))) {
  977. message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
  978. return -1;
  979.     }
  980.     
  981.     if (!(account_is_operator_or_admin(conn_get_account(c),channel_get_name(conn_get_channel(c))) || channel_account_is_tmpOP(conn_get_channel(c),conn_get_account(c)))) {
  982. message_send_text(c,message_type_error,c,"You must be at least a Channel Operator or tmpOP to use this command.");
  983. return -1;
  984.     }
  985.     
  986.     text = skip_command(text);
  987.     
  988.     if (!(username = &text[0])) {
  989. message_send_text(c, message_type_info, c, "You need to supply a username.");
  990. return -1;
  991.     }
  992.     
  993.     if(!(acc = accountlist_find_account(username))) {
  994. sprintf(msgtemp, "There's no account with username %.64s.", username);
  995. message_send_text(c, message_type_info, c, msgtemp);
  996. return -1;
  997.     }
  998.     if (channel_account_is_tmpOP(conn_get_channel(c),acc))
  999.        sprintf(msgtemp,"%s has already tmpOP in this channel",username);
  1000.     else 
  1001.     {
  1002.        t_connection * con;
  1003.        if ((!(con = connlist_find_connection_by_account(acc))) ||
  1004.            (conn_get_channel(c) != conn_get_channel(con)))
  1005.        sprintf(msgtemp,"%s must be on the same channel to tempOP him",username);
  1006.        else
  1007.        {
  1008.          account_set_tmpOP_channel(acc,channel);
  1009.          sprintf(msgtemp,"%s has been promoted to tmpOP in this channel",username);
  1010.        }
  1011.     }
  1012.     
  1013.     message_send_text(c, message_type_info, c, msgtemp);
  1014.     command_set_flags(connlist_find_connection_by_accountname(username));
  1015.     return 0;
  1016. }
  1017. static int _handle_deop_command(t_connection * c, char const * text)
  1018. {
  1019.     char const * username;
  1020.     char const * channel;
  1021.     t_account * acc;
  1022.     int OP_lvl;
  1023.     
  1024.     if (!(channel = channel_get_name(conn_get_channel(c)))) {
  1025. message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
  1026. return -1;
  1027.     }
  1028.     acc = conn_get_account(c);
  1029.     OP_lvl = 0;
  1030.     
  1031.     if (account_is_operator_or_admin(acc,channel))
  1032.       OP_lvl = 1;
  1033.     else if (channel_account_is_tmpOP(conn_get_channel(c),acc))
  1034.       OP_lvl = 2;
  1035.     if (OP_lvl==0)
  1036.     {
  1037. message_send_text(c,message_type_error,c,"You must be at least a Channel Operator or tempOP to use this command.");
  1038. return -1;
  1039.     }
  1040.     
  1041.     text = skip_command(text);
  1042.     
  1043.     if (!(username = &text[0])) {
  1044. message_send_text(c, message_type_info, c, "You need to supply a username.");
  1045. return -1;
  1046.     }
  1047.     
  1048.     if(!(acc = accountlist_find_account(username))) {
  1049. sprintf(msgtemp, "There's no account with username %.64s.", username);
  1050. message_send_text(c, message_type_info, c, msgtemp);
  1051. return -1;
  1052.     }
  1053.   
  1054.     if (OP_lvl==1) // user is real OP and allowed to deOP
  1055.       {    
  1056. if (account_get_auth_admin(acc,channel) == 1 || account_get_auth_operator(acc,channel) == 1) {
  1057.   if (account_get_auth_admin(acc,channel) == 1) {
  1058.     if (account_get_auth_admin(conn_get_account(c),channel)!=1 && account_get_auth_admin(conn_get_account(c),NULL)!=1)
  1059.       message_send_text(c,message_type_info,c,"You must be at least a Channel Admin to demote another Channel Admin");
  1060.     else {
  1061.       account_set_auth_admin(acc,channel,0);
  1062.       account_set_tmpOP_channel(acc,NULL);
  1063.       sprintf(msgtemp, "%s has been demoted from a Channel Admin.", username);
  1064.       message_send_text(c, message_type_info, c, msgtemp);
  1065.     }
  1066.   }
  1067.   if (account_get_auth_operator(acc,channel) == 1) {
  1068.     account_set_auth_operator(acc,channel,0);
  1069.     account_set_tmpOP_channel(acc,NULL);
  1070.     sprintf(msgtemp,"%s has been demoted from a Channel Operator",username);
  1071.     message_send_text(c, message_type_info, c, msgtemp);
  1072.   }
  1073. else if (channel_account_is_tmpOP(conn_get_channel(c),acc))
  1074.   {
  1075.     account_set_tmpOP_channel(acc,NULL);
  1076.     sprintf(msgtemp,"%s has been demoted from a tempOP of this channel",username);
  1077.     message_send_text(c, message_type_info, c, msgtemp);
  1078.   }
  1079. else {
  1080.   sprintf(msgtemp,"%s is no Channel Admin or Channel Operator or tempOP, so you can't demote him.",username);
  1081.   message_send_text(c, message_type_info, c, msgtemp);
  1082. }
  1083.       }
  1084.     else //user is just a tempOP and may only deOP other tempOPs
  1085.       {
  1086. if (channel_account_is_tmpOP(conn_get_channel(c),acc))
  1087.   {
  1088.     account_set_tmpOP_channel(acc,NULL);
  1089.     sprintf(msgtemp,"%s has been demoted from a tempOP of this channel",username);
  1090.     message_send_text(c, message_type_info, c, msgtemp);
  1091.   }
  1092. else
  1093.   {
  1094.     sprintf(msgtemp,"%s is no tempOP, so you can't demote him",username);
  1095.     message_send_text(c, message_type_info, c, msgtemp);
  1096.   }
  1097.       }
  1098.     
  1099.     command_set_flags(connlist_find_connection_by_accountname(username));
  1100.     return 0;
  1101. }
  1102. static int _handle_friends_command(t_connection * c, char const * text)
  1103. {
  1104.     int i;
  1105.     t_account *my_acc = conn_get_account(c);
  1106.     text = skip_command(text);;
  1107.     if(text[0]=='' || strstart(text,"help")==0 || strstart(text, "h")==0) {
  1108. message_send_text(c,message_type_info,c,"Friends List (Used in Arranged Teams and finding online friends.)");
  1109. message_send_text(c,message_type_info,c,"Type: /f add <username> (adds a friend to your list)");
  1110. message_send_text(c,message_type_info,c,"Type: /f del <username> (removes a friend from your list)");
  1111. message_send_text(c,message_type_info,c,"Type: /f promote <username> (promote a friend in your list)");
  1112. message_send_text(c,message_type_info,c,"Type: /f demote <username> (demote a friend in your list)");
  1113. message_send_text(c,message_type_info,c,"Type: /f list (shows your full friends list)");
  1114. message_send_text(c,message_type_info,c,"Type: /f msg (whispers a message to all your friends at once)");
  1115. return 0;
  1116.     }
  1117.     if (strstart(text,"add")==0 || strstart(text,"a")==0) {
  1118. char msgtemp[MAX_MESSAGE_LEN];
  1119. t_packet  * rpacket;
  1120. t_connection  * dest_c;
  1121. t_account     * friend_acc;
  1122. t_server_friendslistreply_status status;
  1123. t_game * game;
  1124. t_channel * channel;
  1125.         char stat;
  1126. t_list * flist;
  1127. t_friend * fr;
  1128. text = skip_command(text);
  1129. if (text[0] == '') {
  1130.     message_send_text(c,message_type_info,c,"usage: /f add <username>");
  1131.     return 0;
  1132. }
  1133. if (!(friend_acc = accountlist_find_account(text))) {
  1134.     message_send_text(c,message_type_info,c,"That user does not exist.");
  1135.     return 0;
  1136. }
  1137. switch(account_add_friend(my_acc, friend_acc)) {
  1138.     case -1:
  1139.      message_send_text(c,message_type_error,c,"Server error.");
  1140.      return 0;
  1141.     case -2:
  1142.      message_send_text(c,message_type_info,c,"You can't add yourself to your friends list.");
  1143.      return 0;
  1144.     case -3:
  1145.      sprintf(msgtemp, "You can only have a maximum of %d friends.", prefs_get_max_friends());
  1146.      message_send_text(c,message_type_info,c,msgtemp);
  1147.      return 0;
  1148.     case -4:
  1149. sprintf(msgtemp, "%s is already on your friends list!", text);
  1150. message_send_text(c,message_type_info,c,msgtemp);
  1151. return 0;
  1152. }
  1153. sprintf( msgtemp, "Added %s to your friends list.", text);
  1154. message_send_text(c,message_type_info,c,msgtemp);
  1155. dest_c = connlist_find_connection_by_account(friend_acc);
  1156. if(dest_c!=NULL) {
  1157.          sprintf(msgtemp,"%s added you to his/her friends list.",conn_get_username(c));
  1158.          message_send_text(dest_c,message_type_info,dest_c,msgtemp);
  1159. }
  1160. if (!(rpacket = packet_create(packet_class_bnet)))
  1161.          return 0;
  1162. packet_set_size(rpacket,sizeof(t_server_friendadd_ack));
  1163. packet_set_type(rpacket,SERVER_FRIENDADD_ACK);
  1164. packet_append_string(rpacket, account_get_name(friend_acc));
  1165. game = NULL;
  1166.         channel = NULL;
  1167. if(!(dest_c))
  1168.           {
  1169.     bn_byte_set(&status.location,FRIENDSTATUS_OFFLINE);
  1170.     bn_byte_set(&status.status,0);
  1171.             bn_int_set(&status.clienttag,0);
  1172.           }
  1173.   else 
  1174.           {
  1175.     bn_int_set(&status.clienttag, *((int const *)conn_get_clienttag(dest_c)));
  1176.             stat = 0;
  1177.     flist = account_get_friends(my_acc);
  1178.     fr = friendlist_find_account(flist,friend_acc);
  1179.             if ((friend_get_mutual(fr)))    stat |= FRIEND_TYPE_MUTUAL;
  1180.             if ((conn_get_dndstr(dest_c)))  stat |= FRIEND_TYPE_DND;
  1181.     if ((conn_get_awaystr(dest_c))) stat |= FRIEND_TYPE_AWAY;
  1182.     bn_byte_set(&status.status,stat);
  1183.             if((game = conn_get_game(dest_c))) 
  1184.       {
  1185.         if (game_get_flag(game) != game_flag_private)
  1186.   bn_byte_set(&status.location,FRIENDSTATUS_PUBLIC_GAME);
  1187. else
  1188.                   bn_byte_set(&status.location,FRIENDSTATUS_PRIVATE_GAME);
  1189.       }
  1190.     else if((channel = conn_get_channel(dest_c))) 
  1191.       {
  1192.         bn_byte_set(&status.location,FRIENDSTATUS_CHAT);
  1193.       }
  1194.     else 
  1195.       {
  1196. bn_byte_set(&status.location,FRIENDSTATUS_ONLINE);
  1197.       }
  1198.           }
  1199. packet_append_data(rpacket, &status, sizeof(status));
  1200.         if (game) packet_append_string(rpacket,game_get_name(game));
  1201. else if (channel) packet_append_string(rpacket,channel_get_name(channel));
  1202. else packet_append_string(rpacket,"");
  1203. conn_push_outqueue(c,rpacket);
  1204. packet_del_ref(rpacket);
  1205. return 0;
  1206.     }
  1207.     if (strstart(text,"msg")==0 || strstart(text,"w")==0 || strstart(text,"whisper")==0 || strstart(text,"m")==0) 
  1208.     {
  1209. char const *msg;
  1210. int cnt = 0;
  1211. t_connection * dest_c;
  1212. t_elem  * curr;
  1213. t_friend * fr;
  1214. t_list  * flist;
  1215. msg = skip_command(text);
  1216. /* if the message test is empty then ignore command */
  1217. if (msg[0]=='') {
  1218.     message_send_text(c,message_type_info,c,"Did not message any friends. Type some text next time.");
  1219.     return 0; 
  1220. }
  1221.   
  1222. flist=account_get_friends(my_acc);
  1223. if(flist==NULL)
  1224.          return -1;
  1225. LIST_TRAVERSE(flist,curr)
  1226. {
  1227.          if (!(fr = elem_get_data(curr))) {
  1228.          eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list");
  1229.          continue;
  1230.          }
  1231.          if(friend_get_mutual(fr)) {
  1232.          dest_c = connlist_find_connection_by_account(friend_get_account(fr));
  1233. if (!dest_c) continue;
  1234.          message_send_text(dest_c,message_type_whisper,c,msg);
  1235.          cnt++;
  1236.          }
  1237. }
  1238. if(cnt)
  1239.     message_send_text(c,message_type_friendwhisperack,c,msg);
  1240.         else
  1241.     message_send_text(c,message_type_info,c,"All your friends are offline.");
  1242. return 0;
  1243.     }
  1244.     if (strstart(text,"r")==0 || strstart(text,"remove")==0
  1245. || strstart(text,"del")==0 || strstart(text,"delete")==0) {
  1246. int num;
  1247. char msgtemp[MAX_MESSAGE_LEN];
  1248. t_packet * rpacket;
  1249.     
  1250. text = skip_command(text);
  1251. if (text[0]=='') {
  1252.     message_send_text(c,message_type_info,c,"usage: /f remove <username>");
  1253.     return 0;
  1254. }
  1255. switch((num = account_remove_friend2(my_acc, text))) {
  1256.     case -1: return -1;
  1257.     case -2:
  1258. sprintf(msgtemp, "%s was not found on your friends list.", text);
  1259. message_send_text(c,message_type_info,c,msgtemp);
  1260. return 0;
  1261.     default:
  1262. sprintf(msgtemp, "Removed %s from your friends list.", text);
  1263. message_send_text(c,message_type_info,c,msgtemp);
  1264. if (!(rpacket = packet_create(packet_class_bnet)))
  1265.          return 0;
  1266. packet_set_size(rpacket,sizeof(t_server_frienddel_ack));
  1267. packet_set_type(rpacket,SERVER_FRIENDDEL_ACK);
  1268. bn_byte_set(&rpacket->u.server_frienddel_ack.friendnum, num);
  1269. conn_push_outqueue(c,rpacket);
  1270. packet_del_ref(rpacket);
  1271.      return 0; 
  1272. }
  1273.     }
  1274.     if (strstart(text,"p")==0 || strstart(text,"promote")==0) {
  1275. int num;
  1276. int n;
  1277. char msgtemp[MAX_MESSAGE_LEN];
  1278. char const * dest_name;
  1279. t_packet * rpacket;
  1280. t_list * flist;
  1281. t_friend * fr;
  1282. t_account * dest_acc;
  1283. unsigned int dest_uid;
  1284.     
  1285. text = skip_command(text);
  1286. if (text[0]=='') {
  1287.     message_send_text(c,message_type_info,c,"usage: /f promote <username>");
  1288.     return 0;
  1289. }
  1290. num = account_get_friendcount(my_acc);
  1291. flist = account_get_friends(my_acc);
  1292. for(n = 1; n<num; n++)
  1293.     if( (dest_uid = account_get_friend(my_acc, n)) && 
  1294. (fr = friendlist_find_uid(flist, dest_uid)) && 
  1295. (dest_acc = friend_get_account(fr)) && 
  1296. (dest_name = account_get_name(dest_acc)) && 
  1297. (strcasecmp(dest_name, text) == 0) ) 
  1298.     {
  1299. account_set_friend(my_acc, n, account_get_friend(my_acc, n-1));
  1300. account_set_friend(my_acc, n-1, dest_uid);
  1301. sprintf(msgtemp, "Premoted %s in your friends list.", dest_name);
  1302. message_send_text(c,message_type_info,c,msgtemp);
  1303. if (!(rpacket = packet_create(packet_class_bnet)))
  1304.          return 0;
  1305. packet_set_size(rpacket,sizeof(t_server_friendmove_ack));
  1306. packet_set_type(rpacket,SERVER_FRIENDMOVE_ACK);
  1307.      bn_byte_set(&rpacket->u.server_friendmove_ack.pos1, n-1);
  1308.      bn_byte_set(&rpacket->u.server_friendmove_ack.pos2, n);
  1309. conn_push_outqueue(c,rpacket);
  1310. packet_del_ref(rpacket);
  1311. return 0; 
  1312.     }
  1313. return 0; 
  1314.     }
  1315.     if (strstart(text,"d")==0 || strstart(text,"demote")==0) {
  1316. int num;
  1317. int n;
  1318. char msgtemp[MAX_MESSAGE_LEN];
  1319. char const * dest_name;
  1320. t_packet * rpacket;
  1321. t_list * flist;
  1322. t_friend * fr;
  1323. t_account * dest_acc;
  1324. unsigned int dest_uid;
  1325.     
  1326. text = skip_command(text);
  1327. if (text[0]=='') {
  1328.     message_send_text(c,message_type_info,c,"usage: /f demote <username>");
  1329.     return 0;
  1330. }
  1331. num = account_get_friendcount(my_acc);
  1332. flist = account_get_friends(my_acc);
  1333. for(n = 0; n<num-1; n++)
  1334.     if( (dest_uid = account_get_friend(my_acc, n)) && 
  1335. (fr = friendlist_find_uid(flist, dest_uid)) && 
  1336. (dest_acc = friend_get_account(fr)) && 
  1337. (dest_name = account_get_name(dest_acc)) && 
  1338. (strcasecmp(dest_name, text) == 0) ) 
  1339.     {
  1340. account_set_friend(my_acc, n, account_get_friend(my_acc, n+1));
  1341. account_set_friend(my_acc, n+1, dest_uid);
  1342. sprintf(msgtemp, "Premoted %s in your friends list.", dest_name);
  1343. message_send_text(c,message_type_info,c,msgtemp);
  1344. if (!(rpacket = packet_create(packet_class_bnet)))
  1345.          return 0;
  1346. packet_set_size(rpacket,sizeof(t_server_friendmove_ack));
  1347. packet_set_type(rpacket,SERVER_FRIENDMOVE_ACK);
  1348.      bn_byte_set(&rpacket->u.server_friendmove_ack.pos1, n);
  1349.      bn_byte_set(&rpacket->u.server_friendmove_ack.pos2, n+1);
  1350. conn_push_outqueue(c,rpacket);
  1351. packet_del_ref(rpacket);
  1352. return 0; 
  1353.     }
  1354. return 0; 
  1355.     }
  1356.     if (strstart(text,"list")==0 || strstart(text,"l")==0) {
  1357. char const * friend;
  1358. char status[128];
  1359. char software[64];
  1360. char msgtemp[MAX_MESSAGE_LEN];
  1361. t_connection * dest_c;
  1362. t_account * friend_acc;
  1363. t_game const * game;
  1364. t_channel const * channel;
  1365. t_friend * fr;
  1366. t_list  * flist;
  1367. int num;
  1368. unsigned int uid;
  1369. message_send_text(c,message_type_info,c,"Your PvPGN - Friends List");
  1370. message_send_text(c,message_type_info,c,"=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
  1371. num = account_get_friendcount(my_acc);
  1372. flist=account_get_friends(my_acc);
  1373. if(flist!=NULL) {
  1374.     for (i=0;i<num;i++)
  1375.     {
  1376.      if ((!(uid = account_get_friend(my_acc,i))) || (!(fr = friendlist_find_uid(flist,uid))))
  1377.      {
  1378.              eventlog(eventlog_level_error,__FUNCTION__,"friend uid in list");
  1379.              continue;
  1380.      }
  1381.      software[0]='';
  1382.      friend_acc=friend_get_account(fr);
  1383. if (!(dest_c = connlist_find_connection_by_account(friend_acc)))
  1384.          sprintf(status, ", offline");
  1385. else {
  1386.          sprintf(software," using %s", conn_get_user_game_title(conn_get_clienttag(dest_c)));
  1387.          if(friend_get_mutual(fr)) {
  1388.         if ((game = conn_get_game(dest_c)))
  1389.             sprintf(status, ", in game "%.64s"", game_get_name(game));
  1390.         else if ((channel = conn_get_channel(dest_c))) {
  1391.             if(strcasecmp(channel_get_name(channel),"Arranged Teams")==0)
  1392.                 sprintf(status, ", in game AT Preparation");
  1393.             else                        
  1394.                 sprintf(status, ", in channel "%.64s",", channel_get_name(channel));
  1395.          }
  1396.         else
  1397.             sprintf(status, ", is in AT Preparation");
  1398.          } else {
  1399.         if ((game = conn_get_game(dest_c)))
  1400.             sprintf(status, ", is in a game");
  1401.         else if ((channel = conn_get_channel(dest_c))) 
  1402.             sprintf(status, ", is in a chat channel");
  1403.         else
  1404.             sprintf(status, ", is in AT Preparation");
  1405.          }
  1406. }
  1407. friend=account_get_name(friend_acc);
  1408.      if (software[0]) sprintf(msgtemp, "%d: %s%.16s%.128s, %.64s", i+1, friend_get_mutual(fr)?"*":" ", friend, status,software);
  1409. else sprintf(msgtemp, "%d: %.16s%.128s", i+1, friend, status);
  1410. message_send_text(c,message_type_info,c,msgtemp);
  1411.     }
  1412. }
  1413. message_send_text(c,message_type_info,c,"=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
  1414. message_send_text(c,message_type_info,c,"End of Friends List");
  1415. return 0;
  1416.     }
  1417.     return 0;
  1418. }
  1419. static int _handle_me_command(t_connection * c, char const * text)
  1420. {
  1421.   t_channel const * channel;
  1422.   
  1423.   if (!(channel = conn_get_channel(c)))
  1424.     {
  1425.       message_send_text(c,message_type_error,c,"You are not in a channel.");
  1426.       return 0;
  1427.     }
  1428.   
  1429.   text = skip_command(text);
  1430.   if ((text[0]!='') && (!conn_quota_exceeded(c,text)))
  1431.     channel_message_send(channel,message_type_emote,c,text);
  1432.   return 0;
  1433. }
  1434. static int _handle_whisper_command(t_connection * c, char const *text)
  1435. {
  1436.   char         dest[USER_NAME_MAX+REALM_NAME_LEN]; /* both include NUL, so no need to add one for middle @ or * */
  1437.   unsigned int i,j;
  1438.   
  1439.   for (i=0; text[i]!=' ' && text[i]!=''; i++); /* skip command */
  1440.   for (; text[i]==' '; i++);
  1441.   for (j=0; text[i]!=' ' && text[i]!=''; i++) /* get dest */
  1442.     if (j<sizeof(dest)-1) dest[j++] = text[i];
  1443.   dest[j] = '';
  1444.   for (; text[i]==' '; i++);
  1445.   
  1446.   if ((dest[0]=='') || (text[i]==''))
  1447.     {
  1448.       message_send_text(c,message_type_info,c,"usage: /whisper <username> <text to whisper>");
  1449.       return 0;
  1450.     }
  1451.   
  1452.   do_whisper(c,dest,&text[i]);
  1453.   
  1454.   return 0;
  1455. }
  1456. static int _handle_status_command(t_connection * c, char const *text)
  1457. {
  1458.     char ctag[5];
  1459.     unsigned int i,j;
  1460.     
  1461.     for (i=0; text[i]!=' ' && text[i]!=''; i++); /* skip command */
  1462.     for (; text[i]==' '; i++);
  1463.     for (j=0; text[i]!=' ' && text[i]!=''; i++) /* get clienttag */
  1464. if (j<sizeof(ctag)-1) ctag[j++] = text[i];
  1465.     ctag[j] = '';
  1466.     
  1467.     if (ctag[0]=='') {
  1468. sprintf(msgtemp,"There are currently %d users online, in %d games and %d channels.",
  1469.     connlist_login_get_length(),
  1470.     gamelist_get_length(),
  1471.     channellist_get_length());
  1472. message_send_text(c,message_type_info,c,msgtemp);
  1473.     }
  1474.     
  1475.     for (i=0; i<strlen(ctag); i++)
  1476. if (isascii((int)ctag[i]) && islower((int)ctag[i]))
  1477.     ctag[i] = toupper((int)ctag[i]);
  1478.     
  1479.     if ((strcmp(ctag,"ALL") == 0) || (strcmp(ctag,CLIENTTAG_WAR3XP) == 0)) {
  1480. sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
  1481.     conn_get_user_count_by_clienttag(CLIENTTAG_WAR3XP),
  1482.     game_get_count_by_clienttag(CLIENTTAG_WAR3XP),
  1483.     conn_get_user_game_title(CLIENTTAG_WAR3XP));
  1484. message_send_text(c,message_type_info,c,msgtemp);
  1485.     }
  1486.     if ((strcmp(ctag,"ALL") == 0) || (strcmp(ctag,CLIENTTAG_WARCRAFT3) == 0)) {
  1487. sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
  1488.     conn_get_user_count_by_clienttag(CLIENTTAG_WARCRAFT3),
  1489.     game_get_count_by_clienttag(CLIENTTAG_WARCRAFT3),
  1490.     conn_get_user_game_title(CLIENTTAG_WARCRAFT3));
  1491. message_send_text(c,message_type_info,c,msgtemp);
  1492.     }
  1493.     if ((strcmp(ctag,"ALL") == 0) || (strcmp(ctag,CLIENTTAG_DIABLO2XP) == 0)) {
  1494. sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
  1495.     conn_get_user_count_by_clienttag(CLIENTTAG_DIABLO2XP),
  1496.     game_get_count_by_clienttag(CLIENTTAG_DIABLO2XP),
  1497.     conn_get_user_game_title(CLIENTTAG_DIABLO2XP));
  1498. message_send_text(c,message_type_info,c,msgtemp);
  1499.     }
  1500.     if ((strcmp(ctag,"ALL") == 0) || (strcmp(ctag,CLIENTTAG_DIABLO2DV) == 0)) {
  1501. sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
  1502.     conn_get_user_count_by_clienttag(CLIENTTAG_DIABLO2DV),
  1503.     game_get_count_by_clienttag(CLIENTTAG_DIABLO2DV),
  1504.     conn_get_user_game_title(CLIENTTAG_DIABLO2DV));
  1505. message_send_text(c,message_type_info,c,msgtemp);
  1506.     }
  1507.     if ((strcmp(ctag,"ALL") == 0) || (strcmp(ctag,CLIENTTAG_BROODWARS) == 0)) {
  1508. sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
  1509.     conn_get_user_count_by_clienttag(CLIENTTAG_BROODWARS),
  1510.     game_get_count_by_clienttag(CLIENTTAG_BROODWARS),
  1511.     conn_get_user_game_title(CLIENTTAG_BROODWARS));
  1512. message_send_text(c,message_type_info,c,msgtemp);
  1513.     }
  1514.     if ((strcmp(ctag,"ALL") == 0) || (strcmp(ctag,CLIENTTAG_STARCRAFT) == 0)) {
  1515. sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
  1516.     conn_get_user_count_by_clienttag(CLIENTTAG_STARCRAFT),
  1517.     game_get_count_by_clienttag(CLIENTTAG_STARCRAFT),
  1518.     conn_get_user_game_title(CLIENTTAG_STARCRAFT));
  1519. message_send_text(c,message_type_info,c,msgtemp);
  1520.     }
  1521.     if ((strcmp(ctag,"ALL") == 0) || (strcmp(ctag,CLIENTTAG_WARCIIBNE) == 0)) {
  1522. sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
  1523.     conn_get_user_count_by_clienttag(CLIENTTAG_WARCIIBNE),
  1524.     game_get_count_by_clienttag(CLIENTTAG_WARCIIBNE),
  1525.     conn_get_user_game_title(CLIENTTAG_WARCIIBNE));
  1526. message_send_text(c,message_type_info,c,msgtemp);
  1527.     }
  1528.     if ((strcmp(ctag,"ALL") == 0) || (strcmp(ctag,CLIENTTAG_DIABLORTL) == 0)) {
  1529. sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
  1530.     conn_get_user_count_by_clienttag(CLIENTTAG_DIABLORTL),
  1531.     game_get_count_by_clienttag(CLIENTTAG_DIABLORTL),
  1532.     conn_get_user_game_title(CLIENTTAG_DIABLORTL));
  1533. message_send_text(c,message_type_info,c,msgtemp);
  1534.     }
  1535.     
  1536.     return 0;
  1537. }
  1538. static int _handle_who_command(t_connection * c, char const *text)
  1539. {
  1540.   t_connection const * conn;
  1541.   t_channel const *    channel;
  1542.   unsigned int         i;
  1543.   char const *         tname;
  1544.   for (i=0; text[i]!=' ' && text[i]!=''; i++); /* skip command */
  1545.   for (; text[i]==' '; i++);
  1546.   if (text[i]=='')
  1547.   {
  1548. message_send_text(c,message_type_info,c,"usage: /who <channel>");
  1549. return 0;
  1550.   }
  1551.   
  1552.   if (!(channel = channellist_find_channel_by_name(&text[i],conn_get_country(c),conn_get_realmname(c))))
  1553.     {
  1554.       message_send_text(c,message_type_error,c,"That channel does not exist.");
  1555.       message_send_text(c,message_type_error,c,"(If you are trying to search for a user, use the /whois command.)");
  1556.       return 0;
  1557.     }
  1558.   if (channel_check_banning(channel,c)==1)
  1559.     {
  1560.       message_send_text(c,message_type_error,c,"You are banned from that channel.");
  1561.       return 0;
  1562.     }
  1563.   
  1564.   sprintf(msgtemp,"Users in channel %.64s:",&text[i]);
  1565.   i = strlen(msgtemp);
  1566.   for (conn=channel_get_first(channel); conn; conn=channel_get_next())
  1567.     {
  1568.       if (i+strlen((tname = conn_get_username(conn)))+2>sizeof(msgtemp)) /* " ", name, '' */
  1569. {
  1570.   message_send_text(c,message_type_info,c,msgtemp);
  1571.   i = 0;
  1572. }
  1573.       sprintf(&msgtemp[i]," %s",tname);
  1574.       conn_unget_username(conn,tname);
  1575.       i += strlen(&msgtemp[i]);
  1576.     }
  1577.   if (i>0)
  1578.     message_send_text(c,message_type_info,c,msgtemp);
  1579.   
  1580.   return 0;
  1581. }
  1582. static int _handle_whois_command(t_connection * c, char const * text)
  1583. {
  1584.   unsigned int i;
  1585.   
  1586.   for (i=0; text[i]!=' ' && text[i]!=''; i++); /* skip command */
  1587.   for (; text[i]==' '; i++);
  1588.   
  1589.   if (text[i]=='')
  1590.   {
  1591.     message_send_text(c,message_type_info,c,"usage: /whois <username>");
  1592.     return 0;
  1593.   }
  1594.   
  1595.   do_whois(c,&text[i]);
  1596.   
  1597.   return 0;
  1598. }
  1599. static int _handle_whoami_command(t_connection * c, char const *text)
  1600. {
  1601.   char const * tname;
  1602.   
  1603.   if (!(tname = conn_get_username(c)))
  1604.     {
  1605.       message_send_text(c,message_type_error,c,"Unable to obtain your account name.");
  1606.       return 0;
  1607.     }
  1608.   
  1609.   do_whois(c,tname);
  1610.   conn_unget_username(c,tname);
  1611.   
  1612.   return 0;
  1613. }
  1614. static int _handle_announce_command(t_connection * c, char const *text)
  1615. {
  1616.   unsigned int i;
  1617.   char const * tname;
  1618.   t_message *  message;
  1619.   
  1620.   for (i=0; text[i]!=' ' && text[i]!=''; i++); /* skip command */
  1621.   for (; text[i]==' '; i++);
  1622.   
  1623.   if (text[i]=='')
  1624.   {
  1625. message_send_text(c,message_type_info,c,"usage: /announce <announcement>");
  1626. return 0;
  1627.   }
  1628.   
  1629.   sprintf(msgtemp,"Announcement from %.64s: %.128s",(tname = conn_get_username(c)),&text[i]);
  1630.   conn_unget_username(c,tname);
  1631.   if (!(message = message_create(message_type_broadcast,c,NULL,msgtemp)))
  1632.     message_send_text(c,message_type_info,c,"Could not broadcast message.");
  1633.   else
  1634.     {
  1635.       if (message_send_all(message)<0)
  1636. message_send_text(c,message_type_info,c,"Could not broadcast message.");
  1637.       message_destroy(message);
  1638.     }
  1639.   
  1640.   return 0;
  1641. }
  1642. static int _handle_beep_command(t_connection * c, char const *text)
  1643. {
  1644.   message_send_text(c,message_type_info,c,"Audible notification on."); /* FIXME: actually do something */
  1645.   return 0; /* FIXME: these only affect CHAT clients... I think they prevent ^G from being sent */
  1646. }
  1647. static int _handle_nobeep_command(t_connection * c, char const *text)
  1648. {
  1649.   message_send_text(c,message_type_info,c,"Audible notification off."); /* FIXME: actually do something */
  1650.   return 0;
  1651. }
  1652. static int _handle_version_command(t_connection * c, char const *text)
  1653. {
  1654.   message_send_text(c,message_type_info,c,PVPGN_SOFTWARE" "PVPGN_VERSION);  
  1655.   return 0;
  1656. }
  1657. static int _handle_copyright_command(t_connection * c, char const *text)
  1658. {
  1659.   static char const * const info[] =
  1660.     {
  1661.       " Copyright (C) 2002  See source for details",
  1662.       " ",
  1663.       " PvPGN is free software; you can redistribute it and/or",
  1664.       " modify it under the terms of the GNU General Public License",
  1665.       " as published by the Free Software Foundation; either version 2",
  1666.       " of the License, or (at your option) any later version.",
  1667.       " ",
  1668.       " This program is distributed in the hope that it will be useful,",
  1669.       " but WITHOUT ANY WARRANTY; without even the implied warranty of",
  1670.       " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",
  1671.       " GNU General Public License for more details.",
  1672.       " ",
  1673.       " You should have received a copy of the GNU General Public License",
  1674.       " along with this program; if not, write to the Free Software",
  1675.       " Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.",
  1676.       NULL
  1677.     };
  1678.   unsigned int i;
  1679.   
  1680.   for (i=0; info[i]; i++)
  1681.     message_send_text(c,message_type_info,c,info[i]);
  1682.   
  1683.   return 0;
  1684. }
  1685. static int _handle_uptime_command(t_connection * c, char const *text)
  1686. {
  1687.   
  1688.   sprintf(msgtemp,"Uptime: %s",seconds_to_timestr(server_get_uptime()));
  1689.   message_send_text(c,message_type_info,c,msgtemp);
  1690.   
  1691.   return 0;
  1692. }
  1693. static int _handle_stats_command(t_connection * c, char const *text)
  1694. {
  1695.   char         dest[USER_NAME_MAX];
  1696.   unsigned int i,j;
  1697.   t_account *  account;
  1698.   char const * clienttag;
  1699.   char const * tname;
  1700.   
  1701.   for (i=0; text[i]!=' ' && text[i]!=''; i++); /* skip command */
  1702.   for (; text[i]==' '; i++);
  1703.   for (j=0; text[i]!=' ' && text[i]!=''; i++) /* get dest */
  1704.     if (j<sizeof(dest)-1) dest[j++] = text[i];
  1705.   dest[j] = '';
  1706.   for (; text[i]==' '; i++);
  1707.   
  1708.   
  1709.   // [quetzal] 20020815 - /stats without an argument should work as doing /stats yourself
  1710.   if (!dest[0]) {
  1711.     account = conn_get_account(c);
  1712.   } else if (!(account = accountlist_find_account(dest))) {
  1713.     message_send_text(c,message_type_error,c,"Invalid user.");
  1714.     return 0;
  1715.   }
  1716.   if (text[i]!='')
  1717.     clienttag = &text[i];
  1718.   else if (!(clienttag = conn_get_clienttag(c)))
  1719.     {
  1720.       message_send_text(c,message_type_error,c,"Unable to determine client game.");
  1721.       return 0;
  1722.     }
  1723.   
  1724.   if (strlen(clienttag)!=4)
  1725.     {
  1726.       sprintf(msgtemp,"You must supply a user name and a valid program ID. (Program ID "%.32s" is invalid.)",clienttag);
  1727.       message_send_text(c,message_type_error,c,msgtemp);
  1728.       message_send_text(c,message_type_error,c,"Example: /stats joe STAR");
  1729.       return 0;
  1730.     }
  1731.   
  1732.   if (strcasecmp(clienttag,CLIENTTAG_BNCHATBOT)==0)
  1733.     {
  1734.       message_send_text(c,message_type_error,c,"This game does not support win/loss records.");
  1735.       message_send_text(c,message_type_error,c,"You must supply a user name and a valid program ID.");
  1736.       message_send_text(c,message_type_error,c,"Example: /stats joe STAR");
  1737.       return 0;
  1738.     }
  1739.   else if (strcasecmp(clienttag,CLIENTTAG_DIABLORTL)==0 ||
  1740.    strcasecmp(clienttag,CLIENTTAG_DIABLOSHR)==0)
  1741.     {
  1742.       sprintf(msgtemp,"%.64s's record:",(tname = account_get_name(account)));
  1743.       account_unget_name(tname);
  1744.       message_send_text(c,message_type_info,c,msgtemp);
  1745.       
  1746.       sprintf(msgtemp,"level: %u",account_get_normal_level(account,clienttag));
  1747.       message_send_text(c,message_type_info,c,msgtemp);
  1748.       
  1749.       sprintf(msgtemp,"class: %.16s",bnclass_get_str(account_get_normal_class(account,clienttag)));
  1750.       
  1751.       message_send_text(c,message_type_info,c,msgtemp);
  1752.       
  1753.       sprintf(msgtemp,"stats: %u str  %u mag  %u dex  %u vit  %u gld",
  1754.       account_get_normal_strength(account,clienttag),
  1755.       account_get_normal_magic(account,clienttag),
  1756.       account_get_normal_dexterity(account,clienttag),
  1757.       account_get_normal_vitality(account,clienttag),
  1758.       account_get_normal_gold(account,clienttag));
  1759.       message_send_text(c,message_type_info,c,msgtemp);
  1760.       
  1761.       sprintf(msgtemp,"Diablo kills: %u",account_get_normal_diablo_kills(account,clienttag));
  1762.       message_send_text(c,message_type_info,c,msgtemp);
  1763.     }
  1764.   else if (strcasecmp(clienttag,CLIENTTAG_WARCIIBNE)==0)
  1765.     {
  1766.       sprintf(msgtemp,"%.64s's record:",(tname = account_get_name(account)));
  1767.       account_unget_name(tname);
  1768.       message_send_text(c,message_type_info,c,msgtemp);
  1769.       
  1770.       sprintf(msgtemp,"Normal games: %u-%u-%u",
  1771.       account_get_normal_wins(account,clienttag),
  1772.       account_get_normal_losses(account,clienttag),
  1773.       account_get_normal_disconnects(account,clienttag));
  1774.       message_send_text(c,message_type_info,c,msgtemp);
  1775.       
  1776.       if (account_get_ladder_rating(account,clienttag,ladder_id_normal)>0)
  1777. sprintf(msgtemp,"Ladder games: %u-%u-%u (rating %d)",
  1778. account_get_ladder_wins(account,clienttag,ladder_id_normal),
  1779. account_get_ladder_losses(account,clienttag,ladder_id_normal),
  1780. account_get_ladder_disconnects(account,clienttag,ladder_id_normal),
  1781. account_get_ladder_rating(account,clienttag,ladder_id_normal));
  1782.     else
  1783.       strcpy(msgtemp,"Ladder games: 0-0-0");
  1784.       message_send_text(c,message_type_info,c,msgtemp);
  1785.       
  1786.       if (account_get_ladder_rating(account,clienttag,ladder_id_ironman)>0)
  1787. sprintf(msgtemp,"IronMan games: %u-%u-%u (rating %d)",
  1788. account_get_ladder_wins(account,clienttag,ladder_id_ironman),
  1789. account_get_ladder_losses(account,clienttag,ladder_id_ironman),
  1790. account_get_ladder_disconnects(account,clienttag,ladder_id_ironman),
  1791. account_get_ladder_rating(account,clienttag,ladder_id_ironman));
  1792.       else
  1793. strcpy(msgtemp,"IronMan games: 0-0-0");
  1794.       message_send_text(c,message_type_info,c,msgtemp);
  1795.     }
  1796.   else if (strcasecmp(clienttag,CLIENTTAG_WARCRAFT3)==0 || strcasecmp(clienttag,CLIENTTAG_WAR3XP)==0) // 7-31-02 THEUNDYING - Display stats for war3
  1797.     {
  1798.       sprintf(msgtemp,"%.64s's Ladder Record's:",(tname=account_get_name(account)));
  1799.       account_unget_name(tname);
  1800.       message_send_text(c,message_type_info,c,msgtemp);
  1801.       sprintf(msgtemp,"Users Solo Level: %u, Experience: %u",
  1802.       account_get_sololevel(account,clienttag),
  1803.       account_get_soloxp(account,clienttag));
  1804.       message_send_text(c,message_type_info,c,msgtemp);
  1805.       sprintf(msgtemp,"SOLO Ladder Record: %u-%u-0",
  1806.       account_get_solowin(account,clienttag),
  1807.       account_get_sololoss(account,clienttag));
  1808.       message_send_text(c,message_type_info,c,msgtemp);
  1809.       // aaron -->
  1810.       sprintf(msgtemp,"SOLO Rank: %u",
  1811.       account_get_solorank(account,clienttag));
  1812.       message_send_text(c,message_type_info,c,msgtemp);
  1813.       // <---
  1814.       
  1815.       sprintf(msgtemp,"Users Team Level: %u, Experience: %u",
  1816.       account_get_teamlevel(account,clienttag),
  1817.       account_get_teamxp(account,clienttag));
  1818.       message_send_text(c,message_type_info,c,msgtemp);
  1819.       sprintf(msgtemp,"TEAM Ladder Record: %u-%u-0",
  1820.       account_get_teamwin(account,clienttag),
  1821.       account_get_teamloss(account,clienttag));
  1822.       message_send_text(c,message_type_info,c,msgtemp);
  1823.       // aaron -->
  1824.       sprintf(msgtemp,"TEAM Rank: %u",
  1825.       account_get_teamrank(account,clienttag));
  1826.       message_send_text(c,message_type_info,c,msgtemp);
  1827.       
  1828.       sprintf(msgtemp,"Users FFA Level: %u, Experience: %u",
  1829.       account_get_ffalevel(account,clienttag),
  1830.       account_get_ffaxp(account,clienttag));
  1831.       message_send_text(c,message_type_info,c,msgtemp);
  1832.       sprintf(msgtemp,"FFA Ladder Record: %u-%u-0",
  1833.       account_get_ffawin(account,clienttag),
  1834.       account_get_ffaloss(account,clienttag));
  1835.       message_send_text(c,message_type_info,c,msgtemp);
  1836.       sprintf(msgtemp,"FFA Rank: %u",
  1837.       account_get_ffarank(account,clienttag));
  1838.       message_send_text(c,message_type_info,c,msgtemp);
  1839.       if (account_get_atteamcount(account,clienttag))
  1840. {
  1841.   int teamcount;
  1842.   for (teamcount=1; teamcount<=account_get_atteamcount(account,clienttag); teamcount++)
  1843.     {
  1844.       sprintf(msgtemp,"Users AT Team No. %u",teamcount);
  1845.       message_send_text(c,message_type_info,c,msgtemp);
  1846.       sprintf(msgtemp,"Users AT TEAM Level: %u, Experience: %u",
  1847.       account_get_atteamlevel(account,teamcount,clienttag),
  1848.       account_get_atteamxp(account,teamcount,clienttag));
  1849.       message_send_text(c,message_type_info,c,msgtemp);
  1850.       sprintf(msgtemp,"AT TEAM Ladder Record: %u-%u-0",
  1851.       account_get_atteamwin(account,teamcount,clienttag),
  1852.       account_get_atteamloss(account,teamcount,clienttag));
  1853.       message_send_text(c,message_type_info,c,msgtemp);
  1854.       sprintf(msgtemp,"AT TEAM Rank: %u",
  1855.       account_get_atteamrank(account,teamcount,clienttag));
  1856.       message_send_text(c,message_type_info,c,msgtemp);
  1857.     }
  1858.   
  1859. }
  1860.       // <---
  1861.     }
  1862.   else
  1863.     {
  1864.       sprintf(msgtemp,"%.64s's record:",(tname = account_get_name(account)));
  1865.       account_unget_name(tname);
  1866.       message_send_text(c,message_type_info,c,msgtemp);
  1867.       
  1868.       sprintf(msgtemp,"Normal games: %u-%u-%u",
  1869.       account_get_normal_wins(account,clienttag),
  1870.       account_get_normal_losses(account,clienttag),
  1871.       account_get_normal_disconnects(account,clienttag));
  1872.       message_send_text(c,message_type_info,c,msgtemp);
  1873.       
  1874.       if (account_get_ladder_rating(account,clienttag,ladder_id_normal)>0)
  1875. sprintf(msgtemp,"Ladder games: %u-%u-%u (rating %d)",
  1876. account_get_ladder_wins(account,clienttag,ladder_id_normal),
  1877. account_get_ladder_losses(account,clienttag,ladder_id_normal),
  1878. account_get_ladder_disconnects(account,clienttag,ladder_id_normal),
  1879. account_get_ladder_rating(account,clienttag,ladder_id_normal));
  1880.       else
  1881. strcpy(msgtemp,"Ladder games: 0-0-0");
  1882.       message_send_text(c,message_type_info,c,msgtemp);
  1883.     }
  1884.   
  1885.   return 0;
  1886. }
  1887. static int _handle_time_command(t_connection * c, char const *text)
  1888. {
  1889.   t_bnettime  btsystem;
  1890.   t_bnettime  btlocal;
  1891.   time_t      now;
  1892.   struct tm * tmnow;
  1893.   
  1894.   btsystem = bnettime();
  1895.   
  1896.   /* Battle.net time: Wed Jun 23 15:15:29 */
  1897.   btlocal = bnettime_add_tzbias(btsystem,local_tzbias());
  1898.   now = bnettime_to_time(btlocal);
  1899.   if (!(tmnow = gmtime(&now)))
  1900.     strcpy(msgtemp,"PvPGN Server Time: ?");
  1901.   else
  1902.     strftime(msgtemp,sizeof(msgtemp),"PvPGN Server Time: %a %b %d %H:%M:%S",tmnow);
  1903.   message_send_text(c,message_type_info,c,msgtemp);
  1904.   if (conn_get_class(c)==conn_class_bnet)
  1905.     {
  1906.       btlocal = bnettime_add_tzbias(btsystem,conn_get_tzbias(c));
  1907.       now = bnettime_to_time(btlocal);
  1908.       if (!(tmnow = gmtime(&now)))
  1909. strcpy(msgtemp,"Your local time: ?");
  1910.       else
  1911. strftime(msgtemp,sizeof(msgtemp),"Your local time: %a %b %d %H:%M:%S",tmnow);
  1912.       message_send_text(c,message_type_info,c,msgtemp);
  1913.     }
  1914.   
  1915.   return 0;
  1916. }
  1917. static int _handle_channel_command(t_connection * c, char const *text)
  1918.  {
  1919.    t_channel * channel;
  1920.    text = skip_command(text);
  1921.    
  1922.    if (text[0]=='')
  1923.      {
  1924.        message_send_text(c,message_type_info,c,"usage /channel <channel>");
  1925.        return 0;
  1926.      }
  1927.    
  1928.    if(strcasecmp(text,"Arranged Teams")==0)
  1929.      {
  1930. //       if(account_get_auth_admin(conn_get_account(c))>0)
  1931. //  {
  1932. //    message_send_text(c,message_type_error,c,"Please do not talk in channel Arranged Teams");
  1933. //    message_send_text(c,message_type_error,c,"This channel is dedicated for the preparation of");
  1934. //    message_send_text(c,message_type_error,c,"Arranged Team Games.");
  1935. //  }
  1936. //       else
  1937. //  {
  1938.    message_send_text(c,message_type_error,c,"Channel Arranged Teams is a RESTRICTED Channel!");
  1939.    return 0;
  1940. //  }
  1941.      }
  1942.    if ((channel = conn_get_channel(c)) && (strcasecmp(channel_get_name(channel),text)==0))
  1943.      return 0; // we don't have to do anything, we are allready in this channel
  1944.    
  1945.    if (conn_set_channel(c,text)<0)
  1946.      conn_set_channel(c,CHANNEL_NAME_BANNED); /* should not fail */
  1947.    if (strcmp(conn_get_clienttag(c), CLIENTTAG_WARCRAFT3) == 0 || strcmp(conn_get_clienttag(c), CLIENTTAG_WAR3XP) == 0) 
  1948.      conn_update_w3_playerinfo(c);
  1949.    command_set_flags(c);
  1950.    
  1951.    return 0;
  1952.  }
  1953. static int _handle_rejoin_command(t_connection * c, char const *text)
  1954. {
  1955.   if (channel_rejoin(c)!=0)
  1956.       message_send_text(c,message_type_error,c,"You are not in a channel.");
  1957.   if (strcmp(conn_get_clienttag(c), CLIENTTAG_WARCRAFT3) == 0 || strcmp(conn_get_clienttag(c), CLIENTTAG_WAR3XP) == 0) 
  1958.     conn_update_w3_playerinfo(c);
  1959.   command_set_flags(c);
  1960.   
  1961.   return 0;
  1962. }
  1963. static int _handle_away_command(t_connection * c, char const *text)
  1964. {
  1965.   text = skip_command(text);
  1966.   
  1967.   if (text[0]=='') /* toggle away mode */
  1968.     {
  1969.       if (!conn_get_awaystr(c))
  1970.       {
  1971. message_send_text(c,message_type_info,c,"You are now marked as being away.");
  1972. conn_set_awaystr(c,"Currently not available");
  1973.       }
  1974.       else
  1975.       {
  1976.         message_send_text(c,message_type_info,c,"You are no longer marked as away.");
  1977.         conn_set_awaystr(c,NULL);
  1978.       }
  1979.     }
  1980.   else
  1981.     {
  1982.       message_send_text(c,message_type_info,c,"You are now marked as being away.");
  1983.       conn_set_awaystr(c,text);
  1984.     }
  1985.   
  1986.   return 0;
  1987. }
  1988. static int _handle_dnd_command(t_connection * c, char const *text)
  1989. {
  1990.   
  1991.   text = skip_command(text);
  1992.   
  1993.   if (text[0]=='') /* toggle dnd mode */
  1994.     {
  1995.       if (!conn_get_dndstr(c))
  1996.       {
  1997. message_send_text(c,message_type_info,c,"Do Not Diturb mode engaged.");
  1998. conn_set_dndstr(c,"Not available");
  1999.       }
  2000.       else
  2001.       {
  2002.         message_send_text(c,message_type_info,c,"Do Not Disturb mode cancelled.");
  2003.         conn_set_dndstr(c,NULL);
  2004.       }
  2005.     }
  2006.   else
  2007.     {
  2008.       message_send_text(c,message_type_info,c,"Do Not Disturb mode engaged.");
  2009.       conn_set_dndstr(c,text);
  2010.     }
  2011.   
  2012.   return 0;
  2013. }
  2014. static int _handle_squelch_command(t_connection * c, char const *text)
  2015. {
  2016.   t_account *  account;
  2017.   text = skip_command(text);
  2018.   
  2019.   /* D2 puts * before username - FIXME: the client don't see it until
  2020.      the player rejoins the channel */
  2021.   if (text[0]=='*')
  2022.     text++;
  2023.  
  2024.   if (text[0]=='')
  2025.     {
  2026.       message_send_text(c,message_type_info,c,"usage: /squelch <username>");
  2027.       return 0;
  2028.     }
  2029.   
  2030.   if (!(account = accountlist_find_account(text)))
  2031.     {
  2032.       message_send_text(c,message_type_error,c,"No such user.");
  2033.       return 0;
  2034.     }
  2035.   
  2036.   if (conn_get_account(c)==account)
  2037.     {
  2038.       message_send_text(c,message_type_error,c,"You can't squelch yourself.");
  2039.       return 0;
  2040.     }
  2041.   
  2042.   if (conn_add_ignore(c,account)<0)
  2043.     message_send_text(c,message_type_error,c,"Could not squelch user.");
  2044.   else