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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Tue Jun 6 03:41:37 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU
CVS Tags: arelease
Changes since 1.1: +0 -0 lines
Content type: text/x-csrc
Error occurred while calculating annotation data.
no message

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

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