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

Annotation of /pvpgn-1.7.4/src/bnetd/command.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations)
Sat Jun 24 09:19:06 2006 UTC (19 years, 8 months ago) by sysadm
Branch: MAIN
Changes since 1.1: +137 -0 lines
Content type: text/x-csrc
Auto check void game, fix bug

1 sysadm 1.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     * Copyright (C) 2003,2004 Aaron
10     * Copyright (C) 2004 Donny Redmond (dredmond@linuxmail.org)
11     *
12     * This program is free software; you can redistribute it and/or
13     * modify it under the terms of the GNU General Public License
14     * as published by the Free Software Foundation; either version 2
15     * of the License, or (at your option) any later version.
16     *
17     * This program is distributed in the hope that it will be useful,
18     * but WITHOUT ANY WARRANTY; without even the implied warranty of
19     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20     * GNU General Public License for more details.
21     *
22     * You should have received a copy of the GNU General Public License
23     * along with this program; if not, write to the Free Software
24     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25     */
26     #include "common/setup_before.h"
27     #include <stdio.h>
28     #ifdef HAVE_STDDEF_H
29     # include <stddef.h>
30     #else
31     # ifndef NULL
32     # define NULL ((void *)0)
33     # endif
34     #endif
35     #ifdef STDC_HEADERS
36     # include <stdlib.h>
37     #else
38     # ifdef HAVE_MALLOC_H
39     # include <malloc.h>
40     # endif
41     #endif
42     #include "compat/strtoul.h"
43     #ifdef HAVE_STRING_H
44     # include <string.h>
45     #else
46     # ifdef HAVE_STRINGS_H
47     # include <strings.h>
48     # endif
49     #endif
50     #include "compat/strdup.h"
51     #include "compat/strcasecmp.h"
52     #include <ctype.h>
53     #include <errno.h>
54     #include "compat/strerror.h"
55     #ifdef TIME_WITH_SYS_TIME
56     # include <sys/time.h>
57     # include <time.h>
58     #else
59     # ifdef HAVE_SYS_TIME_H
60     # include <sys/time.h>
61     # else
62     # include <time.h>
63     # endif
64     #endif
65     #ifdef HAVE_SYS_TYPES
66     # include <sys/types.h>
67     #endif
68     #include "compat/strftime.h"
69     #include "message.h"
70     #include "common/tag.h"
71     #include "connection.h"
72     #include "channel.h"
73     #include "game.h"
74     #include "common/util.h"
75     #include "common/version.h"
76     #include "team.h"
77     #include "account.h"
78     #include "account_wrap.h"
79     #include "server.h"
80     #include "prefs.h"
81     #include "common/eventlog.h"
82     #include "ladder.h"
83     #include "timer.h"
84     #include "common/bnettime.h"
85     #include "common/addr.h"
86     #include "common/packet.h"
87     #include "helpfile.h"
88     #include "mail.h"
89     #include "common/bnethash.h"
90     #include "runprog.h"
91     #include "common/list.h"
92     #include "common/proginfo.h"
93     #include "alias_command.h"
94     #include "realm.h"
95     #include "ipban.h"
96     #include "command_groups.h"
97     #include "common/queue.h"
98     #include "common/bn_type.h"
99     #include "common/xalloc.h"
100     #include "command.h"
101     #include "news.h"
102     #include "common/trans.h"
103     #include "common/lstr.h"
104     // aaron
105     #include "topic.h"
106     #include "friends.h"
107     #include "clan.h"
108     #include "common/setup_after.h"
109    
110 sysadm 1.2 #ifndef CHAR_STATUS_DUMP_FILE
111     # define CHAR_STATUS_DUMP_FILE "/tmp/d2charstatus.dat"
112     #endif
113 sysadm 1.1
114     static char const * bnclass_get_str(unsigned int class);
115     static void do_whisper(t_connection * user_c, char const * dest, char const * text);
116     static void do_whois(t_connection * c, char const * dest);
117     static void user_timer_cb(t_connection * c, time_t now, t_timer_data str);
118    
119     char msgtemp[MAX_MESSAGE_LEN];
120     char msgtemp2[MAX_MESSAGE_LEN];
121    
122     static char const * bnclass_get_str(unsigned int class)
123     {
124     switch (class)
125     {
126     case PLAYERINFO_DRTL_CLASS_WARRIOR:
127     return "warrior";
128     case PLAYERINFO_DRTL_CLASS_ROGUE:
129     return "rogue";
130     case PLAYERINFO_DRTL_CLASS_SORCERER:
131     return "sorcerer";
132     default:
133     return "unknown";
134     }
135     }
136    
137    
138     static void do_whisper(t_connection * user_c, char const * dest, char const * text)
139     {
140     t_connection * dest_c;
141     char const * tname;
142    
143     if (!(dest_c = connlist_find_connection_by_name(dest,conn_get_realm(user_c))))
144     {
145     message_send_text(user_c,message_type_error,user_c,"That user is not logged on.");
146     return;
147     }
148    
149     if (conn_get_dndstr(dest_c))
150     {
151     sprintf(msgtemp,"%.64s is unavailable (%.128s)",conn_get_username(dest_c),conn_get_dndstr(dest_c));
152     message_send_text(user_c,message_type_info,user_c,msgtemp);
153     return;
154     }
155    
156     message_send_text(user_c,message_type_whisperack,dest_c,text);
157    
158     if (conn_get_awaystr(dest_c))
159     {
160     sprintf(msgtemp,"%.64s is away (%.128s)",conn_get_username(dest_c),conn_get_awaystr(dest_c));
161     message_send_text(user_c,message_type_info,user_c,msgtemp);
162     }
163    
164     message_send_text(dest_c,message_type_whisper,user_c,text);
165    
166     if ((tname = conn_get_username(user_c)))
167     {
168     char username[1+USER_NAME_MAX]; /* '*' + username (including NUL) */
169    
170     if (strlen(tname)<USER_NAME_MAX)
171     {
172     sprintf(username,"*%s",tname);
173     conn_set_lastsender(dest_c,username);
174     }
175     }
176     }
177    
178    
179     static void do_whois(t_connection * c, char const * dest)
180     {
181     t_connection * dest_c;
182     char namepart[136]; /* 64 + " (" + 64 + ")" + NUL */
183     char const * verb;
184     t_game const * game;
185     t_channel const * channel;
186    
187     if ((!(dest_c = connlist_find_connection_by_accountname(dest))) &&
188     (!(dest_c = connlist_find_connection_by_name(dest,conn_get_realm(c)))))
189     {
190     t_account * dest_a;
191     t_bnettime btlogin;
192     time_t ulogin;
193     struct tm * tmlogin;
194    
195     if (!(dest_a = accountlist_find_account(dest))) {
196     message_send_text(c,message_type_error,c,"Unknown user.");
197     return;
198     }
199    
200     if (conn_get_class(c) == conn_class_bnet) {
201     btlogin = time_to_bnettime((time_t)account_get_ll_time(dest_a),0);
202     btlogin = bnettime_add_tzbias(btlogin, conn_get_tzbias(c));
203     ulogin = bnettime_to_time(btlogin);
204     if (!(tmlogin = gmtime(&ulogin)))
205     strcpy(msgtemp, "User was last seen on ?");
206     else
207     strftime(msgtemp, sizeof(msgtemp), "User was last seen on : %a %b %d %H:%M:%S",tmlogin);
208     } else strcpy(msgtemp, "User is offline");
209     message_send_text(c, message_type_info, c, msgtemp);
210     return;
211     }
212    
213     if (c==dest_c)
214     {
215     strcpy(namepart,"You");
216     verb = "are";
217     }
218     else
219     {
220     char const * tname;
221    
222     sprintf(namepart,"%.64s",(tname = conn_get_chatcharname(dest_c,c)));
223     conn_unget_chatcharname(dest_c,tname);
224     verb = "is";
225     }
226    
227     if ((game = conn_get_game(dest_c)))
228     {
229     sprintf(msgtemp,"%s %s using %s and %s currently in %s game \"%.64s\".",
230     namepart,
231     verb,
232     clienttag_get_title(conn_get_clienttag(dest_c)),
233     verb,
234     game_get_flag(game) == game_flag_private ? "private" : "",
235     game_get_name(game));
236     }
237     else if ((channel = conn_get_channel(dest_c)))
238     {
239     sprintf(msgtemp,"%s %s using %s and %s currently in channel \"%.64s\".",
240     namepart,
241     verb,
242     clienttag_get_title(conn_get_clienttag(dest_c)),
243     verb,
244     channel_get_name(channel));
245     }
246     else
247     sprintf(msgtemp,"%s %s using %s.",
248     namepart,
249     verb,
250     clienttag_get_title(conn_get_clienttag(dest_c)));
251     message_send_text(c,message_type_info,c,msgtemp);
252    
253     if (conn_get_dndstr(dest_c))
254     {
255     sprintf(msgtemp,"%s %s refusing messages (%.128s)",
256     namepart,
257     verb,
258     conn_get_dndstr(dest_c));
259     message_send_text(c,message_type_info,c,msgtemp);
260     }
261     else
262     if (conn_get_awaystr(dest_c))
263     {
264     sprintf(msgtemp,"%s away (%.128s)",
265     namepart,
266     conn_get_awaystr(dest_c));
267     message_send_text(c,message_type_info,c,msgtemp);
268     }
269     }
270    
271    
272     static void user_timer_cb(t_connection * c, time_t now, t_timer_data str)
273     {
274     if (!c)
275     {
276     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
277     return;
278     }
279     if (!str.p)
280     {
281     eventlog(eventlog_level_error,__FUNCTION__,"got NULL str");
282     return;
283     }
284    
285     if (now!=(time_t)0) /* zero means user logged out before expiration */
286     message_send_text(c,message_type_info,c,str.p);
287     xfree(str.p);
288     }
289    
290     typedef int (* t_command)(t_connection * c, char const * text);
291    
292     typedef struct {
293     const char * command_string;
294     t_command command_handler;
295     } t_command_table_row;
296    
297     static int command_set_flags(t_connection * c); // [Omega]
298     // command handler prototypes
299     static int _handle_clan_command(t_connection * c, char const * text);
300     static int _handle_admin_command(t_connection * c, char const * text);
301     static int _handle_aop_command(t_connection * c, char const * text);
302     static int _handle_op_command(t_connection * c, char const * text);
303     static int _handle_tmpop_command(t_connection * c, char const * text);
304     static int _handle_deop_command(t_connection * c, char const * text);
305     static int _handle_voice_command(t_connection * c, char const * text);
306     static int _handle_devoice_command(t_connection * c, char const * text);
307     static int _handle_vop_command(t_connection * c, char const * text);
308     static int _handle_friends_command(t_connection * c, char const * text);
309     static int _handle_me_command(t_connection * c, char const * text);
310     static int _handle_whisper_command(t_connection * c, char const * text);
311     static int _handle_status_command(t_connection * c, char const * text);
312     static int _handle_who_command(t_connection * c, char const * text);
313     static int _handle_whois_command(t_connection * c, char const * text);
314     static int _handle_whoami_command(t_connection * c, char const * text);
315     static int _handle_announce_command(t_connection * c, char const * text);
316     static int _handle_beep_command(t_connection * c, char const * text);
317     static int _handle_nobeep_command(t_connection * c, char const * text);
318     static int _handle_version_command(t_connection * c, char const * text);
319     static int _handle_copyright_command(t_connection * c, char const * text);
320     static int _handle_uptime_command(t_connection * c, char const * text);
321     static int _handle_stats_command(t_connection * c, char const * text);
322     static int _handle_time_command(t_connection * c, char const * text);
323     static int _handle_channel_command(t_connection * c, char const * text);
324     static int _handle_rejoin_command(t_connection * c, char const * text);
325     static int _handle_away_command(t_connection * c, char const * text);
326     static int _handle_dnd_command(t_connection * c, char const * text);
327     static int _handle_squelch_command(t_connection * c, char const * text);
328     static int _handle_unsquelch_command(t_connection * c, char const * text);
329     //static int _handle_designate_command(t_connection * c, char const * text); Obsolete function [Omega]
330     //static int _handle_resign_command(t_connection * c, char const * text); Obsolete function [Omega]
331     static int _handle_kick_command(t_connection * c, char const * text);
332     static int _handle_ban_command(t_connection * c, char const * text);
333     static int _handle_unban_command(t_connection * c, char const * text);
334     static int _handle_reply_command(t_connection * c, char const * text);
335     static int _handle_realmann_command(t_connection * c, char const * text);
336     static int _handle_watch_command(t_connection * c, char const * text);
337     static int _handle_unwatch_command(t_connection * c, char const * text);
338     static int _handle_watchall_command(t_connection * c, char const * text);
339     static int _handle_unwatchall_command(t_connection * c, char const * text);
340     static int _handle_lusers_command(t_connection * c, char const * text);
341     static int _handle_news_command(t_connection * c, char const * text);
342     static int _handle_games_command(t_connection * c, char const * text);
343 sysadm 1.2 static int _handle_games_ext_command(t_connection * c, char const * text);
344 sysadm 1.1 static int _handle_channels_command(t_connection * c, char const * text);
345     static int _handle_addacct_command(t_connection * c, char const * text);
346     static int _handle_chpass_command(t_connection * c, char const * text);
347     static int _handle_connections_command(t_connection * c, char const * text);
348     static int _handle_finger_command(t_connection * c, char const * text);
349     static int _handle_operator_command(t_connection * c, char const * text);
350     static int _handle_admins_command(t_connection * c, char const * text);
351     static int _handle_quit_command(t_connection * c, char const * text);
352     static int _handle_kill_command(t_connection * c, char const * text);
353     static int _handle_killsession_command(t_connection * c, char const * text);
354     static int _handle_gameinfo_command(t_connection * c, char const * text);
355     static int _handle_ladderactivate_command(t_connection * c, char const * text);
356     static int _handle_rehash_command(t_connection * c, char const * text);
357     //static int _handle_rank_all_accounts_command(t_connection * c, char const * text);
358     static int _handle_shutdown_command(t_connection * c, char const * text);
359     static int _handle_ladderinfo_command(t_connection * c, char const * text);
360     static int _handle_timer_command(t_connection * c, char const * text);
361     static int _handle_serverban_command(t_connection * c, char const * text);
362     static int _handle_netinfo_command(t_connection * c, char const * text);
363     static int _handle_quota_command(t_connection * c, char const * text);
364     static int _handle_lockacct_command(t_connection * c, char const * text);
365     static int _handle_unlockacct_command(t_connection * c, char const * text);
366     static int _handle_flag_command(t_connection * c, char const * text);
367     static int _handle_tag_command(t_connection * c, char const * text);
368     //static int _handle_ipban_command(t_connection * c, char const * text); Redirected to handle_ipban_command() in ipban.c [Omega]
369     static int _handle_set_command(t_connection * c, char const * text);
370     static int _handle_motd_command(t_connection * c, char const * text);
371     static int _handle_ping_command(t_connection * c, char const * text);
372     static int _handle_commandgroups_command(t_connection * c, char const * text);
373     static int _handle_topic_command(t_connection * c, char const * text);
374     static int _handle_moderate_command(t_connection * c, char const * text);
375     static int _handle_clearstats_command(t_connection * c, char const * text);
376 sysadm 1.2 static int _handle_char_status_command(t_connection * c, char const *text);
377 sysadm 1.1
378     static const t_command_table_row standard_command_table[] =
379     {
380     { "/clan" , _handle_clan_command },
381     { "/c" , _handle_clan_command },
382     { "/admin" , _handle_admin_command },
383     { "/f" , _handle_friends_command },
384     { "/friends" , _handle_friends_command },
385     { "/me" , _handle_me_command },
386     { "/msg" , _handle_whisper_command },
387     { "/whisper" , _handle_whisper_command },
388     { "/w" , _handle_whisper_command },
389     { "/m" , _handle_whisper_command },
390     { "/status" , _handle_status_command },
391     { "/users" , _handle_status_command },
392     { "/who" , _handle_who_command },
393     { "/whois" , _handle_whois_command },
394     { "/whereis" , _handle_whois_command },
395     { "/where" , _handle_whois_command },
396     { "/whoami" , _handle_whoami_command },
397     { "/announce" , _handle_announce_command },
398     { "/beep" , _handle_beep_command },
399     { "/nobeep" , _handle_nobeep_command },
400     { "/version" , _handle_version_command },
401     { "/copyright" , _handle_copyright_command },
402     { "/warrenty" , _handle_copyright_command },
403     { "/license" , _handle_copyright_command },
404     { "/uptime" , _handle_uptime_command },
405     { "/stats" , _handle_stats_command },
406     { "/astat" , _handle_stats_command },
407     { "/time" , _handle_time_command },
408     { "/channel" , _handle_channel_command },
409     { "/join" , _handle_channel_command },
410     { "/rejoin" , _handle_rejoin_command },
411     { "/away" , _handle_away_command },
412     { "/dnd" , _handle_dnd_command },
413     { "/ignore" , _handle_squelch_command },
414     { "/squelch" , _handle_squelch_command },
415     { "/unignore" , _handle_unsquelch_command },
416     { "/unsquelch" , _handle_unsquelch_command },
417     // { "/designate" , _handle_designate_command }, Obsotele command [Omega]
418     // { "/resign" , _handle_resign_command }, Obsolete command [Omega]
419     { "/kick" , _handle_kick_command },
420     { "/ban" , _handle_ban_command },
421     { "/unban" , _handle_unban_command },
422 sysadm 1.2 { "/charstatus" , _handle_char_status_command },
423 sysadm 1.1
424     { NULL , NULL }
425    
426     };
427    
428     static const t_command_table_row extended_command_table[] =
429     {
430     { "/ann" , _handle_announce_command },
431     { "/r" , _handle_reply_command },
432     { "/reply" , _handle_reply_command },
433     { "/realmann" , _handle_realmann_command },
434     { "/watch" , _handle_watch_command },
435     { "/unwatch" , _handle_unwatch_command },
436     { "/watchall" , _handle_watchall_command },
437     { "/unwatchall" , _handle_unwatchall_command },
438     { "/lusers" , _handle_lusers_command },
439     { "/news" , _handle_news_command },
440     { "/games" , _handle_games_command },
441 sysadm 1.2 { "/games_ext" , _handle_games_ext_command },
442 sysadm 1.1 { "/channels" , _handle_channels_command },
443     { "/chs" , _handle_channels_command },
444     { "/addacct" , _handle_addacct_command },
445     { "/chpass" , _handle_chpass_command },
446     { "/connections" , _handle_connections_command },
447     { "/con" , _handle_connections_command },
448     { "/finger" , _handle_finger_command },
449     { "/operator" , _handle_operator_command },
450     { "/aop" , _handle_aop_command },
451     { "/op" , _handle_op_command },
452     { "/tmpop" , _handle_tmpop_command },
453     { "/deop" , _handle_deop_command },
454     { "/voice" , _handle_voice_command },
455     { "/devoice" , _handle_devoice_command },
456     { "/vop" , _handle_vop_command },
457     { "/admins" , _handle_admins_command },
458     { "/logout" , _handle_quit_command },
459     { "/quit" , _handle_quit_command },
460     { "/exit" , _handle_quit_command },
461     { "/kill" , _handle_kill_command },
462     { "/killsession" , _handle_killsession_command },
463     { "/gameinfo" , _handle_gameinfo_command },
464     { "/ladderactivate" , _handle_ladderactivate_command },
465     { "/rehash" , _handle_rehash_command },
466     // { "/rank_all_accounts" , _handle_rank_all_accounts_command },
467     { "/shutdown" , _handle_shutdown_command },
468     { "/ladderinfo" , _handle_ladderinfo_command },
469     { "/timer" , _handle_timer_command },
470     { "/serverban" , _handle_serverban_command },
471     { "/netinfo" , _handle_netinfo_command },
472     { "/quota" , _handle_quota_command },
473     { "/lockacct" , _handle_lockacct_command },
474     { "/unlockacct" , _handle_unlockacct_command },
475     { "/flag" , _handle_flag_command },
476     { "/tag" , _handle_tag_command },
477     { "/help" , handle_help_command },
478     { "/mail" , handle_mail_command },
479     { "/ipban" , handle_ipban_command }, // in ipban.c
480     { "/set" , _handle_set_command },
481     { "/motd" , _handle_motd_command },
482     { "/latency" , _handle_ping_command },
483     { "/ping" , _handle_ping_command },
484     { "/p" , _handle_ping_command },
485     { "/commandgroups" , _handle_commandgroups_command },
486     { "/cg" , _handle_commandgroups_command },
487     { "/topic" , _handle_topic_command },
488     { "/moderate" , _handle_moderate_command },
489     { "/clearstats" , _handle_clearstats_command },
490    
491     { NULL , NULL }
492    
493     };
494    
495     char const * skip_command(char const * org_text)
496     {
497     unsigned int i;
498     char * text = (char *)org_text;
499     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
500     if (text[i]!='\0') text[i++]='\0'; /* \0-terminate command */
501     for (; text[i]==' '; i++);
502     return &text[i];
503     }
504    
505     extern int handle_command(t_connection * c, char const * text)
506     {
507     t_command_table_row const *p;
508    
509     for (p = standard_command_table; p->command_string != NULL; p++)
510     {
511     if (strstart(text, p->command_string)==0)
512     {
513     if (!(command_get_group(p->command_string)))
514     {
515     message_send_text(c,message_type_error,c,"This command has been deactivated");
516     return 0;
517     }
518     if (!((command_get_group(p->command_string) & account_get_command_groups(conn_get_account(c)))))
519     {
520     message_send_text(c,message_type_error,c,"This command is reserved for admins.");
521     return 0;
522     }
523     if (p->command_handler != NULL) return ((p->command_handler)(c,text));
524     }
525     }
526    
527    
528     if (prefs_get_extra_commands()==0)
529     {
530     message_send_text(c,message_type_error,c,"Unknown command.");
531     eventlog(eventlog_level_debug,__FUNCTION__,"got unknown standard command \"%s\"",text);
532     return 0;
533     }
534    
535     for (p = extended_command_table; p->command_string != NULL; p++)
536     {
537     if (strstart(text, p->command_string)==0)
538     {
539     if (!(command_get_group(p->command_string)))
540     {
541     message_send_text(c,message_type_error,c,"This command has been deactivated");
542     return 0;
543     }
544     if (!((command_get_group(p->command_string) & account_get_command_groups(conn_get_account(c)))))
545     {
546     message_send_text(c,message_type_error,c,"This command is reserved for admins.");
547     return 0;
548     }
549     if (p->command_handler != NULL) return ((p->command_handler)(c,text));
550     }
551     }
552    
553     if (strlen(text)>=2 && strncmp(text,"//",2)==0)
554     {
555     handle_alias_command(c,text);
556     return 0;
557     }
558    
559     message_send_text(c,message_type_error,c,"Unknown command.");
560     eventlog(eventlog_level_debug,__FUNCTION__,"got unknown command \"%s\"",text);
561     return 0;
562     }
563    
564     // +++++++++++++++++++++++++++++++++ command implementations +++++++++++++++++++++++++++++++++++++++
565    
566     static int _handle_clan_command(t_connection * c, char const * text)
567     {
568     t_account * acc;
569     t_clanmember * member;
570     t_clan * clan;
571    
572     text = skip_command(text);
573    
574     if ( text[0] == '\0' )
575     {
576     message_send_text(c,message_type_info,c,"usage:");
577     message_send_text(c,message_type_info,c,"/clan public /clan pub");
578     message_send_text(c,message_type_info,c,"Opens the clan channel up to the public so that anyone may enter.");
579     message_send_text(c,message_type_info,c,"/clan private /clan priv");
580     message_send_text(c,message_type_info,c,"Closes the clan channel such that only members of the clan may enter.");
581     message_send_text(c,message_type_info,c,"/clan motd MESSAGE");
582     message_send_text(c,message_type_info,c,"Update the clan message of the day to MESSAGE.");
583     return 0;
584     }
585    
586     if((acc = conn_get_account(c)) && (member = account_get_clanmember(acc)) && (clan = clanmember_get_clan(member)))
587     {
588     if(clanmember_get_status(member)>=CLAN_SHAMAN)
589     {
590     if (strstart(text,"public")==0 || strstart(text,"pub")==0) {
591     if(clan_get_channel_type(clan)!=0)
592     {
593     clan_set_channel_type(clan,0);
594     message_send_text(c,message_type_info,c,"Clan channel is opened up!");
595     }
596     else
597     message_send_text(c,message_type_error,c,"Clan channel has already been opened up!");
598     }
599     else
600     if (strstart(text,"private")==0 || strstart(text,"priv")==0) {
601     if(clan_get_channel_type(clan)!=1)
602     {
603     clan_set_channel_type(clan,1);
604     message_send_text(c,message_type_info,c,"Clan channel is closed!");
605     }
606     else
607     message_send_text(c,message_type_error,c,"Clan channel has already been closed!");
608     }
609     else
610     if (strstart(text,"motd")==0) {
611     const char * msg=skip_command(text);
612     if(msg[0]=='\0')
613     {
614     message_send_text(c,message_type_info,c,"usage:");
615     message_send_text(c,message_type_info,c,"/clan motd MESSAGE");
616     message_send_text(c,message_type_info,c,"Update the clan message of the day to MESSAGE.");
617     }
618     else
619     {
620     clan_set_motd(clan, msg);
621     message_send_text(c,message_type_info,c,"Clan message of day is updated!");
622     }
623     }
624     }
625     else
626     message_send_text(c,message_type_error,c,"You are not the chieftain or shaman of clan!");
627     }
628     else
629     message_send_text(c,message_type_error,c,"You are not in a clan!");
630    
631     return 0;
632     }
633    
634     static int command_set_flags(t_connection * c)
635     {
636     return channel_set_userflags(c);
637     }
638    
639     static int _handle_admin_command(t_connection * c, char const * text)
640     {
641     char const * username;
642     char command;
643     t_account * acc;
644     t_connection * dst_c;
645     int changed=0;
646    
647     text = skip_command(text);
648    
649     if ((text[0]=='\0') || ((text[0] != '+') && (text[0] != '-'))) {
650     message_send_text(c,message_type_info,c,"usage: /admin +username to promote user to Server Admin.");
651     message_send_text(c,message_type_info,c," /admin -username to demote user from Aerver Admin.");
652     return -1;
653     }
654    
655     command = text[0];
656     username = &text[1];
657    
658     if(!*username) {
659     message_send_text(c,message_type_info,c,"You need to supply a username.");
660     return -1;
661     }
662    
663     if(!(acc = accountlist_find_account(username))) {
664     sprintf(msgtemp, "There's no account with username %.64s.", username);
665     message_send_text(c, message_type_info, c, msgtemp);
666     return -1;
667     }
668     dst_c = account_get_conn(acc);
669    
670     if (command == '+') {
671     if (account_get_auth_admin(acc,NULL) == 1) {
672     sprintf(msgtemp,"%s is already a Server Admin",username);
673     } else {
674     account_set_auth_admin(acc,NULL,1);
675     sprintf(msgtemp,"%s has been promoted to a Server Admin",username);
676     sprintf(msgtemp2,"%s has promoted you to a Server Admin",conn_get_loggeduser(c));
677     changed = 1;
678     }
679     } else {
680     if (account_get_auth_admin(acc,NULL) != 1)
681     sprintf(msgtemp,"%s is no Server Admin, so you can't demote him",username);
682     else {
683     account_set_auth_admin(acc,NULL,0);
684     sprintf(msgtemp,"%s has been demoted from a Server Admin",username);
685     sprintf(msgtemp2,"%s has demoted you from a Server Admin",conn_get_loggeduser(c));
686     changed = 1;
687     }
688     }
689    
690     if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2);
691     message_send_text(c, message_type_info, c, msgtemp);
692     command_set_flags(dst_c);
693     return 0;
694     }
695    
696     static int _handle_operator_command(t_connection * c, char const * text)
697     {
698     char const * username;
699     char command;
700     t_account * acc;
701     t_connection * dst_c;
702     int changed = 0;
703    
704     text = skip_command(text);
705    
706     if ((text[0]=='\0') || ((text[0] != '+') && (text[0] != '-'))) {
707     message_send_text(c,message_type_info,c,"usage: /operator +username to promote user to Server Operator.");
708     message_send_text(c,message_type_info,c," /operator -username to demote user from Server Operator.");
709     return -1;
710     }
711    
712     command = text[0];
713     username = &text[1];
714    
715     if(!*username) {
716     message_send_text(c,message_type_info,c,"You need to supply a username.");
717     return -1;
718     }
719    
720     if(!(acc = accountlist_find_account(username))) {
721     sprintf(msgtemp, "There's no account with username %.64s.", username);
722     message_send_text(c, message_type_info, c, msgtemp);
723     return -1;
724     }
725     dst_c = account_get_conn(acc);
726    
727     if (command == '+') {
728     if (account_get_auth_operator(acc,NULL) == 1)
729     sprintf(msgtemp,"%s is already a Server Operator",username);
730     else {
731     account_set_auth_operator(acc,NULL,1);
732     sprintf(msgtemp,"%s has been promoted to a Server Operator",username);
733     sprintf(msgtemp2,"%s has promoted you to a Server Operator",conn_get_loggeduser(c));
734     changed = 1;
735     }
736     } else {
737     if (account_get_auth_operator(acc,NULL) != 1)
738     sprintf(msgtemp,"%s is no Server Operator, so you can't demote him",username);
739     else {
740     account_set_auth_operator(acc,NULL,0);
741     sprintf(msgtemp,"%s has been demoted from a Server Operator",username);
742     sprintf(msgtemp2,"%s has promoted you to a Server Operator",conn_get_loggeduser(c));
743     changed = 1;
744     }
745     }
746    
747     if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2);
748     message_send_text(c, message_type_info, c, msgtemp);
749     command_set_flags(dst_c);
750     return 0;
751     }
752    
753     static int _handle_aop_command(t_connection * c, char const * text)
754     {
755     char const * username;
756     char const * channel;
757     t_account * acc;
758     t_connection * dst_c;
759     int changed = 0;
760    
761     if (!(conn_get_channel(c)) || !(channel = channel_get_name(conn_get_channel(c)))) {
762     message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
763     return -1;
764     }
765    
766     if (account_get_auth_admin(conn_get_account(c),NULL)!=1 && account_get_auth_admin(conn_get_account(c),channel)!=1) {
767     message_send_text(c,message_type_error,c,"You must be at least a Channel Admin to use this command.");
768     return -1;
769     }
770    
771     text = skip_command(text);
772    
773     if (!(username = &text[0])) {
774     message_send_text(c, message_type_info, c, "You need to supply a username.");
775     return -1;
776     }
777    
778     if(!(acc = accountlist_find_account(username))) {
779     sprintf(msgtemp, "There's no account with username %.64s.", username);
780     message_send_text(c, message_type_info, c, msgtemp);
781     return -1;
782     }
783    
784     dst_c = account_get_conn(acc);
785    
786     if (account_get_auth_admin(acc,channel) == 1)
787     sprintf(msgtemp,"%s is already a Channel Admin",username);
788     else {
789     account_set_auth_admin(acc,channel,1);
790     sprintf(msgtemp,"%s has been promoted to a Channel Admin",username);
791     sprintf(msgtemp2,"%s has promoted you to a Channel Admin for channel \"%s\"",conn_get_loggeduser(c),channel);
792     changed = 1;
793     }
794    
795     if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2);
796     message_send_text(c, message_type_info, c, msgtemp);
797     command_set_flags(dst_c);
798     return 0;
799     }
800    
801     static int _handle_vop_command(t_connection * c, char const * text)
802     {
803     char const * username;
804     char const * channel;
805     t_account * acc;
806     t_connection * dst_c;
807     int changed = 0;
808    
809     if (!(conn_get_channel(c)) || !(channel = channel_get_name(conn_get_channel(c)))) {
810     message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
811     return -1;
812     }
813    
814     if (account_get_auth_admin(conn_get_account(c),NULL)!=1 && account_get_auth_admin(conn_get_account(c),channel)!=1) {
815     message_send_text(c,message_type_error,c,"You must be at least a Channel Admin to use this command.");
816     return -1;
817     }
818    
819     text = skip_command(text);
820    
821     if (!(username = &text[0])) {
822     message_send_text(c, message_type_info, c, "You need to supply a username.");
823     return -1;
824     }
825    
826     if(!(acc = accountlist_find_account(username))) {
827     sprintf(msgtemp, "There's no account with username %.64s.", username);
828     message_send_text(c, message_type_info, c, msgtemp);
829     return -1;
830     }
831    
832     dst_c = account_get_conn(acc);
833    
834     if (account_get_auth_voice(acc,channel) == 1)
835     sprintf(msgtemp,"%s is already on VOP list",username);
836     else {
837     account_set_auth_voice(acc,channel,1);
838     sprintf(msgtemp,"%s has been added to the VOP list",username);
839     sprintf(msgtemp2,"%s has added you to the VOP list of channel \"%s\"",conn_get_loggeduser(c),channel);
840     changed = 1;
841     }
842    
843     if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2);
844     message_send_text(c, message_type_info, c, msgtemp);
845     command_set_flags(dst_c);
846     return 0;
847     }
848    
849     static int _handle_voice_command(t_connection * c, char const * text)
850     {
851     char const * username;
852     char const * channel;
853     t_account * acc;
854     t_connection * dst_c;
855     int changed = 0;
856    
857     if (!(conn_get_channel(c)) || !(channel = channel_get_name(conn_get_channel(c)))) {
858     message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
859     return -1;
860     }
861    
862     if (!(account_is_operator_or_admin(conn_get_account(c),channel_get_name(conn_get_channel(c))))) {
863     message_send_text(c,message_type_error,c,"You must be at least a Channel Operator to use this command.");
864     return -1;
865     }
866    
867     text = skip_command(text);
868    
869     if (!(username = &text[0])) {
870     message_send_text(c, message_type_info, c, "You need to supply a username.");
871     return -1;
872     }
873    
874     if(!(acc = accountlist_find_account(username))) {
875     sprintf(msgtemp, "There's no account with username %.64s.", username);
876     message_send_text(c, message_type_info, c, msgtemp);
877     return -1;
878     }
879     dst_c = account_get_conn(acc);
880     if (account_get_auth_voice(acc,channel)==1)
881     sprintf(msgtemp,"%s is already on VOP list, no need to Voice him", username);
882     else
883     {
884     if ((!dst_c) || conn_get_channel(c)!=conn_get_channel(dst_c))
885     {
886     sprintf(msgtemp,"%s must be on the same channel to voice him",username);
887     }
888     else
889     {
890     if (channel_conn_has_tmpVOICE(conn_get_channel(c),dst_c))
891     sprintf(msgtemp,"%s has already Voice in this channel",username);
892     else {
893     if (account_is_operator_or_admin(acc,channel))
894     sprintf(msgtemp,"%s allready is operator or admin, no need to voice him",username);
895     else
896     {
897     conn_set_tmpVOICE_channel(dst_c,channel);
898     sprintf(msgtemp,"%s has been granted Voice in this channel",username);
899     sprintf(msgtemp2,"%s has granted you Voice in this channel",conn_get_loggeduser(c));
900     changed = 1;
901     }
902     }
903     }
904     }
905    
906     if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2);
907     message_send_text(c, message_type_info, c, msgtemp);
908     command_set_flags(dst_c);
909     return 0;
910     }
911    
912     static int _handle_devoice_command(t_connection * c, char const * text)
913     {
914     char const * username;
915     char const * channel;
916     t_account * acc;
917     t_connection * dst_c;
918     int done = 0;
919     int changed = 0;
920    
921     if (!(conn_get_channel(c)) || !(channel = channel_get_name(conn_get_channel(c)))) {
922     message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
923     return -1;
924     }
925    
926     if (!(account_is_operator_or_admin(conn_get_account(c),channel_get_name(conn_get_channel(c))))) {
927     message_send_text(c,message_type_error,c,"You must be at least a Channel Operator 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     dst_c = account_get_conn(acc);
944    
945     if (account_get_auth_voice(acc,channel)==1)
946     {
947     if ((account_get_auth_admin(conn_get_account(c),channel)==1) || (account_get_auth_admin(conn_get_account(c),NULL)==1))
948     {
949     account_set_auth_voice(acc,channel,0);
950     sprintf(msgtemp,"%s has been removed from VOP list.",username);
951     sprintf(msgtemp2,"%s has removed you from VOP list of channel \"%s\"",conn_get_loggeduser(c),channel);
952     changed = 1;
953     }
954     else
955     {
956     sprintf(msgtemp,"You must be at least Channel Admin to remove %s from the VOP list",username);
957     }
958     done = 1;
959     }
960    
961     if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2);
962     message_send_text(c, message_type_info, c, msgtemp);
963     changed = 0;
964    
965     if ((dst_c) && channel_conn_has_tmpVOICE(conn_get_channel(c),dst_c)==1)
966     {
967     conn_set_tmpVOICE_channel(dst_c,NULL);
968     sprintf(msgtemp,"Voice has been taken from %s in this channel",username);
969     sprintf(msgtemp2,"%s has taken your Voice in channel \"%s\"",conn_get_loggeduser(c),channel);
970     changed = 1;
971     done = 1;
972     }
973    
974     if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2);
975     message_send_text(c, message_type_info, c, msgtemp);
976    
977     if (!done)
978     {
979     sprintf(msgtemp,"%s has no Voice in this channel, so it can't be taken away",username);
980     message_send_text(c, message_type_info, c, msgtemp);
981     }
982    
983     command_set_flags(dst_c);
984     return 0;
985     }
986    
987     static int _handle_op_command(t_connection * c, char const * text)
988     {
989     char const * username;
990     char const * channel;
991     t_account * acc;
992     int OP_lvl;
993     t_connection * dst_c;
994     int changed = 0;
995    
996     if (!(conn_get_channel(c)) || !(channel = channel_get_name(conn_get_channel(c)))) {
997     message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
998     return -1;
999     }
1000    
1001     acc = conn_get_account(c);
1002     OP_lvl = 0;
1003    
1004     if (account_is_operator_or_admin(acc,channel))
1005     OP_lvl = 1;
1006     else if (channel_conn_is_tmpOP(conn_get_channel(c),c))
1007     OP_lvl = 2;
1008    
1009     if (OP_lvl==0)
1010     {
1011     message_send_text(c,message_type_error,c,"You must be at least a Channel Operator or tempOP to use this command.");
1012     return -1;
1013     }
1014    
1015     text = skip_command(text);
1016    
1017     if (!(username = &text[0])) {
1018     message_send_text(c, message_type_info, c, "You need to supply a username.");
1019     return -1;
1020     }
1021    
1022     if(!(acc = accountlist_find_account(username))) {
1023     sprintf(msgtemp, "There's no account with username %.64s.", username);
1024     message_send_text(c, message_type_info, c, msgtemp);
1025     return -1;
1026     }
1027    
1028     dst_c = account_get_conn(acc);
1029    
1030     if (OP_lvl==1) // user is full op so he may fully op others
1031     {
1032     if (account_get_auth_operator(acc,channel) == 1)
1033     sprintf(msgtemp,"%s is allready a Channel Operator",username);
1034     else {
1035     account_set_auth_operator(acc,channel,1);
1036     sprintf(msgtemp,"%s has been promoted to a Channel Operator",username);
1037     sprintf(msgtemp2,"%s has promoted you to a Channel Operator in channel \"%s\"",conn_get_loggeduser(c),channel);
1038     changed = 1;
1039     }
1040     }
1041     else { // user is only tempOP so he may only tempOP others
1042     if ((!(dst_c)) || (conn_get_channel(c) != conn_get_channel(dst_c)))
1043     sprintf(msgtemp,"%s must be on the same channel to tempOP him",username);
1044     else
1045     {
1046     if (account_is_operator_or_admin(acc,channel))
1047     sprintf(msgtemp,"%s allready is operator or admin, no need to tempOP him",username);
1048     else
1049     {
1050     conn_set_tmpOP_channel(dst_c,channel);
1051     sprintf(msgtemp,"%s has been promoted to a tempOP",username);
1052     sprintf(msgtemp2,"%s has promoted you to a tempOP in this channel",conn_get_loggeduser(c));
1053     changed = 1;
1054     }
1055     }
1056     }
1057    
1058     if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2);
1059     message_send_text(c, message_type_info, c, msgtemp);
1060     command_set_flags(dst_c);
1061     return 0;
1062     }
1063    
1064     static int _handle_tmpop_command(t_connection * c, char const * text)
1065     {
1066     char const * username;
1067     char const * channel;
1068     t_account * acc;
1069     t_connection * dst_c;
1070     int changed = 0;
1071    
1072     if (!(conn_get_channel(c)) || !(channel = channel_get_name(conn_get_channel(c)))) {
1073     message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
1074     return -1;
1075     }
1076    
1077     if (!(account_is_operator_or_admin(conn_get_account(c),channel_get_name(conn_get_channel(c))) || channel_conn_is_tmpOP(conn_get_channel(c),c))) {
1078     message_send_text(c,message_type_error,c,"You must be at least a Channel Operator or tmpOP to use this command.");
1079     return -1;
1080     }
1081    
1082     text = skip_command(text);
1083    
1084     if (!(username = &text[0])) {
1085     message_send_text(c, message_type_info, c, "You need to supply a username.");
1086     return -1;
1087     }
1088    
1089     if(!(acc = accountlist_find_account(username))) {
1090     sprintf(msgtemp, "There's no account with username %.64s.", username);
1091     message_send_text(c, message_type_info, c, msgtemp);
1092     return -1;
1093     }
1094    
1095     dst_c = account_get_conn(acc);
1096    
1097     if (channel_conn_is_tmpOP(conn_get_channel(c),dst_c))
1098     sprintf(msgtemp,"%s has already tmpOP in this channel",username);
1099     else
1100     {
1101     if ((!(dst_c)) || (conn_get_channel(c) != conn_get_channel(dst_c)))
1102     sprintf(msgtemp,"%s must be on the same channel to tempOP him",username);
1103     else
1104     {
1105     if (account_is_operator_or_admin(acc,channel))
1106     sprintf(msgtemp,"%s allready is operator or admin, no need to tempOP him",username);
1107     else
1108     {
1109     conn_set_tmpOP_channel(dst_c,channel);
1110     sprintf(msgtemp,"%s has been promoted to tmpOP in this channel",username);
1111     sprintf(msgtemp2,"%s has promoted you to a tempOP in this channel",conn_get_loggeduser(c));
1112     changed = 1;
1113     }
1114     }
1115     }
1116    
1117     if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2);
1118     message_send_text(c, message_type_info, c, msgtemp);
1119     command_set_flags(dst_c);
1120     return 0;
1121     }
1122    
1123     static int _handle_deop_command(t_connection * c, char const * text)
1124     {
1125     char const * username;
1126     char const * channel;
1127     t_account * acc;
1128     int OP_lvl;
1129     t_connection * dst_c;
1130     int done = 0;
1131    
1132     if (!(conn_get_channel(c)) || !(channel = channel_get_name(conn_get_channel(c)))) {
1133     message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
1134     return -1;
1135     }
1136    
1137     acc = conn_get_account(c);
1138     OP_lvl = 0;
1139    
1140     if (account_is_operator_or_admin(acc,channel))
1141     OP_lvl = 1;
1142     else if (channel_conn_is_tmpOP(conn_get_channel(c),account_get_conn(acc)))
1143     OP_lvl = 2;
1144    
1145     if (OP_lvl==0)
1146     {
1147     message_send_text(c,message_type_error,c,"You must be at least a Channel Operator or tempOP to use this command.");
1148     return -1;
1149     }
1150    
1151     text = skip_command(text);
1152    
1153     if (!(username = &text[0])) {
1154     message_send_text(c, message_type_info, c, "You need to supply a username.");
1155     return -1;
1156     }
1157    
1158     if(!(acc = accountlist_find_account(username))) {
1159     sprintf(msgtemp, "There's no account with username %.64s.", username);
1160     message_send_text(c, message_type_info, c, msgtemp);
1161     return -1;
1162     }
1163    
1164     dst_c = account_get_conn(acc);
1165    
1166     if (OP_lvl==1) // user is real OP and allowed to deOP
1167     {
1168     if (account_get_auth_admin(acc,channel) == 1 || account_get_auth_operator(acc,channel) == 1) {
1169     if (account_get_auth_admin(acc,channel) == 1) {
1170     if (account_get_auth_admin(conn_get_account(c),channel)!=1 && account_get_auth_admin(conn_get_account(c),NULL)!=1)
1171     message_send_text(c,message_type_info,c,"You must be at least a Channel Admin to demote another Channel Admin");
1172     else {
1173     account_set_auth_admin(acc,channel,0);
1174     sprintf(msgtemp, "%s has been demoted from a Channel Admin.", username);
1175     message_send_text(c, message_type_info, c, msgtemp);
1176     if (dst_c)
1177     {
1178     sprintf(msgtemp2,"%s has demoted you from a Channel Admin of channel \"%s\"",conn_get_loggeduser(c),channel);
1179     message_send_text(dst_c, message_type_info, c, msgtemp2);
1180     }
1181     }
1182     }
1183     if (account_get_auth_operator(acc,channel) == 1) {
1184     account_set_auth_operator(acc,channel,0);
1185     sprintf(msgtemp,"%s has been demoted from a Channel Operator",username);
1186     message_send_text(c, message_type_info, c, msgtemp);
1187     if (dst_c)
1188     {
1189     sprintf(msgtemp2,"%s has demoted you from a Channel Operator of channel \"%s\"",conn_get_loggeduser(c),channel);
1190     message_send_text(dst_c, message_type_info, c, msgtemp2);
1191     }
1192     }
1193     done = 1;
1194     }
1195     if ((dst_c) && channel_conn_is_tmpOP(conn_get_channel(c),dst_c))
1196     {
1197     conn_set_tmpOP_channel(dst_c,NULL);
1198     sprintf(msgtemp,"%s has been demoted from a tempOP of this channel",username);
1199     message_send_text(c, message_type_info, c, msgtemp);
1200     if (dst_c)
1201     {
1202     sprintf(msgtemp2,"%s has demoted you from a tmpOP of channel \"%s\"",conn_get_loggeduser(c),channel);
1203     message_send_text(dst_c, message_type_info, c, msgtemp2);
1204     }
1205     done = 1;
1206     }
1207     if (!done) {
1208     sprintf(msgtemp,"%s is no Channel Admin or Channel Operator or tempOP, so you can't demote him.",username);
1209     message_send_text(c, message_type_info, c, msgtemp);
1210     }
1211     }
1212     else //user is just a tempOP and may only deOP other tempOPs
1213     {
1214     if (dst_c && channel_conn_is_tmpOP(conn_get_channel(c),dst_c))
1215     {
1216     conn_set_tmpOP_channel(account_get_conn(acc),NULL);
1217     sprintf(msgtemp,"%s has been demoted from a tempOP of this channel",username);
1218     message_send_text(c, message_type_info, c, msgtemp);
1219     sprintf(msgtemp2,"%s has demoted you from a tempOP of channel \"%s\"",conn_get_loggeduser(c),channel);
1220     if (dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2);
1221     }
1222     else
1223     {
1224     sprintf(msgtemp,"%s is no tempOP in this channel, so you can't demote him",username);
1225     message_send_text(c, message_type_info, c, msgtemp);
1226     }
1227     }
1228    
1229     command_set_flags(connlist_find_connection_by_accountname(username));
1230     return 0;
1231     }
1232    
1233     static int _handle_friends_command(t_connection * c, char const * text)
1234     {
1235     int i;
1236     t_account *my_acc = conn_get_account(c);
1237    
1238     text = skip_command(text);;
1239    
1240     if(text[0]=='\0' || strstart(text,"help")==0 || strstart(text, "h")==0) {
1241     message_send_text(c,message_type_info,c,"Friends List (Used in Arranged Teams and finding online friends.)");
1242     message_send_text(c,message_type_info,c,"Type: /f add <username> (adds a friend to your list)");
1243     message_send_text(c,message_type_info,c,"Type: /f del <username> (removes a friend from your list)");
1244     message_send_text(c,message_type_info,c,"Type: /f promote <username> (promote a friend in your list)");
1245     message_send_text(c,message_type_info,c,"Type: /f demote <username> (demote a friend in your list)");
1246     message_send_text(c,message_type_info,c,"Type: /f list (shows your full friends list)");
1247     message_send_text(c,message_type_info,c,"Type: /f msg (whispers a message to all your friends at once)");
1248     return 0;
1249     }
1250    
1251     if (strstart(text,"add")==0 || strstart(text,"a")==0) {
1252     char msgtemp[MAX_MESSAGE_LEN];
1253     t_packet * rpacket;
1254     t_connection * dest_c;
1255     t_account * friend_acc;
1256     t_server_friendslistreply_status status;
1257     t_game * game;
1258     t_channel * channel;
1259     char stat;
1260     t_list * flist;
1261     t_friend * fr;
1262    
1263     text = skip_command(text);
1264    
1265     if (text[0] == '\0') {
1266     message_send_text(c,message_type_info,c,"usage: /f add <username>");
1267     return 0;
1268     }
1269    
1270     if (!(friend_acc = accountlist_find_account(text))) {
1271     message_send_text(c,message_type_info,c,"That user does not exist.");
1272     return 0;
1273     }
1274    
1275     switch(account_add_friend(my_acc, friend_acc)) {
1276     case -1:
1277     message_send_text(c,message_type_error,c,"Server error.");
1278     return 0;
1279     case -2:
1280     message_send_text(c,message_type_info,c,"You can't add yourself to your friends list.");
1281     return 0;
1282     case -3:
1283     sprintf(msgtemp, "You can only have a maximum of %d friends.", prefs_get_max_friends());
1284     message_send_text(c,message_type_info,c,msgtemp);
1285     return 0;
1286     case -4:
1287     sprintf(msgtemp, "%s is already on your friends list!", text);
1288     message_send_text(c,message_type_info,c,msgtemp);
1289     return 0;
1290     }
1291    
1292     sprintf( msgtemp, "Added %s to your friends list.", text);
1293     message_send_text(c,message_type_info,c,msgtemp);
1294     dest_c = connlist_find_connection_by_account(friend_acc);
1295     if(dest_c!=NULL) {
1296     sprintf(msgtemp,"%s added you to his/her friends list.",conn_get_username(c));
1297     message_send_text(dest_c,message_type_info,dest_c,msgtemp);
1298     }
1299    
1300     if ((conn_get_class(c)!=conn_class_bnet) || (!(rpacket = packet_create(packet_class_bnet))))
1301     return 0;
1302    
1303     packet_set_size(rpacket,sizeof(t_server_friendadd_ack));
1304     packet_set_type(rpacket,SERVER_FRIENDADD_ACK);
1305    
1306     packet_append_string(rpacket, account_get_name(friend_acc));
1307    
1308     game = NULL;
1309     channel = NULL;
1310    
1311     if(!(dest_c))
1312     {
1313     bn_byte_set(&status.location,FRIENDSTATUS_OFFLINE);
1314     bn_byte_set(&status.status,0);
1315     bn_int_set(&status.clienttag,0);
1316     }
1317     else
1318     {
1319     bn_int_set(&status.clienttag, conn_get_clienttag(dest_c));
1320     stat = 0;
1321     flist = account_get_friends(my_acc);
1322     fr = friendlist_find_account(flist,friend_acc);
1323     if ((friend_get_mutual(fr))) stat |= FRIEND_TYPE_MUTUAL;
1324     if ((conn_get_dndstr(dest_c))) stat |= FRIEND_TYPE_DND;
1325     if ((conn_get_awaystr(dest_c))) stat |= FRIEND_TYPE_AWAY;
1326     bn_byte_set(&status.status,stat);
1327     if((game = conn_get_game(dest_c)))
1328     {
1329     if (game_get_flag(game) != game_flag_private)
1330     bn_byte_set(&status.location,FRIENDSTATUS_PUBLIC_GAME);
1331     else
1332     bn_byte_set(&status.location,FRIENDSTATUS_PRIVATE_GAME);
1333     }
1334     else if((channel = conn_get_channel(dest_c)))
1335     {
1336     bn_byte_set(&status.location,FRIENDSTATUS_CHAT);
1337     }
1338     else
1339     {
1340     bn_byte_set(&status.location,FRIENDSTATUS_ONLINE);
1341     }
1342     }
1343    
1344     packet_append_data(rpacket, &status, sizeof(status));
1345    
1346     if (game) packet_append_string(rpacket,game_get_name(game));
1347     else if (channel) packet_append_string(rpacket,channel_get_name(channel));
1348     else packet_append_string(rpacket,"");
1349    
1350     conn_push_outqueue(c,rpacket);
1351     packet_del_ref(rpacket);
1352    
1353     return 0;
1354     }
1355    
1356     if (strstart(text,"msg")==0 || strstart(text,"w")==0 || strstart(text,"whisper")==0 || strstart(text,"m")==0)
1357     {
1358     char const *msg;
1359     int cnt = 0;
1360     t_connection * dest_c;
1361     t_elem * curr;
1362     t_friend * fr;
1363     t_list * flist;
1364    
1365     msg = skip_command(text);
1366     /* if the message test is empty then ignore command */
1367     if (msg[0]=='\0') {
1368     message_send_text(c,message_type_info,c,"Did not message any friends. Type some text next time.");
1369     return 0;
1370     }
1371    
1372     flist=account_get_friends(my_acc);
1373     if(flist==NULL)
1374     return -1;
1375    
1376     LIST_TRAVERSE(flist,curr)
1377     {
1378     if (!(fr = elem_get_data(curr))) {
1379     eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list");
1380     continue;
1381     }
1382     if(friend_get_mutual(fr)) {
1383     dest_c = connlist_find_connection_by_account(friend_get_account(fr));
1384     if (!dest_c) continue;
1385     message_send_text(dest_c,message_type_whisper,c,msg);
1386     cnt++;
1387     }
1388     }
1389     if(cnt)
1390     message_send_text(c,message_type_friendwhisperack,c,msg);
1391     else
1392     message_send_text(c,message_type_info,c,"All your friends are offline.");
1393    
1394     return 0;
1395     }
1396    
1397     if (strstart(text,"r")==0 || strstart(text,"remove")==0
1398     || strstart(text,"del")==0 || strstart(text,"delete")==0) {
1399    
1400     int num;
1401     char msgtemp[MAX_MESSAGE_LEN];
1402     t_packet * rpacket;
1403    
1404     text = skip_command(text);
1405    
1406     if (text[0]=='\0') {
1407     message_send_text(c,message_type_info,c,"usage: /f remove <username>");
1408     return 0;
1409     }
1410    
1411     switch((num = account_remove_friend2(my_acc, text))) {
1412     case -1: return -1;
1413     case -2:
1414     sprintf(msgtemp, "%s was not found on your friends list.", text);
1415     message_send_text(c,message_type_info,c,msgtemp);
1416     return 0;
1417     default:
1418     sprintf(msgtemp, "Removed %s from your friends list.", text);
1419     message_send_text(c,message_type_info,c,msgtemp);
1420    
1421     if ((conn_get_class(c)!=conn_class_bnet) || (!(rpacket = packet_create(packet_class_bnet))))
1422     return 0;
1423    
1424     packet_set_size(rpacket,sizeof(t_server_frienddel_ack));
1425     packet_set_type(rpacket,SERVER_FRIENDDEL_ACK);
1426    
1427     bn_byte_set(&rpacket->u.server_frienddel_ack.friendnum, num);
1428    
1429     conn_push_outqueue(c,rpacket);
1430     packet_del_ref(rpacket);
1431    
1432     return 0;
1433     }
1434     }
1435    
1436     if (strstart(text,"p")==0 || strstart(text,"promote")==0) {
1437     int num;
1438     int n;
1439     char msgtemp[MAX_MESSAGE_LEN];
1440     char const * dest_name;
1441     t_packet * rpacket;
1442     t_list * flist;
1443     t_friend * fr;
1444     t_account * dest_acc;
1445     unsigned int dest_uid;
1446    
1447     text = skip_command(text);
1448    
1449     if (text[0]=='\0') {
1450     message_send_text(c,message_type_info,c,"usage: /f promote <username>");
1451     return 0;
1452     }
1453    
1454     num = account_get_friendcount(my_acc);
1455     flist = account_get_friends(my_acc);
1456     for(n = 1; n<num; n++)
1457     if( (dest_uid = account_get_friend(my_acc, n)) &&
1458     (fr = friendlist_find_uid(flist, dest_uid)) &&
1459     (dest_acc = friend_get_account(fr)) &&
1460     (dest_name = account_get_name(dest_acc)) &&
1461     (strcasecmp(dest_name, text) == 0) )
1462     {
1463     account_set_friend(my_acc, n, account_get_friend(my_acc, n-1));
1464     account_set_friend(my_acc, n-1, dest_uid);
1465     sprintf(msgtemp, "Premoted %s in your friends list.", dest_name);
1466     message_send_text(c,message_type_info,c,msgtemp);
1467    
1468     if ((conn_get_class(c)!=conn_class_bnet) || (!(rpacket = packet_create(packet_class_bnet))))
1469     return 0;
1470    
1471     packet_set_size(rpacket,sizeof(t_server_friendmove_ack));
1472     packet_set_type(rpacket,SERVER_FRIENDMOVE_ACK);
1473     bn_byte_set(&rpacket->u.server_friendmove_ack.pos1, n-1);
1474     bn_byte_set(&rpacket->u.server_friendmove_ack.pos2, n);
1475    
1476     conn_push_outqueue(c,rpacket);
1477     packet_del_ref(rpacket);
1478     return 0;
1479     }
1480     return 0;
1481     }
1482    
1483     if (strstart(text,"d")==0 || strstart(text,"demote")==0) {
1484     int num;
1485     int n;
1486     char msgtemp[MAX_MESSAGE_LEN];
1487     char const * dest_name;
1488     t_packet * rpacket;
1489     t_list * flist;
1490     t_friend * fr;
1491     t_account * dest_acc;
1492     unsigned int dest_uid;
1493    
1494     text = skip_command(text);
1495    
1496     if (text[0]=='\0') {
1497     message_send_text(c,message_type_info,c,"usage: /f demote <username>");
1498     return 0;
1499     }
1500    
1501     num = account_get_friendcount(my_acc);
1502     flist = account_get_friends(my_acc);
1503     for(n = 0; n<num-1; n++)
1504     if( (dest_uid = account_get_friend(my_acc, n)) &&
1505     (fr = friendlist_find_uid(flist, dest_uid)) &&
1506     (dest_acc = friend_get_account(fr)) &&
1507     (dest_name = account_get_name(dest_acc)) &&
1508     (strcasecmp(dest_name, text) == 0) )
1509     {
1510     account_set_friend(my_acc, n, account_get_friend(my_acc, n+1));
1511     account_set_friend(my_acc, n+1, dest_uid);
1512     sprintf(msgtemp, "Premoted %s in your friends list.", dest_name);
1513     message_send_text(c,message_type_info,c,msgtemp);
1514    
1515     if ((conn_get_class(c)!=conn_class_bnet) || (!(rpacket = packet_create(packet_class_bnet))))
1516     return 0;
1517    
1518     packet_set_size(rpacket,sizeof(t_server_friendmove_ack));
1519     packet_set_type(rpacket,SERVER_FRIENDMOVE_ACK);
1520     bn_byte_set(&rpacket->u.server_friendmove_ack.pos1, n);
1521     bn_byte_set(&rpacket->u.server_friendmove_ack.pos2, n+1);
1522    
1523     conn_push_outqueue(c,rpacket);
1524     packet_del_ref(rpacket);
1525     return 0;
1526     }
1527     return 0;
1528     }
1529    
1530     if (strstart(text,"list")==0 || strstart(text,"l")==0) {
1531     char const * friend;
1532     char status[128];
1533     char software[64];
1534     char msgtemp[MAX_MESSAGE_LEN];
1535     t_connection * dest_c;
1536     t_account * friend_acc;
1537     t_game const * game;
1538     t_channel const * channel;
1539     t_friend * fr;
1540     t_list * flist;
1541     int num;
1542     unsigned int uid;
1543    
1544     message_send_text(c,message_type_info,c,"Your PvPGN - Friends List");
1545     message_send_text(c,message_type_info,c,"=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
1546     num = account_get_friendcount(my_acc);
1547    
1548     flist=account_get_friends(my_acc);
1549     if(flist!=NULL) {
1550     for (i=0;i<num;i++)
1551     {
1552     if ((!(uid = account_get_friend(my_acc,i))) || (!(fr = friendlist_find_uid(flist,uid))))
1553     {
1554     eventlog(eventlog_level_error,__FUNCTION__,"friend uid in list");
1555     continue;
1556     }
1557     software[0]='\0';
1558     friend_acc=friend_get_account(fr);
1559     if (!(dest_c = connlist_find_connection_by_account(friend_acc)))
1560     sprintf(status, ", offline");
1561     else {
1562     sprintf(software," using %s", clienttag_get_title(conn_get_clienttag(dest_c)));
1563    
1564     if(friend_get_mutual(fr)) {
1565     if ((game = conn_get_game(dest_c)))
1566     sprintf(status, ", in game \"%.64s\"", game_get_name(game));
1567     else if ((channel = conn_get_channel(dest_c))) {
1568     if(strcasecmp(channel_get_name(channel),"Arranged Teams")==0)
1569     sprintf(status, ", in game AT Preparation");
1570     else
1571     sprintf(status, ", in channel \"%.64s\",", channel_get_name(channel));
1572     }
1573     else
1574     sprintf(status, ", is in AT Preparation");
1575     } else {
1576     if ((game = conn_get_game(dest_c)))
1577     sprintf(status, ", is in a game");
1578     else if ((channel = conn_get_channel(dest_c)))
1579     sprintf(status, ", is in a chat channel");
1580     else
1581     sprintf(status, ", is in AT Preparation");
1582     }
1583     }
1584    
1585     friend=account_get_name(friend_acc);
1586     if (software[0]) sprintf(msgtemp, "%d: %s%.16s%.128s, %.64s", i+1, friend_get_mutual(fr)?"*":" ", friend, status,software);
1587     else sprintf(msgtemp, "%d: %.16s%.128s", i+1, friend, status);
1588     message_send_text(c,message_type_info,c,msgtemp);
1589     }
1590     }
1591     message_send_text(c,message_type_info,c,"=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
1592     message_send_text(c,message_type_info,c,"End of Friends List");
1593    
1594     return 0;
1595     }
1596    
1597     return 0;
1598     }
1599    
1600     static int _handle_me_command(t_connection * c, char const * text)
1601     {
1602     t_channel const * channel;
1603    
1604     if (!(channel = conn_get_channel(c)))
1605     {
1606     message_send_text(c,message_type_error,c,"You are not in a channel.");
1607     return 0;
1608     }
1609    
1610     text = skip_command(text);
1611    
1612     if ((text[0]!='\0') && (!conn_quota_exceeded(c,text)))
1613     channel_message_send(channel,message_type_emote,c,text);
1614     return 0;
1615     }
1616    
1617     static int _handle_whisper_command(t_connection * c, char const *text)
1618     {
1619     char dest[USER_NAME_MAX+REALM_NAME_LEN]; /* both include NUL, so no need to add one for middle @ or * */
1620     unsigned int i,j;
1621    
1622     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
1623     for (; text[i]==' '; i++);
1624     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */
1625     if (j<sizeof(dest)-1) dest[j++] = text[i];
1626     dest[j] = '\0';
1627     for (; text[i]==' '; i++);
1628    
1629     if ((dest[0]=='\0') || (text[i]=='\0'))
1630     {
1631     message_send_text(c,message_type_info,c,"usage: /whisper <username> <text to whisper>");
1632     return 0;
1633     }
1634    
1635     do_whisper(c,dest,&text[i]);
1636    
1637     return 0;
1638     }
1639    
1640     static int _handle_status_command(t_connection * c, char const *text)
1641     {
1642     char ctag[5];
1643     unsigned int i,j;
1644     t_clienttag clienttag;
1645    
1646     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
1647     for (; text[i]==' '; i++);
1648     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get clienttag */
1649     if (j<sizeof(ctag)-1) ctag[j++] = text[i];
1650     ctag[j] = '\0';
1651    
1652     if (ctag[0]=='\0') {
1653     sprintf(msgtemp,"There are currently %d users online, in %d games and %d channels.",
1654     connlist_login_get_length(),
1655     gamelist_get_length(),
1656     channellist_get_length());
1657     message_send_text(c,message_type_info,c,msgtemp);
1658     tag_uint_to_str(ctag,conn_get_clienttag(c));
1659     }
1660    
1661     for (i=0; i<strlen(ctag); i++)
1662     if (isascii((int)ctag[i]) && islower((int)ctag[i]))
1663     ctag[i] = toupper((int)ctag[i]);
1664    
1665     if (strcmp(ctag,"ALL") == 0)
1666     clienttag = 0;
1667     else
1668     clienttag = tag_case_str_to_uint(ctag);
1669    
1670     switch (clienttag)
1671     {
1672     case 0:
1673     case CLIENTTAG_WAR3XP_UINT:
1674     sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
1675     conn_get_user_count_by_clienttag(CLIENTTAG_WAR3XP_UINT),
1676     game_get_count_by_clienttag(CLIENTTAG_WAR3XP_UINT),
1677     clienttag_get_title(CLIENTTAG_WAR3XP_UINT));
1678     message_send_text(c,message_type_info,c,msgtemp);
1679     if (clienttag) break;
1680     case CLIENTTAG_WARCRAFT3_UINT:
1681     sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
1682     conn_get_user_count_by_clienttag(CLIENTTAG_WARCRAFT3_UINT),
1683     game_get_count_by_clienttag(CLIENTTAG_WARCRAFT3_UINT),
1684     clienttag_get_title(CLIENTTAG_WARCRAFT3_UINT));
1685     message_send_text(c,message_type_info,c,msgtemp);
1686     if (clienttag) break;
1687     case CLIENTTAG_DIABLO2XP_UINT:
1688     sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
1689     conn_get_user_count_by_clienttag(CLIENTTAG_DIABLO2XP_UINT),
1690     game_get_count_by_clienttag(CLIENTTAG_DIABLO2XP_UINT),
1691     clienttag_get_title(CLIENTTAG_DIABLO2XP_UINT));
1692     message_send_text(c,message_type_info,c,msgtemp);
1693     if (clienttag) break;
1694     case CLIENTTAG_DIABLO2DV_UINT:
1695     sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
1696     conn_get_user_count_by_clienttag(CLIENTTAG_DIABLO2DV_UINT),
1697     game_get_count_by_clienttag(CLIENTTAG_DIABLO2DV_UINT),
1698     clienttag_get_title(CLIENTTAG_DIABLO2DV_UINT));
1699     message_send_text(c,message_type_info,c,msgtemp);
1700     if (clienttag) break;
1701     case CLIENTTAG_BROODWARS_UINT:
1702     sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
1703     conn_get_user_count_by_clienttag(CLIENTTAG_BROODWARS_UINT),
1704     game_get_count_by_clienttag(CLIENTTAG_BROODWARS_UINT),
1705     clienttag_get_title(CLIENTTAG_BROODWARS_UINT));
1706     message_send_text(c,message_type_info,c,msgtemp);
1707     if (clienttag) break;
1708     case CLIENTTAG_STARCRAFT_UINT:
1709     sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
1710     conn_get_user_count_by_clienttag(CLIENTTAG_STARCRAFT_UINT),
1711     game_get_count_by_clienttag(CLIENTTAG_STARCRAFT_UINT),
1712     clienttag_get_title(CLIENTTAG_STARCRAFT_UINT));
1713     message_send_text(c,message_type_info,c,msgtemp);
1714     if (clienttag) break;
1715     case CLIENTTAG_WARCIIBNE_UINT:
1716     sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
1717     conn_get_user_count_by_clienttag(CLIENTTAG_WARCIIBNE_UINT),
1718     game_get_count_by_clienttag(CLIENTTAG_WARCIIBNE_UINT),
1719     clienttag_get_title(CLIENTTAG_WARCIIBNE_UINT));
1720     message_send_text(c,message_type_info,c,msgtemp);
1721     if (clienttag) break;
1722     case CLIENTTAG_DIABLORTL_UINT:
1723     sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
1724     conn_get_user_count_by_clienttag(CLIENTTAG_DIABLORTL_UINT),
1725     game_get_count_by_clienttag(CLIENTTAG_DIABLORTL_UINT),
1726     clienttag_get_title(CLIENTTAG_DIABLORTL_UINT));
1727     message_send_text(c,message_type_info,c,msgtemp);
1728     if (clienttag) break;
1729     default:
1730     sprintf(msgtemp,"There are currently %u user(s) in %u games of %s",
1731     conn_get_user_count_by_clienttag(conn_get_clienttag(c)),
1732     game_get_count_by_clienttag(conn_get_clienttag(c)),
1733     clienttag_get_title(conn_get_clienttag(c)));
1734     message_send_text(c,message_type_info,c,msgtemp);
1735     }
1736    
1737     return 0;
1738     }
1739    
1740     static int _handle_who_command(t_connection * c, char const *text)
1741     {
1742     t_connection const * conn;
1743     t_channel const * channel;
1744     unsigned int i;
1745     char const * tname;
1746    
1747     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
1748     for (; text[i]==' '; i++);
1749    
1750     if (text[i]=='\0')
1751     {
1752     message_send_text(c,message_type_info,c,"usage: /who <channel>");
1753     return 0;
1754     }
1755    
1756     if (!(channel = channellist_find_channel_by_name(&text[i],conn_get_country(c),realm_get_name(conn_get_realm(c)))))
1757     {
1758     message_send_text(c,message_type_error,c,"That channel does not exist.");
1759     message_send_text(c,message_type_error,c,"(If you are trying to search for a user, use the /whois command.)");
1760     return 0;
1761     }
1762     if (channel_check_banning(channel,c)==1)
1763     {
1764     message_send_text(c,message_type_error,c,"You are banned from that channel.");
1765     return 0;
1766     }
1767    
1768     sprintf(msgtemp,"Users in channel %.64s:",&text[i]);
1769     i = strlen(msgtemp);
1770     for (conn=channel_get_first(channel); conn; conn=channel_get_next())
1771     {
1772     if (i+strlen((tname = conn_get_username(conn)))+2>sizeof(msgtemp)) /* " ", name, '\0' */
1773     {
1774     message_send_text(c,message_type_info,c,msgtemp);
1775     i = 0;
1776     }
1777     sprintf(&msgtemp[i]," %s",tname);
1778     i += strlen(&msgtemp[i]);
1779     }
1780     if (i>0)
1781     message_send_text(c,message_type_info,c,msgtemp);
1782    
1783     return 0;
1784     }
1785    
1786     static int _handle_whois_command(t_connection * c, char const * text)
1787     {
1788     unsigned int i;
1789    
1790     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
1791     for (; text[i]==' '; i++);
1792    
1793     if (text[i]=='\0')
1794     {
1795     message_send_text(c,message_type_info,c,"usage: /whois <username>");
1796     return 0;
1797     }
1798    
1799     do_whois(c,&text[i]);
1800    
1801     return 0;
1802     }
1803    
1804     static int _handle_whoami_command(t_connection * c, char const *text)
1805     {
1806     char const * tname;
1807    
1808     if (!(tname = conn_get_username(c)))
1809     {
1810     message_send_text(c,message_type_error,c,"Unable to obtain your account name.");
1811     return 0;
1812     }
1813    
1814     do_whois(c,tname);
1815    
1816     return 0;
1817     }
1818    
1819     static int _handle_announce_command(t_connection * c, char const *text)
1820     {
1821     unsigned int i;
1822     t_message * message;
1823    
1824     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
1825     for (; text[i]==' '; i++);
1826    
1827     if (text[i]=='\0')
1828     {
1829     message_send_text(c,message_type_info,c,"usage: /announce <announcement>");
1830     return 0;
1831     }
1832    
1833     sprintf(msgtemp,"Announcement from %.64s: %.128s",conn_get_username(c),&text[i]);
1834     if (!(message = message_create(message_type_broadcast,c,NULL,msgtemp)))
1835     message_send_text(c,message_type_info,c,"Could not broadcast message.");
1836     else
1837     {
1838     if (message_send_all(message)<0)
1839     message_send_text(c,message_type_info,c,"Could not broadcast message.");
1840     message_destroy(message);
1841     }
1842    
1843     return 0;
1844     }
1845    
1846     static int _handle_beep_command(t_connection * c, char const *text)
1847     {
1848     message_send_text(c,message_type_info,c,"Audible notification on."); /* FIXME: actually do something */
1849     return 0; /* FIXME: these only affect CHAT clients... I think they prevent ^G from being sent */
1850     }
1851    
1852     static int _handle_nobeep_command(t_connection * c, char const *text)
1853     {
1854     message_send_text(c,message_type_info,c,"Audible notification off."); /* FIXME: actually do something */
1855     return 0;
1856     }
1857    
1858     static int _handle_version_command(t_connection * c, char const *text)
1859     {
1860     message_send_text(c,message_type_info,c,PVPGN_SOFTWARE" "PVPGN_VERSION);
1861     return 0;
1862     }
1863    
1864     static int _handle_copyright_command(t_connection * c, char const *text)
1865     {
1866     static char const * const info[] =
1867     {
1868     " Copyright (C) 2002 See source for details",
1869     " ",
1870     " PvPGN is free software; you can redistribute it and/or",
1871     " modify it under the terms of the GNU General Public License",
1872     " as published by the Free Software Foundation; either version 2",
1873     " of the License, or (at your option) any later version.",
1874     " ",
1875     " This program is distributed in the hope that it will be useful,",
1876     " but WITHOUT ANY WARRANTY; without even the implied warranty of",
1877     " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
1878     " GNU General Public License for more details.",
1879     " ",
1880     " You should have received a copy of the GNU General Public License",
1881     " along with this program; if not, write to the Free Software",
1882     " Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.",
1883     NULL
1884     };
1885     unsigned int i;
1886    
1887     for (i=0; info[i]; i++)
1888     message_send_text(c,message_type_info,c,info[i]);
1889    
1890     return 0;
1891     }
1892    
1893     static int _handle_uptime_command(t_connection * c, char const *text)
1894     {
1895    
1896     sprintf(msgtemp,"Uptime: %s",seconds_to_timestr(server_get_uptime()));
1897     message_send_text(c,message_type_info,c,msgtemp);
1898    
1899     return 0;
1900     }
1901    
1902     static int _handle_stats_command(t_connection * c, char const *text)
1903     {
1904     char dest[USER_NAME_MAX];
1905     unsigned int i,j;
1906     t_account * account;
1907     char const * clienttag=NULL;
1908     t_clienttag clienttag_uint;
1909     char clienttag_str[5];
1910    
1911     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
1912     for (; text[i]==' '; i++);
1913     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */
1914     if (j<sizeof(dest)-1) dest[j++] = text[i];
1915     dest[j] = '\0';
1916     for (; text[i]==' '; i++);
1917    
1918     if (!dest[0]) {
1919     account = conn_get_account(c);
1920     } else if (!(account = accountlist_find_account(dest))) {
1921     message_send_text(c,message_type_error,c,"Invalid user.");
1922     return 0;
1923     }
1924    
1925     if (text[i]!='\0')
1926     clienttag = &text[i];
1927     else if (!(clienttag = tag_uint_to_str(clienttag_str,conn_get_clienttag(c)))) {
1928     message_send_text(c,message_type_error,c,"Unable to determine client game.");
1929     return 0;
1930     }
1931    
1932     if (strlen(clienttag)!=4) {
1933     sprintf(msgtemp,"You must supply a user name and a valid program ID. (Program ID \"%.32s\" is invalid.)",clienttag);
1934     message_send_text(c,message_type_error,c,msgtemp);
1935     message_send_text(c,message_type_error,c,"Example: /stats joe STAR");
1936     return 0;
1937     }
1938    
1939     clienttag_uint = tag_case_str_to_uint(clienttag);
1940    
1941     switch (clienttag_uint)
1942     {
1943     case CLIENTTAG_BNCHATBOT_UINT:
1944     message_send_text(c,message_type_error,c,"This game does not support win/loss records.");
1945     message_send_text(c,message_type_error,c,"You must supply a user name and a valid program ID.");
1946     message_send_text(c,message_type_error,c,"Example: /stats joe STAR");
1947     return 0;
1948     case CLIENTTAG_DIABLORTL_UINT:
1949     case CLIENTTAG_DIABLOSHR_UINT:
1950     sprintf(msgtemp,"%.64s's record:",account_get_name(account));
1951     message_send_text(c,message_type_info,c,msgtemp);
1952     sprintf(msgtemp,"level: %u",account_get_normal_level(account,clienttag_uint));
1953     message_send_text(c,message_type_info,c,msgtemp);
1954     sprintf(msgtemp,"class: %.16s",bnclass_get_str(account_get_normal_class(account,clienttag_uint)));
1955     message_send_text(c,message_type_info,c,msgtemp);
1956     sprintf(msgtemp,"stats: %u str %u mag %u dex %u vit %u gld",
1957     account_get_normal_strength(account,clienttag_uint),
1958     account_get_normal_magic(account,clienttag_uint),
1959     account_get_normal_dexterity(account,clienttag_uint),
1960     account_get_normal_vitality(account,clienttag_uint),
1961     account_get_normal_gold(account,clienttag_uint));
1962     message_send_text(c,message_type_info,c,msgtemp);
1963     sprintf(msgtemp,"Diablo kills: %u",account_get_normal_diablo_kills(account,clienttag_uint));
1964     message_send_text(c,message_type_info,c,msgtemp);
1965     return 0;
1966     case CLIENTTAG_WARCIIBNE_UINT:
1967     sprintf(msgtemp,"%.64s's record:",account_get_name(account));
1968     message_send_text(c,message_type_info,c,msgtemp);
1969     sprintf(msgtemp,"Normal games: %u-%u-%u",
1970     account_get_normal_wins(account,clienttag_uint),
1971     account_get_normal_losses(account,clienttag_uint),
1972     account_get_normal_disconnects(account,clienttag_uint));
1973     message_send_text(c,message_type_info,c,msgtemp);
1974     if (account_get_ladder_rating(account,clienttag_uint,ladder_id_normal)>0)
1975     sprintf(msgtemp,"Ladder games: %u-%u-%u (rating %d)",
1976     account_get_ladder_wins(account,clienttag_uint,ladder_id_normal),
1977     account_get_ladder_losses(account,clienttag_uint,ladder_id_normal),
1978     account_get_ladder_disconnects(account,clienttag_uint,ladder_id_normal),
1979     account_get_ladder_rating(account,clienttag_uint,ladder_id_normal));
1980     else
1981     strcpy(msgtemp,"Ladder games: 0-0-0");
1982     message_send_text(c,message_type_info,c,msgtemp);
1983     if (account_get_ladder_rating(account,clienttag_uint,ladder_id_ironman)>0)
1984     sprintf(msgtemp,"IronMan games: %u-%u-%u (rating %d)",
1985     account_get_ladder_wins(account,clienttag_uint,ladder_id_ironman),
1986     account_get_ladder_losses(account,clienttag_uint,ladder_id_ironman),
1987     account_get_ladder_disconnects(account,clienttag_uint,ladder_id_ironman),
1988     account_get_ladder_rating(account,clienttag_uint,ladder_id_ironman));
1989     else
1990     strcpy(msgtemp,"IronMan games: 0-0-0");
1991     message_send_text(c,message_type_info,c,msgtemp);
1992     return 0;
1993     case CLIENTTAG_WARCRAFT3_UINT:
1994     case CLIENTTAG_WAR3XP_UINT:
1995     sprintf(msgtemp,"%.64s's Ladder Record's:",account_get_name(account));
1996     message_send_text(c,message_type_info,c,msgtemp);
1997     sprintf(msgtemp,"Users Solo Level: %u, Experience: %u",
1998     account_get_ladder_level(account,clienttag_uint,ladder_id_solo),
1999     account_get_ladder_xp(account,clienttag_uint,ladder_id_solo));
2000     message_send_text(c,message_type_info,c,msgtemp);
2001     sprintf(msgtemp,"SOLO Ladder Record: %u-%u-0",
2002     account_get_ladder_wins(account,clienttag_uint,ladder_id_solo),
2003     account_get_ladder_losses(account,clienttag_uint,ladder_id_solo));
2004     message_send_text(c,message_type_info,c,msgtemp);
2005     sprintf(msgtemp,"SOLO Rank: %u",
2006     account_get_ladder_rank(account,clienttag_uint,ladder_id_solo));
2007     message_send_text(c,message_type_info,c,msgtemp);
2008     sprintf(msgtemp,"Users Team Level: %u, Experience: %u",
2009     account_get_ladder_level(account,clienttag_uint,ladder_id_team),
2010     account_get_ladder_xp(account,clienttag_uint,ladder_id_team));
2011     message_send_text(c,message_type_info,c,msgtemp);
2012     sprintf(msgtemp,"TEAM Ladder Record: %u-%u-0",
2013     account_get_ladder_wins(account,clienttag_uint,ladder_id_team),
2014     account_get_ladder_losses(account,clienttag_uint,ladder_id_team));
2015     message_send_text(c,message_type_info,c,msgtemp);
2016     sprintf(msgtemp,"TEAM Rank: %u",
2017     account_get_ladder_rank(account,clienttag_uint,ladder_id_team));
2018     message_send_text(c,message_type_info,c,msgtemp);
2019     sprintf(msgtemp,"Users FFA Level: %u, Experience: %u",
2020     account_get_ladder_level(account,clienttag_uint,ladder_id_ffa),
2021     account_get_ladder_xp(account,clienttag_uint,ladder_id_ffa));
2022     message_send_text(c,message_type_info,c,msgtemp);
2023     sprintf(msgtemp,"FFA Ladder Record: %u-%u-0",
2024     account_get_ladder_wins(account,clienttag_uint,ladder_id_ffa),
2025     account_get_ladder_losses(account,clienttag_uint,ladder_id_ffa));
2026     message_send_text(c,message_type_info,c,msgtemp);
2027     sprintf(msgtemp,"FFA Rank: %u",
2028     account_get_ladder_rank(account,clienttag_uint,ladder_id_ffa));
2029     message_send_text(c,message_type_info,c,msgtemp);
2030     if (account_get_teams(account)) {
2031     t_elem * curr;
2032     t_list * list;
2033     t_team * team;
2034     int teamcount = 0;
2035    
2036     list = account_get_teams(account);
2037    
2038     LIST_TRAVERSE(list,curr)
2039     {
2040     if (!(team = elem_get_data(curr)))
2041     {
2042     eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
2043     continue;
2044     }
2045    
2046     if (team_get_clienttag(team) != clienttag_uint)
2047     continue;
2048    
2049     teamcount++;
2050     sprintf(msgtemp,"Users AT Team No. %u",teamcount);
2051     message_send_text(c,message_type_info,c,msgtemp);
2052     sprintf(msgtemp,"Users AT TEAM Level: %u, Experience: %u",
2053     team_get_level(team),team_get_xp(team));
2054     message_send_text(c,message_type_info,c,msgtemp);
2055     sprintf(msgtemp,"AT TEAM Ladder Record: %u-%u-0",
2056     team_get_wins(team),team_get_losses(team));
2057     message_send_text(c,message_type_info,c,msgtemp);
2058     sprintf(msgtemp,"AT TEAM Rank: %u",
2059     team_get_rank(team));
2060     message_send_text(c,message_type_info,c,msgtemp);
2061     }
2062     }
2063     return 0;
2064     default:
2065     sprintf(msgtemp,"%.64s's record:",account_get_name(account));
2066     message_send_text(c,message_type_info,c,msgtemp);
2067     sprintf(msgtemp,"Normal games: %u-%u-%u",
2068     account_get_normal_wins(account,clienttag_uint),
2069     account_get_normal_losses(account,clienttag_uint),
2070     account_get_normal_disconnects(account,clienttag_uint));
2071     message_send_text(c,message_type_info,c,msgtemp);
2072     if (account_get_ladder_rating(account,clienttag_uint,ladder_id_normal)>0)
2073     sprintf(msgtemp,"Ladder games: %u-%u-%u (rating %d)",
2074     account_get_ladder_wins(account,clienttag_uint,ladder_id_normal),
2075     account_get_ladder_losses(account,clienttag_uint,ladder_id_normal),
2076     account_get_ladder_disconnects(account,clienttag_uint,ladder_id_normal),
2077     account_get_ladder_rating(account,clienttag_uint,ladder_id_normal));
2078     else
2079     strcpy(msgtemp,"Ladder games: 0-0-0");
2080     message_send_text(c,message_type_info,c,msgtemp);
2081     return 0;
2082     }
2083     }
2084    
2085     static int _handle_time_command(t_connection * c, char const *text)
2086     {
2087     t_bnettime btsystem;
2088     t_bnettime btlocal;
2089     time_t now;
2090     struct tm * tmnow;
2091    
2092     btsystem = bnettime();
2093    
2094     /* Battle.net time: Wed Jun 23 15:15:29 */
2095     btlocal = bnettime_add_tzbias(btsystem,local_tzbias());
2096     now = bnettime_to_time(btlocal);
2097     if (!(tmnow = gmtime(&now)))
2098     strcpy(msgtemp,"PvPGN Server Time: ?");
2099     else
2100     strftime(msgtemp,sizeof(msgtemp),"PvPGN Server Time: %a %b %d %H:%M:%S",tmnow);
2101     message_send_text(c,message_type_info,c,msgtemp);
2102     if (conn_get_class(c)==conn_class_bnet)
2103     {
2104     btlocal = bnettime_add_tzbias(btsystem,conn_get_tzbias(c));
2105     now = bnettime_to_time(btlocal);
2106     if (!(tmnow = gmtime(&now)))
2107     strcpy(msgtemp,"Your local time: ?");
2108     else
2109     strftime(msgtemp,sizeof(msgtemp),"Your local time: %a %b %d %H:%M:%S",tmnow);
2110     message_send_text(c,message_type_info,c,msgtemp);
2111     }
2112    
2113     return 0;
2114     }
2115    
2116     static int _handle_channel_command(t_connection * c, char const *text)
2117     {
2118     t_channel * channel;
2119    
2120     text = skip_command(text);
2121    
2122     if (text[0]=='\0')
2123     {
2124     message_send_text(c,message_type_info,c,"usage /channel <channel>");
2125     return 0;
2126     }
2127    
2128     if(strcasecmp(text,"Arranged Teams")==0)
2129     {
2130     // if(account_get_auth_admin(conn_get_account(c))>0)
2131     // {
2132     // message_send_text(c,message_type_error,c,"Please do not talk in channel Arranged Teams");
2133     // message_send_text(c,message_type_error,c,"This channel is dedicated for the preparation of");
2134     // message_send_text(c,message_type_error,c,"Arranged Team Games.");
2135     // }
2136     // else
2137     // {
2138     message_send_text(c,message_type_error,c,"Channel Arranged Teams is a RESTRICTED Channel!");
2139     return 0;
2140     // }
2141     }
2142    
2143     if ((channel = conn_get_channel(c)) && (strcasecmp(channel_get_name(channel),text)==0))
2144     return 0; // we don't have to do anything, we are allready in this channel
2145    
2146     if (conn_set_channel(c,text)<0)
2147     conn_set_channel(c,CHANNEL_NAME_BANNED); /* should not fail */
2148     if ((conn_get_clienttag(c) == CLIENTTAG_WARCRAFT3_UINT) || (conn_get_clienttag(c) == CLIENTTAG_WAR3XP_UINT))
2149     conn_update_w3_playerinfo(c);
2150     command_set_flags(c);
2151    
2152     return 0;
2153     }
2154    
2155     static int _handle_rejoin_command(t_connection * c, char const *text)
2156     {
2157    
2158     if (channel_rejoin(c)!=0)
2159     message_send_text(c,message_type_error,c,"You are not in a channel.");
2160     if ((conn_get_clienttag(c) == CLIENTTAG_WARCRAFT3_UINT) || (conn_get_clienttag(c) == CLIENTTAG_WAR3XP_UINT))
2161     conn_update_w3_playerinfo(c);
2162     command_set_flags(c);
2163    
2164     return 0;
2165     }
2166    
2167     static int _handle_away_command(t_connection * c, char const *text)
2168     {
2169    
2170     text = skip_command(text);
2171    
2172     if (text[0]=='\0') /* toggle away mode */
2173     {
2174     if (!conn_get_awaystr(c))
2175     {
2176     message_send_text(c,message_type_info,c,"You are now marked as being away.");
2177     conn_set_awaystr(c,"Currently not available");
2178     }
2179     else
2180     {
2181     message_send_text(c,message_type_info,c,"You are no longer marked as away.");
2182     conn_set_awaystr(c,NULL);
2183     }
2184     }
2185     else
2186     {
2187     message_send_text(c,message_type_info,c,"You are now marked as being away.");
2188     conn_set_awaystr(c,text);
2189     }
2190    
2191     return 0;
2192     }
2193    
2194     static int _handle_dnd_command(t_connection * c, char const *text)
2195     {
2196    
2197     text = skip_command(text);
2198    
2199     if (text[0]=='\0') /* toggle dnd mode */
2200     {
2201     if (!conn_get_dndstr(c))
2202     {
2203     message_send_text(c,message_type_info,c,"Do Not Diturb mode engaged.");
2204     conn_set_dndstr(c,"Not available");
2205     }
2206     else
2207     {
2208     message_send_text(c,message_type_info,c,"Do Not Disturb mode cancelled.");
2209     conn_set_dndstr(c,NULL);
2210     }
2211     }
2212     else
2213     {
2214     message_send_text(c,message_type_info,c,"Do Not Disturb mode engaged.");
2215     conn_set_dndstr(c,text);
2216     }
2217    
2218     return 0;
2219     }
2220    
2221     static int _handle_squelch_command(t_connection * c, char const *text)
2222     {
2223     t_account * account;
2224    
2225     text = skip_command(text);
2226    
2227     /* D2 puts * before username */
2228     if (text[0]=='*')
2229     text++;
2230    
2231     if (text[0]=='\0')
2232     {
2233     message_send_text(c,message_type_info,c,"usage: /squelch <username>");
2234     return 0;
2235     }
2236    
2237     if (!(account = accountlist_find_account(text)))
2238     {
2239     message_send_text(c,message_type_error,c,"No such user.");
2240     return 0;
2241     }
2242    
2243     if (conn_get_account(c)==account)
2244     {
2245     message_send_text(c,message_type_error,c,"You can't squelch yourself.");
2246     return 0;
2247     }
2248    
2249     if (conn_add_ignore(c,account)<0)
2250     message_send_text(c,message_type_error,c,"Could not squelch user.");
2251     else
2252     {
2253     sprintf(msgtemp,"%-.20s has been squelched.",account_get_name(account));
2254     message_send_text(c,message_type_info,c,msgtemp);
2255     }
2256    
2257     return 0;
2258     }
2259    
2260     static int _handle_unsquelch_command(t_connection * c, char const *text)
2261     {
2262     t_account * account;
2263     t_connection * dest_c;
2264    
2265     text = skip_command(text);
2266    
2267     /* D2 puts * before username */
2268     if (text[0]=='*')
2269     text++;
2270    
2271     if (text[0]=='\0')
2272     {
2273     message_send_text(c,message_type_info,c,"usage: /unsquelch <username>");
2274     return 0;
2275     }
2276    
2277     if (!(account = accountlist_find_account(text)))
2278     {
2279     message_send_text(c,message_type_info,c,"No such user.");
2280     return 0;
2281     }
2282    
2283     if (conn_del_ignore(c,account)<0)
2284     message_send_text(c,message_type_info,c,"User was not being ignored.");
2285     else
2286     {
2287     t_message * message;
2288    
2289     message_send_text(c,message_type_info,c,"No longer ignoring.");
2290    
2291     if ((dest_c = account_get_conn(account)))
2292     {
2293     if (!(message = message_create(message_type_userflags,dest_c,NULL,NULL))) /* handles NULL text */
2294     return 0;
2295     message_send(message,c);
2296     message_destroy(message);
2297     }
2298     }
2299    
2300     return 0;
2301     }
2302    
2303     static int _handle_kick_command(t_connection * c, char const *text)
2304     {
2305     char dest[USER_NAME_MAX];
2306     unsigned int i,j;
2307     t_channel const * channel;
2308     t_connection * kuc;
2309     t_account * acc;
2310    
2311     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
2312     for (; text[i]==' '; i++);
2313     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */
2314     if (j<sizeof(dest)-1) dest[j++] = text[i];
2315     dest[j] = '\0';
2316     for (; text[i]==' '; i++);
2317    
2318     if (dest[0]=='\0')
2319     {
2320     message_send_text(c,message_type_info,c,"usage: /kick <username>");
2321     return 0;
2322     }
2323    
2324     if (!(channel = conn_get_channel(c)))
2325     {
2326     message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
2327     return 0;
2328     }
2329    
2330     acc = conn_get_account(c);
2331     if (account_get_auth_admin(acc,NULL)!=1 && /* default to false */
2332     account_get_auth_admin(acc,channel_get_name(channel))!=1 && /* default to false */
2333     account_get_auth_operator(acc,NULL)!=1 && /* default to false */
2334     account_get_auth_operator(acc,channel_get_name(channel))!=1 && /* default to false */
2335     !channel_conn_is_tmpOP(channel,account_get_conn(acc)))
2336     {
2337     message_send_text(c,message_type_error,c,"You have to be at least a Channel Operator or tempOP to use this command.");
2338     return 0;
2339     }
2340     if (!(kuc = connlist_find_connection_by_accountname(dest)))
2341     {
2342     message_send_text(c,message_type_error,c,"That user is not logged in.");
2343     return 0;
2344     }
2345     if (conn_get_channel(kuc)!=channel)
2346     {
2347     message_send_text(c,message_type_error,c,"That user is not in this channel.");
2348     return 0;
2349     }
2350     if (account_get_auth_admin(conn_get_account(kuc),NULL)==1 ||
2351     account_get_auth_admin(conn_get_account(kuc),channel_get_name(channel))==1)
2352     {
2353     message_send_text(c,message_type_error,c,"You cannot kick administrators.");
2354     return 0;
2355     }
2356     else if (account_get_auth_operator(conn_get_account(kuc),NULL)==1 ||
2357     account_get_auth_operator(conn_get_account(kuc),channel_get_name(channel))==1)
2358     {
2359     message_send_text(c,message_type_error,c,"You cannot kick operators.");
2360     return 0;
2361     }
2362    
2363     {
2364     char const * tname1;
2365     char const * tname2;
2366    
2367     tname1 = conn_get_loggeduser(kuc);
2368     tname2 = conn_get_loggeduser(c);
2369     if (!tname1 || !tname2) {
2370     eventlog(eventlog_level_error, __FUNCTION__, "got NULL username");
2371     return -1;
2372     }
2373    
2374     if (text[i]!='\0')
2375     sprintf(msgtemp,"%-.20s has been kicked by %-.20s (%s).",tname1,tname2,&text[i]);
2376     else
2377     sprintf(msgtemp,"%-.20s has been kicked by %-.20s.",tname1,tname2);
2378     channel_message_send(channel,message_type_info,c,msgtemp);
2379     }
2380     conn_set_channel(kuc,CHANNEL_NAME_KICKED); /* should not fail */
2381    
2382     return 0;
2383     }
2384    
2385     static int _handle_ban_command(t_connection * c, char const *text)
2386     {
2387     char dest[USER_NAME_MAX];
2388     unsigned int i,j;
2389     t_channel * channel;
2390     t_connection * buc;
2391    
2392     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
2393     for (; text[i]==' '; i++);
2394     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */
2395     if (j<sizeof(dest)-1) dest[j++] = text[i];
2396     dest[j] = '\0';
2397     for (; text[i]==' '; i++);
2398    
2399     if (dest[0]=='\0')
2400     {
2401     message_send_text(c,message_type_info,c,"usage. /ban <username>");
2402     return 0;
2403     }
2404    
2405     if (!(channel = conn_get_channel(c)))
2406     {
2407     message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
2408     return 0;
2409     }
2410     if (account_get_auth_admin(conn_get_account(c),NULL)!=1 && /* default to false */
2411     account_get_auth_admin(conn_get_account(c),channel_get_name(channel))!=1 && /* default to false */
2412     account_get_auth_operator(conn_get_account(c),NULL)!=1 && /* default to false */
2413     account_get_auth_operator(conn_get_account(c),channel_get_name(channel))!=1) /* default to false */
2414     {
2415     message_send_text(c,message_type_error,c,"You have to be at least a Channel Operator to use this command.");
2416     return 0;
2417     }
2418     {
2419     t_account * account;
2420    
2421     if (!(account = accountlist_find_account(dest)))
2422     message_send_text(c,message_type_info,c,"That account doesn't currently exist, banning anyway.");
2423     else if (account_get_auth_admin(account,NULL)==1 || account_get_auth_admin(account,channel_get_name(channel))==1)
2424     {
2425     message_send_text(c,message_type_error,c,"You cannot ban administrators.");
2426     return 0;
2427     }
2428     else if (account_get_auth_operator(account,NULL)==1 ||
2429     account_get_auth_operator(account,channel_get_name(channel))==1)
2430     {
2431     message_send_text(c,message_type_error,c,"You cannot ban operators.");
2432     return 0;
2433     }
2434     }
2435    
2436     if (channel_ban_user(channel,dest)<0)
2437     {
2438     sprintf(msgtemp,"Unable to ban %-.20s.",dest);
2439     message_send_text(c,message_type_error,c,msgtemp);
2440     }
2441     else
2442     {
2443     char const * tname;
2444    
2445     tname = conn_get_loggeduser(c);
2446     if (text[i]!='\0')
2447     sprintf(msgtemp,"%-.20s has been banned by %-.20s (%s).",dest,tname?tname:"unknown",&text[i]);
2448     else
2449     sprintf(msgtemp,"%-.20s has been banned by %-.20s.",dest,tname?tname:"unknown");
2450     channel_message_send(channel,message_type_info,c,msgtemp);
2451     }
2452     if ((buc = connlist_find_connection_by_accountname(dest)) &&
2453     conn_get_channel(buc)==channel)
2454     conn_set_channel(buc,CHANNEL_NAME_BANNED);
2455    
2456     return 0;
2457     }
2458    
2459     static int _handle_unban_command(t_connection * c, char const *text)
2460     {
2461     t_channel * channel;
2462     unsigned int i;
2463    
2464     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
2465     for (; text[i]==' '; i++);
2466    
2467     if (text[i]=='\0')
2468     {
2469     message_send_text(c,message_type_info,c,"usage: /unban <username>");
2470     return 0;
2471     }
2472    
2473     if (!(channel = conn_get_channel(c)))
2474     {
2475     message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
2476     return 0;
2477     }
2478     if (account_get_auth_admin(conn_get_account(c),NULL)!=1 && /* default to false */
2479     account_get_auth_admin(conn_get_account(c),channel_get_name(channel))!=1 && /* default to false */
2480     account_get_auth_operator(conn_get_account(c),NULL)!=1 && /* default to false */
2481     account_get_auth_operator(conn_get_account(c),channel_get_name(channel))!=1) /* default to false */
2482     {
2483     message_send_text(c,message_type_error,c,"You are not a channel operator.");
2484     return 0;
2485     }
2486    
2487     if (channel_unban_user(channel,&text[i])<0)
2488     message_send_text(c,message_type_error,c,"That user is not banned.");
2489     else
2490     {
2491     sprintf(msgtemp,"%s is no longer banned from this channel.",&text[i]);
2492     message_send_text(c,message_type_info,c,msgtemp);
2493     }
2494    
2495     return 0;
2496     }
2497    
2498     static int _handle_reply_command(t_connection * c, char const *text)
2499     {
2500     unsigned int i;
2501     char const * dest;
2502    
2503     if (!(dest = conn_get_lastsender(c)))
2504     {
2505     message_send_text(c,message_type_error,c,"No one messaged you, use /m instead");
2506     return 0;
2507     }
2508    
2509     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
2510     for (; text[i]==' '; i++);
2511    
2512     if (text[i]=='\0')
2513     {
2514     message_send_text(c,message_type_info,c,"usage: /reply <replytext>");
2515     return 0;
2516     }
2517     do_whisper(c,dest,&text[i]);
2518     return 0;
2519     }
2520    
2521     static int _handle_realmann_command(t_connection * c, char const *text)
2522     {
2523     unsigned int i;
2524     t_realm * realm;
2525     t_realm * trealm;
2526     t_connection * tc;
2527     t_elem const * curr;
2528     t_message * message;
2529    
2530     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
2531     for (; text[i]==' '; i++);
2532    
2533     if (!(realm=conn_get_realm(c))) {
2534     message_send_text(c,message_type_info,c,"You must join a realm first");
2535     return 0;
2536     }
2537    
2538     if (text[i]=='\0')
2539     {
2540     message_send_text(c,message_type_info,c,"usage: /realmann <announcement text>");
2541     return 0;
2542     }
2543    
2544     sprintf(msgtemp,"Announcement from %.32s@%.32s: %.128s",conn_get_username(c),realm_get_name(realm),&text[i]);
2545     if (!(message = message_create(message_type_broadcast,c,NULL,msgtemp)))
2546     {
2547     message_send_text(c,message_type_info,c,"Could not broadcast message.");
2548     }
2549     else
2550     {
2551     LIST_TRAVERSE_CONST(connlist(),curr)
2552     {
2553     tc = elem_get_data(curr);
2554     if (!tc)
2555     continue;
2556     if ((trealm = conn_get_realm(tc)) && (trealm==realm))
2557     {
2558     message_send(message,tc);
2559     }
2560     }
2561     }
2562     return 0;
2563     }
2564    
2565     static int _handle_watch_command(t_connection * c, char const *text)
2566     {
2567     unsigned int i;
2568     t_account * account;
2569    
2570     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
2571     for (; text[i]==' '; i++);
2572    
2573     if (text[i]=='\0')
2574     {
2575     message_send_text(c,message_type_info,c,"usage: /watch <username>");
2576     return 0;
2577     }
2578     if (!(account = accountlist_find_account(&text[i])))
2579     {
2580     message_send_text(c,message_type_info,c,"That user does not exist.");
2581     return 0;
2582     }
2583    
2584     if (conn_add_watch(c,account,0)<0) /* FIXME: adds all events for now */
2585     message_send_text(c,message_type_error,c,"Add to watch list failed.");
2586     else
2587     {
2588     sprintf(msgtemp,"User %.64s added to your watch list.",&text[i]);
2589     message_send_text(c,message_type_info,c,msgtemp);
2590     }
2591    
2592     return 0;
2593     }
2594    
2595     static int _handle_unwatch_command(t_connection * c, char const *text)
2596     {
2597     unsigned int i;
2598     t_account * account;
2599    
2600     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
2601     for (; text[i]==' '; i++);
2602    
2603     if (text[i]=='\0')
2604     {
2605     message_send_text(c,message_type_info,c,"usage: /unwatch <username>");
2606     return 0;
2607     }
2608     if (!(account = accountlist_find_account(&text[i])))
2609     {
2610     message_send_text(c,message_type_info,c,"That user does not exist.");
2611     return 0;
2612     }
2613    
2614     if (conn_del_watch(c,account,0)<0) /* FIXME: deletes all events for now */
2615     message_send_text(c,message_type_error,c,"Removal from watch list failed.");
2616     else
2617     {
2618     sprintf(msgtemp,"User %.64s removed from your watch list.",&text[i]);
2619     message_send_text(c,message_type_info,c,msgtemp);
2620     }
2621    
2622     return 0;
2623     }
2624    
2625     static int _handle_watchall_command(t_connection * c, char const *text)
2626     {
2627     t_clienttag clienttag=0;
2628     char clienttag_str[5];
2629    
2630     text = skip_command(text);
2631    
2632     if(text[0] != '\0') {
2633     if (strlen(text) != 4) {
2634     message_send_text(c,message_type_error,c,"You must supply a rank and a valid program ID.");
2635     message_send_text(c,message_type_error,c,"Example: /watchall STAR");
2636     return 0;
2637     }
2638     clienttag = tag_case_str_to_uint(text);
2639     }
2640    
2641     if (conn_add_watch(c,NULL,clienttag)<0) /* FIXME: adds all events for now */
2642     message_send_text(c,message_type_error,c,"Add to watch list failed.");
2643     else
2644     if(clienttag) {
2645     char msgtemp[MAX_MESSAGE_LEN];
2646     sprintf(msgtemp, "All %s users added to your watch list.", tag_uint_to_str(clienttag_str,clienttag));
2647     message_send_text(c,message_type_info,c,msgtemp);
2648     }
2649     else
2650     message_send_text(c,message_type_info,c,"All users added to your watch list.");
2651    
2652     return 0;
2653     }
2654    
2655     static int _handle_unwatchall_command(t_connection * c, char const *text)
2656     {
2657     t_clienttag clienttag=0;
2658     char clienttag_str[5];
2659    
2660     text = skip_command(text);
2661    
2662     if(text[0] != '\0') {
2663     if (strlen(text) != 4) {
2664     message_send_text(c,message_type_error,c,"You must supply a rank and a valid program ID.");
2665     message_send_text(c,message_type_error,c,"Example: /unwatchall STAR");
2666     }
2667     clienttag = tag_case_str_to_uint(text);
2668     }
2669    
2670     if (conn_del_watch(c,NULL,clienttag)<0) /* FIXME: deletes all events for now */
2671     message_send_text(c,message_type_error,c,"Removal from watch list failed.");
2672     else
2673     if(clienttag) {
2674     char msgtemp[MAX_MESSAGE_LEN];
2675     sprintf(msgtemp, "All %s users removed from your watch list.", tag_uint_to_str(clienttag_str,clienttag));
2676     message_send_text(c,message_type_info,c,msgtemp);
2677     }
2678     else
2679     message_send_text(c,message_type_info,c,"All users removed from your watch list.");
2680    
2681     return 0;
2682     }
2683    
2684     static int _handle_lusers_command(t_connection * c, char const *text)
2685     {
2686     t_channel * channel;
2687     t_elem const * curr;
2688     char const * banned;
2689     unsigned int i;
2690    
2691     if (!(channel = conn_get_channel(c)))
2692     {
2693     message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
2694     return 0;
2695     }
2696    
2697     strcpy(msgtemp,"Banned users:");
2698     i = strlen(msgtemp);
2699     LIST_TRAVERSE_CONST(channel_get_banlist(channel),curr)
2700     {
2701     banned = elem_get_data(curr);
2702     if (i+strlen(banned)+2>sizeof(msgtemp)) /* " ", name, '\0' */
2703     {
2704     message_send_text(c,message_type_info,c,msgtemp);
2705     i = 0;
2706     }
2707     sprintf(&msgtemp[i]," %s",banned);
2708     i += strlen(&msgtemp[i]);
2709     }
2710     if (i>0)
2711     message_send_text(c,message_type_info,c,msgtemp);
2712    
2713     return 0;
2714     }
2715    
2716     static int _news_cb(time_t date, t_lstr *lstr, void *data)
2717     {
2718     char strdate[64];
2719     struct tm *tm;
2720     char save, *p, *q;
2721     t_connection *c = (t_connection*)data;
2722    
2723     tm = localtime(&date);
2724     if (tm) strftime(strdate, 64,"%B %d, %Y", tm);
2725     else strcpy(strdate, "(invalid date)");
2726     message_send_text(c,message_type_info,c,strdate);
2727    
2728     for (p = lstr_get_str(lstr); *p;) {
2729     for(q = p + 1; *q && *q != '\r' && *q != '\n';q++);
2730     save = *q;
2731     *q = '\0';
2732     message_send_text(c,message_type_info,c,p);
2733     *q = save;
2734     p = q;
2735     for(;*p == '\n' || *p == '\r';p++);
2736     }
2737    
2738     return 0;
2739     }
2740    
2741     static int _handle_news_command(t_connection * c, char const *text)
2742     {
2743     news_traverse(_news_cb,c);
2744     return 0;
2745     }
2746    
2747     struct glist_cb_struct {
2748     t_game_difficulty diff;
2749     t_clienttag tag;
2750     t_connection *c;
2751     };
2752    
2753     static int _glist_cb(t_game *game, void *data)
2754     {
2755     struct glist_cb_struct *cbdata = (struct glist_cb_struct*)data;
2756    
2757 sysadm 1.2 // Skip void game
2758     if (game_get_ref(game) == 0)
2759     return 0;
2760    
2761 sysadm 1.1 if ((!cbdata->tag || !prefs_get_hide_pass_games() || game_get_flag(game) != game_flag_private) &&
2762     (!cbdata->tag || game_get_clienttag(game)==cbdata->tag) &&
2763     (cbdata->diff==game_difficulty_none || game_get_difficulty(game)==cbdata->diff))
2764     {
2765     sprintf(msgtemp," %-16.16s %1.1s %-8.8s %-21.21s %5u ",
2766     game_get_name(game),
2767     game_get_flag(game) != game_flag_private ? "n":"y",
2768     game_status_get_str(game_get_status(game)),
2769     game_type_get_str(game_get_type(game)),
2770     game_get_ref(game));
2771    
2772     if (!cbdata->tag)
2773     {
2774    
2775     strcat(msgtemp,clienttag_uint_to_str(game_get_clienttag(game)));
2776     strcat(msgtemp," ");
2777     }
2778    
2779     if ((!prefs_get_hide_addr()) || (account_get_command_groups(conn_get_account(cbdata->c)) & command_get_group("/admin-addr"))) /* default to false */
2780     strcat(msgtemp, addr_num_to_addr_str(game_get_addr(game),game_get_port(game)));
2781    
2782     message_send_text(cbdata->c,message_type_info,cbdata->c,msgtemp);
2783     }
2784    
2785     return 0;
2786     }
2787    
2788     static int _handle_games_command(t_connection * c, char const *text)
2789     {
2790     unsigned int i;
2791     unsigned int j;
2792     char clienttag_str[5];
2793     char dest[5];
2794     struct glist_cb_struct cbdata;
2795    
2796     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
2797     for (; text[i]==' '; i++);
2798     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */
2799     if (j<sizeof(dest)-1) dest[j++] = text[i];
2800     dest[j] = '\0';
2801     for (; text[i]==' '; i++);
2802    
2803     cbdata.c = c;
2804    
2805     if(strcmp(&text[i],"norm")==0)
2806     cbdata.diff = game_difficulty_normal;
2807     else if(strcmp(&text[i],"night")==0)
2808     cbdata.diff = game_difficulty_nightmare;
2809     else if(strcmp(&text[i],"hell")==0)
2810     cbdata.diff = game_difficulty_hell;
2811     else
2812     cbdata.diff = game_difficulty_none;
2813    
2814     if (dest[0]=='\0')
2815     {
2816     cbdata.tag = conn_get_clienttag(c);
2817     message_send_text(c,message_type_info,c,"Currently accessable games:");
2818     }
2819     else if (strcasecmp(&dest[0],"all")==0)
2820     {
2821     cbdata.tag = 0;
2822     message_send_text(c,message_type_info,c,"All current games:");
2823     }
2824     else
2825     {
2826     cbdata.tag = tag_case_str_to_uint(&dest[0]);
2827    
2828     if (!tag_check_client(cbdata.tag))
2829     {
2830     message_send_text(c,message_type_error,c,"No valid clienttag specified.");
2831     return -1;
2832     }
2833    
2834     if(cbdata.diff==game_difficulty_none)
2835     sprintf(msgtemp,"Current games of type %s",tag_uint_to_str(clienttag_str,cbdata.tag));
2836     else
2837     sprintf(msgtemp,"Current games of type %s %s",tag_uint_to_str(clienttag_str,cbdata.tag),&text[i]);
2838     message_send_text(c,message_type_info,c,msgtemp);
2839     }
2840    
2841     sprintf(msgtemp," ------name------ p -status- --------type--------- count ");
2842     if (!cbdata.tag)
2843     strcat(msgtemp,"ctag ");
2844     if ((!prefs_get_hide_addr()) || (account_get_command_groups(conn_get_account(c)) & command_get_group("/admin-addr"))) /* default to false */
2845     strcat(msgtemp,"--------addr--------");
2846     message_send_text(c,message_type_info,c,msgtemp);
2847     gamelist_traverse(_glist_cb,&cbdata);
2848    
2849     return 0;
2850     }
2851    
2852     static int _handle_channels_command(t_connection * c, char const *text)
2853     {
2854     unsigned int i;
2855     t_elem const * curr;
2856     t_channel const * channel;
2857     char const * tag;
2858     t_connection const * conn;
2859     t_account * acc;
2860     char const * name;
2861     int first;
2862    
2863    
2864     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
2865     for (; text[i]==' '; i++);
2866    
2867     if (text[i]=='\0')
2868     {
2869     tag = clienttag_uint_to_str(conn_get_clienttag(c));
2870     message_send_text(c,message_type_info,c,"Currently accessable channels:");
2871     }
2872     else if (strcmp(&text[i],"all")==0)
2873     {
2874     tag = NULL;
2875     message_send_text(c,message_type_info,c,"All current channels:");
2876     }
2877     else
2878     {
2879     tag = &text[i];
2880     sprintf(msgtemp,"Current channels of type %s",tag);
2881     message_send_text(c,message_type_info,c,msgtemp);
2882     }
2883    
2884     sprintf(msgtemp," -----------name----------- users ----admin/operator----");
2885     message_send_text(c,message_type_info,c,msgtemp);
2886     LIST_TRAVERSE_CONST(channellist(),curr)
2887     {
2888     channel = elem_get_data(curr);
2889     if ((!(channel_get_flags(channel) & channel_flags_clan)) && (!tag || !prefs_get_hide_temp_channels() || channel_get_permanent(channel)) &&
2890     (!tag || !channel_get_clienttag(channel) ||
2891     strcasecmp(channel_get_clienttag(channel),tag)==0) &&
2892     ((channel_get_max(channel)!=0) || //only show restricted channels to OPs and Admins
2893     ((channel_get_max(channel)==0 && account_is_operator_or_admin(conn_get_account(c),NULL)))) &&
2894     (!(channel_get_flags(channel) & channel_flags_thevoid)) // don't list TheVoid
2895     )
2896     {
2897    
2898     sprintf(msgtemp," %-26.26s %5u - ",
2899     channel_get_name(channel),
2900     channel_get_length(channel));
2901    
2902     first = 1;
2903    
2904     for (conn = channel_get_first(channel);conn;conn=channel_get_next())
2905     {
2906     acc = conn_get_account(conn);
2907     if (account_is_operator_or_admin(acc,channel_get_name(channel)) ||
2908     channel_conn_is_tmpOP(channel,account_get_conn(acc)))
2909     {
2910     name = conn_get_loggeduser(conn);
2911     if (strlen(msgtemp) + strlen(name) +6 >= MAX_MESSAGE_LEN) break;
2912     if (!first) strcat(msgtemp," ,");
2913     strcat(msgtemp,name);
2914     if (account_get_auth_admin(acc,NULL)==1) strcat(msgtemp,"(A)");
2915     else if (account_get_auth_operator(acc,NULL)==1) strcat(msgtemp,"(O)");
2916     else if (account_get_auth_admin(acc,channel_get_name(channel))==1) strcat(msgtemp,"(a)");
2917     else if (account_get_auth_operator(acc,channel_get_name(channel))==1) strcat(msgtemp,"(o)");
2918     first = 0;
2919     }
2920     }
2921    
2922     message_send_text(c,message_type_info,c,msgtemp);
2923     }
2924     }
2925    
2926     return 0;
2927     }
2928    
2929     static int _handle_addacct_command(t_connection * c, char const *text)
2930     {
2931     unsigned int i,j;
2932     t_account * temp;
2933     t_hash passhash;
2934     char username[USER_NAME_MAX];
2935     char pass[256];
2936    
2937     for (i=0; text[i]!=' ' && text[i]!='\0'; i++);
2938     for (; text[i]==' '; i++);
2939    
2940     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get username */
2941     if (j<sizeof(username)-1) username[j++] = text[i];
2942     username[j] = '\0';
2943    
2944     for (; text[i]==' '; i++); /* skip spaces */
2945     for (j=0; text[i]!='\0'; i++) /* get pass (spaces are allowed) */
2946     if (j<sizeof(pass)-1) pass[j++] = text[i];
2947     pass[j] = '\0';
2948    
2949     if (username[0]=='\0' || pass[0]=='\0') {
2950     message_send_text(c,message_type_info,c,"usage: /addacct <username> <password>");
2951     return 0;
2952     }
2953    
2954     if (account_check_name(username)<0) {
2955     message_send_text(c,message_type_error,c,"Account name contains some invalid symbol!");
2956     return 0;
2957     }
2958    
2959     /* FIXME: truncate or err on too long password */
2960     for (i=0; i<strlen(pass); i++)
2961     if (isupper((int)pass[i])) pass[i] = tolower((int)pass[i]);
2962    
2963     bnet_hash(&passhash,strlen(pass),pass);
2964    
2965     sprintf(msgtemp,"Trying to add account \"%s\" with password \"%s\"",username,pass);
2966     message_send_text(c,message_type_info,c,msgtemp);
2967    
2968     sprintf(msgtemp,"Hash is: %s",hash_get_str(passhash));
2969     message_send_text(c,message_type_info,c,msgtemp);
2970    
2971     temp = accountlist_create_account(username,hash_get_str(passhash));
2972     if (!temp) {
2973     message_send_text(c,message_type_error,c,"Failed to create account!");
2974     eventlog(eventlog_level_debug,__FUNCTION__,"[%d] account \"%s\" not created (failed)",conn_get_socket(c),username);
2975     return 0;
2976     }
2977    
2978     sprintf(msgtemp,"Account "UID_FORMAT" created.",account_get_uid(temp));
2979     message_send_text(c,message_type_info,c,msgtemp);
2980     eventlog(eventlog_level_debug,__FUNCTION__,"[%d] account \"%s\" created",conn_get_socket(c),username);
2981    
2982     return 0;
2983     }
2984    
2985     static int _handle_chpass_command(t_connection * c, char const *text)
2986     {
2987     unsigned int i,j;
2988     t_account * account;
2989     t_account * temp;
2990     t_hash passhash;
2991     char arg1[256];
2992     char arg2[256];
2993     char const * username;
2994     char * pass;
2995    
2996     for (i=0; text[i]!=' ' && text[i]!='\0'; i++);
2997     for (; text[i]==' '; i++);
2998    
2999     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get username/pass */
3000     if (j<sizeof(arg1)-1) arg1[j++] = text[i];
3001     arg1[j] = '\0';
3002    
3003     for (; text[i]==' '; i++); /* skip spaces */
3004     for (j=0; text[i]!='\0'; i++) /* get pass (spaces are allowed) */
3005     if (j<sizeof(arg2)-1) arg2[j++] = text[i];
3006     arg2[j] = '\0';
3007    
3008     if (arg2[0]=='\0')
3009     {
3010     username = conn_get_username(c);
3011     pass = arg1;
3012     }
3013     else
3014     {
3015     username = arg1;
3016     pass = arg2;
3017     }
3018    
3019     if (pass[0]=='\0')
3020     {
3021     message_send_text(c,message_type_info,c,"usage: /chpass [username] <password>");
3022     return 0;
3023     }
3024    
3025     temp = accountlist_find_account(username);
3026    
3027     account = conn_get_account(c);
3028    
3029     if ((temp==account && account_get_auth_changepass(account)==0) || /* default to true */
3030     (temp!=account && !(account_get_command_groups(conn_get_account(c)) & command_get_group("/admin-chpass")))) /* default to false */
3031     {
3032     eventlog(eventlog_level_info,__FUNCTION__,"[%d] password change for \"%s\" refused (no change access)",conn_get_socket(c),username);
3033     message_send_text(c,message_type_error,c,"Only admins may change passwords for other accounts.");
3034     return 0;
3035     }
3036    
3037     if (!temp)
3038     {
3039     message_send_text(c,message_type_error,c,"Account does not exist.");
3040     return 0;
3041     }
3042    
3043     if (strlen(pass) > USER_PASS_MAX)
3044     {
3045     sprintf(msgtemp,"Maximum password length allowed is %d",USER_PASS_MAX);
3046     message_send_text(c,message_type_error,c,msgtemp);
3047     return 0;
3048     }
3049    
3050     for (i=0; i<strlen(pass); i++)
3051     if (isupper((int)pass[i])) pass[i] = tolower((int)pass[i]);
3052    
3053     bnet_hash(&passhash,strlen(pass),pass);
3054    
3055     sprintf(msgtemp,"Trying to change password for account \"%s\" to \"%s\"",username,pass);
3056     message_send_text(c,message_type_info,c,msgtemp);
3057    
3058     if (account_set_pass(temp,hash_get_str(passhash))<0)
3059     {
3060     message_send_text(c,message_type_error,c,"Unable to set password.");
3061     return 0;
3062     }
3063    
3064     if (account_get_auth_admin(account,NULL) == 1 ||
3065     account_get_auth_operator(account,NULL) == 1) {
3066     sprintf(msgtemp,
3067     "Password for account "UID_FORMAT" updated.",account_get_uid(temp));
3068     message_send_text(c,message_type_info,c,msgtemp);
3069    
3070     sprintf(msgtemp,"Hash is: %s",hash_get_str(passhash));
3071     message_send_text(c,message_type_info,c,msgtemp);
3072     } else {
3073     sprintf(msgtemp,
3074     "Password for account %s updated.",username);
3075     message_send_text(c,message_type_info,c,msgtemp);
3076     }
3077    
3078     return 0;
3079     }
3080    
3081     static int _handle_connections_command(t_connection *c, char const *text)
3082     {
3083     t_elem const * curr;
3084     t_connection * conn;
3085     char name[19];
3086     unsigned int i; /* for loop */
3087     char const * channel_name;
3088     char const * game_name;
3089     char clienttag_str[5];
3090    
3091     if (!prefs_get_enable_conn_all() && !(account_get_command_groups(conn_get_account(c)) & command_get_group("/admin-con"))) /* default to false */
3092     {
3093     message_send_text(c,message_type_error,c,"This command is only enabled for admins.");
3094     return 0;
3095     }
3096    
3097     message_send_text(c,message_type_info,c,"Current connections:");
3098     /* addon */
3099     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
3100     for (; text[i]==' '; i++);
3101    
3102     if (text[i]=='\0')
3103     {
3104     sprintf(msgtemp," -class -tag -----name------ -lat(ms)- ----channel---- --game--");
3105     message_send_text(c,message_type_info,c,msgtemp);
3106     }
3107     else
3108     if (strcmp(&text[i],"all")==0) /* print extended info */
3109     {
3110     if (prefs_get_hide_addr() && !(account_get_command_groups(conn_get_account(c)) & command_get_group("/admin-addr")))
3111     sprintf(msgtemp," -#- -class ----state--- -tag -----name------ -session-- -flag- -lat(ms)- ----channel---- --game--");
3112     else
3113     sprintf(msgtemp," -#- -class ----state--- -tag -----name------ -session-- -flag- -lat(ms)- ----channel---- --game-- ---------addr--------");
3114     message_send_text(c,message_type_info,c,msgtemp);
3115     }
3116     else
3117     {
3118     message_send_text(c,message_type_error,c,"Unknown option.");
3119     return 0;
3120     }
3121    
3122     LIST_TRAVERSE_CONST(connlist(),curr)
3123     {
3124     conn = elem_get_data(curr);
3125     if (conn_get_account(conn))
3126     sprintf(name,"\"%.16s\"",conn_get_username(conn));
3127     else
3128     strcpy(name,"(none)");
3129    
3130     if (conn_get_channel(conn)!=NULL)
3131     channel_name = channel_get_name(conn_get_channel(conn));
3132     else channel_name = "none";
3133     if (conn_get_game(conn)!=NULL)
3134     game_name = game_get_name(conn_get_game(conn));
3135     else game_name = "none";
3136    
3137     if (text[i]=='\0')
3138     sprintf(msgtemp," %-6.6s %4.4s %-15.15s %9u %-16.16s %-8.8s",
3139     conn_class_get_str(conn_get_class(conn)),
3140     tag_uint_to_str(clienttag_str,conn_get_fake_clienttag(conn)),
3141     name,
3142     conn_get_latency(conn),
3143     channel_name,
3144     game_name);
3145     else
3146     if (prefs_get_hide_addr() && !(account_get_command_groups(conn_get_account(c)) & command_get_group("/admin-addr"))) /* default to false */
3147     sprintf(msgtemp," %3d %-6.6s %-12.12s %4.4s %-15.15s 0x%08x 0x%04x %9u %-16.16s %-8.8s",
3148     conn_get_socket(conn),
3149     conn_class_get_str(conn_get_class(conn)),
3150     conn_state_get_str(conn_get_state(conn)),
3151     tag_uint_to_str(clienttag_str,conn_get_fake_clienttag(conn)),
3152     name,
3153     conn_get_sessionkey(conn),
3154     conn_get_flags(conn),
3155     conn_get_latency(conn),
3156     channel_name,
3157     game_name);
3158     else
3159     sprintf(msgtemp," %3u %-6.6s %-12.12s %4.4s %-15.15s 0x%08x 0x%04x %9u %-16.16s %-8.8s %s",
3160     conn_get_socket(conn),
3161     conn_class_get_str(conn_get_class(conn)),
3162     conn_state_get_str(conn_get_state(conn)),
3163     tag_uint_to_str(clienttag_str,conn_get_fake_clienttag(conn)),
3164     name,
3165     conn_get_sessionkey(conn),
3166     conn_get_flags(conn),
3167     conn_get_latency(conn),
3168     channel_name,
3169     game_name,
3170     addr_num_to_addr_str(conn_get_addr(conn),conn_get_port(conn)));
3171    
3172     message_send_text(c,message_type_info,c,msgtemp);
3173     }
3174    
3175     return 0;
3176     }
3177    
3178     static int _handle_finger_command(t_connection * c, char const *text)
3179     {
3180     char dest[USER_NAME_MAX];
3181     unsigned int i,j;
3182     t_account * account;
3183     t_connection * conn;
3184     char const * ip;
3185     char * tok;
3186     t_clanmember * clanmemb;
3187    
3188     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
3189     for (; text[i]==' '; i++);
3190     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */
3191     if (j<sizeof(dest)-1) dest[j++] = text[i];
3192     dest[j] = '\0';
3193     for (; text[i]==' '; i++);
3194    
3195     if (dest[0]=='\0')
3196     {
3197     message_send_text(c,message_type_info,c,"usage: /finger <account>");
3198     return 0;
3199     }
3200    
3201     if (!(account = accountlist_find_account(dest)))
3202     {
3203     message_send_text(c,message_type_error,c,"Invalid user.");
3204     return 0;
3205     }
3206     sprintf(msgtemp,"Login: %-16.16s "UID_FORMAT" Sex: %.14s",
3207     account_get_name(account),
3208     account_get_uid(account),
3209     account_get_sex(account));
3210     message_send_text(c,message_type_info,c,msgtemp);
3211    
3212     if ((clanmemb = account_get_clanmember(account)))
3213     {
3214     t_clan * clan;
3215     char status;
3216    
3217     if ((clan = clanmember_get_clan(clanmemb)))
3218     {
3219     sprintf(msgtemp,"Clan : %-64.64s",clan_get_name(clan));
3220     if ((status = clanmember_get_status(clanmemb)))
3221     {
3222     switch (status)
3223     {
3224     case CLAN_CHIEFTAIN:
3225     strcat(msgtemp," Rank: Chieftain");
3226     break;
3227     case CLAN_SHAMAN:
3228     strcat(msgtemp," Rank: Shaman");
3229     break;
3230     case CLAN_GRUNT:
3231     strcat(msgtemp," Rank: Grunt");
3232     break;
3233     case CLAN_PEON:
3234     strcat(msgtemp," Rank: Peon");
3235     break;
3236     default:;
3237     }
3238     }
3239     message_send_text(c,message_type_info,c,msgtemp);
3240    
3241     }
3242     }
3243    
3244     sprintf(msgtemp,"Location: %-23.23s Age: %.14s",
3245     account_get_loc(account),
3246     account_get_age(account));
3247     message_send_text(c,message_type_info,c,msgtemp);
3248    
3249     if((conn = connlist_find_connection_by_accountname(dest)))
3250     {
3251     sprintf(msgtemp,"Client: %s Ver: %s Country: %s",
3252     clienttag_get_title(conn_get_clienttag(conn)),
3253     conn_get_clientver(conn),
3254     conn_get_country(conn));
3255     message_send_text(c,message_type_info,c,msgtemp);
3256     }
3257    
3258     if (!(ip=account_get_ll_ip(account)) ||
3259     !(account_get_command_groups(conn_get_account(c)) & command_get_group("/admin-addr"))) /* default to false */
3260     ip = "unknown";
3261    
3262     {
3263     time_t then;
3264     struct tm * tmthen;
3265    
3266     then = account_get_ll_time(account);
3267     tmthen = localtime(&then); /* FIXME: determine user's timezone */
3268     if (!(conn))
3269     if (tmthen)
3270     strftime(msgtemp,sizeof(msgtemp),"Last login %a %b %d %H:%M %Y from ",tmthen);
3271     else
3272     strcpy(msgtemp,"Last login ? from ");
3273     else
3274     if (tmthen)
3275     strftime(msgtemp,sizeof(msgtemp),"On since %a %b %d %H:%M %Y from ",tmthen);
3276     else
3277     strcpy(msgtemp,"On since ? from ");
3278     }
3279     strncat(msgtemp,ip,32);
3280     message_send_text(c,message_type_info,c,msgtemp);
3281    
3282     if (conn)
3283     {
3284     sprintf(msgtemp,"Idle %s",seconds_to_timestr(conn_get_idletime(conn)));
3285     message_send_text(c,message_type_info,c,msgtemp);
3286     }
3287    
3288     strncpy(msgtemp,account_get_desc(account),sizeof(msgtemp));
3289     msgtemp[sizeof(msgtemp)-1] = '\0';
3290     for (tok=strtok(msgtemp,"\r\n"); tok; tok=strtok(NULL,"\r\n"))
3291     message_send_text(c,message_type_info,c,tok);
3292     message_send_text(c,message_type_info,c,"");
3293    
3294     return 0;
3295     }
3296    
3297     /*
3298     * rewrote command /operator to add and remove operator status [Omega]
3299     *
3300     * Fixme: rewrite /operators to show Currently logged on Server and/or Channel operators ...??
3301     */
3302     /*
3303     static int _handle_operator_command(t_connection * c, char const *text)
3304     {
3305     t_connection const * opr;
3306     t_channel const * channel;
3307    
3308     if (!(channel = conn_get_channel(c)))
3309     {
3310     message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
3311     return 0;
3312     }
3313    
3314     if (!(opr = channel_get_operator(channel)))
3315     strcpy(msgtemp,"There is no operator.");
3316     else
3317     sprintf(msgtemp,"%.64s is the operator.",conn_get_username(opr));
3318     message_send_text(c,message_type_info,c,msgtemp);
3319     return 0;
3320     }
3321     */
3322    
3323     /* FIXME: do we want to show just Server Admin or Channel Admin Also? [Omega] */
3324     static int _handle_admins_command(t_connection * c, char const *text)
3325     {
3326     unsigned int i;
3327     t_elem const * curr;
3328     t_connection * tc;
3329     char const * nick;
3330    
3331     strcpy(msgtemp,"Currently logged on Administrators:");
3332     i = strlen(msgtemp);
3333     LIST_TRAVERSE_CONST(connlist(),curr)
3334     {
3335     tc = elem_get_data(curr);
3336     if (!tc)
3337     continue;
3338     if (!conn_get_account(tc))
3339     continue;
3340     if (account_get_auth_admin(conn_get_account(tc),NULL)==1)
3341     {
3342     if ((nick = conn_get_username(tc)))
3343     {
3344     if (i+strlen(nick)+2>sizeof(msgtemp)) /* " ", name, '\0' */
3345     {
3346     message_send_text(c,message_type_info,c,msgtemp);
3347     i = 0;
3348     }
3349     sprintf(&msgtemp[i]," %s", nick);
3350     i += strlen(&msgtemp[i]);
3351     }
3352     }
3353     }
3354     if (i>0)
3355     message_send_text(c,message_type_info,c,msgtemp);
3356    
3357     return 0;
3358     }
3359    
3360     static int _handle_quit_command(t_connection * c, char const *text)
3361     {
3362     if (conn_get_game(c))
3363     eventlog(eventlog_level_warn, __FUNCTION__,"[%d] user '%d' tried to disconnect while in game, cheat attempt ?", conn_get_socket(c), conn_get_loggeduser(c));
3364     else {
3365     message_send_text(c,message_type_info,c,"Connection closed.");
3366     conn_set_state(c,conn_state_destroy);
3367     }
3368    
3369     return 0;
3370     }
3371    
3372     static int _handle_kill_command(t_connection * c, char const *text)
3373     {
3374     unsigned int i,j;
3375     t_connection * user;
3376     char usrnick[USER_NAME_MAX]; /* max length of nick + \0 */ /* FIXME: Is it somewhere defined? */
3377    
3378     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
3379     for (; text[i]==' '; i++);
3380     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get nick */
3381     if (j<sizeof(usrnick)-1) usrnick[j++] = text[i];
3382     usrnick[j]='\0';
3383     for (; text[i]==' '; i++);
3384    
3385     if (usrnick[0]=='\0' || (usrnick[0]=='#' && (usrnick[1] < '0' || usrnick[1] > '9')))
3386     {
3387     message_send_text(c,message_type_info,c,"usage: /kill {<username>|#<socket>} [<min>]");
3388     return 0;
3389     }
3390    
3391     if (usrnick[0] == '#') {
3392     if (!(user = connlist_find_connection_by_socket(atoi(usrnick + 1)))) {
3393     message_send_text(c,message_type_error,c,"That connection doesnt exist.");
3394     return 0;
3395     }
3396     } else {
3397     if (!(user = connlist_find_connection_by_accountname(usrnick))) {
3398     message_send_text(c,message_type_error,c,"That user is not logged in?");
3399     return 0;
3400     }
3401     }
3402    
3403     if (text[i]!='\0' && ipbanlist_add(c,addr_num_to_ip_str(conn_get_addr(user)),ipbanlist_str_to_time_t(c,&text[i]))==0)
3404     {
3405     ipbanlist_save(prefs_get_ipbanfile());
3406     message_send_text(user,message_type_info,user,"Connection closed by admin and banned your ip.");
3407     }
3408     else
3409     message_send_text(user,message_type_info,user,"Connection closed by admin.");
3410     conn_set_state(user,conn_state_destroy);
3411    
3412     return 0;
3413     }
3414    
3415     static int _handle_killsession_command(t_connection * c, char const *text)
3416     {
3417     unsigned int i,j;
3418     t_connection * user;
3419     char session[16];
3420    
3421     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
3422     for (; text[i]==' '; i++);
3423     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get nick */
3424     if (j<sizeof(session)-1) session[j++] = text[i];
3425     session[j]='\0';
3426     for (; text[i]==' '; i++);
3427    
3428     if (session[0]=='\0')
3429     {
3430     message_send_text(c,message_type_info,c,"usage: /killsession <session> [min]");
3431     return 0;
3432     }
3433     if (!isxdigit((int)session[0]))
3434     {
3435     message_send_text(c,message_type_error,c,"That is not a valid session.");
3436     return 0;
3437     }
3438     if (!(user = connlist_find_connection_by_sessionkey((unsigned int)strtoul(session,NULL,16))))
3439     {
3440     message_send_text(c,message_type_error,c,"That session does not exist.");
3441     return 0;
3442     }
3443     if (text[i]!='\0' && ipbanlist_add(c,addr_num_to_ip_str(conn_get_addr(user)),ipbanlist_str_to_time_t(c,&text[i]))==0)
3444     {
3445     ipbanlist_save(prefs_get_ipbanfile());
3446     message_send_text(user,message_type_info,user,"Connection closed by admin and banned your ip's.");
3447     }
3448     else
3449     message_send_text(user,message_type_info,user,"Connection closed by admin.");
3450     conn_set_state(user,conn_state_destroy);
3451     return 0;
3452     }
3453    
3454     static int _handle_gameinfo_command(t_connection * c, char const *text)
3455     {
3456     unsigned int i;
3457     t_game const * game;
3458     char clienttag_str[5];
3459    
3460     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
3461     for (; text[i]==' '; i++);
3462    
3463     if (text[i]=='\0')
3464     {
3465     if (!(game = conn_get_game(c)))
3466     {
3467     message_send_text(c,message_type_error,c,"You are not in a game.");
3468     return 0;
3469     }
3470     }
3471     else
3472     if (!(game = gamelist_find_game(&text[i],game_type_all)))
3473     {
3474     message_send_text(c,message_type_error,c,"That game does not exist.");
3475     return 0;
3476     }
3477    
3478     sprintf(msgtemp,"Name: %-20.20s ID: "GAMEID_FORMAT" (%s)",game_get_name(game),game_get_id(game),game_get_flag(game) != game_flag_private ? "public":"private");
3479     message_send_text(c,message_type_info,c,msgtemp);
3480    
3481     {
3482     t_account * owner;
3483     char const * tname;
3484     char const * namestr;
3485    
3486     if (!(owner = conn_get_account(game_get_owner(game))))
3487     {
3488     tname = NULL;
3489     namestr = "none";
3490     }
3491     else
3492     if (!(tname = conn_get_loggeduser(game_get_owner(game))))
3493     namestr = "unknown";
3494     else
3495     namestr = tname;
3496    
3497     sprintf(msgtemp,"Owner: %-20.20s",namestr);
3498    
3499     }
3500     message_send_text(c,message_type_info,c,msgtemp);
3501    
3502     if (!prefs_get_hide_addr() || (account_get_command_groups(conn_get_account(c)) & command_get_group("/admin-addr"))) /* default to false */
3503     {
3504     unsigned int addr;
3505     unsigned short port;
3506     unsigned int taddr;
3507     unsigned short tport;
3508    
3509     taddr=addr = game_get_addr(game);
3510     tport=port = game_get_port(game);
3511     trans_net(conn_get_addr(c),&taddr,&tport);
3512    
3513     if (taddr==addr && tport==port)
3514     sprintf(msgtemp,"Address: %s",
3515     addr_num_to_addr_str(addr,port));
3516     else
3517     sprintf(msgtemp,"Address: %s (trans %s)",
3518     addr_num_to_addr_str(addr,port),
3519     addr_num_to_addr_str(taddr,tport));
3520     message_send_text(c,message_type_info,c,msgtemp);
3521     }
3522    
3523     sprintf(msgtemp,"Client: %4s (version %s, startver %u)",tag_uint_to_str(clienttag_str,game_get_clienttag(game)),vernum_to_verstr(game_get_version(game)),game_get_startver(game));
3524     message_send_text(c,message_type_info,c,msgtemp);
3525    
3526     {
3527     time_t gametime;
3528     struct tm * gmgametime;
3529    
3530     gametime = game_get_create_time(game);
3531     if (!(gmgametime = localtime(&gametime)))
3532     strcpy(msgtemp,"Created: ?");
3533     else
3534     strftime(msgtemp,sizeof(msgtemp),"Created: "GAME_TIME_FORMAT,gmgametime);
3535     message_send_text(c,message_type_info,c,msgtemp);
3536    
3537     gametime = game_get_start_time(game);
3538     if (gametime!=(time_t)0)
3539     {
3540     if (!(gmgametime = localtime(&gametime)))
3541     strcpy(msgtemp,"Started: ?");
3542     else
3543     strftime(msgtemp,sizeof(msgtemp),"Started: "GAME_TIME_FORMAT,gmgametime);
3544     }
3545     else
3546     strcpy(msgtemp,"Started: ");
3547     message_send_text(c,message_type_info,c,msgtemp);
3548     }
3549    
3550     sprintf(msgtemp,"Status: %s",game_status_get_str(game_get_status(game)));
3551     message_send_text(c,message_type_info,c,msgtemp);
3552    
3553     sprintf(msgtemp,"Type: %-20.20s",game_type_get_str(game_get_type(game)));
3554     message_send_text(c,message_type_info,c,msgtemp);
3555    
3556     sprintf(msgtemp,"Speed: %s",game_speed_get_str(game_get_speed(game)));
3557     message_send_text(c,message_type_info,c,msgtemp);
3558    
3559     sprintf(msgtemp,"Difficulty: %s",game_difficulty_get_str(game_get_difficulty(game)));
3560     message_send_text(c,message_type_info,c,msgtemp);
3561    
3562     sprintf(msgtemp,"Option: %s",game_option_get_str(game_get_option(game)));
3563     message_send_text(c,message_type_info,c,msgtemp);
3564    
3565     {
3566     char const * mapname;
3567    
3568     if (!(mapname = game_get_mapname(game)))
3569     mapname = "unknown";
3570     sprintf(msgtemp,"Map: %-20.20s",mapname);
3571     message_send_text(c,message_type_info,c,msgtemp);
3572     }
3573    
3574     sprintf(msgtemp,"Map Size: %ux%u",game_get_mapsize_x(game),game_get_mapsize_y(game));
3575     message_send_text(c,message_type_info,c,msgtemp);
3576     sprintf(msgtemp,"Map Tileset: %s",game_tileset_get_str(game_get_tileset(game)));
3577     message_send_text(c,message_type_info,c,msgtemp);
3578     sprintf(msgtemp,"Map Type: %s",game_maptype_get_str(game_get_maptype(game)));
3579     message_send_text(c,message_type_info,c,msgtemp);
3580    
3581     sprintf(msgtemp,"Players: %u current, %u total, %u max",game_get_ref(game),game_get_count(game),game_get_maxplayers(game));
3582     message_send_text(c,message_type_info,c,msgtemp);
3583    
3584     {
3585     char const * description;
3586    
3587     if (!(description = game_get_description(game)))
3588     description = "";
3589     sprintf(msgtemp,"Description: %-20.20s",description);
3590     }
3591    
3592     return 0;
3593     }
3594    
3595     static int _handle_ladderactivate_command(t_connection * c, char const *text)
3596     {
3597     ladderlist_make_all_active();
3598     message_send_text(c,message_type_info,c,"Copied current scores to active scores on all ladders.");
3599     return 0;
3600     }
3601    
3602     static int _handle_rehash_command(t_connection * c, char const *text)
3603     {
3604     server_restart_wraper();
3605     return 0;
3606     }
3607    
3608     /*
3609     static int _handle_rank_all_accounts_command(t_connection * c, char const *text)
3610     {
3611     // rank all accounts here
3612     accounts_rank_all();
3613     return 0;
3614     }
3615     */
3616    
3617     static int _handle_shutdown_command(t_connection * c, char const *text)
3618     {
3619     char dest[32];
3620     unsigned int i,j;
3621     unsigned int delay;
3622    
3623     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
3624     for (; text[i]==' '; i++);
3625     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */
3626     if (j<sizeof(dest)-1) dest[j++] = text[i];
3627     dest[j] = '\0';
3628     for (; text[i]==' '; i++);
3629    
3630     if (dest[0]=='\0')
3631     delay = prefs_get_shutdown_delay();
3632     else
3633     if (clockstr_to_seconds(dest,&delay)<0)
3634     {
3635     message_send_text(c,message_type_error,c,"Invalid delay.");
3636     return 0;
3637     }
3638    
3639     server_quit_delay(delay);
3640    
3641     if (delay)
3642     message_send_text(c,message_type_info,c,"You initialized the shutdown sequence.");
3643     else
3644     message_send_text(c,message_type_info,c,"You canceled the shutdown sequence.");
3645    
3646     return 0;
3647     }
3648    
3649     static int _handle_ladderinfo_command(t_connection * c, char const *text)
3650     {
3651     char dest[32];
3652     unsigned int rank;
3653     unsigned int i,j;
3654     t_account * account;
3655     t_clienttag clienttag;
3656    
3657     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
3658     for (; text[i]==' '; i++);
3659     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */
3660     if (j<sizeof(dest)-1) dest[j++] = text[i];
3661     dest[j] = '\0';
3662     for (; text[i]==' '; i++);
3663    
3664     if (dest[0]=='\0')
3665     {
3666     message_send_text(c,message_type_info,c,"usage: /ladderinfo <rank> [clienttag]");
3667     return 0;
3668     }
3669     if (str_to_uint(dest,&rank)<0 || rank<1)
3670     {
3671     message_send_text(c,message_type_error,c,"Invalid rank.");
3672     return 0;
3673     }
3674    
3675     if (text[i]!='\0') {
3676     if (strlen(text)!=4) {
3677     message_send_text(c,message_type_error,c,"You must supply a rank and a valid program ID.");
3678     message_send_text(c,message_type_error,c,"Example: /ladderinfo 1 STAR");
3679     return 0;
3680     }
3681     clienttag = tag_case_str_to_uint(&text[i]);
3682     } else if (!(clienttag = conn_get_clienttag(c)))
3683     {
3684     message_send_text(c,message_type_error,c,"Unable to determine client game.");
3685     return 0;
3686     }
3687     if (clienttag==CLIENTTAG_STARCRAFT_UINT)
3688     {
3689     if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_active,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal)))
3690     {
3691     sprintf(msgtemp,"Starcraft active %5u: %-20.20s %u/%u/%u rating %u",
3692     rank,
3693     account_get_name(account),
3694     account_get_ladder_active_wins(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal),
3695     account_get_ladder_active_losses(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal),
3696     account_get_ladder_active_disconnects(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal),
3697     account_get_ladder_active_rating(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal));
3698     }
3699     else
3700     sprintf(msgtemp,"Starcraft active %5u: <none>",rank);
3701     message_send_text(c,message_type_info,c,msgtemp);
3702    
3703     if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_current,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal)))
3704     {
3705     sprintf(msgtemp,"Starcraft current %5u: %-20.20s %u/%u/%u rating %u",
3706     rank,
3707     account_get_name(account),
3708     account_get_ladder_wins(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal),
3709     account_get_ladder_losses(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal),
3710     account_get_ladder_disconnects(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal),
3711     account_get_ladder_rating(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal));
3712     }
3713     else
3714     sprintf(msgtemp,"Starcraft current %5u: <none>",rank);
3715     message_send_text(c,message_type_info,c,msgtemp);
3716     }
3717     else if (clienttag==CLIENTTAG_BROODWARS_UINT)
3718     {
3719     if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_active,CLIENTTAG_BROODWARS_UINT,ladder_id_normal)))
3720     {
3721     sprintf(msgtemp,"Brood War active %5u: %-20.20s %u/%u/%u rating %u",
3722     rank,
3723     account_get_name(account),
3724     account_get_ladder_active_wins(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal),
3725     account_get_ladder_active_losses(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal),
3726     account_get_ladder_active_disconnects(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal),
3727     account_get_ladder_active_rating(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal));
3728     }
3729     else
3730     sprintf(msgtemp,"Brood War active %5u: <none>",rank);
3731     message_send_text(c,message_type_info,c,msgtemp);
3732    
3733     if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_current,CLIENTTAG_BROODWARS_UINT,ladder_id_normal)))
3734     {
3735     sprintf(msgtemp,"Brood War current %5u: %-20.20s %u/%u/%u rating %u",
3736     rank,
3737     account_get_name(account),
3738     account_get_ladder_wins(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal),
3739     account_get_ladder_losses(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal),
3740     account_get_ladder_disconnects(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal),
3741     account_get_ladder_rating(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal));
3742     }
3743     else
3744     sprintf(msgtemp,"Brood War current %5u: <none>",rank);
3745     message_send_text(c,message_type_info,c,msgtemp);
3746     }
3747     else if (clienttag==CLIENTTAG_WARCIIBNE_UINT)
3748     {
3749     if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_active,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal)))
3750     {
3751     sprintf(msgtemp,"Warcraft II standard active %5u: %-20.20s %u/%u/%u rating %u",
3752     rank,
3753     account_get_name(account),
3754     account_get_ladder_active_wins(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal),
3755     account_get_ladder_active_losses(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal),
3756     account_get_ladder_active_disconnects(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal),
3757     account_get_ladder_active_rating(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal));
3758     }
3759     else
3760     sprintf(msgtemp,"Warcraft II standard active %5u: <none>",rank);
3761     message_send_text(c,message_type_info,c,msgtemp);
3762    
3763     if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_active,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman)))
3764     {
3765     sprintf(msgtemp,"Warcraft II IronMan active %5u: %-20.20s %u/%u/%u rating %u",
3766     rank,
3767     account_get_name(account),
3768     account_get_ladder_active_wins(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman),
3769     account_get_ladder_active_losses(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman),
3770     account_get_ladder_active_disconnects(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman),
3771     account_get_ladder_active_rating(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman));
3772     }
3773     else
3774     sprintf(msgtemp,"Warcraft II IronMan active %5u: <none>",rank);
3775     message_send_text(c,message_type_info,c,msgtemp);
3776    
3777     if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_current,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal)))
3778     {
3779     sprintf(msgtemp,"Warcraft II standard current %5u: %-20.20s %u/%u/%u rating %u",
3780     rank,
3781     account_get_name(account),
3782     account_get_ladder_wins(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal),
3783     account_get_ladder_losses(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal),
3784     account_get_ladder_disconnects(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal),
3785     account_get_ladder_rating(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal));
3786     }
3787     else
3788     sprintf(msgtemp,"Warcraft II standard current %5u: <none>",rank);
3789     message_send_text(c,message_type_info,c,msgtemp);
3790    
3791     if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_current,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman)))
3792     {
3793     sprintf(msgtemp,"Warcraft II IronMan current %5u: %-20.20s %u/%u/%u rating %u",
3794     rank,
3795     account_get_name(account),
3796     account_get_ladder_wins(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman),
3797     account_get_ladder_losses(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman),
3798     account_get_ladder_disconnects(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman),
3799     account_get_ladder_rating(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman));
3800     }
3801     else
3802     sprintf(msgtemp,"Warcraft II IronMan current %5u: <none>",rank);
3803     message_send_text(c,message_type_info,c,msgtemp);
3804     }
3805     // --> aaron
3806     else if (clienttag==CLIENTTAG_WARCRAFT3_UINT || clienttag==CLIENTTAG_WAR3XP_UINT)
3807     {
3808     unsigned int teamcount = 0;
3809     if ((account = ladder_get_account(solo_ladder(clienttag),rank,&teamcount,clienttag)))
3810     {
3811     sprintf(msgtemp,"WarCraft3 Solo %5u: %-20.20s %u/%u/0",
3812     rank,
3813     account_get_name(account),
3814     account_get_ladder_wins(account,clienttag,ladder_id_solo),
3815     account_get_ladder_losses(account,clienttag,ladder_id_solo));
3816     }
3817     else
3818     sprintf(msgtemp,"WarCraft3 Solo %5u: <none>",rank);
3819     message_send_text(c,message_type_info,c,msgtemp);
3820    
3821     if ((account = ladder_get_account(team_ladder(clienttag),rank,&teamcount,clienttag)))
3822     {
3823     sprintf(msgtemp,"WarCraft3 Team %5u: %-20.20s %u/%u/0",
3824     rank,
3825     account_get_name(account),
3826     account_get_ladder_wins(account,clienttag,ladder_id_team),
3827     account_get_ladder_losses(account,clienttag,ladder_id_team));
3828     }
3829     else
3830     sprintf(msgtemp,"WarCraft3 Team %5u: <none>",rank);
3831     message_send_text(c,message_type_info,c,msgtemp);
3832    
3833     if ((account = ladder_get_account(ffa_ladder(clienttag),rank,&teamcount,clienttag)))
3834     {
3835     sprintf(msgtemp,"WarCraft3 FFA %5u: %-20.20s %u/%u/0",
3836     rank,
3837     account_get_name(account),
3838     account_get_ladder_wins(account,clienttag,ladder_id_ffa),
3839     account_get_ladder_losses(account,clienttag,ladder_id_ffa));
3840     }
3841     else
3842     sprintf(msgtemp,"WarCraft3 FFA %5u: <none>",rank);
3843     message_send_text(c,message_type_info,c,msgtemp);
3844    
3845     if ((account = ladder_get_account(at_ladder(clienttag),rank,&teamcount,clienttag)))
3846     {
3847     /*
3848     if (account_get_atteammembers(account,teamcount,clienttag))
3849     sprintf(msgtemp,"WarCraft3 AT Team %5u: %-80.80s %u/%u/0",
3850     rank,
3851     account_get_atteammembers(account,teamcount,clienttag),
3852     account_get_atteamwin(account,teamcount,clienttag),
3853     account_get_atteamloss(account,teamcount,clienttag));
3854    
3855     else */
3856     sprintf(msgtemp,"WarCraft3 AT Team %5u: <invalid team info>",rank);
3857     }
3858     else
3859     sprintf(msgtemp,"WarCraft3 AT Team %5u: <none>",rank);
3860     message_send_text(c,message_type_info,c,msgtemp);
3861     }
3862     //<---
3863     else
3864     {
3865     message_send_text(c,message_type_error,c,"This game does not support win/loss records.");
3866     message_send_text(c,message_type_error,c,"You must supply a rank and a valid program ID.");
3867     message_send_text(c,message_type_error,c,"Example: /ladderinfo 1 STAR");
3868     }
3869    
3870     return 0;
3871     }
3872    
3873     static int _handle_timer_command(t_connection * c, char const *text)
3874     {
3875     unsigned int i,j;
3876     unsigned int delta;
3877     char deltastr[64];
3878     t_timer_data data;
3879    
3880     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
3881     for (; text[i]==' '; i++);
3882     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get comm */
3883     if (j<sizeof(deltastr)-1) deltastr[j++] = text[i];
3884     deltastr[j] = '\0';
3885     for (; text[i]==' '; i++);
3886    
3887     if (deltastr[0]=='\0')
3888     {
3889     message_send_text(c,message_type_info,c,"usage: /timer <duration>");
3890     return 0;
3891     }
3892    
3893     if (clockstr_to_seconds(deltastr,&delta)<0)
3894     {
3895     message_send_text(c,message_type_error,c,"Invalid duration.");
3896     return 0;
3897     }
3898    
3899     if (text[i]=='\0')
3900     data.p = xstrdup("Your timer has expired.");
3901     else
3902     data.p = xstrdup(&text[i]);
3903    
3904     if (timerlist_add_timer(c,time(NULL)+(time_t)delta,user_timer_cb,data)<0)
3905     {
3906     eventlog(eventlog_level_error,__FUNCTION__,"could not add timer");
3907     xfree(data.p);
3908     message_send_text(c,message_type_error,c,"Could not set timer.");
3909     }
3910     else
3911     {
3912     sprintf(msgtemp,"Timer set for %s",seconds_to_timestr(delta));
3913     message_send_text(c,message_type_info,c,msgtemp);
3914     }
3915    
3916     return 0;
3917     }
3918    
3919     static int _handle_serverban_command(t_connection *c, char const *text)
3920     {
3921     char dest[USER_NAME_MAX];
3922     char messagetemp[MAX_MESSAGE_LEN];
3923     t_connection * dest_c;
3924     unsigned int i,j;
3925    
3926     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); // skip command
3927     for (; text[i]==' '; i++);
3928     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) // get dest
3929     if (j<sizeof(dest)-1) dest[j++] = text[i];
3930     dest[j] = '\0';
3931     for (; text[i]==' '; i++);
3932    
3933     if (dest[0]=='\0')
3934     {
3935     message_send_text(c,message_type_info,c,"usage: /serverban <account>");
3936     return 0;
3937     }
3938    
3939     if (!(dest_c = connlist_find_connection_by_accountname(dest)))
3940     {
3941     message_send_text(c,message_type_error,c,"That user is not logged on.");
3942     return 0;
3943     }
3944     sprintf(messagetemp,"Banning User %s who is using IP %s",conn_get_username(dest_c),addr_num_to_ip_str(conn_get_game_addr(dest_c)));
3945     message_send_text(c,message_type_info,c,messagetemp);
3946     message_send_text(c,message_type_info,c,"Users Account is also LOCKED! Only a Admin can Unlock it!");
3947     sprintf(msgtemp,"/ipban a %s",addr_num_to_ip_str(conn_get_game_addr(dest_c)));
3948     handle_ipban_command(c,msgtemp);
3949     account_set_auth_lock(conn_get_account(dest_c),1);
3950     //now kill the connection
3951     sprintf(msgtemp,"You have been banned by Admin: %s",conn_get_username(c));
3952     message_send_text(dest_c,message_type_error,dest_c,msgtemp);
3953     message_send_text(dest_c,message_type_error,dest_c,"Your account is also LOCKED! Only a admin can UNLOCK it!");
3954     conn_set_state(dest_c, conn_state_destroy);
3955     return 0;
3956     }
3957    
3958     static int _handle_netinfo_command(t_connection * c, char const *text)
3959     {
3960     char dest[USER_NAME_MAX];
3961     unsigned int i,j;
3962     t_connection * conn;
3963     t_game const * game;
3964     unsigned int addr;
3965     unsigned short port;
3966     unsigned int taddr;
3967     unsigned short tport;
3968    
3969     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); // skip command
3970     for (; text[i]==' '; i++);
3971     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) // get dest
3972     if (j<sizeof(dest)-1) dest[j++] = text[i];
3973     dest[j] = '\0';
3974     for (; text[i]==' '; i++);
3975    
3976     if (dest[0]=='\0')
3977     strcpy(dest,conn_get_username(c));
3978    
3979     if (!(conn = connlist_find_connection_by_accountname(dest)))
3980     {
3981     message_send_text(c,message_type_error,c,"That user is not logged on.");
3982     return 0;
3983     }
3984    
3985     if (conn_get_account(conn)!=conn_get_account(c) &&
3986     prefs_get_hide_addr() && !(account_get_command_groups(conn_get_account(c)) & command_get_group("/admin-addr"))) // default to false
3987     {
3988     message_send_text(c,message_type_error,c,"Address information for other users is only available to admins.");
3989     return 0;
3990     }
3991    
3992     sprintf(msgtemp,"Server TCP: %s (bind %s)",addr_num_to_addr_str(conn_get_real_local_addr(conn),conn_get_real_local_port(conn)),addr_num_to_addr_str(conn_get_local_addr(conn),conn_get_local_port(conn)));
3993     message_send_text(c,message_type_info,c,msgtemp);
3994    
3995     sprintf(msgtemp,"Client TCP: %s",addr_num_to_addr_str(conn_get_addr(conn),conn_get_port(conn)));
3996     message_send_text(c,message_type_info,c,msgtemp);
3997    
3998     taddr=addr = conn_get_game_addr(conn);
3999     tport=port = conn_get_game_port(conn);
4000     trans_net(conn_get_addr(c),&taddr,&tport);
4001    
4002     if (taddr==addr && tport==port)
4003     sprintf(msgtemp,"Client UDP: %s",
4004     addr_num_to_addr_str(addr,port));
4005     else
4006     sprintf(msgtemp,"Client UDP: %s (trans %s)",
4007     addr_num_to_addr_str(addr,port),
4008     addr_num_to_addr_str(taddr,tport));
4009     message_send_text(c,message_type_info,c,msgtemp);
4010    
4011     if ((game = conn_get_game(conn)))
4012     {
4013     taddr=addr = game_get_addr(game);
4014     tport=port = game_get_port(game);
4015     trans_net(conn_get_addr(c),&taddr,&tport);
4016    
4017     if (taddr==addr && tport==port)
4018     sprintf(msgtemp,"Game UDP: %s",
4019     addr_num_to_addr_str(addr,port));
4020     else
4021     sprintf(msgtemp,"Game UDP: %s (trans %s)",
4022     addr_num_to_addr_str(addr,port),
4023     addr_num_to_addr_str(taddr,tport));
4024     }
4025     else
4026     strcpy(msgtemp,"Game UDP: none");
4027     message_send_text(c,message_type_info,c,msgtemp);
4028    
4029     return 0;
4030     }
4031    
4032     static int _handle_quota_command(t_connection * c, char const * text)
4033     {
4034     sprintf(msgtemp,"Your quota allows you to write %u lines per %u seconds.",prefs_get_quota_lines(),prefs_get_quota_time());
4035     message_send_text(c,message_type_info,c,msgtemp);
4036     sprintf(msgtemp,"Long lines will be considered to wrap every %u characters.",prefs_get_quota_wrapline());
4037     message_send_text(c,message_type_info,c,msgtemp);
4038     sprintf(msgtemp,"You are not allowed to send lines with more than %u characters.",prefs_get_quota_maxline());
4039     message_send_text(c,message_type_info,c,msgtemp);
4040    
4041     return 0;
4042     }
4043    
4044     static int _handle_lockacct_command(t_connection * c, char const *text)
4045     {
4046     t_connection * user;
4047     t_account * account;
4048    
4049     text = skip_command(text);
4050    
4051     if (text[0]=='\0')
4052     {
4053     message_send_text(c,message_type_info,c,"usage: /lockacct <username>");
4054     return 0;
4055     }
4056    
4057     if (!(account = accountlist_find_account(text)))
4058     {
4059     message_send_text(c,message_type_error,c,"Invalid user.");
4060     return 0;
4061     }
4062     if ((user = connlist_find_connection_by_accountname(text)))
4063     message_send_text(user,message_type_info,user,"Your account has just been locked by admin.");
4064    
4065     account_set_auth_lock(account,1);
4066     message_send_text(c,message_type_error,c,"That user account is now locked.");
4067     return 0;
4068     }
4069    
4070     static int _handle_unlockacct_command(t_connection * c, char const *text)
4071     {
4072     t_connection * user;
4073     t_account * account;
4074    
4075     text = skip_command(text);
4076    
4077     if (text[0]=='\0')
4078     {
4079     message_send_text(c,message_type_info,c,"usage: /unlockacct <username>");
4080     return 0;
4081     }
4082     if (!(account = accountlist_find_account(text)))
4083     {
4084     message_send_text(c,message_type_error,c,"Invalid user.");
4085     return 0;
4086     }
4087    
4088     if ((user = connlist_find_connection_by_accountname(text)))
4089     message_send_text(user,message_type_info,user,"Your account has just been unlocked by admin.");
4090    
4091     account_set_auth_lock(account,0);
4092     message_send_text(c,message_type_error,c,"That user account is now unlocked.");
4093     return 0;
4094     }
4095    
4096     static int _handle_flag_command(t_connection * c, char const *text)
4097     {
4098     char dest[32];
4099     unsigned int i,j;
4100     unsigned int newflag;
4101    
4102     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
4103     for (; text[i]==' '; i++);
4104     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */
4105     if (j<sizeof(dest)-1) dest[j++] = text[i];
4106     dest[j] = '\0';
4107     for (; text[i]==' '; i++);
4108    
4109     if (dest[0]=='\0')
4110     {
4111     message_send_text(c,message_type_info,c,"usage: /flag <flag>");
4112     return 0;
4113     }
4114    
4115     newflag = strtoul(dest,NULL,0);
4116     conn_set_flags(c,newflag);
4117    
4118     sprintf(msgtemp,"Flags set to 0x%08x.",newflag);
4119     message_send_text(c,message_type_info,c,msgtemp);
4120     return 0;
4121     }
4122    
4123     static int _handle_tag_command(t_connection * c, char const *text)
4124     {
4125     char dest[8];
4126     unsigned int i,j;
4127     unsigned int newtag;
4128    
4129     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
4130     for (; text[i]==' '; i++);
4131     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */
4132     if (j<sizeof(dest)-1) dest[j++] = text[i];
4133     dest[j] = '\0';
4134     for (; text[i]==' '; i++);
4135    
4136     if (dest[0]=='\0')
4137     {
4138     message_send_text(c,message_type_info,c,"usage: /tag <clienttag>");
4139     return 0;
4140     }
4141     if (strlen(dest)!=4)
4142     {
4143     message_send_text(c,message_type_error,c,"Client tag should be four characters long.");
4144     return 0;
4145     }
4146     newtag = tag_case_str_to_uint(dest);
4147     if (tag_check_client(newtag))
4148     {
4149     unsigned int oldflags = conn_get_flags(c);
4150     conn_set_clienttag(c,newtag);
4151     if ((newtag==CLIENTTAG_WARCRAFT3_UINT) || (newtag==CLIENTTAG_WAR3XP_UINT))
4152     conn_update_w3_playerinfo(c);
4153     channel_rejoin(c);
4154     conn_set_flags(c,oldflags);
4155     channel_update_userflags(c);
4156     sprintf(msgtemp,"Client tag set to %s.",dest);
4157     }
4158     else
4159     sprintf(msgtemp,"Invalid clienttag %s specified",dest);
4160     message_send_text(c,message_type_info,c,msgtemp);
4161     return 0;
4162     }
4163    
4164     static int _handle_set_command(t_connection * c, char const *text)
4165     {
4166     t_account * account;
4167     char *accname;
4168     char *key;
4169     char *value;
4170     char t[MAX_MESSAGE_LEN];
4171     unsigned int i,j;
4172     char arg1[256];
4173     char arg2[256];
4174     char arg3[256];
4175    
4176     strncpy(t, text, MAX_MESSAGE_LEN - 1);
4177     for (i=0; t[i]!=' ' && t[i]!='\0'; i++); /* skip command /set */
4178    
4179     for (; t[i]==' '; i++); /* skip spaces */
4180     for (j=0; t[i]!=' ' && t[i]!='\0'; i++) /* get username */
4181     if (j<sizeof(arg1)-1) arg1[j++] = t[i];
4182     arg1[j] = '\0';
4183    
4184     for (; t[i]==' '; i++); /* skip spaces */
4185     for (j=0; t[i]!=' ' && t[i]!='\0'; i++) /* get key */
4186     if (j<sizeof(arg2)-1) arg2[j++] = t[i];
4187     arg2[j] = '\0';
4188    
4189     for (; t[i]==' '; i++); /* skip spaces */
4190     for (j=0; t[i]!='\0'; i++) /* get value */
4191     if (j<sizeof(arg3)-1) arg3[j++] = t[i];
4192     arg3[j] = '\0';
4193    
4194     accname = arg1;
4195     key = arg2;
4196     value = arg3;
4197    
4198     if ((arg1[0] =='\0') || (arg2[0]=='\0'))
4199     {
4200     message_send_text(c,message_type_info,c,"usage: /set <username> <key> [value]");
4201     }
4202    
4203     if (!(account = accountlist_find_account(accname)))
4204     {
4205     message_send_text(c,message_type_error,c,"Invalid user.");
4206     return 0;
4207     }
4208    
4209     if (*value == '\0')
4210     {
4211     if (account_get_strattr(account,key))
4212     {
4213     sprintf(msgtemp, "current value of %.64s is \"%.128s\"",key,account_get_strattr(account,key));
4214     message_send_text(c,message_type_error,c,msgtemp);
4215     }
4216     else
4217     message_send_text(c,message_type_error,c,"value currently not set");
4218     return 0;
4219     }
4220    
4221     if (account_set_strattr(account,key,value)<0)
4222     message_send_text(c,message_type_error,c,"Unable to set key");
4223     else
4224     message_send_text(c,message_type_error,c,"Key set succesfully");
4225    
4226     return 0;
4227     }
4228    
4229     static int _handle_motd_command(t_connection * c, char const *text)
4230     {
4231     char const * filename;
4232     FILE * fp;
4233    
4234     if ((filename = prefs_get_motdfile())) {
4235     if ((fp = fopen(filename,"r")))
4236     {
4237     message_send_file(c,fp);
4238     if (fclose(fp)<0)
4239     eventlog(eventlog_level_error,__FUNCTION__,"could not close motd file \"%s\" after reading (fopen: %s)",filename,pstrerror(errno));
4240     }
4241     else
4242     {
4243     eventlog(eventlog_level_error,__FUNCTION__,"could not open motd file \"%s\" for reading (fopen: %s)",filename,pstrerror(errno));
4244     message_send_text(c,message_type_error,c,"Unable to open motd.");
4245     }
4246     return 0;
4247     } else {
4248     message_send_text(c,message_type_error,c,"No motd.");
4249     return 0;
4250     }
4251     }
4252    
4253     static int _handle_ping_command(t_connection * c, char const *text)
4254     {
4255     unsigned int i;
4256     t_connection * user;
4257     t_game * game;
4258    
4259     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
4260     for (; text[i]==' '; i++);
4261    
4262     if (text[i]=='\0')
4263     {
4264     if ((game=conn_get_game(c)))
4265     {
4266     for (i=0; i<game_get_count(game); i++)
4267     {
4268     if ((user = game_get_player_conn(game, i)))
4269     {
4270     sprintf(msgtemp,"%s latency: %9u",conn_get_username(user),conn_get_latency(user));
4271     message_send_text(c,message_type_info,c,msgtemp);
4272     }
4273     }
4274     return 0;
4275     }
4276     sprintf(msgtemp,"Your latency %9u",conn_get_latency(c));
4277     }
4278     else if ((user = connlist_find_connection_by_accountname(&text[i])))
4279     sprintf(msgtemp,"%s latency %9u",&text[i],conn_get_latency(user));
4280     else
4281     sprintf(msgtemp,"Invalid user");
4282    
4283     message_send_text(c,message_type_info,c,msgtemp);
4284     return 0;
4285     }
4286    
4287     /* Redirected to handle_ipban_command in ipban.c [Omega]
4288     static int _handle_ipban_command(t_connection * c, char const *text)
4289     {
4290     handle_ipban_command(c,text);
4291     return 0;
4292     }
4293     */
4294    
4295     static int _handle_commandgroups_command(t_connection * c, char const * text)
4296     {
4297     t_account * account;
4298     char * command;
4299     char * username;
4300     unsigned int usergroups; // from user account
4301     unsigned int groups = 0; // converted from arg3
4302     char tempgroups[8]; // converted from usergroups
4303     char t[MAX_MESSAGE_LEN];
4304     unsigned int i,j;
4305     char arg1[256];
4306     char arg2[256];
4307     char arg3[256];
4308    
4309     strncpy(t, text, MAX_MESSAGE_LEN - 1);
4310     for (i=0; t[i]!=' ' && t[i]!='\0'; i++); /* skip command /groups */
4311    
4312     for (; t[i]==' '; i++); /* skip spaces */
4313     for (j=0; t[i]!=' ' && t[i]!='\0'; i++) /* get command */
4314     if (j<sizeof(arg1)-1) arg1[j++] = t[i];
4315     arg1[j] = '\0';
4316    
4317     for (; t[i]==' '; i++); /* skip spaces */
4318     for (j=0; t[i]!=' ' && t[i]!='\0'; i++) /* get username */
4319     if (j<sizeof(arg2)-1) arg2[j++] = t[i];
4320     arg2[j] = '\0';
4321    
4322     for (; t[i]==' '; i++); /* skip spaces */
4323     for (j=0; t[i]!='\0'; i++) /* get groups */
4324     if (j<sizeof(arg3)-1) arg3[j++] = t[i];
4325     arg3[j] = '\0';
4326    
4327     command = arg1;
4328     username = arg2;
4329    
4330     if (arg1[0] =='\0') {
4331     message_send_text(c,message_type_info,c,"usage: /cg <command> <username> [<group(s)>]");
4332     return 0;
4333     }
4334    
4335     if (!strcmp(command,"help") || !strcmp(command,"h")) {
4336     message_send_text(c,message_type_info,c,"Command Groups (Defines the Groups of Commands a User Can Use.)");
4337     message_send_text(c,message_type_info,c,"Type: /cg add <username> <group(s)> - adds group(s) to user profile");
4338     message_send_text(c,message_type_info,c,"Type: /cg del <username> <group(s)> - deletes group(s) from user profile");
4339     message_send_text(c,message_type_info,c,"Type: /cg list <username> - shows current groups user can use");
4340     return 0;
4341     }
4342    
4343     if (arg2[0] =='\0') {
4344     message_send_text(c,message_type_info,c,"usage: /cg <command> <username> [<group(s)>]");
4345     return 0;
4346     }
4347    
4348     if (!(account = accountlist_find_account(username))) {
4349     message_send_text(c,message_type_error,c,"Invalid user.");
4350     return 0;
4351     }
4352    
4353     usergroups = account_get_command_groups(account);
4354    
4355     if (!strcmp(command,"list") || !strcmp(command,"l")) {
4356     if (usergroups & 1) tempgroups[0] = '1'; else tempgroups[0] = ' ';
4357     if (usergroups & 2) tempgroups[1] = '2'; else tempgroups[1] = ' ';
4358     if (usergroups & 4) tempgroups[2] = '3'; else tempgroups[2] = ' ';
4359     if (usergroups & 8) tempgroups[3] = '4'; else tempgroups[3] = ' ';
4360     if (usergroups & 16) tempgroups[4] = '5'; else tempgroups[4] = ' ';
4361     if (usergroups & 32) tempgroups[5] = '6'; else tempgroups[5] = ' ';
4362     if (usergroups & 64) tempgroups[6] = '7'; else tempgroups[6] = ' ';
4363     if (usergroups & 128) tempgroups[7] = '8'; else tempgroups[7] = ' ';
4364     sprintf(msgtemp, "%s's command group(s): %s", username, tempgroups);
4365     message_send_text(c,message_type_info,c,msgtemp);
4366     return 0;
4367     }
4368    
4369     if (arg3[0] =='\0') {
4370     message_send_text(c,message_type_info,c,"usage: /cg <command> <username> [<group(s)>]");
4371     return 0;
4372     }
4373    
4374     for (i=0; arg3[i] != '\0'; i++) {
4375     if (arg3[i] == '1') groups |= 1;
4376     else if (arg3[i] == '2') groups |= 2;
4377     else if (arg3[i] == '3') groups |= 4;
4378     else if (arg3[i] == '4') groups |= 8;
4379     else if (arg3[i] == '5') groups |= 16;
4380     else if (arg3[i] == '6') groups |= 32;
4381     else if (arg3[i] == '7') groups |= 64;
4382     else if (arg3[i] == '8') groups |= 128;
4383     else {
4384     sprintf(msgtemp, "got bad group: %c", arg3[i]);
4385     message_send_text(c,message_type_info,c,msgtemp);
4386     return 0;
4387     }
4388     }
4389    
4390     if (!strcmp(command,"add") || !strcmp(command,"a")) {
4391     account_set_command_groups(account, usergroups | groups);
4392     sprintf(msgtemp, "groups %s has been added to user: %s", arg3, username);
4393     message_send_text(c,message_type_info,c,msgtemp);
4394     return 0;
4395     }
4396    
4397     if (!strcmp(command,"del") || !strcmp(command,"d")) {
4398     account_set_command_groups(account, usergroups & (255 - groups));
4399     sprintf(msgtemp, "groups %s has been deleted from user: %s", arg3, username);
4400     message_send_text(c,message_type_info,c,msgtemp);
4401     return 0;
4402     }
4403    
4404     sprintf(msgtemp, "got unknown command: %s", command);
4405     message_send_text(c,message_type_info,c,msgtemp);
4406     return 0;
4407     }
4408    
4409     static int _handle_topic_command(t_connection * c, char const * text)
4410     {
4411     char const * channel_name;
4412     char const * topic;
4413     char * tmp;
4414     t_channel * channel;
4415     int do_save = NO_SAVE_TOPIC;
4416    
4417     channel_name = skip_command(text);
4418    
4419     if ((topic = strchr(channel_name,'"')))
4420     {
4421     tmp = (char *)topic;
4422     for (tmp--;tmp[0]==' ';tmp--);
4423     tmp[1]='\0';
4424     topic++;
4425     tmp = strchr(topic,'"');
4426     if (tmp) tmp[0]='\0';
4427     }
4428    
4429     if (!(conn_get_channel(c))) {
4430     message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
4431     return -1;
4432     }
4433    
4434     if (channel_name[0]=='\0')
4435     {
4436     if (channel_get_topic(channel_get_name(conn_get_channel(c))))
4437     {
4438     sprintf(msgtemp,"%s topic: %s",channel_get_name(conn_get_channel(c)),channel_get_topic(channel_get_name(conn_get_channel(c))));
4439     }
4440     else
4441     {
4442     sprintf(msgtemp,"%s topic: no topic",channel_get_name(conn_get_channel(c)));
4443     }
4444     message_send_text(c,message_type_info,c,msgtemp);
4445    
4446     return 0;
4447     }
4448    
4449     if (!(topic))
4450     {
4451     if (channel_get_topic(channel_name))
4452     {
4453     sprintf(msgtemp,"%s topic: %s",channel_name, channel_get_topic(channel_name));
4454     }
4455     else
4456     {
4457     sprintf(msgtemp,"%s topic: no topic",channel_name);
4458     }
4459     message_send_text(c,message_type_info,c,msgtemp);
4460     return 0;
4461     }
4462    
4463     if (!(account_is_operator_or_admin(conn_get_account(c),channel_get_name(conn_get_channel(c))))) {
4464     message_send_text(c,message_type_error,c,"You must be at least a Channel Operator to use this command.");
4465     return -1;
4466     }
4467    
4468     if (!(channel = channellist_find_channel_by_name(channel_name,conn_get_country(c),realm_get_name(conn_get_realm(c)))))
4469     {
4470     sprintf(msgtemp,"no such channel, can't set topic");
4471     message_send_text(c,message_type_error,c,msgtemp);
4472     return -1;
4473     }
4474    
4475     if (channel_get_permanent(channel))
4476     do_save = DO_SAVE_TOPIC;
4477    
4478     channel_name = channel_get_name(channel);
4479    
4480     channel_set_topic(channel_name, topic, do_save);
4481    
4482     sprintf(msgtemp,"%s topic: %s",channel_name, topic);
4483     message_send_text(c,message_type_info,c,msgtemp);
4484    
4485     return 0;
4486     }
4487    
4488     static int _handle_moderate_command(t_connection * c, char const * text)
4489     {
4490     t_channel_flags oldflags;
4491     t_channel * channel;
4492    
4493     if (!(channel = conn_get_channel(c))) {
4494     message_send_text(c,message_type_error,c,"This command can only be used inside a channel.");
4495     return -1;
4496     }
4497    
4498     if (!(account_is_operator_or_admin(conn_get_account(c),channel_get_name(channel)))) {
4499     message_send_text(c,message_type_error,c,"You must be at least a Channel Operator to use this command.");
4500     return -1;
4501     }
4502    
4503     oldflags = channel_get_flags(channel);
4504    
4505     if (channel_set_flags(channel, oldflags ^ channel_flags_moderated)) {
4506     eventlog(eventlog_level_error,__FUNCTION__,"could not set channel %s flags",channel_get_name(channel));
4507     message_send_text(c,message_type_error,c,"Unable to change channel flags.");
4508     return -1;
4509     }
4510     else {
4511     if (oldflags & channel_flags_moderated)
4512     channel_message_send(channel,message_type_info,c,"Channel is now unmoderated");
4513     else
4514     channel_message_send(channel,message_type_info,c,"Channel is now moderated");
4515     }
4516    
4517     return 0;
4518     }
4519    
4520     static void _reset_d1_stats(t_account *account, t_clienttag ctag, t_connection *c)
4521     {
4522     account_set_normal_level(account,ctag,0);
4523     account_set_normal_strength(account,ctag,0),
4524     account_set_normal_magic(account,ctag,0),
4525     account_set_normal_dexterity(account,ctag,0),
4526     account_set_normal_vitality(account,ctag,0),
4527     account_set_normal_gold(account,ctag,0);
4528    
4529     sprintf(msgtemp,"Resetted %s's %s Stats",account_get_name(account),clienttag_get_title(ctag));
4530     message_send_text(c,message_type_info,c,msgtemp);
4531     }
4532    
4533     static void _reset_scw2_stats(t_account *account, t_clienttag ctag, t_connection *c)
4534     {
4535     account_set_normal_wins(account,ctag,0);
4536     account_set_normal_losses(account,ctag,0);
4537     account_set_normal_disconnects(account,ctag,0);
4538    
4539     if (account_get_ladder_rating(account,ctag,ladder_id_normal)>0) {
4540     account_set_ladder_wins(account,ctag,ladder_id_normal,0);
4541     account_set_ladder_losses(account,ctag,ladder_id_normal,0);
4542     account_set_ladder_disconnects(account,ctag,ladder_id_normal,0);
4543     account_set_ladder_rating(account,ctag,ladder_id_normal,0);
4544     }
4545    
4546     if (account_get_ladder_rating(account,ctag,ladder_id_ironman)>0) {
4547     account_set_ladder_wins(account,ctag,ladder_id_ironman,0);
4548     account_set_ladder_losses(account,ctag,ladder_id_ironman,0);
4549     account_set_ladder_disconnects(account,ctag,ladder_id_ironman,0);
4550     account_set_ladder_rating(account,ctag,ladder_id_ironman,0);
4551     }
4552    
4553     sprintf(msgtemp,"Resetted %s's %s Stats",account_get_name(account),clienttag_get_title(ctag));
4554     message_send_text(c,message_type_info,c,msgtemp);
4555     }
4556    
4557     static void _reset_w3_stats(t_account *account, t_clienttag ctag, t_connection *c)
4558     {
4559     account_set_ladder_level(account,ctag,ladder_id_solo,0);
4560     account_set_ladder_xp(account,ctag,ladder_id_solo,0);
4561     account_set_ladder_wins(account,ctag,ladder_id_solo,0);
4562     account_set_ladder_losses(account,ctag,ladder_id_solo,0);
4563     account_set_ladder_rank(account,ctag,ladder_id_solo,0);
4564    
4565     account_set_ladder_level(account,ctag,ladder_id_team,0);
4566     account_set_ladder_xp(account,ctag,ladder_id_team,0);
4567     account_set_ladder_wins(account,ctag,ladder_id_team,0);
4568     account_set_ladder_losses(account,ctag,ladder_id_team,0);
4569     account_set_ladder_rank(account,ctag,ladder_id_team,0);
4570    
4571     account_set_ladder_level(account,ctag,ladder_id_ffa,0);
4572     account_set_ladder_xp(account,ctag,ladder_id_ffa,0);
4573     account_set_ladder_wins(account,ctag,ladder_id_ffa,0);
4574     account_set_ladder_losses(account,ctag,ladder_id_ffa,0);
4575     account_set_ladder_rank(account,ctag,ladder_id_ffa,0);
4576     // this would now need a way to delete the team for all members now
4577     //account_set_atteamcount(account,ctag,0);
4578    
4579     sprintf(msgtemp,"Resetted %s's %s Stats",account_get_name(account),clienttag_get_title(ctag));
4580     message_send_text(c,message_type_info,c,msgtemp);
4581     }
4582    
4583     static int _handle_clearstats_command(t_connection *c, char const *text)
4584     {
4585     char dest[USER_NAME_MAX];
4586     unsigned int i,j,all;
4587     t_account * account;
4588     t_clienttag ctag = 0;
4589    
4590     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
4591     for (; text[i]==' '; i++);
4592    
4593     if (!text[i]) {
4594     message_send_text(c,message_type_error,c,"Missing user, syntax error.");
4595     message_send_text(c,message_type_error,c,"Usage example: /clearstats <username> <clienttag>");
4596     message_send_text(c,message_type_error,c," where <clienttag> can be any valid client or ALL for all clients");
4597     return 0;
4598     }
4599    
4600     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */
4601     if (j<sizeof(dest)-1) dest[j++] = text[i];
4602     dest[j] = '\0';
4603    
4604     account = accountlist_find_account(dest);
4605     if (!account) {
4606     message_send_text(c,message_type_error,c,"Invalid user.");
4607     return 0;
4608     }
4609    
4610     for (; text[i]==' '; i++);
4611     if (!text[i]) {
4612     message_send_text(c,message_type_error,c,"Missing clienttag, syntax error.");
4613     message_send_text(c,message_type_error,c,"Usage example: /clearstats <username> <clienttag>");
4614     message_send_text(c,message_type_error,c," where <clienttag> can be any valid client or ALL for all clients");
4615     return 0;
4616     }
4617    
4618     if (strcasecmp(text + i,"all")) {
4619     if (strlen(text + i) != 4) {
4620     message_send_text(c,message_type_error,c,"Invalid clienttag, syntax error.");
4621     return 0;
4622     }
4623     ctag = tag_case_str_to_uint(text + i);
4624     all = 0;
4625     } else all = 1;
4626    
4627     if (all || ctag == CLIENTTAG_DIABLORTL_UINT)
4628     _reset_d1_stats(account,CLIENTTAG_DIABLORTL_UINT,c);
4629    
4630     if (all || ctag == CLIENTTAG_DIABLOSHR_UINT)
4631     _reset_d1_stats(account,CLIENTTAG_DIABLOSHR_UINT,c);
4632    
4633     if (all || ctag == CLIENTTAG_WARCIIBNE_UINT)
4634     _reset_scw2_stats(account,CLIENTTAG_WARCIIBNE_UINT,c);
4635    
4636     if (all || ctag == CLIENTTAG_STARCRAFT_UINT)
4637     _reset_scw2_stats(account,CLIENTTAG_STARCRAFT_UINT,c);
4638    
4639     if (all || ctag == CLIENTTAG_BROODWARS_UINT)
4640     _reset_scw2_stats(account,CLIENTTAG_BROODWARS_UINT,c);
4641    
4642     if (all || ctag == CLIENTTAG_SHAREWARE_UINT)
4643     _reset_scw2_stats(account,CLIENTTAG_SHAREWARE_UINT,c);
4644    
4645     if (all || ctag == CLIENTTAG_WARCRAFT3_UINT)
4646     _reset_w3_stats(account,CLIENTTAG_WARCRAFT3_UINT,c);
4647    
4648     if (all || ctag == CLIENTTAG_WAR3XP_UINT)
4649     _reset_w3_stats(account,CLIENTTAG_WAR3XP_UINT,c);
4650    
4651     return 0;
4652     }
4653 sysadm 1.2
4654     static int _glist_cb_ext(t_game *game, void *data)
4655     {
4656     t_connection * owner_conn = NULL;
4657     t_account * owner_account = NULL;
4658     const char * owner_email = NULL;
4659    
4660     struct glist_cb_struct *cbdata = (struct glist_cb_struct*)data;
4661    
4662     // Skip void game
4663     if (game_get_ref(game) == 0)
4664     return 0;
4665    
4666     if (owner_conn = game_get_owner(game)) {
4667     if (owner_account = conn_get_account(owner_conn)) {
4668     owner_email = account_get_email(owner_account);
4669     }
4670     }
4671    
4672     sprintf(msgtemp," %-16.16s %-16.16s %1.1s %-8.8s %-21.21s %5u %-16.16s %-25.25s",
4673     game_get_name(game),
4674     game_get_pass(game),
4675     game_get_flag(game) != game_flag_private ? "n":"y",
4676     game_status_get_str(game_get_status(game)),
4677     game_type_get_str(game_get_type(game)),
4678     game_get_ref(game),
4679     account_get_name(owner_account),
4680     owner_email ? owner_email : "Unknown");
4681    
4682     if (!cbdata->tag)
4683     {
4684    
4685     strcat(msgtemp,clienttag_uint_to_str(game_get_clienttag(game)));
4686     strcat(msgtemp," ");
4687     }
4688    
4689     strcat(msgtemp, addr_num_to_addr_str(game_get_addr(game),game_get_port(game)));
4690     strcat(msgtemp, " ");
4691     strcat(msgtemp, owner_email ? owner_email : "Unknown");
4692    
4693     message_send_text(cbdata->c,message_type_info,cbdata->c,msgtemp);
4694    
4695     return 0;
4696     }
4697    
4698     static int _handle_games_ext_command(t_connection * c, char const *text)
4699     {
4700     unsigned int i;
4701     unsigned int j;
4702     char clienttag_str[5];
4703     char dest[5];
4704     struct glist_cb_struct cbdata;
4705    
4706     for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
4707     for (; text[i]==' '; i++);
4708     for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */
4709     if (j<sizeof(dest)-1) dest[j++] = text[i];
4710     dest[j] = '\0';
4711     for (; text[i]==' '; i++);
4712    
4713     cbdata.c = c;
4714    
4715     if(strcmp(&text[i],"norm")==0)
4716     cbdata.diff = game_difficulty_normal;
4717     else if(strcmp(&text[i],"night")==0)
4718     cbdata.diff = game_difficulty_nightmare;
4719     else if(strcmp(&text[i],"hell")==0)
4720     cbdata.diff = game_difficulty_hell;
4721     else
4722     cbdata.diff = game_difficulty_none;
4723    
4724     if (dest[0]=='\0')
4725     {
4726     cbdata.tag = conn_get_clienttag(c);
4727     message_send_text(c,message_type_info,c,"Currently running games:");
4728     }
4729     else if (strcasecmp(&dest[0],"all")==0)
4730     {
4731     cbdata.tag = 0;
4732     message_send_text(c,message_type_info,c,"All current games:");
4733     }
4734     else
4735     {
4736     cbdata.tag = tag_case_str_to_uint(&dest[0]);
4737    
4738     if (!tag_check_client(cbdata.tag))
4739     {
4740     message_send_text(c,message_type_error,c,"No valid clienttag specified.");
4741     return -1;
4742     }
4743    
4744     if(cbdata.diff==game_difficulty_none)
4745     sprintf(msgtemp,"Current games of type %s",tag_uint_to_str(clienttag_str,cbdata.tag));
4746     else
4747     sprintf(msgtemp,"Current games of type %s %s",tag_uint_to_str(clienttag_str,cbdata.tag),&text[i]);
4748     message_send_text(c,message_type_info,c,msgtemp);
4749     }
4750    
4751     sprintf(msgtemp," ------name------ ------pass------ p -status- --------type--------- count ---owner name--- --------owner email------- ");
4752     if (!cbdata.tag)
4753     strcat(msgtemp,"ctag ");
4754     strcat(msgtemp,"--------addr--------");
4755     message_send_text(c,message_type_info,c,msgtemp);
4756     gamelist_traverse(_glist_cb_ext,&cbdata);
4757    
4758     return 0;
4759     }
4760    
4761     static int _handle_char_status_command(t_connection * c, char const *text)
4762     {
4763     FILE * fp;
4764    
4765     if (!(fp = fopen(CHAR_STATUS_DUMP_FILE, "r"))) {
4766     eventlog(eventlog_level_error, __FUNCTION__, "Can't read char status file %s", CHAR_STATUS_DUMP_FILE);
4767     sprintf(msgtemp,"Can't read char status file.");
4768     message_send_text(c,message_type_info,c,msgtemp);
4769     } else {
4770     while (fgets(msgtemp, MAX_MESSAGE_LEN, fp)) {
4771     msgtemp[strlen(msgtemp) - 1] = '\0';
4772     message_send_text(c,message_type_info,c,msgtemp);
4773     }
4774     fclose(fp);
4775     }
4776    
4777     return 0;
4778     }

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