/* * Copyright (C) 1998 Mark Baysinger (mbaysing@ucsd.edu) * Copyright (C) 1998,1999,2000,2001 Ross Combs (rocombs@cs.nmsu.edu) * Copyright (C) 1999 Gediminas (gediminas_lt@mailexcite.com) * Copyright (C) 1999 Rob Crittenden (rcrit@greyoak.com) * Copyright (C) 2000,2001 Marco Ziech (mmz@gmx.net) * Copyright (C) 2000 Dizzy * Copyright (C) 2000 Onlyer (onlyer@263.net) * Copyright (C) 2003,2004 Aaron * Copyright (C) 2004 Donny Redmond (dredmond@linuxmail.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "common/setup_before.h" #include #ifdef HAVE_STDDEF_H # include #else # ifndef NULL # define NULL ((void *)0) # endif #endif #ifdef STDC_HEADERS # include #else # ifdef HAVE_MALLOC_H # include # endif #endif #include "compat/strtoul.h" #ifdef HAVE_STRING_H # include #else # ifdef HAVE_STRINGS_H # include # endif #endif #include "compat/strdup.h" #include "compat/strcasecmp.h" #include "compat/snprintf.h" #include #include #include "compat/strerror.h" #ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif #ifdef HAVE_SYS_TYPES # include #endif #include "compat/strftime.h" #include "message.h" #include "common/tag.h" #include "connection.h" #include "channel.h" #include "game.h" #include "common/util.h" #include "common/version.h" #include "team.h" #include "account.h" #include "account_wrap.h" #include "server.h" #include "prefs.h" #include "common/eventlog.h" #include "ladder.h" #include "timer.h" #include "common/bnettime.h" #include "common/addr.h" #include "common/packet.h" #include "helpfile.h" #include "mail.h" #include "common/bnethash.h" #include "runprog.h" #include "common/list.h" #include "common/proginfo.h" #include "alias_command.h" #include "realm.h" #include "ipban.h" #include "command_groups.h" #include "common/queue.h" #include "common/bn_type.h" #include "common/xalloc.h" #include "command.h" #include "news.h" #include "common/trans.h" #include "common/lstr.h" // aaron #include "topic.h" #include "friends.h" #include "clan.h" #include "common/setup_after.h" static char const * bnclass_get_str(unsigned int class); static void do_whisper(t_connection * user_c, char const * dest, char const * text); static void do_whois(t_connection * c, char const * dest); static void user_timer_cb(t_connection * c, time_t now, t_timer_data str); char msgtemp[MAX_MESSAGE_LEN]; char msgtemp2[MAX_MESSAGE_LEN]; static char const * bnclass_get_str(unsigned int class) { switch (class) { case PLAYERINFO_DRTL_CLASS_WARRIOR: return "warrior"; case PLAYERINFO_DRTL_CLASS_ROGUE: return "rogue"; case PLAYERINFO_DRTL_CLASS_SORCERER: return "sorcerer"; default: return "unknown"; } } static void do_whisper(t_connection * user_c, char const * dest, char const * text) { t_connection * dest_c; char const * tname; if (!(dest_c = connlist_find_connection_by_name(dest,conn_get_realm(user_c)))) { message_send_text(user_c,message_type_error,user_c,"That user is not logged on."); return; } if (conn_get_dndstr(dest_c)) { sprintf(msgtemp,"%.64s is unavailable (%.128s)",conn_get_username(dest_c),conn_get_dndstr(dest_c)); message_send_text(user_c,message_type_info,user_c,msgtemp); return; } message_send_text(user_c,message_type_whisperack,dest_c,text); if (conn_get_awaystr(dest_c)) { sprintf(msgtemp,"%.64s is away (%.128s)",conn_get_username(dest_c),conn_get_awaystr(dest_c)); message_send_text(user_c,message_type_info,user_c,msgtemp); } message_send_text(dest_c,message_type_whisper,user_c,text); if ((tname = conn_get_username(user_c))) { char username[1+USER_NAME_MAX]; /* '*' + username (including NUL) */ if (strlen(tname)command_string != NULL; p++) { if (strstart(text, p->command_string)==0) { if (!(command_get_group(p->command_string))) { message_send_text(c,message_type_error,c,"This command has been deactivated"); return 0; } if (!((command_get_group(p->command_string) & account_get_command_groups(conn_get_account(c))))) { message_send_text(c,message_type_error,c,"This command is reserved for admins."); return 0; } if (p->command_handler != NULL) return ((p->command_handler)(c,text)); } } if (prefs_get_extra_commands()==0) { message_send_text(c,message_type_error,c,"Unknown command."); eventlog(eventlog_level_debug,__FUNCTION__,"got unknown standard command \"%s\"",text); return 0; } for (p = extended_command_table; p->command_string != NULL; p++) { if (strstart(text, p->command_string)==0) { if (!(command_get_group(p->command_string))) { message_send_text(c,message_type_error,c,"This command has been deactivated"); return 0; } if (!((command_get_group(p->command_string) & account_get_command_groups(conn_get_account(c))))) { message_send_text(c,message_type_error,c,"This command is reserved for admins."); return 0; } if (p->command_handler != NULL) return ((p->command_handler)(c,text)); } } if (strlen(text)>=2 && strncmp(text,"//",2)==0) { handle_alias_command(c,text); return 0; } message_send_text(c,message_type_error,c,"Unknown command."); eventlog(eventlog_level_debug,__FUNCTION__,"got unknown command \"%s\"",text); return 0; } // +++++++++++++++++++++++++++++++++ command implementations +++++++++++++++++++++++++++++++++++++++ static int _handle_clan_command(t_connection * c, char const * text) { t_account * acc; t_clanmember * member; t_clan * clan; text = skip_command(text); if ( text[0] == '\0' ) { message_send_text(c,message_type_info,c,"usage:"); message_send_text(c,message_type_info,c,"/clan public /clan pub"); message_send_text(c,message_type_info,c,"Opens the clan channel up to the public so that anyone may enter."); message_send_text(c,message_type_info,c,"/clan private /clan priv"); message_send_text(c,message_type_info,c,"Closes the clan channel such that only members of the clan may enter."); message_send_text(c,message_type_info,c,"/clan motd MESSAGE"); message_send_text(c,message_type_info,c,"Update the clan message of the day to MESSAGE."); return 0; } if((acc = conn_get_account(c)) && (member = account_get_clanmember(acc)) && (clan = clanmember_get_clan(member))) { if(clanmember_get_status(member)>=CLAN_SHAMAN) { if (strstart(text,"public")==0 || strstart(text,"pub")==0) { if(clan_get_channel_type(clan)!=0) { clan_set_channel_type(clan,0); message_send_text(c,message_type_info,c,"Clan channel is opened up!"); } else message_send_text(c,message_type_error,c,"Clan channel has already been opened up!"); } else if (strstart(text,"private")==0 || strstart(text,"priv")==0) { if(clan_get_channel_type(clan)!=1) { clan_set_channel_type(clan,1); message_send_text(c,message_type_info,c,"Clan channel is closed!"); } else message_send_text(c,message_type_error,c,"Clan channel has already been closed!"); } else if (strstart(text,"motd")==0) { const char * msg=skip_command(text); if(msg[0]=='\0') { message_send_text(c,message_type_info,c,"usage:"); message_send_text(c,message_type_info,c,"/clan motd MESSAGE"); message_send_text(c,message_type_info,c,"Update the clan message of the day to MESSAGE."); } else { clan_set_motd(clan, msg); message_send_text(c,message_type_info,c,"Clan message of day is updated!"); } } } else message_send_text(c,message_type_error,c,"You are not the chieftain or shaman of clan!"); } else message_send_text(c,message_type_error,c,"You are not in a clan!"); return 0; } static int command_set_flags(t_connection * c) { return channel_set_userflags(c); } static int _handle_admin_command(t_connection * c, char const * text) { char const * username; char command; t_account * acc; t_connection * dst_c; int changed=0; text = skip_command(text); if ((text[0]=='\0') || ((text[0] != '+') && (text[0] != '-'))) { message_send_text(c,message_type_info,c,"usage: /admin +username to promote user to Server Admin."); message_send_text(c,message_type_info,c," /admin -username to demote user from Server Admin."); return -1; } command = text[0]; username = &text[1]; if(!*username) { message_send_text(c,message_type_info,c,"You need to supply a username."); return -1; } if(!(acc = accountlist_find_account(username))) { sprintf(msgtemp, "There's no account with username %.64s.", username); message_send_text(c, message_type_info, c, msgtemp); return -1; } dst_c = account_get_conn(acc); if (command == '+') { if (account_get_auth_admin(acc,NULL) == 1) { sprintf(msgtemp,"%s is already a Server Admin",username); } else { account_set_auth_admin(acc,NULL,1); sprintf(msgtemp,"%s has been promoted to a Server Admin",username); sprintf(msgtemp2,"%s has promoted you to a Server Admin",conn_get_loggeduser(c)); changed = 1; } } else { if (account_get_auth_admin(acc,NULL) != 1) sprintf(msgtemp,"%s is no Server Admin, so you can't demote him",username); else { account_set_auth_admin(acc,NULL,0); sprintf(msgtemp,"%s has been demoted from a Server Admin",username); sprintf(msgtemp2,"%s has demoted you from a Server Admin",conn_get_loggeduser(c)); changed = 1; } } if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2); message_send_text(c, message_type_info, c, msgtemp); command_set_flags(dst_c); return 0; } static int _handle_operator_command(t_connection * c, char const * text) { char const * username; char command; t_account * acc; t_connection * dst_c; int changed = 0; text = skip_command(text); if ((text[0]=='\0') || ((text[0] != '+') && (text[0] != '-'))) { message_send_text(c,message_type_info,c,"usage: /operator +username to promote user to Server Operator."); message_send_text(c,message_type_info,c," /operator -username to demote user from Server Operator."); return -1; } command = text[0]; username = &text[1]; if(!*username) { message_send_text(c,message_type_info,c,"You need to supply a username."); return -1; } if(!(acc = accountlist_find_account(username))) { sprintf(msgtemp, "There's no account with username %.64s.", username); message_send_text(c, message_type_info, c, msgtemp); return -1; } dst_c = account_get_conn(acc); if (command == '+') { if (account_get_auth_operator(acc,NULL) == 1) sprintf(msgtemp,"%s is already a Server Operator",username); else { account_set_auth_operator(acc,NULL,1); sprintf(msgtemp,"%s has been promoted to a Server Operator",username); sprintf(msgtemp2,"%s has promoted you to a Server Operator",conn_get_loggeduser(c)); changed = 1; } } else { if (account_get_auth_operator(acc,NULL) != 1) sprintf(msgtemp,"%s is no Server Operator, so you can't demote him",username); else { account_set_auth_operator(acc,NULL,0); sprintf(msgtemp,"%s has been demoted from a Server Operator",username); sprintf(msgtemp2,"%s has promoted you to a Server Operator",conn_get_loggeduser(c)); changed = 1; } } if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2); message_send_text(c, message_type_info, c, msgtemp); command_set_flags(dst_c); return 0; } static int _handle_aop_command(t_connection * c, char const * text) { char const * username; char const * channel; t_account * acc; t_connection * dst_c; int changed = 0; if (!(conn_get_channel(c)) || !(channel = channel_get_name(conn_get_channel(c)))) { message_send_text(c,message_type_error,c,"This command can only be used inside a channel."); return -1; } if (account_get_auth_admin(conn_get_account(c),NULL)!=1 && account_get_auth_admin(conn_get_account(c),channel)!=1) { message_send_text(c,message_type_error,c,"You must be at least a Channel Admin to use this command."); return -1; } text = skip_command(text); if (!(username = &text[0])) { message_send_text(c, message_type_info, c, "You need to supply a username."); return -1; } if(!(acc = accountlist_find_account(username))) { sprintf(msgtemp, "There's no account with username %.64s.", username); message_send_text(c, message_type_info, c, msgtemp); return -1; } dst_c = account_get_conn(acc); if (account_get_auth_admin(acc,channel) == 1) sprintf(msgtemp,"%s is already a Channel Admin",username); else { account_set_auth_admin(acc,channel,1); sprintf(msgtemp,"%s has been promoted to a Channel Admin",username); sprintf(msgtemp2,"%s has promoted you to a Channel Admin for channel \"%s\"",conn_get_loggeduser(c),channel); changed = 1; } if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2); message_send_text(c, message_type_info, c, msgtemp); command_set_flags(dst_c); return 0; } static int _handle_vop_command(t_connection * c, char const * text) { char const * username; char const * channel; t_account * acc; t_connection * dst_c; int changed = 0; if (!(conn_get_channel(c)) || !(channel = channel_get_name(conn_get_channel(c)))) { message_send_text(c,message_type_error,c,"This command can only be used inside a channel."); return -1; } if (account_get_auth_admin(conn_get_account(c),NULL)!=1 && account_get_auth_admin(conn_get_account(c),channel)!=1) { message_send_text(c,message_type_error,c,"You must be at least a Channel Admin to use this command."); return -1; } text = skip_command(text); if (!(username = &text[0])) { message_send_text(c, message_type_info, c, "You need to supply a username."); return -1; } if(!(acc = accountlist_find_account(username))) { sprintf(msgtemp, "There's no account with username %.64s.", username); message_send_text(c, message_type_info, c, msgtemp); return -1; } dst_c = account_get_conn(acc); if (account_get_auth_voice(acc,channel) == 1) sprintf(msgtemp,"%s is already on VOP list",username); else { account_set_auth_voice(acc,channel,1); sprintf(msgtemp,"%s has been added to the VOP list",username); sprintf(msgtemp2,"%s has added you to the VOP list of channel \"%s\"",conn_get_loggeduser(c),channel); changed = 1; } if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2); message_send_text(c, message_type_info, c, msgtemp); command_set_flags(dst_c); return 0; } static int _handle_voice_command(t_connection * c, char const * text) { char const * username; char const * channel; t_account * acc; t_connection * dst_c; int changed = 0; if (!(conn_get_channel(c)) || !(channel = channel_get_name(conn_get_channel(c)))) { message_send_text(c,message_type_error,c,"This command can only be used inside a channel."); return -1; } if (!(account_is_operator_or_admin(conn_get_account(c),channel_get_name(conn_get_channel(c))))) { message_send_text(c,message_type_error,c,"You must be at least a Channel Operator to use this command."); return -1; } text = skip_command(text); if (!(username = &text[0])) { message_send_text(c, message_type_info, c, "You need to supply a username."); return -1; } if(!(acc = accountlist_find_account(username))) { sprintf(msgtemp, "There's no account with username %.64s.", username); message_send_text(c, message_type_info, c, msgtemp); return -1; } dst_c = account_get_conn(acc); if (account_get_auth_voice(acc,channel)==1) sprintf(msgtemp,"%s is already on VOP list, no need to Voice him", username); else { if ((!dst_c) || conn_get_channel(c)!=conn_get_channel(dst_c)) { sprintf(msgtemp,"%s must be on the same channel to voice him",username); } else { if (channel_conn_has_tmpVOICE(conn_get_channel(c),dst_c)) sprintf(msgtemp,"%s has already Voice in this channel",username); else { if (account_is_operator_or_admin(acc,channel)) sprintf(msgtemp,"%s allready is operator or admin, no need to voice him",username); else { conn_set_tmpVOICE_channel(dst_c,channel); sprintf(msgtemp,"%s has been granted Voice in this channel",username); sprintf(msgtemp2,"%s has granted you Voice in this channel",conn_get_loggeduser(c)); changed = 1; } } } } if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2); message_send_text(c, message_type_info, c, msgtemp); command_set_flags(dst_c); return 0; } static int _handle_devoice_command(t_connection * c, char const * text) { char const * username; char const * channel; t_account * acc; t_connection * dst_c; int done = 0; int changed = 0; if (!(conn_get_channel(c)) || !(channel = channel_get_name(conn_get_channel(c)))) { message_send_text(c,message_type_error,c,"This command can only be used inside a channel."); return -1; } if (!(account_is_operator_or_admin(conn_get_account(c),channel_get_name(conn_get_channel(c))))) { message_send_text(c,message_type_error,c,"You must be at least a Channel Operator to use this command."); return -1; } text = skip_command(text); if (!(username = &text[0])) { message_send_text(c, message_type_info, c, "You need to supply a username."); return -1; } if(!(acc = accountlist_find_account(username))) { sprintf(msgtemp, "There's no account with username %.64s.", username); message_send_text(c, message_type_info, c, msgtemp); return -1; } dst_c = account_get_conn(acc); if (account_get_auth_voice(acc,channel)==1) { if ((account_get_auth_admin(conn_get_account(c),channel)==1) || (account_get_auth_admin(conn_get_account(c),NULL)==1)) { account_set_auth_voice(acc,channel,0); sprintf(msgtemp,"%s has been removed from VOP list.",username); sprintf(msgtemp2,"%s has removed you from VOP list of channel \"%s\"",conn_get_loggeduser(c),channel); changed = 1; } else { sprintf(msgtemp,"You must be at least Channel Admin to remove %s from the VOP list",username); } done = 1; } if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2); message_send_text(c, message_type_info, c, msgtemp); changed = 0; if ((dst_c) && channel_conn_has_tmpVOICE(conn_get_channel(c),dst_c)==1) { conn_set_tmpVOICE_channel(dst_c,NULL); sprintf(msgtemp,"Voice has been taken from %s in this channel",username); sprintf(msgtemp2,"%s has taken your Voice in channel \"%s\"",conn_get_loggeduser(c),channel); changed = 1; done = 1; } if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2); message_send_text(c, message_type_info, c, msgtemp); if (!done) { sprintf(msgtemp,"%s has no Voice in this channel, so it can't be taken away",username); message_send_text(c, message_type_info, c, msgtemp); } command_set_flags(dst_c); return 0; } static int _handle_op_command(t_connection * c, char const * text) { char const * username; char const * channel; t_account * acc; int OP_lvl; t_connection * dst_c; int changed = 0; if (!(conn_get_channel(c)) || !(channel = channel_get_name(conn_get_channel(c)))) { message_send_text(c,message_type_error,c,"This command can only be used inside a channel."); return -1; } acc = conn_get_account(c); OP_lvl = 0; if (account_is_operator_or_admin(acc,channel)) OP_lvl = 1; else if (channel_conn_is_tmpOP(conn_get_channel(c),c)) OP_lvl = 2; if (OP_lvl==0) { message_send_text(c,message_type_error,c,"You must be at least a Channel Operator or tempOP to use this command."); return -1; } text = skip_command(text); if (!(username = &text[0])) { message_send_text(c, message_type_info, c, "You need to supply a username."); return -1; } if(!(acc = accountlist_find_account(username))) { sprintf(msgtemp, "There's no account with username %.64s.", username); message_send_text(c, message_type_info, c, msgtemp); return -1; } dst_c = account_get_conn(acc); if (OP_lvl==1) // user is full op so he may fully op others { if (account_get_auth_operator(acc,channel) == 1) sprintf(msgtemp,"%s is allready a Channel Operator",username); else { account_set_auth_operator(acc,channel,1); sprintf(msgtemp,"%s has been promoted to a Channel Operator",username); sprintf(msgtemp2,"%s has promoted you to a Channel Operator in channel \"%s\"",conn_get_loggeduser(c),channel); changed = 1; } } else { // user is only tempOP so he may only tempOP others if ((!(dst_c)) || (conn_get_channel(c) != conn_get_channel(dst_c))) sprintf(msgtemp,"%s must be on the same channel to tempOP him",username); else { if (account_is_operator_or_admin(acc,channel)) sprintf(msgtemp,"%s allready is operator or admin, no need to tempOP him",username); else { conn_set_tmpOP_channel(dst_c,channel); sprintf(msgtemp,"%s has been promoted to a tempOP",username); sprintf(msgtemp2,"%s has promoted you to a tempOP in this channel",conn_get_loggeduser(c)); changed = 1; } } } if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2); message_send_text(c, message_type_info, c, msgtemp); command_set_flags(dst_c); return 0; } static int _handle_tmpop_command(t_connection * c, char const * text) { char const * username; char const * channel; t_account * acc; t_connection * dst_c; int changed = 0; if (!(conn_get_channel(c)) || !(channel = channel_get_name(conn_get_channel(c)))) { message_send_text(c,message_type_error,c,"This command can only be used inside a channel."); return -1; } 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))) { message_send_text(c,message_type_error,c,"You must be at least a Channel Operator or tmpOP to use this command."); return -1; } text = skip_command(text); if (!(username = &text[0])) { message_send_text(c, message_type_info, c, "You need to supply a username."); return -1; } if(!(acc = accountlist_find_account(username))) { sprintf(msgtemp, "There's no account with username %.64s.", username); message_send_text(c, message_type_info, c, msgtemp); return -1; } dst_c = account_get_conn(acc); if (channel_conn_is_tmpOP(conn_get_channel(c),dst_c)) sprintf(msgtemp,"%s has already tmpOP in this channel",username); else { if ((!(dst_c)) || (conn_get_channel(c) != conn_get_channel(dst_c))) sprintf(msgtemp,"%s must be on the same channel to tempOP him",username); else { if (account_is_operator_or_admin(acc,channel)) sprintf(msgtemp,"%s allready is operator or admin, no need to tempOP him",username); else { conn_set_tmpOP_channel(dst_c,channel); sprintf(msgtemp,"%s has been promoted to tmpOP in this channel",username); sprintf(msgtemp2,"%s has promoted you to a tempOP in this channel",conn_get_loggeduser(c)); changed = 1; } } } if (changed && dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2); message_send_text(c, message_type_info, c, msgtemp); command_set_flags(dst_c); return 0; } static int _handle_deop_command(t_connection * c, char const * text) { char const * username; char const * channel; t_account * acc; int OP_lvl; t_connection * dst_c; int done = 0; if (!(conn_get_channel(c)) || !(channel = channel_get_name(conn_get_channel(c)))) { message_send_text(c,message_type_error,c,"This command can only be used inside a channel."); return -1; } acc = conn_get_account(c); OP_lvl = 0; if (account_is_operator_or_admin(acc,channel)) OP_lvl = 1; else if (channel_conn_is_tmpOP(conn_get_channel(c),account_get_conn(acc))) OP_lvl = 2; if (OP_lvl==0) { message_send_text(c,message_type_error,c,"You must be at least a Channel Operator or tempOP to use this command."); return -1; } text = skip_command(text); if (!(username = &text[0])) { message_send_text(c, message_type_info, c, "You need to supply a username."); return -1; } if(!(acc = accountlist_find_account(username))) { sprintf(msgtemp, "There's no account with username %.64s.", username); message_send_text(c, message_type_info, c, msgtemp); return -1; } dst_c = account_get_conn(acc); if (OP_lvl==1) // user is real OP and allowed to deOP { if (account_get_auth_admin(acc,channel) == 1 || account_get_auth_operator(acc,channel) == 1) { if (account_get_auth_admin(acc,channel) == 1) { if (account_get_auth_admin(conn_get_account(c),channel)!=1 && account_get_auth_admin(conn_get_account(c),NULL)!=1) message_send_text(c,message_type_info,c,"You must be at least a Channel Admin to demote another Channel Admin"); else { account_set_auth_admin(acc,channel,0); sprintf(msgtemp, "%s has been demoted from a Channel Admin.", username); message_send_text(c, message_type_info, c, msgtemp); if (dst_c) { sprintf(msgtemp2,"%s has demoted you from a Channel Admin of channel \"%s\"",conn_get_loggeduser(c),channel); message_send_text(dst_c, message_type_info, c, msgtemp2); } } } if (account_get_auth_operator(acc,channel) == 1) { account_set_auth_operator(acc,channel,0); sprintf(msgtemp,"%s has been demoted from a Channel Operator",username); message_send_text(c, message_type_info, c, msgtemp); if (dst_c) { sprintf(msgtemp2,"%s has demoted you from a Channel Operator of channel \"%s\"",conn_get_loggeduser(c),channel); message_send_text(dst_c, message_type_info, c, msgtemp2); } } done = 1; } if ((dst_c) && channel_conn_is_tmpOP(conn_get_channel(c),dst_c)) { conn_set_tmpOP_channel(dst_c,NULL); sprintf(msgtemp,"%s has been demoted from a tempOP of this channel",username); message_send_text(c, message_type_info, c, msgtemp); if (dst_c) { sprintf(msgtemp2,"%s has demoted you from a tmpOP of channel \"%s\"",conn_get_loggeduser(c),channel); message_send_text(dst_c, message_type_info, c, msgtemp2); } done = 1; } if (!done) { sprintf(msgtemp,"%s is no Channel Admin or Channel Operator or tempOP, so you can't demote him.",username); message_send_text(c, message_type_info, c, msgtemp); } } else //user is just a tempOP and may only deOP other tempOPs { if (dst_c && channel_conn_is_tmpOP(conn_get_channel(c),dst_c)) { conn_set_tmpOP_channel(account_get_conn(acc),NULL); sprintf(msgtemp,"%s has been demoted from a tempOP of this channel",username); message_send_text(c, message_type_info, c, msgtemp); sprintf(msgtemp2,"%s has demoted you from a tempOP of channel \"%s\"",conn_get_loggeduser(c),channel); if (dst_c) message_send_text(dst_c, message_type_info, c, msgtemp2); } else { sprintf(msgtemp,"%s is no tempOP in this channel, so you can't demote him",username); message_send_text(c, message_type_info, c, msgtemp); } } command_set_flags(connlist_find_connection_by_accountname(username)); return 0; } static int _handle_friends_command(t_connection * c, char const * text) { int i; t_account *my_acc = conn_get_account(c); text = skip_command(text);; if(text[0]=='\0' || strstart(text,"help")==0 || strstart(text, "h")==0) { message_send_text(c,message_type_info,c,"Friends List (Used in Arranged Teams and finding online friends.)"); message_send_text(c,message_type_info,c,"Type: /f add (adds a friend to your list)"); message_send_text(c,message_type_info,c,"Type: /f del (removes a friend from your list)"); message_send_text(c,message_type_info,c,"Type: /f promote (promote a friend in your list)"); message_send_text(c,message_type_info,c,"Type: /f demote (demote a friend in your list)"); message_send_text(c,message_type_info,c,"Type: /f list (shows your full friends list)"); message_send_text(c,message_type_info,c,"Type: /f msg (whispers a message to all your friends at once)"); return 0; } if (strstart(text,"add")==0 || strstart(text,"a")==0) { char msgtemp[MAX_MESSAGE_LEN]; t_packet * rpacket; t_connection * dest_c; t_account * friend_acc; t_server_friendslistreply_status status; t_game * game; t_channel * channel; char stat; t_list * flist; t_friend * fr; text = skip_command(text); if (text[0] == '\0') { message_send_text(c,message_type_info,c,"usage: /f add "); return 0; } if (!(friend_acc = accountlist_find_account(text))) { message_send_text(c,message_type_info,c,"That user does not exist."); return 0; } switch(account_add_friend(my_acc, friend_acc)) { case -1: message_send_text(c,message_type_error,c,"Server error."); return 0; case -2: message_send_text(c,message_type_info,c,"You can't add yourself to your friends list."); return 0; case -3: sprintf(msgtemp, "You can only have a maximum of %d friends.", prefs_get_max_friends()); message_send_text(c,message_type_info,c,msgtemp); return 0; case -4: sprintf(msgtemp, "%s is already on your friends list!", text); message_send_text(c,message_type_info,c,msgtemp); return 0; } sprintf( msgtemp, "Added %s to your friends list.", text); message_send_text(c,message_type_info,c,msgtemp); dest_c = connlist_find_connection_by_account(friend_acc); if(dest_c!=NULL) { sprintf(msgtemp,"%s added you to his/her friends list.",conn_get_username(c)); message_send_text(dest_c,message_type_info,dest_c,msgtemp); } if ((conn_get_class(c)!=conn_class_bnet) || (!(rpacket = packet_create(packet_class_bnet)))) return 0; packet_set_size(rpacket,sizeof(t_server_friendadd_ack)); packet_set_type(rpacket,SERVER_FRIENDADD_ACK); packet_append_string(rpacket, account_get_name(friend_acc)); game = NULL; channel = NULL; if(!(dest_c)) { bn_byte_set(&status.location,FRIENDSTATUS_OFFLINE); bn_byte_set(&status.status,0); bn_int_set(&status.clienttag,0); } else { bn_int_set(&status.clienttag, conn_get_clienttag(dest_c)); stat = 0; flist = account_get_friends(my_acc); fr = friendlist_find_account(flist,friend_acc); if ((friend_get_mutual(fr))) stat |= FRIEND_TYPE_MUTUAL; if ((conn_get_dndstr(dest_c))) stat |= FRIEND_TYPE_DND; if ((conn_get_awaystr(dest_c))) stat |= FRIEND_TYPE_AWAY; bn_byte_set(&status.status,stat); if((game = conn_get_game(dest_c))) { if (game_get_flag(game) != game_flag_private) bn_byte_set(&status.location,FRIENDSTATUS_PUBLIC_GAME); else bn_byte_set(&status.location,FRIENDSTATUS_PRIVATE_GAME); } else if((channel = conn_get_channel(dest_c))) { bn_byte_set(&status.location,FRIENDSTATUS_CHAT); } else { bn_byte_set(&status.location,FRIENDSTATUS_ONLINE); } } packet_append_data(rpacket, &status, sizeof(status)); if (game) packet_append_string(rpacket,game_get_name(game)); else if (channel) packet_append_string(rpacket,channel_get_name(channel)); else packet_append_string(rpacket,""); conn_push_outqueue(c,rpacket); packet_del_ref(rpacket); return 0; } if (strstart(text,"msg")==0 || strstart(text,"w")==0 || strstart(text,"whisper")==0 || strstart(text,"m")==0) { char const *msg; int cnt = 0; t_connection * dest_c; t_elem * curr; t_friend * fr; t_list * flist; msg = skip_command(text); /* if the message test is empty then ignore command */ if (msg[0]=='\0') { message_send_text(c,message_type_info,c,"Did not message any friends. Type some text next time."); return 0; } flist=account_get_friends(my_acc); if(flist==NULL) return -1; LIST_TRAVERSE(flist,curr) { if (!(fr = elem_get_data(curr))) { eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list"); continue; } if(friend_get_mutual(fr)) { dest_c = connlist_find_connection_by_account(friend_get_account(fr)); if (!dest_c) continue; message_send_text(dest_c,message_type_whisper,c,msg); cnt++; } } if(cnt) message_send_text(c,message_type_friendwhisperack,c,msg); else message_send_text(c,message_type_info,c,"All your friends are offline."); return 0; } if (strstart(text,"r")==0 || strstart(text,"remove")==0 || strstart(text,"del")==0 || strstart(text,"delete")==0) { int num; char msgtemp[MAX_MESSAGE_LEN]; t_packet * rpacket; text = skip_command(text); if (text[0]=='\0') { message_send_text(c,message_type_info,c,"usage: /f remove "); return 0; } switch((num = account_remove_friend2(my_acc, text))) { case -1: return -1; case -2: sprintf(msgtemp, "%s was not found on your friends list.", text); message_send_text(c,message_type_info,c,msgtemp); return 0; default: sprintf(msgtemp, "Removed %s from your friends list.", text); message_send_text(c,message_type_info,c,msgtemp); if ((conn_get_class(c)!=conn_class_bnet) || (!(rpacket = packet_create(packet_class_bnet)))) return 0; packet_set_size(rpacket,sizeof(t_server_frienddel_ack)); packet_set_type(rpacket,SERVER_FRIENDDEL_ACK); bn_byte_set(&rpacket->u.server_frienddel_ack.friendnum, num); conn_push_outqueue(c,rpacket); packet_del_ref(rpacket); return 0; } } if (strstart(text,"p")==0 || strstart(text,"promote")==0) { int num; int n; char msgtemp[MAX_MESSAGE_LEN]; char const * dest_name; t_packet * rpacket; t_list * flist; t_friend * fr; t_account * dest_acc; unsigned int dest_uid; text = skip_command(text); if (text[0]=='\0') { message_send_text(c,message_type_info,c,"usage: /f promote "); return 0; } num = account_get_friendcount(my_acc); flist = account_get_friends(my_acc); for(n = 1; nu.server_friendmove_ack.pos1, n-1); bn_byte_set(&rpacket->u.server_friendmove_ack.pos2, n); conn_push_outqueue(c,rpacket); packet_del_ref(rpacket); return 0; } return 0; } if (strstart(text,"d")==0 || strstart(text,"demote")==0) { int num; int n; char msgtemp[MAX_MESSAGE_LEN]; char const * dest_name; t_packet * rpacket; t_list * flist; t_friend * fr; t_account * dest_acc; unsigned int dest_uid; text = skip_command(text); if (text[0]=='\0') { message_send_text(c,message_type_info,c,"usage: /f demote "); return 0; } num = account_get_friendcount(my_acc); flist = account_get_friends(my_acc); for(n = 0; nu.server_friendmove_ack.pos1, n); bn_byte_set(&rpacket->u.server_friendmove_ack.pos2, n+1); conn_push_outqueue(c,rpacket); packet_del_ref(rpacket); return 0; } return 0; } if (strstart(text,"list")==0 || strstart(text,"l")==0) { char const * friend; char status[128]; char software[64]; char msgtemp[MAX_MESSAGE_LEN]; t_connection * dest_c; t_account * friend_acc; t_game const * game; t_channel const * channel; t_friend * fr; t_list * flist; int num; unsigned int uid; message_send_text(c,message_type_info,c,"Your PvPGN - Friends List"); message_send_text(c,message_type_info,c,"=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="); num = account_get_friendcount(my_acc); flist=account_get_friends(my_acc); if(flist!=NULL) { for (i=0;i "); return 0; } do_whisper(c,dest,&text[i]); return 0; } static int _handle_status_command(t_connection * c, char const *text) { char ctag[5]; unsigned int i,j; t_clienttag clienttag; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get clienttag */ if (j"); return 0; } if (!(channel = channellist_find_channel_by_name(&text[i],conn_get_country(c),realm_get_name(conn_get_realm(c))))) { message_send_text(c,message_type_error,c,"That channel does not exist."); message_send_text(c,message_type_error,c,"(If you are trying to search for a user, use the /whois command.)"); return 0; } if (channel_check_banning(channel,c)==1) { message_send_text(c,message_type_error,c,"You are banned from that channel."); return 0; } sprintf(msgtemp,"Users in channel %.64s:",&text[i]); i = strlen(msgtemp); for (conn=channel_get_first(channel); conn; conn=channel_get_next()) { if (i+strlen((tname = conn_get_username(conn)))+2>sizeof(msgtemp)) /* " ", name, '\0' */ { message_send_text(c,message_type_info,c,msgtemp); i = 0; } sprintf(&msgtemp[i]," %s",tname); i += strlen(&msgtemp[i]); } if (i>0) message_send_text(c,message_type_info,c,msgtemp); return 0; } static int _handle_whois_command(t_connection * c, char const * text) { unsigned int i; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); if (text[i]=='\0') { message_send_text(c,message_type_info,c,"usage: /whois "); return 0; } do_whois(c,&text[i]); return 0; } static int _handle_whoami_command(t_connection * c, char const *text) { char const * tname; if (!(tname = conn_get_username(c))) { message_send_text(c,message_type_error,c,"Unable to obtain your account name."); return 0; } do_whois(c,tname); return 0; } static int _handle_announce_command(t_connection * c, char const *text) { unsigned int i; t_message * message; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); if (text[i]=='\0') { message_send_text(c,message_type_info,c,"usage: /announce "); return 0; } sprintf(msgtemp,"Announcement from %.64s: %.128s",conn_get_username(c),&text[i]); if (!(message = message_create(message_type_broadcast,c,NULL,msgtemp))) message_send_text(c,message_type_info,c,"Could not broadcast message."); else { if (message_send_all(message)<0) message_send_text(c,message_type_info,c,"Could not broadcast message."); message_destroy(message); } return 0; } static int _handle_beep_command(t_connection * c, char const *text) { message_send_text(c,message_type_info,c,"Audible notification on."); /* FIXME: actually do something */ return 0; /* FIXME: these only affect CHAT clients... I think they prevent ^G from being sent */ } static int _handle_nobeep_command(t_connection * c, char const *text) { message_send_text(c,message_type_info,c,"Audible notification off."); /* FIXME: actually do something */ return 0; } static int _handle_version_command(t_connection * c, char const *text) { message_send_text(c,message_type_info,c,PVPGN_SOFTWARE" "PVPGN_VERSION); return 0; } static int _handle_copyright_command(t_connection * c, char const *text) { static char const * const info[] = { " Copyright (C) 2002 See source for details", " ", " PvPGN is free software; you can redistribute it and/or", " modify it under the terms of the GNU General Public License", " as published by the Free Software Foundation; either version 2", " of the License, or (at your option) any later version.", " ", " This program is distributed in the hope that it will be useful,", " but WITHOUT ANY WARRANTY; without even the implied warranty of", " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", " GNU General Public License for more details.", " ", " You should have received a copy of the GNU General Public License", " along with this program; if not, write to the Free Software", " Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.", NULL }; unsigned int i; for (i=0; info[i]; i++) message_send_text(c,message_type_info,c,info[i]); return 0; } static int _handle_uptime_command(t_connection * c, char const *text) { sprintf(msgtemp,"Uptime: %s",seconds_to_timestr(server_get_uptime())); message_send_text(c,message_type_info,c,msgtemp); return 0; } static int _handle_stats_command(t_connection * c, char const *text) { char dest[USER_NAME_MAX]; unsigned int i,j; t_account * account; char const * clienttag=NULL; t_clienttag clienttag_uint; char clienttag_str[5]; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */ if (j0) sprintf(msgtemp,"Ladder games: %u-%u-%u (rating %d)", account_get_ladder_wins(account,clienttag_uint,ladder_id_normal), account_get_ladder_losses(account,clienttag_uint,ladder_id_normal), account_get_ladder_disconnects(account,clienttag_uint,ladder_id_normal), account_get_ladder_rating(account,clienttag_uint,ladder_id_normal)); else strcpy(msgtemp,"Ladder games: 0-0-0"); message_send_text(c,message_type_info,c,msgtemp); if (account_get_ladder_rating(account,clienttag_uint,ladder_id_ironman)>0) sprintf(msgtemp,"IronMan games: %u-%u-%u (rating %d)", account_get_ladder_wins(account,clienttag_uint,ladder_id_ironman), account_get_ladder_losses(account,clienttag_uint,ladder_id_ironman), account_get_ladder_disconnects(account,clienttag_uint,ladder_id_ironman), account_get_ladder_rating(account,clienttag_uint,ladder_id_ironman)); else strcpy(msgtemp,"IronMan games: 0-0-0"); message_send_text(c,message_type_info,c,msgtemp); return 0; case CLIENTTAG_WARCRAFT3_UINT: case CLIENTTAG_WAR3XP_UINT: sprintf(msgtemp,"%.64s's Ladder Record's:",account_get_name(account)); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"Users Solo Level: %u, Experience: %u", account_get_ladder_level(account,clienttag_uint,ladder_id_solo), account_get_ladder_xp(account,clienttag_uint,ladder_id_solo)); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"SOLO Ladder Record: %u-%u-0", account_get_ladder_wins(account,clienttag_uint,ladder_id_solo), account_get_ladder_losses(account,clienttag_uint,ladder_id_solo)); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"SOLO Rank: %u", account_get_ladder_rank(account,clienttag_uint,ladder_id_solo)); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"Users Team Level: %u, Experience: %u", account_get_ladder_level(account,clienttag_uint,ladder_id_team), account_get_ladder_xp(account,clienttag_uint,ladder_id_team)); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"TEAM Ladder Record: %u-%u-0", account_get_ladder_wins(account,clienttag_uint,ladder_id_team), account_get_ladder_losses(account,clienttag_uint,ladder_id_team)); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"TEAM Rank: %u", account_get_ladder_rank(account,clienttag_uint,ladder_id_team)); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"Users FFA Level: %u, Experience: %u", account_get_ladder_level(account,clienttag_uint,ladder_id_ffa), account_get_ladder_xp(account,clienttag_uint,ladder_id_ffa)); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"FFA Ladder Record: %u-%u-0", account_get_ladder_wins(account,clienttag_uint,ladder_id_ffa), account_get_ladder_losses(account,clienttag_uint,ladder_id_ffa)); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"FFA Rank: %u", account_get_ladder_rank(account,clienttag_uint,ladder_id_ffa)); message_send_text(c,message_type_info,c,msgtemp); if (account_get_teams(account)) { t_elem * curr; t_list * list; t_team * team; int teamcount = 0; list = account_get_teams(account); LIST_TRAVERSE(list,curr) { if (!(team = elem_get_data(curr))) { eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list"); continue; } if (team_get_clienttag(team) != clienttag_uint) continue; teamcount++; sprintf(msgtemp,"Users AT Team No. %u",teamcount); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"Users AT TEAM Level: %u, Experience: %u", team_get_level(team),team_get_xp(team)); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"AT TEAM Ladder Record: %u-%u-0", team_get_wins(team),team_get_losses(team)); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"AT TEAM Rank: %u", team_get_rank(team)); message_send_text(c,message_type_info,c,msgtemp); } } return 0; default: sprintf(msgtemp,"%.64s's record:",account_get_name(account)); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"Normal games: %u-%u-%u", account_get_normal_wins(account,clienttag_uint), account_get_normal_losses(account,clienttag_uint), account_get_normal_disconnects(account,clienttag_uint)); message_send_text(c,message_type_info,c,msgtemp); if (account_get_ladder_rating(account,clienttag_uint,ladder_id_normal)>0) sprintf(msgtemp,"Ladder games: %u-%u-%u (rating %d)", account_get_ladder_wins(account,clienttag_uint,ladder_id_normal), account_get_ladder_losses(account,clienttag_uint,ladder_id_normal), account_get_ladder_disconnects(account,clienttag_uint,ladder_id_normal), account_get_ladder_rating(account,clienttag_uint,ladder_id_normal)); else strcpy(msgtemp,"Ladder games: 0-0-0"); message_send_text(c,message_type_info,c,msgtemp); return 0; } } static int _handle_time_command(t_connection * c, char const *text) { t_bnettime btsystem; t_bnettime btlocal; time_t now; struct tm * tmnow; btsystem = bnettime(); /* Battle.net time: Wed Jun 23 15:15:29 */ btlocal = bnettime_add_tzbias(btsystem,local_tzbias()); now = bnettime_to_time(btlocal); if (!(tmnow = gmtime(&now))) strcpy(msgtemp,"PvPGN Server Time: ?"); else strftime(msgtemp,sizeof(msgtemp),"PvPGN Server Time: %a %b %d %H:%M:%S",tmnow); message_send_text(c,message_type_info,c,msgtemp); if (conn_get_class(c)==conn_class_bnet) { btlocal = bnettime_add_tzbias(btsystem,conn_get_tzbias(c)); now = bnettime_to_time(btlocal); if (!(tmnow = gmtime(&now))) strcpy(msgtemp,"Your local time: ?"); else strftime(msgtemp,sizeof(msgtemp),"Your local time: %a %b %d %H:%M:%S",tmnow); message_send_text(c,message_type_info,c,msgtemp); } return 0; } static int _handle_channel_command(t_connection * c, char const *text) { t_channel * channel; text = skip_command(text); if (conn_get_wol(c)) { message_send_text(c,message_type_error,c,"Sorry, this command is currently disabled for WOL clients."); return 0; } if (text[0]=='\0') { message_send_text(c,message_type_info,c,"usage /channel "); return 0; } if(strcasecmp(text,"Arranged Teams")==0) { // if(account_get_auth_admin(conn_get_account(c))>0) // { // message_send_text(c,message_type_error,c,"Please do not talk in channel Arranged Teams"); // message_send_text(c,message_type_error,c,"This channel is dedicated for the preparation of"); // message_send_text(c,message_type_error,c,"Arranged Team Games."); // } // else // { message_send_text(c,message_type_error,c,"Channel Arranged Teams is a RESTRICTED Channel!"); return 0; // } } if (!(strlen(text) < CHANNEL_NAME_LEN)) { sprintf(msgtemp,"max channel name length exceeded (max %d symbols)", CHANNEL_NAME_LEN - 1); message_send_text(c,message_type_error,c,msgtemp); return 0; } if ((channel = conn_get_channel(c)) && (strcasecmp(channel_get_name(channel),text)==0)) return 0; // we don't have to do anything, we are allready in this channel if (conn_set_channel(c,text)<0) conn_set_channel(c,CHANNEL_NAME_BANNED); /* should not fail */ if ((conn_get_clienttag(c) == CLIENTTAG_WARCRAFT3_UINT) || (conn_get_clienttag(c) == CLIENTTAG_WAR3XP_UINT)) conn_update_w3_playerinfo(c); command_set_flags(c); return 0; } static int _handle_rejoin_command(t_connection * c, char const *text) { if (channel_rejoin(c)!=0) message_send_text(c,message_type_error,c,"You are not in a channel."); if ((conn_get_clienttag(c) == CLIENTTAG_WARCRAFT3_UINT) || (conn_get_clienttag(c) == CLIENTTAG_WAR3XP_UINT)) conn_update_w3_playerinfo(c); command_set_flags(c); return 0; } static int _handle_away_command(t_connection * c, char const *text) { text = skip_command(text); if (text[0]=='\0') /* toggle away mode */ { if (!conn_get_awaystr(c)) { message_send_text(c,message_type_info,c,"You are now marked as being away."); conn_set_awaystr(c,"Currently not available"); } else { message_send_text(c,message_type_info,c,"You are no longer marked as away."); conn_set_awaystr(c,NULL); } } else { message_send_text(c,message_type_info,c,"You are now marked as being away."); conn_set_awaystr(c,text); } return 0; } static int _handle_dnd_command(t_connection * c, char const *text) { text = skip_command(text); if (text[0]=='\0') /* toggle dnd mode */ { if (!conn_get_dndstr(c)) { message_send_text(c,message_type_info,c,"Do Not Diturb mode engaged."); conn_set_dndstr(c,"Not available"); } else { message_send_text(c,message_type_info,c,"Do Not Disturb mode cancelled."); conn_set_dndstr(c,NULL); } } else { message_send_text(c,message_type_info,c,"Do Not Disturb mode engaged."); conn_set_dndstr(c,text); } return 0; } static int _handle_squelch_command(t_connection * c, char const *text) { t_account * account; text = skip_command(text); /* D2 puts * before username */ if (text[0]=='*') text++; if (text[0]=='\0') { message_send_text(c,message_type_info,c,"usage: /squelch "); return 0; } if (!(account = accountlist_find_account(text))) { message_send_text(c,message_type_error,c,"No such user."); return 0; } if (conn_get_account(c)==account) { message_send_text(c,message_type_error,c,"You can't squelch yourself."); return 0; } if (conn_add_ignore(c,account)<0) message_send_text(c,message_type_error,c,"Could not squelch user."); else { sprintf(msgtemp,"%-.20s has been squelched.",account_get_name(account)); message_send_text(c,message_type_info,c,msgtemp); } return 0; } static int _handle_unsquelch_command(t_connection * c, char const *text) { t_account * account; t_connection * dest_c; text = skip_command(text); /* D2 puts * before username */ if (text[0]=='*') text++; if (text[0]=='\0') { message_send_text(c,message_type_info,c,"usage: /unsquelch "); return 0; } if (!(account = accountlist_find_account(text))) { message_send_text(c,message_type_info,c,"No such user."); return 0; } if (conn_del_ignore(c,account)<0) message_send_text(c,message_type_info,c,"User was not being ignored."); else { t_message * message; message_send_text(c,message_type_info,c,"No longer ignoring."); if ((dest_c = account_get_conn(account))) { if (!(message = message_create(message_type_userflags,dest_c,NULL,NULL))) /* handles NULL text */ return 0; message_send(message,c); message_destroy(message); } } return 0; } static int _handle_kick_command(t_connection * c, char const *text) { char dest[USER_NAME_MAX]; unsigned int i,j; t_channel const * channel; t_connection * kuc; t_account * acc; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */ if (j"); return 0; } if (!(channel = conn_get_channel(c))) { message_send_text(c,message_type_error,c,"This command can only be used inside a channel."); return 0; } acc = conn_get_account(c); if (account_get_auth_admin(acc,NULL)!=1 && /* default to false */ account_get_auth_admin(acc,channel_get_name(channel))!=1 && /* default to false */ account_get_auth_operator(acc,NULL)!=1 && /* default to false */ account_get_auth_operator(acc,channel_get_name(channel))!=1 && /* default to false */ !channel_conn_is_tmpOP(channel,account_get_conn(acc))) { message_send_text(c,message_type_error,c,"You have to be at least a Channel Operator or tempOP to use this command."); return 0; } if (!(kuc = connlist_find_connection_by_accountname(dest))) { message_send_text(c,message_type_error,c,"That user is not logged in."); return 0; } if (conn_get_channel(kuc)!=channel) { message_send_text(c,message_type_error,c,"That user is not in this channel."); return 0; } if (account_get_auth_admin(conn_get_account(kuc),NULL)==1 || account_get_auth_admin(conn_get_account(kuc),channel_get_name(channel))==1) { message_send_text(c,message_type_error,c,"You cannot kick administrators."); return 0; } else if (account_get_auth_operator(conn_get_account(kuc),NULL)==1 || account_get_auth_operator(conn_get_account(kuc),channel_get_name(channel))==1) { message_send_text(c,message_type_error,c,"You cannot kick operators."); return 0; } { char const * tname1; char const * tname2; tname1 = conn_get_loggeduser(kuc); tname2 = conn_get_loggeduser(c); if (!tname1 || !tname2) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL username"); return -1; } if (text[i]!='\0') sprintf(msgtemp,"%-.20s has been kicked by %-.20s (%s).",tname1,tname2,&text[i]); else sprintf(msgtemp,"%-.20s has been kicked by %-.20s.",tname1,tname2); channel_message_send(channel,message_type_info,c,msgtemp); } conn_set_channel(kuc,CHANNEL_NAME_KICKED); /* should not fail */ return 0; } static int _handle_ban_command(t_connection * c, char const *text) { char dest[USER_NAME_MAX]; unsigned int i,j; t_channel * channel; t_connection * buc; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */ if (j"); return 0; } if (!(channel = conn_get_channel(c))) { message_send_text(c,message_type_error,c,"This command can only be used inside a channel."); return 0; } if (account_get_auth_admin(conn_get_account(c),NULL)!=1 && /* default to false */ account_get_auth_admin(conn_get_account(c),channel_get_name(channel))!=1 && /* default to false */ account_get_auth_operator(conn_get_account(c),NULL)!=1 && /* default to false */ account_get_auth_operator(conn_get_account(c),channel_get_name(channel))!=1) /* default to false */ { message_send_text(c,message_type_error,c,"You have to be at least a Channel Operator to use this command."); return 0; } { t_account * account; if (!(account = accountlist_find_account(dest))) message_send_text(c,message_type_info,c,"That account doesn't currently exist, banning anyway."); else if (account_get_auth_admin(account,NULL)==1 || account_get_auth_admin(account,channel_get_name(channel))==1) { message_send_text(c,message_type_error,c,"You cannot ban administrators."); return 0; } else if (account_get_auth_operator(account,NULL)==1 || account_get_auth_operator(account,channel_get_name(channel))==1) { message_send_text(c,message_type_error,c,"You cannot ban operators."); return 0; } } if (channel_ban_user(channel,dest)<0) { sprintf(msgtemp,"Unable to ban %-.20s.",dest); message_send_text(c,message_type_error,c,msgtemp); } else { char const * tname; tname = conn_get_loggeduser(c); if (text[i]!='\0') sprintf(msgtemp,"%-.20s has been banned by %-.20s (%s).",dest,tname?tname:"unknown",&text[i]); else sprintf(msgtemp,"%-.20s has been banned by %-.20s.",dest,tname?tname:"unknown"); channel_message_send(channel,message_type_info,c,msgtemp); } if ((buc = connlist_find_connection_by_accountname(dest)) && conn_get_channel(buc)==channel) conn_set_channel(buc,CHANNEL_NAME_BANNED); return 0; } static int _handle_unban_command(t_connection * c, char const *text) { t_channel * channel; unsigned int i; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); if (text[i]=='\0') { message_send_text(c,message_type_info,c,"usage: /unban "); return 0; } if (!(channel = conn_get_channel(c))) { message_send_text(c,message_type_error,c,"This command can only be used inside a channel."); return 0; } if (account_get_auth_admin(conn_get_account(c),NULL)!=1 && /* default to false */ account_get_auth_admin(conn_get_account(c),channel_get_name(channel))!=1 && /* default to false */ account_get_auth_operator(conn_get_account(c),NULL)!=1 && /* default to false */ account_get_auth_operator(conn_get_account(c),channel_get_name(channel))!=1) /* default to false */ { message_send_text(c,message_type_error,c,"You are not a channel operator."); return 0; } if (channel_unban_user(channel,&text[i])<0) message_send_text(c,message_type_error,c,"That user is not banned."); else { sprintf(msgtemp,"%s is no longer banned from this channel.",&text[i]); message_send_text(c,message_type_info,c,msgtemp); } return 0; } static int _handle_reply_command(t_connection * c, char const *text) { unsigned int i; char const * dest; if (!(dest = conn_get_lastsender(c))) { message_send_text(c,message_type_error,c,"No one messaged you, use /m instead"); return 0; } for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); if (text[i]=='\0') { message_send_text(c,message_type_info,c,"usage: /reply "); return 0; } do_whisper(c,dest,&text[i]); return 0; } static int _handle_realmann_command(t_connection * c, char const *text) { unsigned int i; t_realm * realm; t_realm * trealm; t_connection * tc; t_elem const * curr; t_message * message; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); if (!(realm=conn_get_realm(c))) { message_send_text(c,message_type_info,c,"You must join a realm first"); return 0; } if (text[i]=='\0') { message_send_text(c,message_type_info,c,"usage: /realmann "); return 0; } sprintf(msgtemp,"Announcement from %.32s@%.32s: %.128s",conn_get_username(c),realm_get_name(realm),&text[i]); if (!(message = message_create(message_type_broadcast,c,NULL,msgtemp))) { message_send_text(c,message_type_info,c,"Could not broadcast message."); } else { LIST_TRAVERSE_CONST(connlist(),curr) { tc = elem_get_data(curr); if (!tc) continue; if ((trealm = conn_get_realm(tc)) && (trealm==realm)) { message_send(message,tc); } } } return 0; } static int _handle_watch_command(t_connection * c, char const *text) { unsigned int i; t_account * account; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); if (text[i]=='\0') { message_send_text(c,message_type_info,c,"usage: /watch "); return 0; } if (!(account = accountlist_find_account(&text[i]))) { message_send_text(c,message_type_info,c,"That user does not exist."); return 0; } if (conn_add_watch(c,account,0)<0) /* FIXME: adds all events for now */ message_send_text(c,message_type_error,c,"Add to watch list failed."); else { sprintf(msgtemp,"User %.64s added to your watch list.",&text[i]); message_send_text(c,message_type_info,c,msgtemp); } return 0; } static int _handle_unwatch_command(t_connection * c, char const *text) { unsigned int i; t_account * account; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); if (text[i]=='\0') { message_send_text(c,message_type_info,c,"usage: /unwatch "); return 0; } if (!(account = accountlist_find_account(&text[i]))) { message_send_text(c,message_type_info,c,"That user does not exist."); return 0; } if (conn_del_watch(c,account,0)<0) /* FIXME: deletes all events for now */ message_send_text(c,message_type_error,c,"Removal from watch list failed."); else { sprintf(msgtemp,"User %.64s removed from your watch list.",&text[i]); message_send_text(c,message_type_info,c,msgtemp); } return 0; } static int _handle_watchall_command(t_connection * c, char const *text) { t_clienttag clienttag=0; char clienttag_str[5]; text = skip_command(text); if(text[0] != '\0') { if (strlen(text) != 4) { message_send_text(c,message_type_error,c,"You must supply a rank and a valid program ID."); message_send_text(c,message_type_error,c,"Example: /watchall STAR"); return 0; } clienttag = tag_case_str_to_uint(text); } if (conn_add_watch(c,NULL,clienttag)<0) /* FIXME: adds all events for now */ message_send_text(c,message_type_error,c,"Add to watch list failed."); else if(clienttag) { char msgtemp[MAX_MESSAGE_LEN]; sprintf(msgtemp, "All %s users added to your watch list.", tag_uint_to_str(clienttag_str,clienttag)); message_send_text(c,message_type_info,c,msgtemp); } else message_send_text(c,message_type_info,c,"All users added to your watch list."); return 0; } static int _handle_unwatchall_command(t_connection * c, char const *text) { t_clienttag clienttag=0; char clienttag_str[5]; text = skip_command(text); if(text[0] != '\0') { if (strlen(text) != 4) { message_send_text(c,message_type_error,c,"You must supply a rank and a valid program ID."); message_send_text(c,message_type_error,c,"Example: /unwatchall STAR"); } clienttag = tag_case_str_to_uint(text); } if (conn_del_watch(c,NULL,clienttag)<0) /* FIXME: deletes all events for now */ message_send_text(c,message_type_error,c,"Removal from watch list failed."); else if(clienttag) { char msgtemp[MAX_MESSAGE_LEN]; sprintf(msgtemp, "All %s users removed from your watch list.", tag_uint_to_str(clienttag_str,clienttag)); message_send_text(c,message_type_info,c,msgtemp); } else message_send_text(c,message_type_info,c,"All users removed from your watch list."); return 0; } static int _handle_lusers_command(t_connection * c, char const *text) { t_channel * channel; t_elem const * curr; char const * banned; unsigned int i; if (!(channel = conn_get_channel(c))) { message_send_text(c,message_type_error,c,"This command can only be used inside a channel."); return 0; } strcpy(msgtemp,"Banned users:"); i = strlen(msgtemp); LIST_TRAVERSE_CONST(channel_get_banlist(channel),curr) { banned = elem_get_data(curr); if (i+strlen(banned)+2>sizeof(msgtemp)) /* " ", name, '\0' */ { message_send_text(c,message_type_info,c,msgtemp); i = 0; } sprintf(&msgtemp[i]," %s",banned); i += strlen(&msgtemp[i]); } if (i>0) message_send_text(c,message_type_info,c,msgtemp); return 0; } static int _news_cb(time_t date, t_lstr *lstr, void *data) { char strdate[64]; struct tm *tm; char save, *p, *q; t_connection *c = (t_connection*)data; tm = localtime(&date); if (tm) strftime(strdate, 64,"%B %d, %Y", tm); else strcpy(strdate, "(invalid date)"); message_send_text(c,message_type_info,c,strdate); for (p = lstr_get_str(lstr); *p;) { for(q = p; *q && *q != '\r' && *q != '\n';q++); save = *q; *q = '\0'; message_send_text(c,message_type_info,c,p); *q = save; p = q; for(;*p == '\n' || *p == '\r';p++); } return 0; } static int _handle_news_command(t_connection * c, char const *text) { news_traverse(_news_cb,c); return 0; } struct glist_cb_struct { t_game_difficulty diff; t_clienttag tag; t_connection *c; }; static int _glist_cb(t_game *game, void *data) { struct glist_cb_struct *cbdata = (struct glist_cb_struct*)data; if ((!cbdata->tag || !prefs_get_hide_pass_games() || game_get_flag(game) != game_flag_private) && (!cbdata->tag || game_get_clienttag(game)==cbdata->tag) && (cbdata->diff==game_difficulty_none || game_get_difficulty(game)==cbdata->diff)) { sprintf(msgtemp," %-16.16s %1.1s %-8.8s %-21.21s %5u ", game_get_name(game), game_get_flag(game) != game_flag_private ? "n":"y", game_status_get_str(game_get_status(game)), game_type_get_str(game_get_type(game)), game_get_ref(game)); if (!cbdata->tag) { strcat(msgtemp,clienttag_uint_to_str(game_get_clienttag(game))); strcat(msgtemp," "); } if ((!prefs_get_hide_addr()) || (account_get_command_groups(conn_get_account(cbdata->c)) & command_get_group("/admin-addr"))) /* default to false */ strcat(msgtemp, addr_num_to_addr_str(game_get_addr(game),game_get_port(game))); message_send_text(cbdata->c,message_type_info,cbdata->c,msgtemp); } return 0; } static int _handle_games_command(t_connection * c, char const *text) { unsigned int i; unsigned int j; char clienttag_str[5]; char dest[5]; struct glist_cb_struct cbdata; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */ if (j= MAX_MESSAGE_LEN) break; if (!first) strcat(msgtemp," ,"); strcat(msgtemp,name); if (account_get_auth_admin(acc,NULL)==1) strcat(msgtemp,"(A)"); else if (account_get_auth_operator(acc,NULL)==1) strcat(msgtemp,"(O)"); else if (account_get_auth_admin(acc,channel_get_name(channel))==1) strcat(msgtemp,"(a)"); else if (account_get_auth_operator(acc,channel_get_name(channel))==1) strcat(msgtemp,"(o)"); first = 0; } } message_send_text(c,message_type_info,c,msgtemp); } } return 0; } static int _handle_addacct_command(t_connection * c, char const *text) { unsigned int i,j; t_account * temp; t_hash passhash; char username[USER_NAME_MAX]; char pass[256]; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); for (; text[i]==' '; i++); for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get username */ if (j "); return 0; } if (account_check_name(username)<0) { message_send_text(c,message_type_error,c,"Account name contains some invalid symbol!"); return 0; } /* FIXME: truncate or err on too long password */ for (i=0; i"); return 0; } temp = accountlist_find_account(username); account = conn_get_account(c); if ((temp==account && account_get_auth_changepass(account)==0) || /* default to true */ (temp!=account && !(account_get_command_groups(conn_get_account(c)) & command_get_group("/admin-chpass")))) /* default to false */ { eventlog(eventlog_level_info,__FUNCTION__,"[%d] password change for \"%s\" refused (no change access)",conn_get_socket(c),username); message_send_text(c,message_type_error,c,"Only admins may change passwords for other accounts."); return 0; } if (!temp) { message_send_text(c,message_type_error,c,"Account does not exist."); return 0; } if (strlen(pass) > USER_PASS_MAX) { sprintf(msgtemp,"Maximum password length allowed is %d",USER_PASS_MAX); message_send_text(c,message_type_error,c,msgtemp); return 0; } for (i=0; i"); return 0; } if (!(account = accountlist_find_account(dest))) { message_send_text(c,message_type_error,c,"Invalid user."); return 0; } sprintf(msgtemp,"Login: %-16.16s "UID_FORMAT" Sex: %.14s", account_get_name(account), account_get_uid(account), account_get_sex(account)); message_send_text(c,message_type_info,c,msgtemp); if ((clanmemb = account_get_clanmember(account))) { t_clan * clan; char status; if ((clan = clanmember_get_clan(clanmemb))) { sprintf(msgtemp,"Clan : %-64.64s",clan_get_name(clan)); if ((status = clanmember_get_status(clanmemb))) { switch (status) { case CLAN_CHIEFTAIN: strcat(msgtemp," Rank: Chieftain"); break; case CLAN_SHAMAN: strcat(msgtemp," Rank: Shaman"); break; case CLAN_GRUNT: strcat(msgtemp," Rank: Grunt"); break; case CLAN_PEON: strcat(msgtemp," Rank: Peon"); break; default:; } } message_send_text(c,message_type_info,c,msgtemp); } } sprintf(msgtemp,"Location: %-23.23s Age: %.14s", account_get_loc(account), account_get_age(account)); message_send_text(c,message_type_info,c,msgtemp); if((conn = connlist_find_connection_by_accountname(dest))) { sprintf(msgtemp,"Client: %s Ver: %s Country: %s", clienttag_get_title(conn_get_clienttag(conn)), conn_get_clientver(conn), conn_get_country(conn)); message_send_text(c,message_type_info,c,msgtemp); } if (!(ip=account_get_ll_ip(account)) || !(account_get_command_groups(conn_get_account(c)) & command_get_group("/admin-addr"))) /* default to false */ ip = "unknown"; { time_t then; struct tm * tmthen; then = account_get_ll_time(account); tmthen = localtime(&then); /* FIXME: determine user's timezone */ if (!(conn)) if (tmthen) strftime(msgtemp,sizeof(msgtemp),"Last login %a %b %d %H:%M %Y from ",tmthen); else strcpy(msgtemp,"Last login ? from "); else if (tmthen) strftime(msgtemp,sizeof(msgtemp),"On since %a %b %d %H:%M %Y from ",tmthen); else strcpy(msgtemp,"On since ? from "); } strncat(msgtemp,ip,32); message_send_text(c,message_type_info,c,msgtemp); /* check /admin-addr for admin privileges */ if ( (account_get_command_groups(conn_get_account(c)) & command_get_group("/admin-addr"))) { /* the player who requested /finger has admin privileges give him more info about the one he querys; is_admin, is_operator, is_locked, email */ snprintf(msgtemp, sizeof(msgtemp), "email:%s , is_operator: %d , is_admin: %d , is_acc_locked: %d", account_get_email(account), account_get_auth_operator(account,NULL), account_get_auth_admin(account,NULL), account_get_auth_lock(account)); message_send_text(c,message_type_info,c,msgtemp); } if (conn) { sprintf(msgtemp,"Idle %s",seconds_to_timestr(conn_get_idletime(conn))); message_send_text(c,message_type_info,c,msgtemp); } strncpy(msgtemp,account_get_desc(account),sizeof(msgtemp)); msgtemp[sizeof(msgtemp)-1] = '\0'; for (tok=strtok(msgtemp,"\r\n"); tok; tok=strtok(NULL,"\r\n")) message_send_text(c,message_type_info,c,tok); message_send_text(c,message_type_info,c,""); return 0; } /* * rewrote command /operator to add and remove operator status [Omega] * * Fixme: rewrite /operators to show Currently logged on Server and/or Channel operators ...?? */ /* static int _handle_operator_command(t_connection * c, char const *text) { t_connection const * opr; t_channel const * channel; if (!(channel = conn_get_channel(c))) { message_send_text(c,message_type_error,c,"This command can only be used inside a channel."); return 0; } if (!(opr = channel_get_operator(channel))) strcpy(msgtemp,"There is no operator."); else sprintf(msgtemp,"%.64s is the operator.",conn_get_username(opr)); message_send_text(c,message_type_info,c,msgtemp); return 0; } */ /* FIXME: do we want to show just Server Admin or Channel Admin Also? [Omega] */ static int _handle_admins_command(t_connection * c, char const *text) { unsigned int i; t_elem const * curr; t_connection * tc; char const * nick; strcpy(msgtemp,"Currently logged on Administrators:"); i = strlen(msgtemp); LIST_TRAVERSE_CONST(connlist(),curr) { tc = elem_get_data(curr); if (!tc) continue; if (!conn_get_account(tc)) continue; if (account_get_auth_admin(conn_get_account(tc),NULL)==1) { if ((nick = conn_get_username(tc))) { if (i+strlen(nick)+2>sizeof(msgtemp)) /* " ", name, '\0' */ { message_send_text(c,message_type_info,c,msgtemp); i = 0; } sprintf(&msgtemp[i]," %s", nick); i += strlen(&msgtemp[i]); } } } if (i>0) message_send_text(c,message_type_info,c,msgtemp); return 0; } static int _handle_quit_command(t_connection * c, char const *text) { if (conn_get_game(c)) eventlog(eventlog_level_warn, __FUNCTION__,"[%d] user '%s' tried to disconnect while in game, cheat attempt ?", conn_get_socket(c), conn_get_loggeduser(c)); else { message_send_text(c,message_type_info,c,"Connection closed."); conn_set_state(c,conn_state_destroy); } return 0; } static int _handle_kill_command(t_connection * c, char const *text) { unsigned int i,j; t_connection * user; char usrnick[USER_NAME_MAX]; /* max length of nick + \0 */ /* FIXME: Is it somewhere defined? */ for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get nick */ if (j '9'))) { message_send_text(c,message_type_info,c,"usage: /kill {|#} []"); return 0; } if (usrnick[0] == '#') { if (!(user = connlist_find_connection_by_socket(atoi(usrnick + 1)))) { message_send_text(c,message_type_error,c,"That connection doesnt exist."); return 0; } } else { if (!(user = connlist_find_connection_by_accountname(usrnick))) { message_send_text(c,message_type_error,c,"That user is not logged in?"); return 0; } } 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) { ipbanlist_save(prefs_get_ipbanfile()); message_send_text(user,message_type_info,user,"Connection closed by admin and banned your ip."); } else message_send_text(user,message_type_info,user,"Connection closed by admin."); conn_set_state(user,conn_state_destroy); message_send_text(c,message_type_info,c,"Operation successful."); return 0; } static int _handle_killsession_command(t_connection * c, char const *text) { unsigned int i,j; t_connection * user; char session[16]; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get nick */ if (j [min]"); return 0; } if (!isxdigit((int)session[0])) { message_send_text(c,message_type_error,c,"That is not a valid session."); return 0; } if (!(user = connlist_find_connection_by_sessionkey((unsigned int)strtoul(session,NULL,16)))) { message_send_text(c,message_type_error,c,"That session does not exist."); return 0; } 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) { ipbanlist_save(prefs_get_ipbanfile()); message_send_text(user,message_type_info,user,"Connection closed by admin and banned your ip's."); } else message_send_text(user,message_type_info,user,"Connection closed by admin."); conn_set_state(user,conn_state_destroy); return 0; } static int _handle_gameinfo_command(t_connection * c, char const *text) { unsigned int i; t_game const * game; char clienttag_str[5]; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); if (text[i]=='\0') { if (!(game = conn_get_game(c))) { message_send_text(c,message_type_error,c,"You are not in a game."); return 0; } } else if (!(game = gamelist_find_game(&text[i],conn_get_clienttag(c),game_type_all))) { message_send_text(c,message_type_error,c,"That game does not exist."); return 0; } 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"); message_send_text(c,message_type_info,c,msgtemp); { t_account * owner; char const * tname; char const * namestr; if (!(owner = conn_get_account(game_get_owner(game)))) { tname = NULL; namestr = "none"; } else if (!(tname = conn_get_loggeduser(game_get_owner(game)))) namestr = "unknown"; else namestr = tname; sprintf(msgtemp,"Owner: %-20.20s",namestr); } message_send_text(c,message_type_info,c,msgtemp); if (!prefs_get_hide_addr() || (account_get_command_groups(conn_get_account(c)) & command_get_group("/admin-addr"))) /* default to false */ { unsigned int addr; unsigned short port; unsigned int taddr; unsigned short tport; taddr=addr = game_get_addr(game); tport=port = game_get_port(game); trans_net(conn_get_addr(c),&taddr,&tport); if (taddr==addr && tport==port) sprintf(msgtemp,"Address: %s", addr_num_to_addr_str(addr,port)); else sprintf(msgtemp,"Address: %s (trans %s)", addr_num_to_addr_str(addr,port), addr_num_to_addr_str(taddr,tport)); message_send_text(c,message_type_info,c,msgtemp); } 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)); message_send_text(c,message_type_info,c,msgtemp); { time_t gametime; struct tm * gmgametime; gametime = game_get_create_time(game); if (!(gmgametime = localtime(&gametime))) strcpy(msgtemp,"Created: ?"); else strftime(msgtemp,sizeof(msgtemp),"Created: "GAME_TIME_FORMAT,gmgametime); message_send_text(c,message_type_info,c,msgtemp); gametime = game_get_start_time(game); if (gametime!=(time_t)0) { if (!(gmgametime = localtime(&gametime))) strcpy(msgtemp,"Started: ?"); else strftime(msgtemp,sizeof(msgtemp),"Started: "GAME_TIME_FORMAT,gmgametime); } else strcpy(msgtemp,"Started: "); message_send_text(c,message_type_info,c,msgtemp); } sprintf(msgtemp,"Status: %s",game_status_get_str(game_get_status(game))); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"Type: %-20.20s",game_type_get_str(game_get_type(game))); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"Speed: %s",game_speed_get_str(game_get_speed(game))); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"Difficulty: %s",game_difficulty_get_str(game_get_difficulty(game))); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"Option: %s",game_option_get_str(game_get_option(game))); message_send_text(c,message_type_info,c,msgtemp); { char const * mapname; if (!(mapname = game_get_mapname(game))) mapname = "unknown"; sprintf(msgtemp,"Map: %-20.20s",mapname); message_send_text(c,message_type_info,c,msgtemp); } sprintf(msgtemp,"Map Size: %ux%u",game_get_mapsize_x(game),game_get_mapsize_y(game)); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"Map Tileset: %s",game_tileset_get_str(game_get_tileset(game))); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"Map Type: %s",game_maptype_get_str(game_get_maptype(game))); message_send_text(c,message_type_info,c,msgtemp); sprintf(msgtemp,"Players: %u current, %u total, %u max",game_get_ref(game),game_get_count(game),game_get_maxplayers(game)); message_send_text(c,message_type_info,c,msgtemp); { char const * description; if (!(description = game_get_description(game))) description = ""; sprintf(msgtemp,"Description: %-20.20s",description); } return 0; } static int _handle_ladderactivate_command(t_connection * c, char const *text) { ladderlist_make_all_active(); message_send_text(c,message_type_info,c,"Copied current scores to active scores on all ladders."); return 0; } static int _handle_rehash_command(t_connection * c, char const *text) { server_restart_wraper(); return 0; } /* static int _handle_rank_all_accounts_command(t_connection * c, char const *text) { // rank all accounts here accounts_rank_all(); return 0; } */ static int _handle_shutdown_command(t_connection * c, char const *text) { char dest[32]; unsigned int i,j; unsigned int delay; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */ if (j [clienttag]"); return 0; } if (str_to_uint(dest,&rank)<0 || rank<1) { message_send_text(c,message_type_error,c,"Invalid rank."); return 0; } if (text[i]!='\0') { if (strlen(&text[i])!=4) { message_send_text(c,message_type_error,c,"You must supply a rank and a valid program ID."); message_send_text(c,message_type_error,c,"Example: /ladderinfo 1 STAR"); return 0; } clienttag = tag_case_str_to_uint(&text[i]); } else if (!(clienttag = conn_get_clienttag(c))) { message_send_text(c,message_type_error,c,"Unable to determine client game."); return 0; } if (clienttag==CLIENTTAG_STARCRAFT_UINT) { if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_active,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal))) { sprintf(msgtemp,"Starcraft active %5u: %-20.20s %u/%u/%u rating %u", rank, account_get_name(account), account_get_ladder_active_wins(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal), account_get_ladder_active_losses(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal), account_get_ladder_active_disconnects(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal), account_get_ladder_active_rating(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal)); } else sprintf(msgtemp,"Starcraft active %5u: ",rank); message_send_text(c,message_type_info,c,msgtemp); if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_current,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal))) { sprintf(msgtemp,"Starcraft current %5u: %-20.20s %u/%u/%u rating %u", rank, account_get_name(account), account_get_ladder_wins(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal), account_get_ladder_losses(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal), account_get_ladder_disconnects(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal), account_get_ladder_rating(account,CLIENTTAG_STARCRAFT_UINT,ladder_id_normal)); } else sprintf(msgtemp,"Starcraft current %5u: ",rank); message_send_text(c,message_type_info,c,msgtemp); } else if (clienttag==CLIENTTAG_BROODWARS_UINT) { if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_active,CLIENTTAG_BROODWARS_UINT,ladder_id_normal))) { sprintf(msgtemp,"Brood War active %5u: %-20.20s %u/%u/%u rating %u", rank, account_get_name(account), account_get_ladder_active_wins(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal), account_get_ladder_active_losses(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal), account_get_ladder_active_disconnects(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal), account_get_ladder_active_rating(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal)); } else sprintf(msgtemp,"Brood War active %5u: ",rank); message_send_text(c,message_type_info,c,msgtemp); if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_current,CLIENTTAG_BROODWARS_UINT,ladder_id_normal))) { sprintf(msgtemp,"Brood War current %5u: %-20.20s %u/%u/%u rating %u", rank, account_get_name(account), account_get_ladder_wins(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal), account_get_ladder_losses(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal), account_get_ladder_disconnects(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal), account_get_ladder_rating(account,CLIENTTAG_BROODWARS_UINT,ladder_id_normal)); } else sprintf(msgtemp,"Brood War current %5u: ",rank); message_send_text(c,message_type_info,c,msgtemp); } else if (clienttag==CLIENTTAG_WARCIIBNE_UINT) { if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_active,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal))) { sprintf(msgtemp,"Warcraft II standard active %5u: %-20.20s %u/%u/%u rating %u", rank, account_get_name(account), account_get_ladder_active_wins(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal), account_get_ladder_active_losses(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal), account_get_ladder_active_disconnects(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal), account_get_ladder_active_rating(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal)); } else sprintf(msgtemp,"Warcraft II standard active %5u: ",rank); message_send_text(c,message_type_info,c,msgtemp); if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_active,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman))) { sprintf(msgtemp,"Warcraft II IronMan active %5u: %-20.20s %u/%u/%u rating %u", rank, account_get_name(account), account_get_ladder_active_wins(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman), account_get_ladder_active_losses(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman), account_get_ladder_active_disconnects(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman), account_get_ladder_active_rating(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman)); } else sprintf(msgtemp,"Warcraft II IronMan active %5u: ",rank); message_send_text(c,message_type_info,c,msgtemp); if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_current,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal))) { sprintf(msgtemp,"Warcraft II standard current %5u: %-20.20s %u/%u/%u rating %u", rank, account_get_name(account), account_get_ladder_wins(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal), account_get_ladder_losses(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal), account_get_ladder_disconnects(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal), account_get_ladder_rating(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_normal)); } else sprintf(msgtemp,"Warcraft II standard current %5u: ",rank); message_send_text(c,message_type_info,c,msgtemp); if ((account = ladder_get_account_by_rank(rank,ladder_sort_highestrated,ladder_time_current,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman))) { sprintf(msgtemp,"Warcraft II IronMan current %5u: %-20.20s %u/%u/%u rating %u", rank, account_get_name(account), account_get_ladder_wins(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman), account_get_ladder_losses(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman), account_get_ladder_disconnects(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman), account_get_ladder_rating(account,CLIENTTAG_WARCIIBNE_UINT,ladder_id_ironman)); } else sprintf(msgtemp,"Warcraft II IronMan current %5u: ",rank); message_send_text(c,message_type_info,c,msgtemp); } // --> aaron else if (clienttag==CLIENTTAG_WARCRAFT3_UINT || clienttag==CLIENTTAG_WAR3XP_UINT) { unsigned int teamcount = 0; if ((account = ladder_get_account(solo_ladder(clienttag),rank,&teamcount,clienttag))) { sprintf(msgtemp,"WarCraft3 Solo %5u: %-20.20s %u/%u/0", rank, account_get_name(account), account_get_ladder_wins(account,clienttag,ladder_id_solo), account_get_ladder_losses(account,clienttag,ladder_id_solo)); } else sprintf(msgtemp,"WarCraft3 Solo %5u: ",rank); message_send_text(c,message_type_info,c,msgtemp); if ((account = ladder_get_account(team_ladder(clienttag),rank,&teamcount,clienttag))) { sprintf(msgtemp,"WarCraft3 Team %5u: %-20.20s %u/%u/0", rank, account_get_name(account), account_get_ladder_wins(account,clienttag,ladder_id_team), account_get_ladder_losses(account,clienttag,ladder_id_team)); } else sprintf(msgtemp,"WarCraft3 Team %5u: ",rank); message_send_text(c,message_type_info,c,msgtemp); if ((account = ladder_get_account(ffa_ladder(clienttag),rank,&teamcount,clienttag))) { sprintf(msgtemp,"WarCraft3 FFA %5u: %-20.20s %u/%u/0", rank, account_get_name(account), account_get_ladder_wins(account,clienttag,ladder_id_ffa), account_get_ladder_losses(account,clienttag,ladder_id_ffa)); } else sprintf(msgtemp,"WarCraft3 FFA %5u: ",rank); message_send_text(c,message_type_info,c,msgtemp); if ((account = ladder_get_account(at_ladder(clienttag),rank,&teamcount,clienttag))) { /* if (account_get_atteammembers(account,teamcount,clienttag)) sprintf(msgtemp,"WarCraft3 AT Team %5u: %-80.80s %u/%u/0", rank, account_get_atteammembers(account,teamcount,clienttag), account_get_atteamwin(account,teamcount,clienttag), account_get_atteamloss(account,teamcount,clienttag)); else */ sprintf(msgtemp,"WarCraft3 AT Team %5u: ",rank); } else sprintf(msgtemp,"WarCraft3 AT Team %5u: ",rank); message_send_text(c,message_type_info,c,msgtemp); } //<--- else { message_send_text(c,message_type_error,c,"This game does not support win/loss records."); message_send_text(c,message_type_error,c,"You must supply a rank and a valid program ID."); message_send_text(c,message_type_error,c,"Example: /ladderinfo 1 STAR"); } return 0; } static int _handle_timer_command(t_connection * c, char const *text) { unsigned int i,j; unsigned int delta; char deltastr[64]; t_timer_data data; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get comm */ if (j"); return 0; } if (clockstr_to_seconds(deltastr,&delta)<0) { message_send_text(c,message_type_error,c,"Invalid duration."); return 0; } if (text[i]=='\0') data.p = xstrdup("Your timer has expired."); else data.p = xstrdup(&text[i]); if (timerlist_add_timer(c,time(NULL)+(time_t)delta,user_timer_cb,data)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not add timer"); xfree(data.p); message_send_text(c,message_type_error,c,"Could not set timer."); } else { sprintf(msgtemp,"Timer set for %s",seconds_to_timestr(delta)); message_send_text(c,message_type_info,c,msgtemp); } return 0; } static int _handle_serverban_command(t_connection *c, char const *text) { char dest[USER_NAME_MAX]; char messagetemp[MAX_MESSAGE_LEN]; t_connection * dest_c; unsigned int i,j; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); // skip command for (; text[i]==' '; i++); for (j=0; text[i]!=' ' && text[i]!='\0'; i++) // get dest if (j"); return 0; } if (!(dest_c = connlist_find_connection_by_accountname(dest))) { message_send_text(c,message_type_error,c,"That user is not logged on."); return 0; } 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))); message_send_text(c,message_type_info,c,messagetemp); message_send_text(c,message_type_info,c,"Users Account is also LOCKED! Only a Admin can Unlock it!"); sprintf(msgtemp,"/ipban a %s",addr_num_to_ip_str(conn_get_game_addr(dest_c))); handle_ipban_command(c,msgtemp); account_set_auth_lock(conn_get_account(dest_c),1); //now kill the connection sprintf(msgtemp,"You have been banned by Admin: %s",conn_get_username(c)); message_send_text(dest_c,message_type_error,dest_c,msgtemp); message_send_text(dest_c,message_type_error,dest_c,"Your account is also LOCKED! Only a admin can UNLOCK it!"); conn_set_state(dest_c, conn_state_destroy); return 0; } static int _handle_netinfo_command(t_connection * c, char const *text) { char dest[USER_NAME_MAX]; unsigned int i,j; t_connection * conn; t_game const * game; unsigned int addr; unsigned short port; unsigned int taddr; unsigned short tport; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); // skip command for (; text[i]==' '; i++); for (j=0; text[i]!=' ' && text[i]!='\0'; i++) // get dest if (j"); return 0; } if (!(account = accountlist_find_account(text))) { message_send_text(c,message_type_error,c,"Invalid user."); return 0; } if ((user = connlist_find_connection_by_accountname(text))) message_send_text(user,message_type_info,user,"Your account has just been locked by admin."); account_set_auth_lock(account,1); message_send_text(c,message_type_error,c,"That user account is now locked."); return 0; } static int _handle_unlockacct_command(t_connection * c, char const *text) { t_connection * user; t_account * account; text = skip_command(text); if (text[0]=='\0') { message_send_text(c,message_type_info,c,"usage: /unlockacct "); return 0; } if (!(account = accountlist_find_account(text))) { message_send_text(c,message_type_error,c,"Invalid user."); return 0; } if ((user = connlist_find_connection_by_accountname(text))) message_send_text(user,message_type_info,user,"Your account has just been unlocked by admin."); account_set_auth_lock(account,0); message_send_text(c,message_type_error,c,"That user account is now unlocked."); return 0; } static int _handle_flag_command(t_connection * c, char const *text) { char dest[32]; unsigned int i,j; unsigned int newflag; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */ if (j"); return 0; } newflag = strtoul(dest,NULL,0); conn_set_flags(c,newflag); sprintf(msgtemp,"Flags set to 0x%08x.",newflag); message_send_text(c,message_type_info,c,msgtemp); return 0; } static int _handle_tag_command(t_connection * c, char const *text) { char dest[8]; unsigned int i,j; unsigned int newtag; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */ if (j"); return 0; } if (strlen(dest)!=4) { message_send_text(c,message_type_error,c,"Client tag should be four characters long."); return 0; } newtag = tag_case_str_to_uint(dest); if (tag_check_client(newtag)) { unsigned int oldflags = conn_get_flags(c); conn_set_clienttag(c,newtag); if ((newtag==CLIENTTAG_WARCRAFT3_UINT) || (newtag==CLIENTTAG_WAR3XP_UINT)) conn_update_w3_playerinfo(c); channel_rejoin(c); conn_set_flags(c,oldflags); channel_update_userflags(c); sprintf(msgtemp,"Client tag set to %s.",dest); } else sprintf(msgtemp,"Invalid clienttag %s specified",dest); message_send_text(c,message_type_info,c,msgtemp); return 0; } static int _handle_set_command(t_connection * c, char const *text) { t_account * account; char *accname; char *key; char *value; char t[MAX_MESSAGE_LEN]; unsigned int i,j; char arg1[256]; char arg2[256]; char arg3[256]; strncpy(t, text, MAX_MESSAGE_LEN - 1); for (i=0; t[i]!=' ' && t[i]!='\0'; i++); /* skip command /set */ for (; t[i]==' '; i++); /* skip spaces */ for (j=0; t[i]!=' ' && t[i]!='\0'; i++) /* get username */ if (j [value]"); } if (!(account = accountlist_find_account(accname))) { message_send_text(c,message_type_error,c,"Invalid user."); return 0; } if (*value == '\0') { if (account_get_strattr(account,key)) { sprintf(msgtemp, "current value of %.64s is \"%.128s\"",key,account_get_strattr(account,key)); message_send_text(c,message_type_error,c,msgtemp); } else message_send_text(c,message_type_error,c,"value currently not set"); return 0; } if (account_set_strattr(account,key,value)<0) message_send_text(c,message_type_error,c,"Unable to set key"); else message_send_text(c,message_type_error,c,"Key set succesfully"); return 0; } static int _handle_motd_command(t_connection * c, char const *text) { char const * filename; FILE * fp; if ((filename = prefs_get_motdfile())) { if ((fp = fopen(filename,"r"))) { message_send_file(c,fp); if (fclose(fp)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not close motd file \"%s\" after reading (fopen: %s)",filename,pstrerror(errno)); } else { eventlog(eventlog_level_error,__FUNCTION__,"could not open motd file \"%s\" for reading (fopen: %s)",filename,pstrerror(errno)); message_send_text(c,message_type_error,c,"Unable to open motd."); } return 0; } else { message_send_text(c,message_type_error,c,"No motd."); return 0; } } static int _handle_tos_command(t_connection * c, char const * text) { /* handle /tos - shows terms of service by user request -raistlinthewiz */ char * filename=NULL; FILE * fp; filename = buildpath(prefs_get_filedir(),prefs_get_tosfile()); /* FIXME: if user enters relative path to tos file in config, above routine will fail */ if ((fp = fopen(filename,"r"))) { char * buff; int len; while ((buff = file_get_line(fp))) { if ((len=strlen(buff)) < MAX_MESSAGE_LEN) message_send_text(c,message_type_info,c,buff); else { /* lines in TOS file can be > MAX_MESSAGE_LEN, so split them truncating is not an option for TOS -raistlinthewiz */ while ( len > MAX_MESSAGE_LEN - 1) { strncpy(msgtemp,buff,MAX_MESSAGE_LEN-1); msgtemp[MAX_MESSAGE_LEN]='\0'; buff += MAX_MESSAGE_LEN - 1; len -= MAX_MESSAGE_LEN - 1; message_send_text(c,message_type_info,c,msgtemp); } if ( len > 0 ) /* does it exist a small last part ? */ message_send_text(c,message_type_info,c,buff); } } if (fclose(fp)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not close tos file \"%s\" after reading (fopen: %s)",filename,pstrerror(errno)); } else { eventlog(eventlog_level_error,__FUNCTION__,"could not open tos file \"%s\" for reading (fopen: %s)",filename,pstrerror(errno)); message_send_text(c,message_type_error,c,"Unable to send TOS (terms of service)."); } xfree((void *)filename); return 0; } static int _handle_ping_command(t_connection * c, char const *text) { unsigned int i; t_connection * user; t_game * game; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); if (text[i]=='\0') { if ((game=conn_get_game(c))) { for (i=0; i []"); return 0; } if (!strcmp(command,"help") || !strcmp(command,"h")) { message_send_text(c,message_type_info,c,"Command Groups (Defines the Groups of Commands a User Can Use.)"); message_send_text(c,message_type_info,c,"Type: /cg add - adds group(s) to user profile"); message_send_text(c,message_type_info,c,"Type: /cg del - deletes group(s) from user profile"); message_send_text(c,message_type_info,c,"Type: /cg list - shows current groups user can use"); return 0; } if (arg2[0] =='\0') { message_send_text(c,message_type_info,c,"usage: /cg []"); return 0; } if (!(account = accountlist_find_account(username))) { message_send_text(c,message_type_error,c,"Invalid user."); return 0; } usergroups = account_get_command_groups(account); if (!strcmp(command,"list") || !strcmp(command,"l")) { if (usergroups & 1) tempgroups[0] = '1'; else tempgroups[0] = ' '; if (usergroups & 2) tempgroups[1] = '2'; else tempgroups[1] = ' '; if (usergroups & 4) tempgroups[2] = '3'; else tempgroups[2] = ' '; if (usergroups & 8) tempgroups[3] = '4'; else tempgroups[3] = ' '; if (usergroups & 16) tempgroups[4] = '5'; else tempgroups[4] = ' '; if (usergroups & 32) tempgroups[5] = '6'; else tempgroups[5] = ' '; if (usergroups & 64) tempgroups[6] = '7'; else tempgroups[6] = ' '; if (usergroups & 128) tempgroups[7] = '8'; else tempgroups[7] = ' '; sprintf(msgtemp, "%s's command group(s): %s", username, tempgroups); message_send_text(c,message_type_info,c,msgtemp); return 0; } if (arg3[0] =='\0') { message_send_text(c,message_type_info,c,"usage: /cg []"); return 0; } for (i=0; arg3[i] != '\0'; i++) { if (arg3[i] == '1') groups |= 1; else if (arg3[i] == '2') groups |= 2; else if (arg3[i] == '3') groups |= 4; else if (arg3[i] == '4') groups |= 8; else if (arg3[i] == '5') groups |= 16; else if (arg3[i] == '6') groups |= 32; else if (arg3[i] == '7') groups |= 64; else if (arg3[i] == '8') groups |= 128; else { sprintf(msgtemp, "got bad group: %c", arg3[i]); message_send_text(c,message_type_info,c,msgtemp); return 0; } } if (!strcmp(command,"add") || !strcmp(command,"a")) { account_set_command_groups(account, usergroups | groups); sprintf(msgtemp, "groups %s has been added to user: %s", arg3, username); message_send_text(c,message_type_info,c,msgtemp); return 0; } if (!strcmp(command,"del") || !strcmp(command,"d")) { account_set_command_groups(account, usergroups & (255 - groups)); sprintf(msgtemp, "groups %s has been deleted from user: %s", arg3, username); message_send_text(c,message_type_info,c,msgtemp); return 0; } sprintf(msgtemp, "got unknown command: %s", command); message_send_text(c,message_type_info,c,msgtemp); return 0; } static int _handle_topic_command(t_connection * c, char const * text) { char const * channel_name; char const * topic; char * tmp; t_channel * channel; int do_save = NO_SAVE_TOPIC; channel_name = skip_command(text); if ((topic = strchr(channel_name,'"'))) { tmp = (char *)topic; for (tmp--;tmp[0]==' ';tmp--); tmp[1]='\0'; topic++; tmp = strchr(topic,'"'); if (tmp) tmp[0]='\0'; } if (!(conn_get_channel(c))) { message_send_text(c,message_type_error,c,"This command can only be used inside a channel."); return -1; } if (channel_name[0]=='\0') { if (channel_get_topic(channel_get_name(conn_get_channel(c)))) { sprintf(msgtemp,"%s topic: %s",channel_get_name(conn_get_channel(c)),channel_get_topic(channel_get_name(conn_get_channel(c)))); } else { sprintf(msgtemp,"%s topic: no topic",channel_get_name(conn_get_channel(c))); } message_send_text(c,message_type_info,c,msgtemp); return 0; } if (!(topic)) { if (channel_get_topic(channel_name)) { sprintf(msgtemp,"%s topic: %s",channel_name, channel_get_topic(channel_name)); } else { sprintf(msgtemp,"%s topic: no topic",channel_name); } message_send_text(c,message_type_info,c,msgtemp); return 0; } if (!(channel = channellist_find_channel_by_name(channel_name,conn_get_country(c),realm_get_name(conn_get_realm(c))))) { sprintf(msgtemp,"no such channel, can't set topic"); message_send_text(c,message_type_error,c,msgtemp); return -1; } if (strlen(topic) >= MAX_TOPIC_LEN) { sprintf(msgtemp,"max topic length exceeded (max %d symbols)", MAX_TOPIC_LEN); message_send_text(c,message_type_error,c,msgtemp); return -1; } channel_name = channel_get_name(channel); if (!(account_is_operator_or_admin(conn_get_account(c),channel_name))) { sprintf(msgtemp,"You must be at least a Channel Operator of %s to set the topic",channel_name); message_send_text(c,message_type_error,c,msgtemp); return -1; } if (channel_get_permanent(channel)) do_save = DO_SAVE_TOPIC; channel_set_topic(channel_name, topic, do_save); sprintf(msgtemp,"%s topic: %s",channel_name, topic); message_send_text(c,message_type_info,c,msgtemp); return 0; } static int _handle_moderate_command(t_connection * c, char const * text) { t_channel_flags oldflags; t_channel * channel; if (!(channel = conn_get_channel(c))) { message_send_text(c,message_type_error,c,"This command can only be used inside a channel."); return -1; } if (!(account_is_operator_or_admin(conn_get_account(c),channel_get_name(channel)))) { message_send_text(c,message_type_error,c,"You must be at least a Channel Operator to use this command."); return -1; } oldflags = channel_get_flags(channel); if (channel_set_flags(channel, oldflags ^ channel_flags_moderated)) { eventlog(eventlog_level_error,__FUNCTION__,"could not set channel %s flags",channel_get_name(channel)); message_send_text(c,message_type_error,c,"Unable to change channel flags."); return -1; } else { if (oldflags & channel_flags_moderated) channel_message_send(channel,message_type_info,c,"Channel is now unmoderated"); else channel_message_send(channel,message_type_info,c,"Channel is now moderated"); } return 0; } static void _reset_d1_stats(t_account *account, t_clienttag ctag, t_connection *c) { account_set_normal_level(account,ctag,0); account_set_normal_strength(account,ctag,0), account_set_normal_magic(account,ctag,0), account_set_normal_dexterity(account,ctag,0), account_set_normal_vitality(account,ctag,0), account_set_normal_gold(account,ctag,0); sprintf(msgtemp,"Resetted %s's %s Stats",account_get_name(account),clienttag_get_title(ctag)); message_send_text(c,message_type_info,c,msgtemp); } static void _reset_scw2_stats(t_account *account, t_clienttag ctag, t_connection *c) { account_set_normal_wins(account,ctag,0); account_set_normal_losses(account,ctag,0); account_set_normal_disconnects(account,ctag,0); if (account_get_ladder_rating(account,ctag,ladder_id_normal)>0) { account_set_ladder_wins(account,ctag,ladder_id_normal,0); account_set_ladder_losses(account,ctag,ladder_id_normal,0); account_set_ladder_disconnects(account,ctag,ladder_id_normal,0); account_set_ladder_rating(account,ctag,ladder_id_normal,0); } if (account_get_ladder_rating(account,ctag,ladder_id_ironman)>0) { account_set_ladder_wins(account,ctag,ladder_id_ironman,0); account_set_ladder_losses(account,ctag,ladder_id_ironman,0); account_set_ladder_disconnects(account,ctag,ladder_id_ironman,0); account_set_ladder_rating(account,ctag,ladder_id_ironman,0); } sprintf(msgtemp,"Resetted %s's %s Stats",account_get_name(account),clienttag_get_title(ctag)); message_send_text(c,message_type_info,c,msgtemp); } static void _reset_w3_stats(t_account *account, t_clienttag ctag, t_connection *c) { account_set_ladder_level(account,ctag,ladder_id_solo,0); account_set_ladder_xp(account,ctag,ladder_id_solo,0); account_set_ladder_wins(account,ctag,ladder_id_solo,0); account_set_ladder_losses(account,ctag,ladder_id_solo,0); account_set_ladder_rank(account,ctag,ladder_id_solo,0); account_set_ladder_level(account,ctag,ladder_id_team,0); account_set_ladder_xp(account,ctag,ladder_id_team,0); account_set_ladder_wins(account,ctag,ladder_id_team,0); account_set_ladder_losses(account,ctag,ladder_id_team,0); account_set_ladder_rank(account,ctag,ladder_id_team,0); account_set_ladder_level(account,ctag,ladder_id_ffa,0); account_set_ladder_xp(account,ctag,ladder_id_ffa,0); account_set_ladder_wins(account,ctag,ladder_id_ffa,0); account_set_ladder_losses(account,ctag,ladder_id_ffa,0); account_set_ladder_rank(account,ctag,ladder_id_ffa,0); // this would now need a way to delete the team for all members now //account_set_atteamcount(account,ctag,0); sprintf(msgtemp,"Resetted %s's %s Stats",account_get_name(account),clienttag_get_title(ctag)); message_send_text(c,message_type_info,c,msgtemp); } static int _handle_clearstats_command(t_connection *c, char const *text) { char dest[USER_NAME_MAX]; unsigned int i,j,all; t_account * account; t_clienttag ctag = 0; for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */ for (; text[i]==' '; i++); if (!text[i]) { message_send_text(c,message_type_error,c,"Missing user, syntax error."); message_send_text(c,message_type_error,c,"Usage example: /clearstats "); message_send_text(c,message_type_error,c," where can be any valid client or ALL for all clients"); return 0; } for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get dest */ if (j "); message_send_text(c,message_type_error,c," where can be any valid client or ALL for all clients"); return 0; } if (strcasecmp(text + i,"all")) { if (strlen(text + i) != 4) { message_send_text(c,message_type_error,c,"Invalid clienttag, syntax error."); return 0; } ctag = tag_case_str_to_uint(text + i); all = 0; } else all = 1; if (all || ctag == CLIENTTAG_DIABLORTL_UINT) _reset_d1_stats(account,CLIENTTAG_DIABLORTL_UINT,c); if (all || ctag == CLIENTTAG_DIABLOSHR_UINT) _reset_d1_stats(account,CLIENTTAG_DIABLOSHR_UINT,c); if (all || ctag == CLIENTTAG_WARCIIBNE_UINT) _reset_scw2_stats(account,CLIENTTAG_WARCIIBNE_UINT,c); if (all || ctag == CLIENTTAG_STARCRAFT_UINT) _reset_scw2_stats(account,CLIENTTAG_STARCRAFT_UINT,c); if (all || ctag == CLIENTTAG_BROODWARS_UINT) _reset_scw2_stats(account,CLIENTTAG_BROODWARS_UINT,c); if (all || ctag == CLIENTTAG_SHAREWARE_UINT) _reset_scw2_stats(account,CLIENTTAG_SHAREWARE_UINT,c); if (all || ctag == CLIENTTAG_WARCRAFT3_UINT) _reset_w3_stats(account,CLIENTTAG_WARCRAFT3_UINT,c); if (all || ctag == CLIENTTAG_WAR3XP_UINT) _reset_w3_stats(account,CLIENTTAG_WAR3XP_UINT,c); return 0; }