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

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