From f858164deed48f2dcacd5ffc06a55398a54da7e8 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 14 Jul 2011 02:31:12 -0400 Subject: Rewrote how commands are handled within Anope. This allows naming commands and having spaces within command names. --- modules/core/botserv.h | 2 - modules/core/bs_act.cpp | 93 ---- modules/core/bs_assign.cpp | 117 +++-- modules/core/bs_badwords.cpp | 130 +++--- modules/core/bs_bot.cpp | 149 +++---- modules/core/bs_botlist.cpp | 24 +- modules/core/bs_control.cpp | 158 +++++++ modules/core/bs_help.cpp | 72 --- modules/core/bs_info.cpp | 101 ++--- modules/core/bs_kick.cpp | 223 +++++++--- modules/core/bs_main.cpp | 304 ++++++------- modules/core/bs_say.cpp | 95 ---- modules/core/bs_set.cpp | 95 ++-- modules/core/bs_unassign.cpp | 85 ---- modules/core/chanserv.h | 15 - modules/core/cs_access.cpp | 277 ++++++------ modules/core/cs_akick.cpp | 145 +++--- modules/core/cs_ban.cpp | 48 +- modules/core/cs_clearusers.cpp | 43 +- modules/core/cs_clone.cpp | 53 ++- modules/core/cs_drop.cpp | 53 +-- modules/core/cs_getkey.cpp | 42 +- modules/core/cs_help.cpp | 76 ---- modules/core/cs_info.cpp | 41 +- modules/core/cs_invite.cpp | 54 ++- modules/core/cs_kick.cpp | 44 +- modules/core/cs_list.cpp | 38 +- modules/core/cs_main.cpp | 176 ++------ modules/core/cs_mode.cpp | 47 +- modules/core/cs_modes.cpp | 248 ++++------- modules/core/cs_register.cpp | 88 +++- modules/core/cs_saset.cpp | 125 ++---- modules/core/cs_saset_noexpire.cpp | 52 +-- modules/core/cs_set.cpp | 129 ++---- modules/core/cs_set_bantype.cpp | 75 ++-- modules/core/cs_set_description.cpp | 70 ++- modules/core/cs_set_founder.cpp | 79 ++-- modules/core/cs_set_keeptopic.cpp | 70 ++- modules/core/cs_set_opnotice.cpp | 70 ++- modules/core/cs_set_peace.cpp | 70 ++- modules/core/cs_set_persist.cpp | 93 ++-- modules/core/cs_set_private.cpp | 71 ++- modules/core/cs_set_restricted.cpp | 70 ++- modules/core/cs_set_secure.cpp | 76 ++-- modules/core/cs_set_securefounder.cpp | 68 +-- modules/core/cs_set_secureops.cpp | 70 ++- modules/core/cs_set_signkick.cpp | 73 ++- modules/core/cs_set_successor.cpp | 81 ++-- modules/core/cs_set_topiclock.cpp | 72 ++- modules/core/cs_set_xop.cpp | 73 ++- modules/core/cs_status.cpp | 32 +- modules/core/cs_suspend.cpp | 79 ++-- modules/core/cs_topic.cpp | 49 +-- modules/core/cs_unban.cpp | 53 +-- modules/core/cs_xop.cpp | 270 +++++------- modules/core/db_mysql.cpp | 489 +++++++++----------- modules/core/db_plain.cpp | 95 ++-- modules/core/enc_md5.cpp | 2 +- modules/core/enc_none.cpp | 2 +- modules/core/enc_old.cpp | 2 +- modules/core/enc_sha1.cpp | 2 +- modules/core/enc_sha256.cpp | 2 +- modules/core/gl_global.cpp | 36 +- modules/core/gl_help.cpp | 57 --- modules/core/gl_main.cpp | 65 +-- modules/core/global.h | 2 - modules/core/help.cpp | 120 +++++ modules/core/hostserv.h | 17 - modules/core/hs_del.cpp | 66 ++- modules/core/hs_delall.cpp | 78 ---- modules/core/hs_group.cpp | 38 +- modules/core/hs_help.cpp | 58 --- modules/core/hs_list.cpp | 29 +- modules/core/hs_main.cpp | 81 +--- modules/core/hs_off.cpp | 23 +- modules/core/hs_on.cpp | 23 +- modules/core/hs_set.cpp | 155 +++++-- modules/core/hs_setall.cpp | 135 ------ modules/core/memoserv.h | 2 - modules/core/ms_cancel.cpp | 32 +- modules/core/ms_check.cpp | 31 +- modules/core/ms_del.cpp | 43 +- modules/core/ms_help.cpp | 68 --- modules/core/ms_ignore.cpp | 30 +- modules/core/ms_info.cpp | 64 ++- modules/core/ms_list.cpp | 56 +-- modules/core/ms_main.cpp | 85 ++-- modules/core/ms_read.cpp | 46 +- modules/core/ms_rsend.cpp | 34 +- modules/core/ms_send.cpp | 26 +- modules/core/ms_sendall.cpp | 29 +- modules/core/ms_set.cpp | 86 ++-- modules/core/ms_staff.cpp | 30 +- modules/core/nickserv.h | 2 - modules/core/ns_access.cpp | 73 ++- modules/core/ns_ajoin.cpp | 38 +- modules/core/ns_alist.cpp | 62 ++- modules/core/ns_cert.cpp | 80 ++-- modules/core/ns_drop.cpp | 45 +- modules/core/ns_getemail.cpp | 28 +- modules/core/ns_getpass.cpp | 31 +- modules/core/ns_ghost.cpp | 43 +- modules/core/ns_group.cpp | 106 ++--- modules/core/ns_help.cpp | 80 ---- modules/core/ns_identify.cpp | 39 +- modules/core/ns_info.cpp | 33 +- modules/core/ns_list.cpp | 105 ++--- modules/core/ns_logout.cpp | 55 +-- modules/core/ns_main.cpp | 106 +++-- modules/core/ns_recover.cpp | 51 +-- modules/core/ns_register.cpp | 132 +++--- modules/core/ns_release.cpp | 41 +- modules/core/ns_resetpass.cpp | 50 +-- modules/core/ns_saset.cpp | 198 +++------ modules/core/ns_saset_noexpire.cpp | 43 +- modules/core/ns_sendpass.cpp | 41 +- modules/core/ns_set.cpp | 183 +++----- modules/core/ns_set_autoop.cpp | 81 ++-- modules/core/ns_set_email.cpp | 91 ++-- modules/core/ns_set_greet.cpp | 69 ++- modules/core/ns_set_hide.cpp | 92 ++-- modules/core/ns_set_kill.cpp | 84 ++-- modules/core/ns_set_language.cpp | 81 ++-- modules/core/ns_set_message.cpp | 75 ++-- modules/core/ns_set_private.cpp | 85 ++-- modules/core/ns_set_secure.cpp | 80 ++-- modules/core/ns_status.cpp | 22 +- modules/core/ns_suspend.cpp | 70 ++- modules/core/ns_update.cpp | 31 +- modules/core/operserv.h | 15 - modules/core/os_akill.cpp | 139 +++--- modules/core/os_chankill.cpp | 43 +- modules/core/os_chanlist.cpp | 109 ----- modules/core/os_config.cpp | 36 +- modules/core/os_forbid.cpp | 68 ++- modules/core/os_help.cpp | 57 --- modules/core/os_ignore.cpp | 101 ++--- modules/core/os_jupe.cpp | 27 +- modules/core/os_kick.cpp | 41 +- modules/core/os_list.cpp | 187 ++++++++ modules/core/os_login.cpp | 35 +- modules/core/os_main.cpp | 337 +++++++++++--- modules/core/os_mode.cpp | 37 +- modules/core/os_modinfo.cpp | 218 +++++++-- modules/core/os_modlist.cpp | 189 -------- modules/core/os_modload.cpp | 83 ---- modules/core/os_modreload.cpp | 108 ----- modules/core/os_module.cpp | 202 +++++++++ modules/core/os_modunload.cpp | 90 ---- modules/core/os_news.cpp | 116 ++--- modules/core/os_noop.cpp | 31 +- modules/core/os_oline.cpp | 45 +- modules/core/os_oper.cpp | 36 +- modules/core/os_quit.cpp | 63 --- modules/core/os_reload.cpp | 21 +- modules/core/os_restart.cpp | 60 --- modules/core/os_session.cpp | 149 +++---- modules/core/os_set.cpp | 72 ++- modules/core/os_shutdown.cpp | 84 +++- modules/core/os_snline.cpp | 474 -------------------- modules/core/os_sqline.cpp | 455 ------------------- modules/core/os_stats.cpp | 89 ++-- modules/core/os_svsnick.cpp | 39 +- modules/core/os_sxline.cpp | 807 ++++++++++++++++++++++++++++++++++ modules/core/os_szline.cpp | 457 ------------------- modules/core/os_update.cpp | 22 +- modules/core/os_userlist.cpp | 110 ----- 167 files changed, 6286 insertions(+), 8837 deletions(-) delete mode 100644 modules/core/bs_act.cpp create mode 100644 modules/core/bs_control.cpp delete mode 100644 modules/core/bs_help.cpp delete mode 100644 modules/core/bs_say.cpp delete mode 100644 modules/core/bs_unassign.cpp delete mode 100644 modules/core/chanserv.h delete mode 100644 modules/core/cs_help.cpp delete mode 100644 modules/core/gl_help.cpp create mode 100644 modules/core/help.cpp delete mode 100644 modules/core/hostserv.h delete mode 100644 modules/core/hs_delall.cpp delete mode 100644 modules/core/hs_help.cpp delete mode 100644 modules/core/hs_setall.cpp delete mode 100644 modules/core/ms_help.cpp delete mode 100644 modules/core/ns_help.cpp delete mode 100644 modules/core/operserv.h delete mode 100644 modules/core/os_chanlist.cpp delete mode 100644 modules/core/os_help.cpp create mode 100644 modules/core/os_list.cpp delete mode 100644 modules/core/os_modlist.cpp delete mode 100644 modules/core/os_modload.cpp delete mode 100644 modules/core/os_modreload.cpp create mode 100644 modules/core/os_module.cpp delete mode 100644 modules/core/os_modunload.cpp delete mode 100644 modules/core/os_quit.cpp delete mode 100644 modules/core/os_restart.cpp delete mode 100644 modules/core/os_snline.cpp delete mode 100644 modules/core/os_sqline.cpp create mode 100644 modules/core/os_sxline.cpp delete mode 100644 modules/core/os_szline.cpp delete mode 100644 modules/core/os_userlist.cpp (limited to 'modules/core') diff --git a/modules/core/botserv.h b/modules/core/botserv.h index 5c707278a..5fa03f870 100644 --- a/modules/core/botserv.h +++ b/modules/core/botserv.h @@ -52,8 +52,6 @@ class BotServService : public Service public: BotServService(Module *m) : Service(m, "BotServ") { } - virtual BotInfo *Bot() = 0; - virtual UserData *GetUserData(User *u, Channel *c) = 0; virtual BanData *GetBanData(User *u, Channel *c) = 0; diff --git a/modules/core/bs_act.cpp b/modules/core/bs_act.cpp deleted file mode 100644 index d06fc1848..000000000 --- a/modules/core/bs_act.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* BotServ core functions - * - * (C) 2003-2011 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" -#include "botserv.h" - -class CommandBSAct : public Command -{ - public: - CommandBSAct() : Command("ACT", 2, 2) - { - this->SetDesc(_("Makes the bot do the equivalent of a \"/me\" command")); - } - - CommandReturn Execute(CommandSource &source, const std::vector ¶ms) - { - User *u = source.u; - ChannelInfo *ci = source.ci; - Anope::string message = params[1]; - - if (!check_access(u, ci, CA_SAY)) - { - source.Reply(_(ACCESS_DENIED)); - return MOD_CONT; - } - - if (!ci->bi) - { - source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str()); - return MOD_CONT; - } - - if (!ci->c || !ci->c->FindUser(ci->bi)) - { - source.Reply(_(BOT_NOT_ON_CHANNEL), ci->name.c_str()); - return MOD_CONT; - } - - size_t i = 0; - while ((i = message.find(1)) && i != Anope::string::npos) - message.erase(i, 1); - - ircdproto->SendAction(ci->bi, ci->name, "%s", message.c_str()); - ci->bi->lastmsg = Anope::CurTime; - - // XXX Need to be able to find if someone is overriding this. - Log(LOG_COMMAND, u, this, ci) << message; - - return MOD_CONT; - } - - void OnSyntaxError(CommandSource &source, const Anope::string &subcommand) - { - SyntaxError(source, "ACT", _("ACT \037channel\037 \037text\037")); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) - { - source.Reply(_("Syntax: \002ACT \037channel\037 \037text\037\002\n" - " \n" - "Makes the bot do the equivalent of a \"/me\" command\n" - "on the given channel using the given text.")); - return true; - } -}; - -class BSAct : public Module -{ - CommandBSAct commandbsact; - - public: - BSAct(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE) - { - this->SetAuthor("Anope"); - - if (!botserv) - throw ModuleException("BotServ is not loaded!"); - - this->AddCommand(botserv->Bot(), &commandbsact); - } -}; - -MODULE_INIT(BSAct) diff --git a/modules/core/bs_assign.cpp b/modules/core/bs_assign.cpp index f1e2e4f69..0a08eec3b 100644 --- a/modules/core/bs_assign.cpp +++ b/modules/core/bs_assign.cpp @@ -12,52 +12,59 @@ /*************************************************************************/ #include "module.h" -#include "botserv.h" class CommandBSAssign : public Command { public: - CommandBSAssign() : Command("ASSIGN", 2, 2) + CommandBSAssign(Module *creator) : Command(creator, "botserv/assign", 2, 2) { this->SetDesc(_("Assigns a bot to a channel")); + this->SetSyntax(_("\037channel\037 \037nick\037")); } - CommandReturn Execute(CommandSource &source, const std::vector ¶ms) + void Execute(CommandSource &source, const std::vector ¶ms) { const Anope::string &chan = params[0]; const Anope::string &nick = params[1]; + User *u = source.u; - ChannelInfo *ci = source.ci; if (readonly) { - source.Reply(_(BOT_ASSIGN_READONLY)); - return MOD_CONT; + source.Reply(BOT_ASSIGN_READONLY); + return; + } + + ChannelInfo *ci = cs_findchan(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; } BotInfo *bi = findbot(nick); if (!bi) { - source.Reply(_(BOT_DOES_NOT_EXIST), nick.c_str()); - return MOD_CONT; + source.Reply(BOT_DOES_NOT_EXIST, nick.c_str()); + return; } if (ci->botflags.HasFlag(BS_NOBOT) || (!check_access(u, ci, CA_ASSIGN) && !u->HasPriv("botserv/administration"))) { - source.Reply(_(ACCESS_DENIED)); - return MOD_CONT; + source.Reply(ACCESS_DENIED); + return; } - if (bi->HasFlag(BI_PRIVATE) && !u->HasCommand("botserv/assign/private")) + if (bi->HasFlag(BI_PRIVATE) && !u->HasCommand("botserv/botserv/assign/private")) { - source.Reply(_(ACCESS_DENIED)); - return MOD_CONT; + source.Reply(ACCESS_DENIED); + return; } - if (ci->bi && nick.equals_ci(ci->bi->nick)) + if (ci->bi == bi) { source.Reply(_("Bot \002%s\002 is already assigned to channel \002%s\002."), ci->bi->nick.c_str(), chan.c_str()); - return MOD_CONT; + return; } bool override = !check_access(u, ci, CA_ASSIGN); @@ -65,38 +72,96 @@ class CommandBSAssign : public Command bi->Assign(u, ci); source.Reply(_("Bot \002%s\002 has been assigned to %s."), bi->nick.c_str(), ci->name.c_str()); - return MOD_CONT; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) { - source.Reply(_("Syntax: \002ASSIGN \037chan\037 \037nick\037\002\n" - " \n" - "Assigns a bot pointed out by nick to the channel chan. You\n" + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Assigns a bot pointed out by nick to the channel chan. You\n" "can then configure the bot for the channel so it fits\n" "your needs.")); return true; } +}; + +class CommandBSUnassign : public Command +{ + public: + CommandBSUnassign(Module *creator) : Command(creator, "botserv/unassign", 1, 1) + { + this->SetDesc(_("Unassigns a bot from a channel")); + this->SetSyntax(_("\037channel\037 \037nick\037")); + } + + void Execute(CommandSource &source, const std::vector ¶ms) + { + User *u = source.u; + + if (readonly) + { + source.Reply(BOT_ASSIGN_READONLY); + return; + } + + ChannelInfo *ci = cs_findchan(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + if (!u->HasPriv("botserv/administration") && !check_access(u, ci, CA_ASSIGN)) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (!ci->bi) + { + source.Reply(BOT_NOT_ASSIGNED); + return; + } + + if (ci->HasFlag(CI_PERSIST) && !ModeManager::FindChannelModeByName(CMODE_PERM)) + { + source.Reply(_("You can not unassign bots while persist is set on the channel.")); + return; + } + + bool override = !check_access(u, ci, CA_ASSIGN); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "for " << ci->bi->nick; + + ci->bi->UnAssign(u, ci); + source.Reply(_("There is no bot assigned to %s anymore."), ci->name.c_str()); + } - void OnSyntaxError(CommandSource &source, const Anope::string &subcommand) + bool OnHelp(CommandSource &source, const Anope::string &subcommand) { - SyntaxError(source, "ASSIGN", _("ASSIGN \037chan\037 \037nick\037")); + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Unassigns a bot from a channel. When you use this command,\n" + "the bot won't join the channel anymore. However, bot\n" + "configuration for the channel is kept, so you will always\n" + "be able to reassign a bot later without have to reconfigure\n" + "it entirely.")); + return true; } }; class BSAssign : public Module { CommandBSAssign commandbsassign; + CommandBSUnassign commandbsunassign; public: - BSAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE) + BSAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + commandbsassign(this), commandbsunassign(this) { this->SetAuthor("Anope"); - if (!botserv) - throw ModuleException("BotServ is not loaded!"); - - this->AddCommand(botserv->Bot(), &commandbsassign); + ModuleManager::RegisterService(&commandbsassign); + ModuleManager::RegisterService(&commandbsunassign); } }; diff --git a/modules/core/bs_badwords.cpp b/modules/core/bs_badwords.cpp index 1ea8161f1..a272bdff9 100644 --- a/modules/core/bs_badwords.cpp +++ b/modules/core/bs_badwords.cpp @@ -12,36 +12,36 @@ /*************************************************************************/ #include "module.h" -#include "botserv.h" class BadwordsListCallback : public NumberList { CommandSource &source; + ChannelInfo *ci; bool SentHeader; public: - BadwordsListCallback(CommandSource &_source, const Anope::string &list) : NumberList(list, false), source(_source), SentHeader(false) + BadwordsListCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &list) : NumberList(list, false), source(_source), ci(_ci), SentHeader(false) { } ~BadwordsListCallback() { if (!SentHeader) - source.Reply(_("No matching entries on %s bad words list."), source.ci->name.c_str()); + source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str()); } void HandleNumber(unsigned Number) { - if (!Number || Number > source.ci->GetBadWordCount()) + if (!Number || Number > ci->GetBadWordCount()) return; if (!SentHeader) { SentHeader = true; source.Reply(_("Bad words list for %s:\n" - " Num Word Type"), source.ci->name.c_str()); + " Num Word Type"), ci->name.c_str()); } - DoList(source, Number - 1, source.ci->GetBadWord(Number - 1)); + DoList(source, Number - 1, ci->GetBadWord(Number - 1)); } static void DoList(CommandSource &source, unsigned Number, BadWord *bw) @@ -53,43 +53,43 @@ class BadwordsListCallback : public NumberList class BadwordsDelCallback : public NumberList { CommandSource &source; + ChannelInfo *ci; Command *c; unsigned Deleted; bool override; public: - BadwordsDelCallback(CommandSource &_source, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), c(_c), Deleted(0), override(false) + BadwordsDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c), Deleted(0), override(false) { - if (!check_access(source.u, source.ci, CA_BADWORDS) && source.u->HasPriv("botserv/administration")) + if (!check_access(source.u, ci, CA_BADWORDS) && source.u->HasPriv("botserv/administration")) this->override = true; } ~BadwordsDelCallback() { if (!Deleted) - source.Reply(_("No matching entries on %s bad words list."), source.ci->name.c_str()); + source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str()); else if (Deleted == 1) - source.Reply(_("Deleted 1 entry from %s bad words list."), source.ci->name.c_str()); + source.Reply(_("Deleted 1 entry from %s bad words list."), ci->name.c_str()); else - source.Reply(_("Deleted %d entries from %s bad words list."), Deleted, source.ci->name.c_str()); + source.Reply(_("Deleted %d entries from %s bad words list."), Deleted, ci->name.c_str()); } void HandleNumber(unsigned Number) { - if (!Number || Number > source.ci->GetBadWordCount()) + if (!Number || Number > ci->GetBadWordCount()) return; - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, source.ci) << "DEL " << source.ci->GetBadWord(Number - 1)->word; + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, ci) << "DEL " << ci->GetBadWord(Number - 1)->word; ++Deleted; - source.ci->EraseBadWord(Number - 1); + ci->EraseBadWord(Number - 1); } }; class CommandBSBadwords : public Command { private: - CommandReturn DoList(CommandSource &source, const Anope::string &word) + void DoList(CommandSource &source, ChannelInfo *ci, const Anope::string &word) { - ChannelInfo *ci = source.ci; bool override = !check_access(source.u, ci, CA_BADWORDS); Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "LIST"; @@ -97,7 +97,7 @@ class CommandBSBadwords : public Command source.Reply(_("%s bad words list is empty."), ci->name.c_str()); else if (!word.empty() && word.find_first_not_of("1234567890,-") == Anope::string::npos) { - BadwordsListCallback list(source, word); + BadwordsListCallback list(source, ci, word); list.Process(); } else @@ -126,12 +126,11 @@ class CommandBSBadwords : public Command source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str()); } - return MOD_CONT; + return; } - CommandReturn DoAdd(CommandSource &source, const Anope::string &word) + void DoAdd(CommandSource &source, ChannelInfo *ci, const Anope::string &word) { - ChannelInfo *ci = source.ci; size_t pos = word.rfind(' '); BadWordType type = BW_ANY; Anope::string realword = word; @@ -154,7 +153,7 @@ class CommandBSBadwords : public Command if (ci->GetBadWordCount() >= Config->BSBadWordsMax) { source.Reply(_("Sorry, you can only have %d bad words entries on a channel."), Config->BSBadWordsMax); - return MOD_CONT; + return; } for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i) @@ -164,7 +163,7 @@ class CommandBSBadwords : public Command if (!bw->word.empty() && ((Config->BSCaseSensitive && realword.equals_cs(bw->word)) || (!Config->BSCaseSensitive && realword.equals_ci(bw->word)))) { source.Reply(_("\002%s\002 already exists in %s bad words list."), bw->word.c_str(), ci->name.c_str()); - return MOD_CONT; + return; } } @@ -174,16 +173,15 @@ class CommandBSBadwords : public Command source.Reply(_("\002%s\002 added to %s bad words list."), realword.c_str(), ci->name.c_str()); - return MOD_CONT; + return; } - CommandReturn DoDelete(CommandSource &source, const Anope::string &word) + void DoDelete(CommandSource &source, ChannelInfo *ci, const Anope::string &word) { - ChannelInfo *ci = source.ci; /* Special case: is it a number/list? Only do search if it isn't. */ if (!word.empty() && isdigit(word[0]) && word.find_first_not_of("1234567890,-") == Anope::string::npos) { - BadwordsDelCallback list(source, this, word); + BadwordsDelCallback list(source, ci, this, word); list.Process(); } else @@ -202,7 +200,7 @@ class CommandBSBadwords : public Command if (i == end) { source.Reply(_("\002%s\002 not found on %s bad words list."), word.c_str(), ci->name.c_str()); - return MOD_CONT; + return; } bool override = !check_access(source.u, ci, CA_BADWORDS); @@ -213,78 +211,83 @@ class CommandBSBadwords : public Command ci->EraseBadWord(i); } - return MOD_CONT; + return; } - CommandReturn DoClear(CommandSource &source) + void DoClear(CommandSource &source, ChannelInfo *ci) { - ChannelInfo *ci = source.ci; bool override = !check_access(source.u, ci, CA_BADWORDS); Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "CLEAR"; ci->ClearBadWords(); source.Reply(_("Bad words list is now empty.")); - return MOD_CONT; + return; } public: - CommandBSBadwords() : Command("BADWORDS", 2, 3) + CommandBSBadwords(Module *creator) : Command(creator, "botserv/badwords", 2, 3) { this->SetDesc(_("Maintains bad words list")); + this->SetSyntax(_("\037channel\037 ADD \037word\037 [\037SINGLE\037 | \037START\037 | \037END\037]")); + this->SetSyntax(_("\037channel\037 DEL {\037word\037 | \037entry-num\037 | \037list\037}")); + this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037list\037]")); + this->SetSyntax(_("\037channel\037 CLEAR")); } - CommandReturn Execute(CommandSource &source, const std::vector ¶ms) + void Execute(CommandSource &source, const std::vector ¶ms) { const Anope::string &cmd = params[1]; const Anope::string &word = params.size() > 2 ? params[2] : ""; User *u = source.u; - ChannelInfo *ci = source.ci; bool need_args = cmd.equals_ci("LIST") || cmd.equals_ci("CLEAR"); if (!need_args && word.empty()) { this->OnSyntaxError(source, cmd); - return MOD_CONT; + return; + } + + ChannelInfo *ci = cs_findchan(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; } + if (!check_access(u, ci, CA_BADWORDS) && (!need_args || !u->HasPriv("botserv/administration"))) { - source.Reply(_(ACCESS_DENIED)); - return MOD_CONT; + source.Reply(ACCESS_DENIED); + return; } if (readonly) { source.Reply(_("Sorry, channel bad words list modification is temporarily disabled.")); - return MOD_CONT; + return; } if (cmd.equals_ci("ADD")) - return this->DoAdd(source, word); + return this->DoAdd(source, ci, word); else if (cmd.equals_ci("DEL")) - return this->DoDelete(source, word); + return this->DoDelete(source, ci, word); else if (cmd.equals_ci("LIST")) - return this->DoList(source, word); + return this->DoList(source, ci, word); else if (cmd.equals_ci("CLEAR")) - return this->DoClear(source); + return this->DoClear(source, ci); else this->OnSyntaxError(source, ""); - - return MOD_CONT; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) { - source.Reply(_("Syntax: \002BADWORDS \037channel\037 ADD \037word\037 [\037SINGLE\037 | \037START\037 | \037END\037]\002\n" - " \002BADWORDS \037channel\037 DEL {\037word\037 | \037entry-num\037 | \037list\037}\002\n" - " \002BADWORDS \037channel\037 LIST [\037mask\037 | \037list\037]\002\n" - " \002BADWORDS \037channel\037 CLEAR\002\n" - " \n" - "Maintains the \002bad words list\002 for a channel. The bad\n" + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Maintains the \002bad words list\002 for a channel. The bad\n" "words list determines which words are to be kicked\n" "when the bad words kicker is enabled. For more information,\n" - "type \002%s%s HELP KICK BADWORDS\002.\n" + "type \002%s%s HELP KICK %s\002.\n" " \n" - "The \002BADWORDS ADD\002 command adds the given word to the\n" + "The \002ADD\002 command adds the given word to the\n" "badword list. If SINGLE is specified, a kick will be\n" "done only if a user says the entire word. If START is \n" "specified, a kick will be done if a user says a word\n" @@ -292,28 +295,23 @@ class CommandBSBadwords : public Command "will be done if a user says a word that ends with\n" "\037word\037. If you don't specify anything, a kick will\n" "be issued every time \037word\037 is said by a user.\n" - " \n"), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str()); - source.Reply(_("The \002BADWORDS DEL\002 command removes the given word from the\n" + " \n"), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str(), source.command.c_str()); + source.Reply(_("The \002DEL\002 command removes the given word from the\n" "bad words list. If a list of entry numbers is given, those\n" "entries are deleted. (See the example for LIST below.)\n" " \n" - "The \002BADWORDS LIST\002 command displays the bad words list. If\n" + "The \002LIST\002 command displays the bad words list. If\n" "a wildcard mask is given, only those entries matching the\n" "mask are displayed. If a list of entry numbers is given,\n" "only those entries are shown; for example:\n" - " \002BADWORDS #channel LIST 2-5,7-9\002\n" + " \002#channel LIST 2-5,7-9\002\n" " Lists bad words entries numbered 2 through 5 and\n" " 7 through 9.\n" " \n" - "The \002BADWORDS CLEAR\002 command clears all entries of the\n" + "The \002CLEAR\002 command clears all entries of the\n" "bad words list.")); return true; } - - void OnSyntaxError(CommandSource &source, const Anope::string &subcommand) - { - SyntaxError(source, "BADWORDS", _("BADWORDS \037channel\037 {ADD|DEL|LIST|CLEAR} [\037word\037 | \037entry-list\037] [SINGLE|START|END]")); - } }; class BSBadwords : public Module @@ -321,14 +319,12 @@ class BSBadwords : public Module CommandBSBadwords commandbsbadwords; public: - BSBadwords(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE) + BSBadwords(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + commandbsbadwords(this) { this->SetAuthor("Anope"); - if (!botserv) - throw ModuleException("BotServ is not loaded!"); - - this->AddCommand(botserv->Bot(), &commandbsbadwords); + ModuleManager::RegisterService(&commandbsbadwords); } }; diff --git a/modules/core/bs_bot.cpp b/modules/core/bs_bot.cpp index 4d42380f3..ec0bea734 100644 --- a/modules/core/bs_bot.cpp +++ b/modules/core/bs_bot.cpp @@ -12,12 +12,11 @@ /*************************************************************************/ #include "module.h" -#include "botserv.h" class CommandBSBot : public Command { private: - CommandReturn DoAdd(CommandSource &source, const std::vector ¶ms) + void DoAdd(CommandSource &source, const std::vector ¶ms) { const Anope::string &nick = params[1]; const Anope::string &user = params[2]; @@ -28,60 +27,60 @@ class CommandBSBot : public Command if (findbot(nick)) { source.Reply(_("Bot \002%s\002 already exists."), nick.c_str()); - return MOD_CONT; + return; } if (nick.length() > Config->NickLen) { source.Reply(_("Bot Nicks may only contain valid nick characters.")); - return MOD_CONT; + return; } if (user.length() > Config->UserLen) { source.Reply(_("Bot Idents may only contain %d characters."), Config->UserLen); - return MOD_CONT; + return; } if (host.length() > Config->HostLen) { source.Reply(_("Bot Hosts may only contain %d characters."), Config->HostLen); - return MOD_CONT; + return; } /* Check the nick is valid re RFC 2812 */ if (isdigit(nick[0]) || nick[0] == '-') { source.Reply(_("Bot Nicks may only contain valid nick characters.")); - return MOD_CONT; + return; } for (unsigned i = 0, end = nick.length(); i < end && i < Config->NickLen; ++i) if (!isvalidnick(nick[i])) { source.Reply(_("Bot Nicks may only contain valid nick characters.")); - return MOD_CONT; + return; } /* check for hardcored ircd forbidden nicks */ if (!ircdproto->IsNickValid(nick)) { source.Reply(_("Bot Nicks may only contain valid nick characters.")); - return MOD_CONT; + return; } /* Check the host is valid re RFC 2812 */ if (!isValidHost(host, 3)) { source.Reply(_("Bot Hosts may only contain valid host characters.")); - return MOD_CONT; + return; } for (unsigned i = 0, end = user.length(); i < end && i < Config->UserLen; ++i) if (!isalnum(user[i])) { source.Reply(_("Bot Idents may only contain valid characters."), Config->UserLen); - return MOD_CONT; + return; } /* We check whether the nick is registered, and inform the user @@ -90,26 +89,21 @@ class CommandBSBot : public Command */ if (findnick(nick)) { - source.Reply(_(NICK_ALREADY_REGISTERED), nick.c_str()); - return MOD_CONT; + source.Reply(NICK_ALREADY_REGISTERED, nick.c_str()); + return; } - if (!(bi = new BotInfo(nick, user, host, real))) - { - // XXX this cant happen? - source.Reply(_("Sorry, bot creation failed.")); - return MOD_CONT; - } + bi = new BotInfo(nick, user, host, real); Log(LOG_ADMIN, source.u, this) << "ADD " << bi->GetMask() << " " << bi->realname; source.Reply(_("%s!%s@%s (%s) added to the bot list."), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str()); FOREACH_MOD(I_OnBotCreate, OnBotCreate(bi)); - return MOD_CONT; + return; } - CommandReturn DoChange(CommandSource &source, const std::vector ¶ms) + void DoChange(CommandSource &source, const std::vector ¶ms) { const Anope::string &oldnick = params[1]; const Anope::string &nick = params.size() > 2 ? params[2] : ""; @@ -121,43 +115,43 @@ class CommandBSBot : public Command if (oldnick.empty() || nick.empty()) { this->OnSyntaxError(source, "CHANGE"); - return MOD_CONT; + return; } if (!(bi = findbot(oldnick))) { - source.Reply(_(BOT_DOES_NOT_EXIST), oldnick.c_str()); - return MOD_CONT; + source.Reply(BOT_DOES_NOT_EXIST, oldnick.c_str()); + return; } if (!oldnick.equals_ci(nick) && nickIsServices(oldnick, false)) { - source.Reply(_(BOT_DOES_NOT_EXIST), oldnick.c_str()); - return MOD_CONT; + source.Reply(BOT_DOES_NOT_EXIST, oldnick.c_str()); + return; } if (nick.length() > Config->NickLen) { source.Reply(_("Bot Nicks may only contain valid nick characters.")); - return MOD_CONT; + return; } if (!user.empty() && user.length() > Config->UserLen) { source.Reply(_("Bot Idents may only contain %d characters."), Config->UserLen); - return MOD_CONT; + return; } if (!host.empty() && host.length() > Config->HostLen) { source.Reply(_("Bot Hosts may only contain %d characters."), Config->HostLen); - return MOD_CONT; + return; } if (!oldnick.equals_ci(nick) && nickIsServices(nick, false)) { - source.Reply(_(BOT_DOES_NOT_EXIST), oldnick.c_str()); - return MOD_CONT; + source.Reply(BOT_DOES_NOT_EXIST, oldnick.c_str()); + return; } /* Checks whether there *are* changes. @@ -168,34 +162,34 @@ class CommandBSBot : public Command if (nick.equals_cs(bi->nick) && (!user.empty() ? user.equals_cs(bi->GetIdent()) : 1) && (!host.empty() ? host.equals_cs(bi->host) : 1) && (!real.empty() ? real.equals_cs(bi->realname) : 1)) { source.Reply(_("Old info is equal to the new one.")); - return MOD_CONT; + return; } /* Check the nick is valid re RFC 2812 */ if (isdigit(nick[0]) || nick[0] == '-') { source.Reply(_("Bot Nicks may only contain valid nick characters.")); - return MOD_CONT; + return; } for (unsigned i = 0, end = nick.length(); i < end && i < Config->NickLen; ++i) if (!isvalidnick(nick[i])) { source.Reply(_("Bot Nicks may only contain valid nick characters.")); - return MOD_CONT; + return; } /* check for hardcored ircd forbidden nicks */ if (!ircdproto->IsNickValid(nick)) { source.Reply(_("Bot Nicks may only contain valid nick characters.")); - return MOD_CONT; + return; } if (!host.empty() && !isValidHost(host, 3)) { source.Reply(_("Bot Hosts may only contain valid host characters.")); - return MOD_CONT; + return; } if (!user.empty()) @@ -203,13 +197,13 @@ class CommandBSBot : public Command if (!isalnum(user[i])) { source.Reply(_("Bot Idents may only contain valid characters."), Config->UserLen); - return MOD_CONT; + return; } if (!nick.equals_ci(bi->nick) && findbot(nick)) { source.Reply(_("Bot \002%s\002 already exists."), nick.c_str()); - return MOD_CONT; + return; } if (!nick.equals_ci(bi->nick)) @@ -220,8 +214,8 @@ class CommandBSBot : public Command */ if (findnick(nick)) { - source.Reply(_(NICK_ALREADY_REGISTERED), nick.c_str()); - return MOD_CONT; + source.Reply(NICK_ALREADY_REGISTERED, nick.c_str()); + return; } /* The new nick is really different, so we remove the Q line for the old nick. */ @@ -263,10 +257,10 @@ class CommandBSBot : public Command Log(LOG_ADMIN, source.u, this) << "CHANGE " << oldnick << " to " << bi->GetMask() << " " << bi->realname; FOREACH_MOD(I_OnBotChange, OnBotChange(bi)); - return MOD_CONT; + return; } - CommandReturn DoDel(CommandSource &source, const std::vector ¶ms) + void DoDel(CommandSource &source, const std::vector ¶ms) { const Anope::string &nick = params[1]; BotInfo *bi; @@ -274,19 +268,19 @@ class CommandBSBot : public Command if (nick.empty()) { this->OnSyntaxError(source, "DEL"); - return MOD_CONT; + return; } if (!(bi = findbot(nick))) { - source.Reply(_(BOT_DOES_NOT_EXIST), nick.c_str()); - return MOD_CONT; + source.Reply(BOT_DOES_NOT_EXIST, nick.c_str()); + return; } if (nickIsServices(nick, false)) { - source.Reply(_(BOT_DOES_NOT_EXIST), nick.c_str()); - return MOD_CONT; + source.Reply(BOT_DOES_NOT_EXIST, nick.c_str()); + return; } FOREACH_MOD(I_OnBotDelete, OnBotDelete(bi)); @@ -295,16 +289,18 @@ class CommandBSBot : public Command source.Reply(_("Bot \002%s\002 has been deleted."), nick.c_str()); delete bi; - return MOD_CONT; + return; } public: - CommandBSBot() : Command("BOT", 1, 6) + CommandBSBot(Module *creator) : Command(creator, "botserv/bot", 1, 6) { - this->SetFlag(CFLAG_STRIP_CHANNEL); this->SetDesc(_("Maintains network bot list")); + this->SetSyntax(_("\002ADD \037nick\037 \037user\037 \037host\037 \037real\037\002")); + this->SetSyntax(_("\002CHANGE \037oldnick\037 \037newnick\037 [\037user\037 [\037host\037 [\037real\037]]]\002")); + this->SetSyntax(_("\002DEL \037nick\037\002")); } - CommandReturn Execute(CommandSource &source, const std::vector ¶ms) + void Execute(CommandSource &source, const std::vector ¶ms) { const Anope::string &cmd = params[0]; User *u = source.u; @@ -312,22 +308,22 @@ class CommandBSBot : public Command if (readonly) { source.Reply(_("Sorry, bot modification is temporarily disabled.")); - return MOD_CONT; + return; } if (cmd.equals_ci("ADD")) { // ADD nick user host real - 5 - if (!u->HasCommand("botserv/bot/add")) + if (!u->HasCommand("botserv/botserv/bot/add")) { - source.Reply(_(ACCESS_DENIED)); - return MOD_CONT; + source.Reply(ACCESS_DENIED); + return; } if (params.size() < 5) { this->OnSyntaxError(source, "ADD"); - return MOD_CONT; + return; } std::vector tempparams = params; @@ -341,16 +337,16 @@ class CommandBSBot : public Command { // CHANGE oldn newn user host real - 6 // but only oldn and newn are required - if (!u->HasCommand("botserv/bot/change")) + if (!u->HasCommand("botserv/botserv/bot/change")) { - source.Reply(_(ACCESS_DENIED)); - return MOD_CONT; + source.Reply(ACCESS_DENIED); + return; } if (params.size() < 3) { this->OnSyntaxError(source, "CHANGE"); - return MOD_CONT; + return; } return this->DoChange(source, params); @@ -358,16 +354,16 @@ class CommandBSBot : public Command else if (cmd.equals_ci("DEL")) { // DEL nick - if (!u->HasCommand("botserv/bot/del")) + if (!u->HasCommand("botserv/botserv/bot/del")) { - source.Reply(_(ACCESS_DENIED)); - return MOD_CONT; + source.Reply(ACCESS_DENIED); + return; } if (params.size() < 1) { this->OnSyntaxError(source, "DEL"); - return MOD_CONT; + return; } return this->DoDel(source, params); @@ -375,16 +371,14 @@ class CommandBSBot : public Command else this->OnSyntaxError(source, ""); - return MOD_CONT; + return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) { - source.Reply(_("Syntax: \002BOT ADD \037nick\037 \037user\037 \037host\037 \037real\037\002\n" - " \002BOT CHANGE \037oldnick\037 \037newnick\037 [\037user\037 [\037host\037 [\037real\037]]]\002\n" - " \002BOT DEL \037nick\037\002\n" - " \n" - "Allows Services Operators to create, modify, and delete\n" + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Allows Services Operators to create, modify, and delete\n" "bots that users will be able to use on their own\n" "channels.\n" " \n" @@ -401,13 +395,6 @@ class CommandBSBot : public Command "using the nick, they will be killed.")); return true; } - - void OnSyntaxError(CommandSource &source, const Anope::string &subcommand) - { - SyntaxError(source, "BOT", _("BOT ADD \037nick\037 \037user\037 \037host\037 \037real\037\n" - "\002BOT CHANGE \037oldnick\037 \037newnick\037 [\037user\037 [\037host\037 [\037real\037]]]\002\n" - "\002BOT DEL \037nick\037\002")); - } }; class BSBot : public Module @@ -415,14 +402,12 @@ class BSBot : public Module CommandBSBot commandbsbot; public: - BSBot(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE) + BSBot(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + commandbsbot(this) { this->SetAuthor("Anope"); - if (!botserv) - throw ModuleException("BotServ is not loaded!"); - - this->AddCommand(botserv->Bot(), &commandbsbot); + ModuleManager::RegisterService(&commandbsbot); } }; diff --git a/modules/core/bs_botlist.cpp b/modules/core/bs_botlist.cpp index aa4731189..ee7e4d2d8 100644 --- a/modules/core/bs_botlist.cpp +++ b/modules/core/bs_botlist.cpp @@ -12,17 +12,17 @@ /*************************************************************************/ #include "module.h" -#include "botserv.h" class CommandBSBotList : public Command { public: - CommandBSBotList() : Command("BOTLIST", 0, 0) + CommandBSBotList(Module *creator) : Command(creator, "botserv/botlist", 0, 0) { this->SetDesc(_("Lists available bots")); + this->SetSyntax(""); } - CommandReturn Execute(CommandSource &source, const std::vector ¶ms) + void Execute(CommandSource &source, const std::vector ¶ms) { User *u = source.u; unsigned count = 0; @@ -40,7 +40,7 @@ class CommandBSBotList : public Command } } - if (u->HasCommand("botserv/botlist") && count < BotListByNick.size()) + if (u->HasCommand("botserv/botserv/botlist") && count < BotListByNick.size()) { source.Reply(_("Bots reserved to IRC operators:")); @@ -62,14 +62,14 @@ class CommandBSBotList : public Command else source.Reply(_("%d bots available."), count); - return MOD_CONT; + return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) { - source.Reply(_("Syntax: \002BOTLIST\002\n" - " \n" - "Lists all available bots on this network.")); + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Lists all available bots on this network.")); return true; } }; @@ -79,14 +79,12 @@ class BSBotList : public Module CommandBSBotList commandbsbotlist; public: - BSBotList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE) + BSBotList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + commandbsbotlist(this) { this->SetAuthor("Anope"); - if (!botserv) - throw ModuleException("BotServ is not loaded!"); - - this->AddCommand(botserv->Bot(), &commandbsbotlist); + ModuleManager::RegisterService(&commandbsbotlist); } }; diff --git a/modules/core/bs_control.cpp b/modules/core/bs_control.cpp new file mode 100644 index 000000000..431739693 --- /dev/null +++ b/modules/core/bs_control.cpp @@ -0,0 +1,158 @@ +/* BotServ core functions + * + * (C) 2003-2011 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +/*************************************************************************/ + +#include "module.h" + +class CommandBSSay : public Command +{ + public: + CommandBSSay(Module *creator) : Command(creator, "botserv/say", 2, 2) + { + this->SetDesc(_("Makes the bot say the given text on the given channel")); + this->SetSyntax(_("\037channel\037 \037text\037")); + } + + void Execute(CommandSource &source, const std::vector ¶ms) + { + const Anope::string &text = params[1]; + + User *u = source.u; + + ChannelInfo *ci = cs_findchan(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + if (!check_access(u, ci, CA_SAY)) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (!ci->bi) + { + source.Reply(BOT_NOT_ASSIGNED); + return; + } + + if (!ci->c || !ci->c->FindUser(ci->bi)) + { + source.Reply(BOT_NOT_ON_CHANNEL, ci->name.c_str()); + return; + } + + if (text[0] == '\001') + { + this->OnSyntaxError(source, ""); + return; + } + + ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", text.c_str()); + ci->bi->lastmsg = Anope::CurTime; + + // XXX need a way to find if someone is overriding this + Log(LOG_COMMAND, u, this, ci) << text; + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Makes the bot say the given text on the given channel.")); + return true; + } +}; + +class CommandBSAct : public Command +{ + public: + CommandBSAct(Module *creator) : Command(creator, "botserv/act", 2, 2) + { + this->SetDesc(_("Makes the bot do the equivalent of a \"/me\" command")); + this->SetSyntax(_("\037channel\037 \037text\037")); + } + + void Execute(CommandSource &source, const std::vector ¶ms) + { + User *u = source.u; + Anope::string message = params[1]; + + ChannelInfo *ci = cs_findchan(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + if (!check_access(u, ci, CA_SAY)) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (!ci->bi) + { + source.Reply(BOT_NOT_ASSIGNED); + return; + } + + if (!ci->c || !ci->c->FindUser(ci->bi)) + { + source.Reply(BOT_NOT_ON_CHANNEL, ci->name.c_str()); + return; + } + + size_t i = 0; + while ((i = message.find(1)) && i != Anope::string::npos) + message.erase(i, 1); + + ircdproto->SendAction(ci->bi, ci->name, "%s", message.c_str()); + ci->bi->lastmsg = Anope::CurTime; + + // XXX Need to be able to find if someone is overriding this. + Log(LOG_COMMAND, u, this, ci) << message; + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Makes the bot do the equivalent of a \"/me\" command\n" + "on the given channel using the given text.")); + return true; + } +}; + +class BSControl : public Module +{ + CommandBSSay commandbssay; + CommandBSAct commandbsact; + + public: + BSControl(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + commandbssay(this), commandbsact(this) + { + this->SetAuthor("Anope"); + + ModuleManager::RegisterService(&commandbssay); + ModuleManager::RegisterService(&commandbsact); + } +}; + +MODULE_INIT(BSControl) diff --git a/modules/core/bs_help.cpp b/modules/core/bs_help.cpp deleted file mode 100644 index 953c5f37e..000000000 --- a/modules/core/bs_help.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* BotServ core functions - * - * (C) 2003-2011 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" -#include "botserv.h" - -class CommandBSHelp : public Command -{ - public: - CommandBSHelp() : Command("HELP", 1, 1) - { - this->SetFlag(CFLAG_ALLOW_UNREGISTERED); - this->SetFlag(CFLAG_STRIP_CHANNEL); - this->SetDesc(_("Displays this list and give information about commands")); - } - - CommandReturn Execute(CommandSource &source, const std::vector ¶ms) - { - mod_help_cmd(botserv->Bot(), source.u, NULL, params[0]); - return MOD_CONT; - } - - void OnSyntaxError(CommandSource &source, const Anope::string &subcommand) - { - // Abuse syntax error to display general list help. - User *u = source.u; - source.Reply(_("\002%s\002 allows you to have a bot on your own channel.\n" - "It has been created for users that can't host or\n" - "configure a bot, or for use on networks that don't\n" - "allow user bots. Available commands are listed \n" - "below; to use them, type \002%s%s \037command\037\002. For\n" - "more information on a specific command, type\n" - "\002%s%s HELP \037command\037\002."), - Config->s_BotServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str(), - Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str()); - for (CommandMap::const_iterator it = botserv->Bot()->Commands.begin(), it_end = botserv->Bot()->Commands.end(); it != it_end; ++it) - if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission)) - it->second->OnServHelp(source); - source.Reply(_("Bot will join a channel whenever there is at least\n" - "\002%d\002 user(s) on it. Additionally, all %s commands\n" - "can be used if fantasy is enabled by prefixing the command\n" - "name with a %c."), Config->BSMinUsers, Config->s_ChanServ.c_str(), Config->BSFantasyCharacter[0]); - } -}; - -class BSHelp : public Module -{ - CommandBSHelp commandbshelp; - - public: - BSHelp(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE) - { - this->SetAuthor("Anope"); - - if (!botserv) - throw ModuleException("BotServ is not loaded!"); - - this->AddCommand(botserv->Bot(), &commandbshelp); - } -}; - -MODULE_INIT(BSHelp) diff --git a/modules/core/bs_info.cpp b/modules/core/bs_info.cpp index 9c996b247..38178a07b 100644 --- a/modules/core/bs_info.cpp +++ b/modules/core/bs_info.cpp @@ -13,7 +13,6 @@ /*************************************************************************/ #include "module.h" -#include "botserv.h" class CommandBSInfo : public Command { @@ -41,13 +40,13 @@ class CommandBSInfo : public Command return; } public: - CommandBSInfo() : Command("INFO", 1, 1) + CommandBSInfo(Module *creator) : Command(creator, "botserv/info", 1, 1) { - this->SetFlag(CFLAG_STRIP_CHANNEL); this->SetDesc(_("Allows you to see BotServ information about a channel or a bot")); + this->SetSyntax(_("\002INFO {\037chan\037 | \037nick\037}\002")); } - CommandReturn Execute(CommandSource &source, const std::vector ¶ms) + void Execute(CommandSource &source, const std::vector ¶ms) { const Anope::string &query = params[0]; @@ -73,11 +72,11 @@ class CommandBSInfo : public Command { if (!check_access(u, ci, CA_FOUNDER) && !u->HasPriv("botserv/administration")) { - source.Reply(_(ACCESS_DENIED)); - return MOD_CONT; + source.Reply(ACCESS_DENIED); + return; } - source.Reply(_(CHAN_INFO_HEADER), ci->name.c_str()); + source.Reply(CHAN_INFO_HEADER, ci->name.c_str()); if (ci->bi) source.Reply(_(" Bot nick : %s"), ci->bi->nick.c_str()); else @@ -86,93 +85,93 @@ class CommandBSInfo : public Command if (ci->botflags.HasFlag(BS_KICK_BADWORDS)) { if (ci->ttb[TTB_BADWORDS]) - source.Reply(_(" Bad words kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_BADWORDS]); + source.Reply(_(" Bad words kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_BADWORDS]); else - source.Reply(_(" Bad words kicker : %s"), _(ENABLED)); + source.Reply(_(" Bad words kicker : %s"), ENABLED); } else - source.Reply(_(" Bad words kicker : %s"), _(DISABLED)); + source.Reply(_(" Bad words kicker : %s"), DISABLED); if (ci->botflags.HasFlag(BS_KICK_BOLDS)) { if (ci->ttb[TTB_BOLDS]) - source.Reply(_(" Bolds kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_BOLDS]); + source.Reply(_(" Bolds kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_BOLDS]); else - source.Reply(_(" Bolds kicker : %s"), _(ENABLED)); + source.Reply(_(" Bolds kicker : %s"), ENABLED); } else - source.Reply(_(" Bolds kicker : %s"), _(DISABLED)); + source.Reply(_(" Bolds kicker : %s"), DISABLED); if (ci->botflags.HasFlag(BS_KICK_CAPS)) { if (ci->ttb[TTB_CAPS]) - source.Reply(_(" Caps kicker : %s (%d kick(s) to ban; minimum %d/%d%%)"), _(ENABLED), ci->ttb[TTB_CAPS], ci->capsmin, ci->capspercent); + source.Reply(_(" Caps kicker : %s (%d kick(s) to ban; minimum %d/%d%%)"), ENABLED, ci->ttb[TTB_CAPS], ci->capsmin, ci->capspercent); else - source.Reply(_(" Caps kicker : %s (minimum %d/%d%%)"), _(ENABLED), ci->capsmin, ci->capspercent); + source.Reply(_(" Caps kicker : %s (minimum %d/%d%%)"), ENABLED, ci->capsmin, ci->capspercent); } else - source.Reply(_(" Caps kicker : %s"), _(DISABLED)); + source.Reply(_(" Caps kicker : %s"), DISABLED); if (ci->botflags.HasFlag(BS_KICK_COLORS)) { if (ci->ttb[TTB_COLORS]) - source.Reply(_(" Colors kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_COLORS]); + source.Reply(_(" Colors kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_COLORS]); else - source.Reply(_(" Colors kicker : %s"), _(ENABLED)); + source.Reply(_(" Colors kicker : %s"), ENABLED); } else - source.Reply(_(" Colors kicker : %s"), _(DISABLED)); + source.Reply(_(" Colors kicker : %s"), DISABLED); if (ci->botflags.HasFlag(BS_KICK_FLOOD)) { if (ci->ttb[TTB_FLOOD]) - source.Reply(_(" Flood kicker : %s (%d kick(s) to ban; %d lines in %ds)"), _(ENABLED), ci->ttb[TTB_FLOOD], ci->floodlines, ci->floodsecs); + source.Reply(_(" Flood kicker : %s (%d kick(s) to ban; %d lines in %ds)"), ENABLED, ci->ttb[TTB_FLOOD], ci->floodlines, ci->floodsecs); else - source.Reply(_(" Flood kicker : %s (%d lines in %ds)"), _(ENABLED), ci->floodlines, ci->floodsecs); + source.Reply(_(" Flood kicker : %s (%d lines in %ds)"), ENABLED, ci->floodlines, ci->floodsecs); } else - source.Reply(_(" Flood kicker : %s"), _(DISABLED)); + source.Reply(_(" Flood kicker : %s"), DISABLED); if (ci->botflags.HasFlag(BS_KICK_REPEAT)) { if (ci->ttb[TTB_REPEAT]) - source.Reply(_(" Repeat kicker : %s (%d kick(s) to ban; %d times)"), _(ENABLED), ci->ttb[TTB_REPEAT], ci->repeattimes); + source.Reply(_(" Repeat kicker : %s (%d kick(s) to ban; %d times)"), ENABLED, ci->ttb[TTB_REPEAT], ci->repeattimes); else - source.Reply(_(" Repeat kicker : %s (%d times)"), _(ENABLED), ci->repeattimes); + source.Reply(_(" Repeat kicker : %s (%d times)"), ENABLED, ci->repeattimes); } else - source.Reply(_(" Repeat kicker : %s"), _(DISABLED)); + source.Reply(_(" Repeat kicker : %s"), DISABLED); if (ci->botflags.HasFlag(BS_KICK_REVERSES)) { if (ci->ttb[TTB_REVERSES]) - source.Reply(_(" Reverses kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_REVERSES]); + source.Reply(_(" Reverses kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_REVERSES]); else - source.Reply(_(" Reverses kicker : %s"), _(ENABLED)); + source.Reply(_(" Reverses kicker : %s"), ENABLED); } else - source.Reply(_(" Reverses kicker : %s"), _(DISABLED)); + source.Reply(_(" Reverses kicker : %s"), DISABLED); if (ci->botflags.HasFlag(BS_KICK_UNDERLINES)) { if (ci->ttb[TTB_UNDERLINES]) - source.Reply(_(" Underlines kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_UNDERLINES]); + source.Reply(_(" Underlines kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_UNDERLINES]); else - source.Reply(_(" Underlines kicker : %s"), _(ENABLED)); + source.Reply(_(" Underlines kicker : %s"), ENABLED); } else - source.Reply(_(" Underlines kicker : %s"), _(DISABLED)); + source.Reply(_(" Underlines kicker : %s"), DISABLED); if (ci->botflags.HasFlag(BS_KICK_ITALICS)) { if (ci->ttb[TTB_ITALICS]) - source.Reply(_(" Italics kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_ITALICS]); + source.Reply(_(" Italics kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_ITALICS]); else - source.Reply(_(" Italics kicker : %s"), _(ENABLED)); + source.Reply(_(" Italics kicker : %s"), ENABLED); } else - source.Reply(_(" Italics kicker : %s"), _(DISABLED)); + source.Reply(_(" Italics kicker : %s"), DISABLED); if (ci->botflags.HasFlag(BS_KICK_AMSGS)) { if (ci->ttb[TTB_AMSGS]) - source.Reply(_(" AMSG kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_AMSGS]); + source.Reply(_(" AMSG kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_AMSGS]); else - source.Reply(_(" AMSG kicker : %s"), _(ENABLED)); + source.Reply(_(" AMSG kicker : %s"), ENABLED); } else - source.Reply(_(" AMSG kicker : %s"), _(DISABLED)); + source.Reply(_(" AMSG kicker : %s"), DISABLED); if (ci->botflags.HasFlag(BS_MSG_PRIVMSG)) source.Reply(_(" Fantasy reply : %s"), "PRIVMSG"); @@ -208,34 +207,24 @@ class CommandBSInfo : public Command end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("No bot")); need_comma = true; } - if (ci->botflags.HasFlag(BS_SYMBIOSIS)) - { - end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("Symbiosis")); - need_comma = true; - } source.Reply(_(" Options : %s"), *buf ? buf : _("None")); } else source.Reply(_("\002%s\002 is not a valid bot or registered channel."), query.c_str()); - return MOD_CONT; + return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) { - source.Reply(_("Syntax: \002INFO {\037chan\037 | \037nick\037}\002\n" - " \n" - "Allows you to see %s information about a channel or a bot.\n" + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Allows you to see %s information about a channel or a bot.\n" "If the parameter is a channel, then you'll get information\n" "such as enabled kickers. If the parameter is a nick,\n" "you'll get information about a bot, such as creation\n" - "time or number of channels it is on."), Config->s_NickServ.c_str()); + "time or number of channels it is on."), source.owner->nick.c_str()); return true; } - - void OnSyntaxError(CommandSource &source, const Anope::string &subcommand) - { - SyntaxError(source, "INFO", _("INFO {\037chan\037 | \037nick\037}")); - } }; class BSInfo : public Module @@ -243,14 +232,12 @@ class BSInfo : public Module CommandBSInfo commandbsinfo; public: - BSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE) + BSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + commandbsinfo(this) { this->SetAuthor("Anope"); - if (!botserv) - throw ModuleException("BotServ is not loaded!"); - - this->AddCommand(botserv->Bot(), &commandbsinfo); + ModuleManager::RegisterService(&commandbsinfo); } }; diff --git a/modules/core/bs_kick.cpp b/modules/core/bs_kick.cpp index 467f4104e..a8c34e5cd 100644 --- a/modules/core/bs_kick.cpp +++ b/modules/core/bs_kick.cpp @@ -13,17 +13,17 @@ /*************************************************************************/ #include "module.h" -#include "botserv.h" class CommandBSKick : public Command { public: - CommandBSKick() : Command("KICK", 3, 6) + CommandBSKick(Module *creator) : Command(creator, "botserv/kick", 3, 6) { this->SetDesc(_("Configures kickers")); + this->SetSyntax(_("\037channel\037 \037option\037 {\037ON|\037} [\037settings\037]")); } - CommandReturn Execute(CommandSource &source, const std::vector ¶ms) + void Execute(CommandSource &source, const std::vector ¶ms) { const Anope::string &chan = params[0]; const Anope::string &option = params[1]; @@ -31,18 +31,20 @@ class CommandBSKick : public Command const Anope::string &ttb = params.size() > 3 ? params[3] : ""; User *u = source.u; - ChannelInfo *ci = source.ci; + ChannelInfo *ci = cs_findchan(params[0]); if (readonly) source.Reply(_("Sorry, kicker configuration is temporarily disabled.")); + else if (ci == NULL) + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); else if (chan.empty() || option.empty() || value.empty()) - SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]")); + this->OnSyntaxError(source, ""); else if (!value.equals_ci("ON") && !value.equals_ci("OFF")) - SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]")); + this->OnSyntaxError(source, ""); else if (!check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration")) - source.Reply(_(ACCESS_DENIED)); + source.Reply(ACCESS_DENIED); else if (!ci->bi) - source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str()); + source.Reply(BOT_NOT_ASSIGNED); else { bool override = !check_access(u, ci, CA_SET); @@ -65,7 +67,7 @@ class CommandBSKick : public Command /* reset the value back to 0 - TSL */ ci->ttb[TTB_BADWORDS] = 0; source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str()); - return MOD_CONT; + return; } } else @@ -102,7 +104,7 @@ class CommandBSKick : public Command { ci->ttb[TTB_BOLDS] = 0; source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str()); - return MOD_CONT; + return; } } else @@ -138,7 +140,7 @@ class CommandBSKick : public Command { ci->ttb[TTB_CAPS] = 0; source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str()); - return MOD_CONT; + return; } } else @@ -193,7 +195,7 @@ class CommandBSKick : public Command { ci->ttb[TTB_COLORS] = 0; source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str()); - return MOD_CONT; + return; } } else @@ -230,7 +232,7 @@ class CommandBSKick : public Command { ci->ttb[TTB_FLOOD] = 0; source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str()); - return MOD_CONT; + return; }