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