From 484160eb4ed560eeda97c94a42dd8e31431ab251 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Wed, 24 Jan 2024 12:34:03 +0000 Subject: Shuffle modules around a bit. --- modules/commands/bs_assign.cpp | 260 ------- modules/commands/bs_badwords.cpp | 476 ------------ modules/commands/bs_bot.cpp | 387 ---------- modules/commands/bs_botlist.cpp | 82 -- modules/commands/bs_control.cpp | 149 ---- modules/commands/bs_info.cpp | 134 ---- modules/commands/bs_kick.cpp | 1491 ------------------------------------- modules/commands/bs_set.cpp | 231 ------ modules/commands/cs_access.cpp | 939 ----------------------- modules/commands/cs_akick.cpp | 585 --------------- modules/commands/cs_ban.cpp | 254 ------- modules/commands/cs_clone.cpp | 262 ------- modules/commands/cs_drop.cpp | 97 --- modules/commands/cs_enforce.cpp | 279 ------- modules/commands/cs_entrymsg.cpp | 294 -------- modules/commands/cs_flags.cpp | 518 ------------- modules/commands/cs_getkey.cpp | 75 -- modules/commands/cs_info.cpp | 100 --- modules/commands/cs_invite.cpp | 113 --- modules/commands/cs_kick.cpp | 149 ---- modules/commands/cs_list.cpp | 267 ------- modules/commands/cs_log.cpp | 404 ---------- modules/commands/cs_mode.cpp | 1066 -------------------------- modules/commands/cs_register.cpp | 126 ---- modules/commands/cs_seen.cpp | 461 ------------ modules/commands/cs_set.cpp | 1326 --------------------------------- modules/commands/cs_set_misc.cpp | 222 ------ modules/commands/cs_status.cpp | 125 ---- modules/commands/cs_suspend.cpp | 296 -------- modules/commands/cs_sync.cpp | 68 -- modules/commands/cs_topic.cpp | 273 ------- modules/commands/cs_unban.cpp | 132 ---- modules/commands/cs_updown.cpp | 245 ------ modules/commands/cs_xop.cpp | 651 ---------------- modules/commands/gl_global.cpp | 68 -- modules/commands/greet.cpp | 220 ------ modules/commands/help.cpp | 199 ----- modules/commands/hs_del.cpp | 116 --- modules/commands/hs_group.cpp | 118 --- modules/commands/hs_list.cpp | 160 ---- modules/commands/hs_off.cpp | 71 -- modules/commands/hs_on.cpp | 77 -- modules/commands/hs_request.cpp | 399 ---------- modules/commands/hs_set.cpp | 231 ------ modules/commands/ms_cancel.cpp | 103 --- modules/commands/ms_check.cpp | 89 --- modules/commands/ms_del.cpp | 162 ---- modules/commands/ms_ignore.cpp | 134 ---- modules/commands/ms_info.cpp | 235 ------ modules/commands/ms_list.cpp | 167 ----- modules/commands/ms_read.cpp | 227 ------ modules/commands/ms_rsend.cpp | 106 --- modules/commands/ms_send.cpp | 90 --- modules/commands/ms_sendall.cpp | 70 -- modules/commands/ms_set.cpp | 317 -------- modules/commands/ms_staff.cpp | 67 -- modules/commands/ns_access.cpp | 208 ------ modules/commands/ns_ajoin.cpp | 408 ---------- modules/commands/ns_alist.cpp | 148 ---- modules/commands/ns_cert.cpp | 412 ---------- modules/commands/ns_drop.cpp | 88 --- modules/commands/ns_getemail.cpp | 74 -- modules/commands/ns_group.cpp | 399 ---------- modules/commands/ns_identify.cpp | 131 ---- modules/commands/ns_info.cpp | 287 ------- modules/commands/ns_list.cpp | 303 -------- modules/commands/ns_logout.cpp | 93 --- modules/commands/ns_recover.cpp | 301 -------- modules/commands/ns_register.cpp | 445 ----------- modules/commands/ns_resetpass.cpp | 146 ---- modules/commands/ns_set.cpp | 1464 ------------------------------------ modules/commands/ns_set_misc.cpp | 238 ------ modules/commands/ns_status.cpp | 89 --- modules/commands/ns_suspend.cpp | 291 -------- modules/commands/ns_update.cpp | 64 -- modules/commands/os_akill.cpp | 487 ------------ modules/commands/os_chankill.cpp | 119 --- modules/commands/os_config.cpp | 149 ---- modules/commands/os_defcon.cpp | 603 --------------- modules/commands/os_dns.cpp | 944 ----------------------- modules/commands/os_forbid.cpp | 573 -------------- modules/commands/os_ignore.cpp | 421 ----------- modules/commands/os_info.cpp | 291 -------- modules/commands/os_jupe.cpp | 82 -- modules/commands/os_kick.cpp | 86 --- modules/commands/os_kill.cpp | 69 -- modules/commands/os_list.cpp | 289 ------- modules/commands/os_login.cpp | 135 ---- modules/commands/os_logsearch.cpp | 187 ----- modules/commands/os_mode.cpp | 192 ----- modules/commands/os_modinfo.cpp | 211 ------ modules/commands/os_module.cpp | 192 ----- modules/commands/os_news.cpp | 478 ------------ modules/commands/os_noop.cpp | 100 --- modules/commands/os_oper.cpp | 292 -------- modules/commands/os_reload.cpp | 69 -- modules/commands/os_session.cpp | 738 ------------------ modules/commands/os_set.cpp | 269 ------- modules/commands/os_shutdown.cpp | 112 --- modules/commands/os_stats.cpp | 281 ------- modules/commands/os_svs.cpp | 182 ----- modules/commands/os_sxline.cpp | 731 ------------------ modules/commands/os_update.cpp | 54 -- 103 files changed, 29888 deletions(-) delete mode 100644 modules/commands/bs_assign.cpp delete mode 100644 modules/commands/bs_badwords.cpp delete mode 100644 modules/commands/bs_bot.cpp delete mode 100644 modules/commands/bs_botlist.cpp delete mode 100644 modules/commands/bs_control.cpp delete mode 100644 modules/commands/bs_info.cpp delete mode 100644 modules/commands/bs_kick.cpp delete mode 100644 modules/commands/bs_set.cpp delete mode 100644 modules/commands/cs_access.cpp delete mode 100644 modules/commands/cs_akick.cpp delete mode 100644 modules/commands/cs_ban.cpp delete mode 100644 modules/commands/cs_clone.cpp delete mode 100644 modules/commands/cs_drop.cpp delete mode 100644 modules/commands/cs_enforce.cpp delete mode 100644 modules/commands/cs_entrymsg.cpp delete mode 100644 modules/commands/cs_flags.cpp delete mode 100644 modules/commands/cs_getkey.cpp delete mode 100644 modules/commands/cs_info.cpp delete mode 100644 modules/commands/cs_invite.cpp delete mode 100644 modules/commands/cs_kick.cpp delete mode 100644 modules/commands/cs_list.cpp delete mode 100644 modules/commands/cs_log.cpp delete mode 100644 modules/commands/cs_mode.cpp delete mode 100644 modules/commands/cs_register.cpp delete mode 100644 modules/commands/cs_seen.cpp delete mode 100644 modules/commands/cs_set.cpp delete mode 100644 modules/commands/cs_set_misc.cpp delete mode 100644 modules/commands/cs_status.cpp delete mode 100644 modules/commands/cs_suspend.cpp delete mode 100644 modules/commands/cs_sync.cpp delete mode 100644 modules/commands/cs_topic.cpp delete mode 100644 modules/commands/cs_unban.cpp delete mode 100644 modules/commands/cs_updown.cpp delete mode 100644 modules/commands/cs_xop.cpp delete mode 100644 modules/commands/gl_global.cpp delete mode 100644 modules/commands/greet.cpp delete mode 100644 modules/commands/help.cpp delete mode 100644 modules/commands/hs_del.cpp delete mode 100644 modules/commands/hs_group.cpp delete mode 100644 modules/commands/hs_list.cpp delete mode 100644 modules/commands/hs_off.cpp delete mode 100644 modules/commands/hs_on.cpp delete mode 100644 modules/commands/hs_request.cpp delete mode 100644 modules/commands/hs_set.cpp delete mode 100644 modules/commands/ms_cancel.cpp delete mode 100644 modules/commands/ms_check.cpp delete mode 100644 modules/commands/ms_del.cpp delete mode 100644 modules/commands/ms_ignore.cpp delete mode 100644 modules/commands/ms_info.cpp delete mode 100644 modules/commands/ms_list.cpp delete mode 100644 modules/commands/ms_read.cpp delete mode 100644 modules/commands/ms_rsend.cpp delete mode 100644 modules/commands/ms_send.cpp delete mode 100644 modules/commands/ms_sendall.cpp delete mode 100644 modules/commands/ms_set.cpp delete mode 100644 modules/commands/ms_staff.cpp delete mode 100644 modules/commands/ns_access.cpp delete mode 100644 modules/commands/ns_ajoin.cpp delete mode 100644 modules/commands/ns_alist.cpp delete mode 100644 modules/commands/ns_cert.cpp delete mode 100644 modules/commands/ns_drop.cpp delete mode 100644 modules/commands/ns_getemail.cpp delete mode 100644 modules/commands/ns_group.cpp delete mode 100644 modules/commands/ns_identify.cpp delete mode 100644 modules/commands/ns_info.cpp delete mode 100644 modules/commands/ns_list.cpp delete mode 100644 modules/commands/ns_logout.cpp delete mode 100644 modules/commands/ns_recover.cpp delete mode 100644 modules/commands/ns_register.cpp delete mode 100644 modules/commands/ns_resetpass.cpp delete mode 100644 modules/commands/ns_set.cpp delete mode 100644 modules/commands/ns_set_misc.cpp delete mode 100644 modules/commands/ns_status.cpp delete mode 100644 modules/commands/ns_suspend.cpp delete mode 100644 modules/commands/ns_update.cpp delete mode 100644 modules/commands/os_akill.cpp delete mode 100644 modules/commands/os_chankill.cpp delete mode 100644 modules/commands/os_config.cpp delete mode 100644 modules/commands/os_defcon.cpp delete mode 100644 modules/commands/os_dns.cpp delete mode 100644 modules/commands/os_forbid.cpp delete mode 100644 modules/commands/os_ignore.cpp delete mode 100644 modules/commands/os_info.cpp delete mode 100644 modules/commands/os_jupe.cpp delete mode 100644 modules/commands/os_kick.cpp delete mode 100644 modules/commands/os_kill.cpp delete mode 100644 modules/commands/os_list.cpp delete mode 100644 modules/commands/os_login.cpp delete mode 100644 modules/commands/os_logsearch.cpp delete mode 100644 modules/commands/os_mode.cpp delete mode 100644 modules/commands/os_modinfo.cpp delete mode 100644 modules/commands/os_module.cpp delete mode 100644 modules/commands/os_news.cpp delete mode 100644 modules/commands/os_noop.cpp delete mode 100644 modules/commands/os_oper.cpp delete mode 100644 modules/commands/os_reload.cpp delete mode 100644 modules/commands/os_session.cpp delete mode 100644 modules/commands/os_set.cpp delete mode 100644 modules/commands/os_shutdown.cpp delete mode 100644 modules/commands/os_stats.cpp delete mode 100644 modules/commands/os_svs.cpp delete mode 100644 modules/commands/os_sxline.cpp delete mode 100644 modules/commands/os_update.cpp (limited to 'modules/commands') diff --git a/modules/commands/bs_assign.cpp b/modules/commands/bs_assign.cpp deleted file mode 100644 index 43abdd55f..000000000 --- a/modules/commands/bs_assign.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* BotServ core functions - * - * (C) 2003-2024 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 CommandBSAssign final - : public Command -{ -public: - CommandBSAssign(Module *creator) : Command(creator, "botserv/assign", 2, 2) - { - this->SetDesc(_("Assigns a bot to a channel")); - this->SetSyntax(_("\037channel\037 \037nick\037")); - } - - void Execute(CommandSource &source, const std::vector ¶ms) override - { - const Anope::string &chan = params[0]; - const Anope::string &nick = params[1]; - - if (Anope::ReadOnly) - { - source.Reply(_("Sorry, bot assignment is temporarily disabled.")); - return; - } - - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - BotInfo *bi = BotInfo::Find(nick, true); - if (!bi) - { - source.Reply(BOT_DOES_NOT_EXIST, nick.c_str()); - return; - } - - AccessGroup access = source.AccessFor(ci); - if (ci->HasExt("BS_NOBOT") || (!access.HasPriv("ASSIGN") && !source.HasPriv("botserv/administration"))) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (bi->oper_only && !source.HasPriv("botserv/administration")) - { - source.Reply(ACCESS_DENIED); - return; - } - - 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; - } - - bool override = !access.HasPriv("ASSIGN"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << bi->nick; - - bi->Assign(source.GetUser(), ci); - source.Reply(_("Bot \002%s\002 has been assigned to %s."), bi->nick.c_str(), ci->name.c_str()); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Assigns the specified bot to a channel. You\n" - "can then configure the bot for the channel so it fits\n" - "your needs.")); - return true; - } -}; - -class CommandBSUnassign final - : public Command -{ -public: - CommandBSUnassign(Module *creator) : Command(creator, "botserv/unassign", 1, 1) - { - this->SetDesc(_("Unassigns a bot from a channel")); - this->SetSyntax(_("\037channel\037")); - } - - void Execute(CommandSource &source, const std::vector ¶ms) override - { - if (Anope::ReadOnly) - { - source.Reply(_("Sorry, bot assignment is temporarily disabled.")); - return; - } - - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - AccessGroup access = source.AccessFor(ci); - if (!source.HasPriv("botserv/administration") && !access.HasPriv("ASSIGN")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (!ci->bi) - { - source.Reply(BOT_NOT_ASSIGNED); - return; - } - - if (ci->HasExt("PERSIST") && !ModeManager::FindChannelModeByName("PERM")) - { - source.Reply(_("You cannot unassign bots while persist is set on the channel.")); - return; - } - - bool override = !access.HasPriv("ASSIGN"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << ci->bi->nick; - - ci->bi->UnAssign(source.GetUser(), ci); - source.Reply(_("There is no bot assigned to %s anymore."), ci->name.c_str()); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) override - { - 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 having to reconfigure\n" - "it entirely.")); - return true; - } -}; - -class CommandBSSetNoBot final - : public Command -{ -public: - CommandBSSetNoBot(Module *creator, const Anope::string &sname = "botserv/set/nobot") : Command(creator, sname, 2, 2) - { - this->SetDesc(_("Prevent a bot from being assigned to a channel")); - this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}")); - } - - void Execute(CommandSource &source, const std::vector ¶ms) override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - const Anope::string &value = params[1]; - - if (Anope::ReadOnly) - { - source.Reply(_("Sorry, bot modification is temporarily disabled.")); - return; - } - - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - if (value.equals_ci("ON")) - { - Log(LOG_ADMIN, source, this, ci) << "to enable nobot"; - - ci->Extend("BS_NOBOT"); - if (ci->bi) - ci->bi->UnAssign(source.GetUser(), ci); - source.Reply(_("No-bot mode is now \002on\002 on channel %s."), ci->name.c_str()); - } - else if (value.equals_ci("OFF")) - { - Log(LOG_ADMIN, source, this, ci) << "to disable nobot"; - - ci->Shrink("BS_NOBOT"); - source.Reply(_("No-bot mode is now \002off\002 on channel %s."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, source.command); - } - - bool OnHelp(CommandSource &source, const Anope::string &) override - { - this->SendSyntax(source); - source.Reply(_(" \n" - "This option makes a channel unassignable. If a bot\n" - "is already assigned to the channel, it is unassigned\n" - "automatically when you enable it.")); - return true; - } -}; - -class BSAssign final - : public Module -{ - ExtensibleItem nobot; - - CommandBSAssign commandbsassign; - CommandBSUnassign commandbsunassign; - CommandBSSetNoBot commandbssetnobot; - -public: - BSAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), - nobot(this, "BS_NOBOT"), - commandbsassign(this), commandbsunassign(this), commandbssetnobot(this) - { - } - - void OnInvite(User *source, Channel *c, User *targ) override - { - BotInfo *bi; - if (Anope::ReadOnly || !c->ci || targ->server != Me || !(bi = dynamic_cast(targ))) - return; - - AccessGroup access = c->ci->AccessFor(source); - if (nobot.HasExt(c->ci) || (!access.HasPriv("ASSIGN") && !source->HasPriv("botserv/administration"))) - { - targ->SendMessage(bi, ACCESS_DENIED); - return; - } - - if (bi->oper_only && !source->HasPriv("botserv/administration")) - { - targ->SendMessage(bi, ACCESS_DENIED); - return; - } - - if (c->ci->bi == bi) - { - targ->SendMessage(bi, _("Bot \002%s\002 is already assigned to channel \002%s\002."), c->ci->bi->nick.c_str(), c->name.c_str()); - return; - } - - bi->Assign(source, c->ci); - targ->SendMessage(bi, _("Bot \002%s\002 has been assigned to %s."), bi->nick.c_str(), c->name.c_str()); - } - - void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info) override - { - if (nobot.HasExt(ci)) - info.AddOption(_("No bot")); - } -}; - -MODULE_INIT(BSAssign) diff --git a/modules/commands/bs_badwords.cpp b/modules/commands/bs_badwords.cpp deleted file mode 100644 index e513170e7..000000000 --- a/modules/commands/bs_badwords.cpp +++ /dev/null @@ -1,476 +0,0 @@ -/* BotServ core functions - * - * (C) 2003-2024 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 "modules/bs_badwords.h" - -struct BadWordImpl final - : BadWord - , Serializable -{ - BadWordImpl() : Serializable("BadWord") { } - ~BadWordImpl() override; - - void Serialize(Serialize::Data &data) const override - { - data["ci"] << this->chan; - data["word"] << this->word; - data.SetType("type", Serialize::Data::DT_INT); data["type"] << this->type; - } - - static Serializable* Unserialize(Serializable *obj, Serialize::Data &); -}; - -struct BadWordsImpl final - : BadWords -{ - Serialize::Reference ci; - typedef std::vector list; - Serialize::Checker badwords; - - BadWordsImpl(Extensible *obj) : ci(anope_dynamic_static_cast(obj)), badwords("BadWord") { } - - ~BadWordsImpl() override; - - BadWord* AddBadWord(const Anope::string &word, BadWordType type) override - { - auto *bw = new BadWordImpl(); - bw->chan = ci->name; - bw->word = word; - bw->type = type; - - this->badwords->push_back(bw); - - FOREACH_MOD(OnBadWordAdd, (ci, bw)); - - return bw; - } - - BadWord* GetBadWord(unsigned index) const override - { - if (this->badwords->empty() || index >= this->badwords->size()) - return NULL; - - BadWordImpl *bw = (*this->badwords)[index]; - bw->QueueUpdate(); - return bw; - } - - unsigned GetBadWordCount() const override - { - return this->badwords->size(); - } - - void EraseBadWord(unsigned index) override - { - if (this->badwords->empty() || index >= this->badwords->size()) - return; - - FOREACH_MOD(OnBadWordDel, (ci, (*this->badwords)[index])); - - delete this->badwords->at(index); - } - - void ClearBadWords() override - { - while (!this->badwords->empty()) - delete this->badwords->back(); - } - - void Check() override - { - if (this->badwords->empty()) - ci->Shrink("badwords"); - } -}; - -BadWordsImpl::~BadWordsImpl() -{ - for (list::iterator it = badwords->begin(); it != badwords->end();) - { - BadWord *bw = *it; - ++it; - delete bw; - } -} - -BadWordImpl::~BadWordImpl() -{ - ChannelInfo *ci = ChannelInfo::Find(chan); - if (ci) - { - BadWordsImpl *badwords = ci->GetExt("badwords"); - if (badwords) - { - BadWordsImpl::list::iterator it = std::find(badwords->badwords->begin(), badwords->badwords->end(), this); - if (it != badwords->badwords->end()) - badwords->badwords->erase(it); - } - } -} - -Serializable* BadWordImpl::Unserialize(Serializable *obj, Serialize::Data &data) -{ - Anope::string sci, sword; - - data["ci"] >> sci; - data["word"] >> sword; - - ChannelInfo *ci = ChannelInfo::Find(sci); - if (!ci) - return NULL; - - unsigned int n; - data["type"] >> n; - - BadWordImpl *bw; - if (obj) - bw = anope_dynamic_static_cast(obj); - else - bw = new BadWordImpl(); - bw->chan = sci; - bw->word = sword; - bw->type = static_cast(n); - - BadWordsImpl *bws = ci->Require("badwords"); - if (!obj) - bws->badwords->push_back(bw); - - return bw; -} - -class BadwordsDelCallback final - : public NumberList -{ - CommandSource &source; - ChannelInfo *ci; - BadWords *bw; - Command *c; - unsigned deleted = 0; - bool override = false; -public: - BadwordsDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c) - { - if (!source.AccessFor(ci).HasPriv("BADWORDS") && source.HasPriv("botserv/administration")) - this->override = true; - bw = ci->Require("badwords"); - } - - ~BadwordsDelCallback() override - { - if (!deleted) - 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."), ci->name.c_str()); - else - source.Reply(_("Deleted %d entries from %s bad words list."), deleted, ci->name.c_str()); - } - - void HandleNumber(unsigned Number) override - { - if (!bw || !Number || Number > bw->GetBadWordCount()) - return; - - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, c, ci) << "DEL " << bw->GetBadWord(Number - 1)->word; - ++deleted; - bw->EraseBadWord(Number - 1); - } -}; - -class CommandBSBadwords final - : public Command -{ -private: - void DoList(CommandSource &source, ChannelInfo *ci, const Anope::string &word) - { - bool override = !source.AccessFor(ci).HasPriv("BADWORDS"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "LIST"; - ListFormatter list(source.GetAccount()); - BadWords *bw = ci->GetExt("badwords"); - - list.AddColumn(_("Number")).AddColumn(_("Word")).AddColumn(_("Type")); - - if (!bw || !bw->GetBadWordCount()) - { - source.Reply(_("%s bad words list is empty."), ci->name.c_str()); - return; - } - else if (!word.empty() && word.find_first_not_of("1234567890,-") == Anope::string::npos) - { - class BadwordsListCallback final - : public NumberList - { - ListFormatter &list; - BadWords *bw; - public: - BadwordsListCallback(ListFormatter &_list, BadWords *_bw, const Anope::string &numlist) : NumberList(numlist, false), list(_list), bw(_bw) - { - } - - void HandleNumber(unsigned Number) override - { - if (!Number || Number > bw->GetBadWordCount()) - return; - - const BadWord *b = bw->GetBadWord(Number - 1); - ListFormatter::ListEntry entry; - entry["Number"] = stringify(Number); - entry["Word"] = b->word; - entry["Type"] = b->type == BW_SINGLE ? "(SINGLE)" : (b->type == BW_START ? "(START)" : (b->type == BW_END ? "(END)" : "")); - this->list.AddEntry(entry); - } - } - nl_list(list, bw, word); - nl_list.Process(); - } - else - { - for (unsigned i = 0, end = bw->GetBadWordCount(); i < end; ++i) - { - const BadWord *b = bw->GetBadWord(i); - - if (!word.empty() && !Anope::Match(b->word, word)) - continue; - - ListFormatter::ListEntry entry; - entry["Number"] = stringify(i + 1); - entry["Word"] = b->word; - entry["Type"] = b->type == BW_SINGLE ? "(SINGLE)" : (b->type == BW_START ? "(START)" : (b->type == BW_END ? "(END)" : "")); - list.AddEntry(entry); - } - } - - if (list.IsEmpty()) - source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str()); - else - { - std::vector replies; - list.Process(replies); - - source.Reply(_("Bad words list for %s:"), ci->name.c_str()); - - for (const auto &reply : replies) - source.Reply(reply); - - source.Reply(_("End of bad words list.")); - } - } - - void DoAdd(CommandSource &source, ChannelInfo *ci, const Anope::string &word) - { - size_t pos = word.rfind(' '); - BadWordType bwtype = BW_ANY; - Anope::string realword = word; - BadWords *badwords = ci->Require("badwords"); - - if (pos != Anope::string::npos) - { - Anope::string opt = word.substr(pos + 1); - if (!opt.empty()) - { - if (opt.equals_ci("SINGLE")) - bwtype = BW_SINGLE; - else if (opt.equals_ci("START")) - bwtype = BW_START; - else if (opt.equals_ci("END")) - bwtype = BW_END; - } - realword = word.substr(0, pos); - } - - unsigned badwordsmax = Config->GetModule(this->module)->Get("badwordsmax"); - if (badwords->GetBadWordCount() >= badwordsmax) - { - source.Reply(_("Sorry, you can only have %d bad words entries on a channel."), badwordsmax); - return; - } - - bool casesensitive = Config->GetModule(this->module)->Get("casesensitive"); - - for (unsigned i = 0, end = badwords->GetBadWordCount(); i < end; ++i) - { - const BadWord *bw = badwords->GetBadWord(i); - - if ((casesensitive && realword.equals_cs(bw->word)) || (!casesensitive && 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; - } - } - - bool override = !source.AccessFor(ci).HasPriv("BADWORDS"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "ADD " << realword; - badwords->AddBadWord(realword, bwtype); - - source.Reply(_("\002%s\002 added to %s bad words list."), realword.c_str(), ci->name.c_str()); - } - - void DoDelete(CommandSource &source, ChannelInfo *ci, const Anope::string &word) - { - BadWords *badwords = ci->GetExt("badwords"); - - if (!badwords || !badwords->GetBadWordCount()) - { - source.Reply(_("%s bad words list is empty."), ci->name.c_str()); - return; - } - - /* 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, ci, this, word); - list.Process(); - } - else - { - unsigned i, end; - const BadWord *badword; - - for (i = 0, end = badwords->GetBadWordCount(); i < end; ++i) - { - badword = badwords->GetBadWord(i); - - if (word.equals_ci(badword->word)) - break; - } - - if (i == end) - { - source.Reply(_("\002%s\002 not found on %s bad words list."), word.c_str(), ci->name.c_str()); - return; - } - - bool override = !source.AccessFor(ci).HasPriv("BADWORDS"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "DEL " << badword->word; - - source.Reply(_("\002%s\002 deleted from %s bad words list."), badword->word.c_str(), ci->name.c_str()); - - badwords->EraseBadWord(i); - } - - badwords->Check(); - } - - void DoClear(CommandSource &source, ChannelInfo *ci) - { - bool override = !source.AccessFor(ci).HasPriv("BADWORDS"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "CLEAR"; - - BadWords *badwords = ci->GetExt("badwords"); - if (badwords) - badwords->ClearBadWords(); - source.Reply(_("Bad words list is now empty.")); - } - -public: - CommandBSBadwords(Module *creator) : Command(creator, "botserv/badwords", 2, 3) - { - this->SetDesc(_("Maintains the 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")); - } - - void Execute(CommandSource &source, const std::vector ¶ms) override - { - const Anope::string &cmd = params[1]; - const Anope::string &word = params.size() > 2 ? params[2] : ""; - bool need_args = cmd.equals_ci("LIST") || cmd.equals_ci("CLEAR"); - - if (!need_args && word.empty()) - { - this->OnSyntaxError(source, cmd); - return; - } - - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - if (!source.AccessFor(ci).HasPriv("BADWORDS") && !source.HasPriv("botserv/administration")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (Anope::ReadOnly) - { - source.Reply(_("Sorry, bad words list modification is temporarily disabled.")); - return; - } - - if (cmd.equals_ci("ADD")) - return this->DoAdd(source, ci, word); - else if (cmd.equals_ci("DEL")) - return this->DoDelete(source, ci, word); - else if (cmd.equals_ci("LIST")) - return this->DoList(source, ci, word); - else if (cmd.equals_ci("CLEAR")) - return this->DoClear(source, ci); - else - this->OnSyntaxError(source, ""); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) override - { - 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 %s\002.\n" - " \n" - "The \002ADD\002 command adds the given word to the\n" - "bad words 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" - "that starts with \037word\037. If END is specified, a kick\n" - "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->StrictPrivmsg.c_str(), source.service->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 \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" - " \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 \002CLEAR\002 command clears all entries from the\n" - "bad words list.")); - return true; - } -}; - -class BSBadwords final - : public Module -{ - CommandBSBadwords commandbsbadwords; - ExtensibleItem badwords; - Serialize::Type badword_type; - -public: - BSBadwords(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), - commandbsbadwords(this), badwords(this, "badwords"), badword_type("BadWord", BadWordImpl::Unserialize) - { - } -}; - -MODULE_INIT(BSBadwords) diff --git a/modules/commands/bs_bot.cpp b/modules/commands/bs_bot.cpp deleted file mode 100644 index 170e1073a..000000000 --- a/modules/commands/bs_bot.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/* BotServ core functions - * - * (C) 2003-2024 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 CommandBSBot final - : public Command -{ -private: - void DoAdd(CommandSource &source, const std::vector ¶ms) - { - const Anope::string &nick = params[1]; - const Anope::string &user = params[2]; - const Anope::string &host = params[3]; - const Anope::string &real = params[4]; - - if (BotInfo::Find(nick, true)) - { - source.Reply(_("Bot \002%s\002 already exists."), nick.c_str()); - return; - } - - Configuration::Block *networkinfo = Config->GetBlock("networkinfo"); - - if (nick.length() > networkinfo->Get("nicklen")) - { - source.Reply(_("Bot nicks may only be %d characters long."), networkinfo->Get("nicklen")); - return; - } - - if (user.length() > networkinfo->Get("userlen")) - { - source.Reply(_("Bot idents may only be %d characters long."), networkinfo->Get("userlen")); - return; - } - - if (host.length() > networkinfo->Get("hostlen")) - { - source.Reply(_("Bot hosts may only be %d characters long."), networkinfo->Get("hostlen")); - return; - } - - if (!IRCD->IsNickValid(nick)) - { - source.Reply(_("Bot nicks may only contain valid nick characters.")); - return; - } - - if (!IRCD->IsIdentValid(user)) - { - source.Reply(_("Bot idents may only contain valid ident characters.")); - return; - } - - if (!IRCD->IsHostValid(host)) - { - source.Reply(_("Bot hosts may only contain valid host characters.")); - return; - } - - /* We check whether the nick is registered, and inform the user - * if so. You need to drop the nick manually before you can use - * it as a bot nick from now on -GD - */ - if (NickAlias::Find(nick)) - { - source.Reply(NICK_ALREADY_REGISTERED, nick.c_str()); - return; - } - - User *u = User::Find(nick, true); - if (u) - { - source.Reply(_("Nick \002%s\002 is currently in use."), u->nick.c_str()); - return; - } - - auto *bi = new BotInfo(nick, user, host, real); - - Log(LOG_ADMIN, source, 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(OnBotCreate, (bi)); - return; - } - - void DoChange(CommandSource &source, const std::vector ¶ms) - { - const Anope::string &oldnick = params[1]; - const Anope::string &nick = params.size() > 2 ? params[2] : ""; - const Anope::string &user = params.size() > 3 ? params[3] : ""; - const Anope::string &host = params.size() > 4 ? params[4] : ""; - const Anope::string &real = params.size() > 5 ? params[5] : ""; - - if (oldnick.empty() || nick.empty()) - { - this->OnSyntaxError(source, "CHANGE"); - return; - } - - BotInfo *bi = BotInfo::Find(oldnick, true); - if (!bi) - { - source.Reply(BOT_DOES_NOT_EXIST, oldnick.c_str()); - return; - } - - if (bi->conf) - { - source.Reply(_("Bot %s is not changeable."), bi->nick.c_str()); - return; - } - - Configuration::Block *networkinfo = Config->GetBlock("networkinfo"); - - if (nick.length() > networkinfo->Get("nicklen")) - { - source.Reply(_("Bot nicks may only be %d characters long."), networkinfo->Get("nicklen")); - return; - } - - if (user.length() > networkinfo->Get("userlen")) - { - source.Reply(_("Bot idents may only be %d characters long."), networkinfo->Get("userlen")); - return; - } - - if (host.length() > networkinfo->Get("hostlen")) - { - source.Reply(_("Bot hosts may only be %d characters long."), networkinfo->Get("hostlen")); - return; - } - - /* Checks whether there *are* changes. - * Case sensitive because we may want to change just the case. - * And we must finally check that the nick is not already - * taken by another bot. - */ - 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(_("The old information is the same as the new information specified.")); - return; - } - - if (!IRCD->IsNickValid(nick)) - { - source.Reply(_("Bot nicks may only contain valid nick characters.")); - return; - } - - if (!user.empty() && !IRCD->IsIdentValid(user)) - { - source.Reply(_("Bot idents may only contain valid ident characters.")); - return; - } - - if (!host.empty() && !IRCD->IsHostValid(host)) - { - source.Reply(_("Bot hosts may only contain valid host characters.")); - return; - } - - if (!nick.equals_ci(bi->nick)) - { - if (BotInfo::Find(nick, true)) - { - source.Reply(_("Bot \002%s\002 already exists."), nick.c_str()); - return; - } - - if (User::Find(nick, true)) - { - source.Reply(_("Nick \002%s\002 is currently in use."), nick.c_str()); - return; - } - } - - if (!nick.equals_ci(bi->nick)) - { - /* We check whether the nick is registered, and inform the user - * if so. You need to drop the nick manually before you can use - * it as a bot nick from now on -GD - */ - if (NickAlias::Find(nick)) - { - 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. */ - XLine x_del(bi->nick); - IRCD->SendSQLineDel(&x_del); - - /* Add a Q line for the new nick */ - XLine x(nick, "Reserved for services"); - IRCD->SendSQLine(NULL, &x); - } - - if (!user.empty()) - { - IRCD->SendQuit(bi, "Quit: Be right back"); - bi->introduced = false; - } - else - IRCD->SendNickChange(bi, nick); - - if (!nick.equals_cs(bi->nick)) - bi->SetNewNick(nick); - - if (!user.empty() && !user.equals_cs(bi->GetIdent())) - bi->SetIdent(user); - if (!host.empty() && !host.equals_cs(bi->host)) - bi->host = host; - if (!real.empty() && !real.equals_cs(bi->realname)) - bi->realname = real; - - if (!user.empty()) - bi->OnKill(); - - source.Reply(_("Bot \002%s\002 has been changed to %s!%s@%s (%s)."), oldnick.c_str(), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str()); - Log(LOG_ADMIN, source, this) << "CHANGE " << oldnick << " to " << bi->GetMask() << " " << bi->realname; - - FOREACH_MOD(OnBotChange, (bi)); - return; - } - - void DoDel(CommandSource &source, const std::vector ¶ms) - { - const Anope::string &nick = params[1]; - - if (nick.empty()) - { - this->OnSyntaxError(source, "DEL"); - return; - } - - BotInfo *bi = BotInfo::Find(nick, true); - if (!bi) - { - source.Reply(BOT_DOES_NOT_EXIST, nick.c_str()); - return; - } - - if (bi->conf) - { - source.Reply(_("Bot %s is not deletable."), bi->nick.c_str()); - return; - } - - FOREACH_MOD(OnBotDelete, (bi)); - - Log(LOG_ADMIN, source, this) << "DEL " << bi->nick; - - source.Reply(_("Bot \002%s\002 has been deleted."), nick.c_str()); - delete bi; - return; - } -public: - CommandBSBot(Module *creator) : Command(creator, "botserv/bot", 1, 6) - { - 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")); - } - - void Execute(CommandSource &source, const std::vector ¶ms) override - { - const Anope::string &cmd = params[0]; - - if (Anope::ReadOnly) - { - source.Reply(_("Sorry, bot modification is temporarily disabled.")); - return; - } - - if (cmd.equals_ci("ADD")) - { - // ADD nick user host real - 5 - if (!source.HasCommand("botserv/bot/add")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params.size() < 5) - { - this->OnSyntaxError(source, "ADD"); - return; - } - - std::vector tempparams = params; - // ADD takes less params than CHANGE, so we need to take 6 if given and append it with a space to 5. - if (tempparams.size() >= 6) - tempparams[4] = tempparams[4] + " " + tempparams[5]; - - return this->DoAdd(source, tempparams); - } - else if (cmd.equals_ci("CHANGE")) - { - // CHANGE oldn newn user host real - 6 - // but only oldn and newn are required - if (!source.HasCommand("botserv/bot/change")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params.size() < 3) - { - this->OnSyntaxError(source, "CHANGE"); - return; - } - - return this->DoChange(source, params); - } - else if (cmd.equals_ci("DEL")) - { - // DEL nick - if (!source.HasCommand("botserv/bot/del")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params.size() < 1) - { - this->OnSyntaxError(source, "DEL"); - return; - } - - return this->DoDel(source, params); - } - else - this->OnSyntaxError(source, ""); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) override - { - 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" - "\002BOT ADD\002 adds a bot with the given nickname, username,\n" - "hostname and realname. Since no integrity checks are done\n" - "for these settings, be really careful.\n" - " \n" - "\002BOT CHANGE\002 allows you to change the nickname, username, hostname\n" - "or realname of a bot without deleting it (and\n" - "all the data associated with it).\n" - " \n" - "\002BOT DEL\002 removes the given bot from the bot list.\n" - " \n" - "\002Note\002: You cannot create a bot with a nick that is\n" - "currently registered. If an unregistered user is currently\n" - "using the nick, they will be killed.")); - return true; - } -}; - -class BSBot final - : public Module -{ - CommandBSBot commandbsbot; - -public: - BSBot(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), - commandbsbot(this) - { - - } -}; - -MODULE_INIT(BSBot) diff --git a/modules/commands/bs_botlist.cpp b/modules/commands/bs_botlist.cpp deleted file mode 100644 index 915117916..000000000 --- a/modules/commands/bs_botlist.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* BotServ core functions - * - * (C) 2003-2024 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 CommandBSBotList final - : public Command -{ -public: - CommandBSBotList(Module *creator) : Command(creator, "botserv/botlist", 0, 0) - { - this->SetDesc(_("Lists available bots")); - } - - void Execute(CommandSource &source, const std::vector ¶ms) override - { - unsigned count = 0; - ListFormatter list(source.GetAccount()); - - list.AddColumn(_("Nick")).AddColumn(_("Mask")); - - for (const auto &[_, bi] : *BotListByNick) - { - if (source.HasPriv("botserv/administration") || !bi->oper_only) - { - ++count; - ListFormatter::ListEntry entry; - entry["Nick"] = (bi->oper_only ? "* " : "") + bi->nick; - entry["Mask"] = bi->GetIdent() + "@" + bi->host; - list.AddEntry(entry); - } - } - - std::vector replies; - list.Process(replies); - - if (!count) - source.Reply(_("There are no bots available at this time.\n" - "Ask a Services Operator to create one!")); - else - { - source.Reply(_("Bot list:")); - - for (const auto &reply : replies) - source.Reply(reply); - - source.Reply(_("%d bots available."), count); - } - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Lists all available bots on this network.\n" - "Bots prefixed by a * are reserved for IRC Operators.")); - return true; - } -}; - -class BSBotList final - : public Module -{ - CommandBSBotList commandbsbotlist; - -public: - BSBotList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), - commandbsbotlist(this) - { - - } -}; - -MODULE_INIT(BSBotList) diff --git a/modules/commands/bs_control.cpp b/modules/commands/bs_control.cpp deleted file mode 100644 index 32101be6e..000000000 --- a/modules/commands/bs_control.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* BotServ core functions - * - * (C) 2003-2024 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 final - : public Command -{ -public: - CommandBSSay(Module *creator) : Command(creator, "botserv/say", 2, 2) - { - this->SetDesc(_("Makes the bot say the specified text on the specified channel")); - this->SetSyntax(_("\037channel\037 \037text\037")); - } - - void Execute(CommandSource &source, const std::vector ¶ms) override - { - const Anope::string &text = params[1]; - - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - if (!source.AccessFor(ci).HasPriv("SAY") && !source.HasPriv("botserv/administration")) - { - 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; - } - - IRCD->SendPrivmsg(*ci->bi, ci->name, "%s", text.c_str()); - ci->bi->lastmsg = Anope::CurTime; - - bool override = !source.AccessFor(ci).HasPriv("SAY"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to say: " << text; - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Makes the bot say the specified text on the specified channel.")); - return true; - } -}; - -class CommandBSAct final - : 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) override - { - Anope::string message = params[1]; - - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - if (!source.AccessFor(ci).HasPriv("SAY") && !source.HasPriv("botserv/administration")) - { - 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; - } - - message = message.replace_all_cs("\1", ""); - if (message.empty()) - return; - - IRCD->SendAction(*ci->bi, ci->name, "%s", message.c_str()); - ci->bi->lastmsg = Anope::CurTime; - - bool override = !source.AccessFor(ci).HasPriv("SAY"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to say: " << message; - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Makes the bot do the equivalent of a \"/me\" command\n" - "on the specified channel using the specified text.")); - return true; - } -}; - -class BSControl final - : public Module -{ - CommandBSSay commandbssay; - CommandBSAct commandbsact; - -public: - BSControl(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), - commandbssay(this), commandbsact(this) - { - - } -}; - -MODULE_INIT(BSControl) diff --git a/modules/commands/bs_info.cpp b/modules/commands/bs_info.cpp deleted file mode 100644 index e42ad23b8..000000000 --- a/modules/commands/bs_info.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* BotServ core functions - * - * (C) 2003-2024 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 CommandBSInfo final - : public Command -{ -private: - void send_bot_channels(std::vector &buffers, const BotInfo *bi) - { - Anope::string buf; - for (const auto &[_, ci] : *RegisteredChannelList) - { - if (ci->bi == bi) - { - buf += " " + ci->name + " "; - if (buf.length() > 300) - { - buffers.push_back(buf); - buf.clear(); - } - } - } - if (!buf.empty()) - buffers.push_back(buf); - } - -public: - CommandBSInfo(Module *creator) : Command(creator, "botserv/info", 1, 1) - { - this->SetSyntax(_("{\037channel\037 | \037nickname\037}")); - } - - void Execute(CommandSource &source, const std::vector ¶ms) override - { - const Anope::string &query = params[0]; - - BotInfo *bi = BotInfo::Find(query, true); - ChannelInfo *ci = ChannelInfo::Find(query); - InfoFormatter info(source.nc); - - if (bi) - { - source.Reply(_("Information for bot \002%s\002:"), bi->nick.c_str()); - info[_("Mask")] = bi->GetIdent() + "@" + bi->host; - info[_("Real name")] = bi->realname; - info[_("Created")] = Anope::strftime(bi->created, source.GetAccount()); - info[_("Options")] = bi->oper_only ? _("Private") : _("None"); - info[_("Used on")] = stringify(bi->GetChannelCount()) + " channel(s)"; - - FOREACH_MOD(OnBotInfo, (source, bi, ci, info)); - - std::vector replies; - info.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); - - if (source.HasPriv("botserv/administration")) - { - std::vector buf; - this->send_bot_channels(buf, bi); - for (const auto &line : buf) - source.Reply(line); - } - - } - else if (ci) - { - if (!source.AccessFor(ci).HasPriv("INFO") && !source.HasPriv("botserv/administration")) - { - source.Reply(ACCESS_DENIED); - return; - } - - source.Reply(CHAN_INFO_HEADER, ci->name.c_str()); - info[_("Bot nick")] = ci->bi ? ci->bi->nick : _("not assigned yet"); - - Anope::string enabled = Language::Translate(source.nc, _("Enabled")); - Anope::string disabled = Language::Translate(source.nc, _("Disabled")); - - FOREACH_MOD(OnBotInfo, (source, bi, ci, info)); - - std::vector replies; - info.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); - } - else - source.Reply(_("\002%s\002 is not a valid bot or registered channel."), query.c_str()); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) override - { - 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."), source.service->nick.c_str()); - return true; - } - - const Anope::string GetDesc(CommandSource &source) const override - { - return Anope::printf(Language::Translate(source.GetAccount(), _("Allows you to see %s information about a channel or a bot")), source.service->nick.c_str()); - } -}; - -class BSInfo final - : public Module -{ - CommandBSInfo commandbsinfo; - -public: - BSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), - commandbsinfo(this) - { - - } -}; - -MODULE_INIT(BSInfo) diff --git a/modules/commands/bs_kick.cpp b/modules/commands/bs_kick.cpp deleted file mode 100644 index f6012d07f..000000000 --- a/modules/commands/bs_kick.cpp +++ /dev/null @@ -1,1491 +0,0 @@ -/* BotServ core functions - * - * (C) 2003-2024 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 "modules/bs_kick.h" -#include "modules/bs_badwords.h" - -static Module *me; - -struct KickerDataImpl final - : KickerData -{ - KickerDataImpl(Extensible *obj) - { - amsgs = badwords = bolds = caps = colors = flood = italics = repeat = reverses = underlines = false; - for (auto &ttbtype : ttb) - ttbtype = 0; - capsmin = capspercent = 0; - floodlines = floodsecs = 0; - repeattimes = 0; - - dontkickops = dontkickvoices = false; - } - - void Check(ChannelInfo *ci) override - { - if (amsgs || badwords || bolds || caps || colors || flood || italics || repeat || reverses || underlines || dontkickops || dontkickvoices) - return; - - ci->Shrink("kickerdata"); - } - - struct ExtensibleItem final - : ::ExtensibleItem - { - ExtensibleItem(Module *m, const Anope::string &ename) : ::ExtensibleItem(m, ename) { } - - void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const override - { - if (s->GetSerializableType()->GetName() != "ChannelInfo") - return; - - const ChannelInfo *ci = anope_dynamic_static_cast(e); - KickerData *kd = this->Get(ci); - if (kd == NULL) - return; - - data["kickerdata:amsgs"] << kd->amsgs; - data["kickerdata:badwords"] << kd->badwords; - data["kickerdata:bolds"] << kd->bolds; - data["kickerdata:caps"] << kd->caps; - data["kickerdata:colors"] << kd->colors; - data["kickerdata:flood"] << kd->flood; - data["kickerdata:italics"] << kd->italics; - data["kickerdata:repeat"] << kd->repeat; - data["kickerdata:reverses"] << kd->reverses; - data["kickerdata:underlines"] << kd->underlines; - - data.SetType("capsmin", Serialize::Data::DT_INT); data["capsmin"] << kd->capsmin; - data.SetType("capspercent", Serialize::Data::DT_INT); data["capspercent"] << kd->capspercent; - data.SetType("floodlines", Serialize::Data::DT_INT); data["floodlines"] << kd->floodlines; - data.SetType("floodsecs", Serialize::Data::DT_INT); data["floodsecs"] << kd->floodsecs; - data.SetType("repeattimes", Serialize::Data::DT_INT); data["repeattimes"] << kd->repeattimes; - data.SetType("dontkickops", Serialize::Data::DT_INT); data["dontkickops"] << kd->dontkickops; - data.SetType("dontkickvoices", Serialize::Data::DT_INT); data["dontkickvoices"] << kd->dontkickvoices; - for (auto ttbtype : kd->ttb) - data["ttb"] << ttbtype << " "; - } - - void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) override - { - if (s->GetSerializableType()->GetName() != "ChannelInfo") - return; - - ChannelInfo *ci = anope_dynamic_static_cast(e); - KickerData *kd = ci->Require("kickerdata"); - - data["kickerdata:amsgs"] >> kd->amsgs; - data["kickerdata:badwords"] >> kd->badwords; - data["kickerdata:bolds"] >> kd->bolds; - data["kickerdata:caps"] >> kd->caps; - data["kickerdata:colors"] >> kd->colors; - data["kickerdata:flood"] >> kd->flood; - data["kickerdata:italics"] >> kd->italics; - data["kickerdata:repeat"] >> kd->repeat; - data["kickerdata:reverses"] >> kd->reverses; - data["kickerdata:underlines"] >> kd->underlines; - - data["capsmin"] >> kd->capsmin; - data["capspercent"] >> kd->capspercent; - data["floodlines"] >> kd->floodlines; - data["floodsecs"] >> kd->floodsecs; - data["repeattimes"] >> kd->repeattimes; - data["dontkickops"] >> kd->dontkickops; - data["dontkickvoices"] >> kd->dontkickvoices; - - Anope::string ttb, tok; - data["ttb"] >> ttb; - spacesepstream sep(ttb); - for (int i = 0; sep.GetToken(tok) && i < TTB_SIZE; ++i) - try - { - kd->ttb[i] = convertTo(tok); - } - catch (const ConvertException &) { } - - kd->Check(ci); - } - }; -}; - -class CommandBSKick final - : public Command -{ -public: - CommandBSKick(Module *creator) : Command(creator, "botserv/kick", 0) - { - this->SetDesc(_("Configures kickers")); - this->SetSyntax(_("\037option\037 \037channel\037 {\037ON|OFF\037} [\037settings\037]")); - } - - void Execute(CommandSource &source, const std::vector ¶ms) override - { - this->OnSyntaxError(source, ""); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Configures bot kickers. \037option\037 can be one of:")); - - Anope::string this_name = source.command; - for (const auto &[c_name, info] : source.service->commands) - { - if (c_name.find_ci(this_name + " ") == 0) - { - ServiceReference command("Command", info.name); - if (command) - { - source.command = c_name; - command->OnServHelp(source); - } - } - } - - source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n" - "on a specific option.\n" - " \n" - "Note: access to this command is controlled by the\n" - "level SET."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str()); - - return true; - } -}; - -class CommandBSKickBase - : public Command -{ -public: - CommandBSKickBase(Module *creator, const Anope::string &cname, int minarg, int maxarg) : Command(creator, cname, minarg, maxarg) - { - } - - void Execute(CommandSource &source, const std::vector ¶ms) override = 0; - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) override = 0; - -protected: - bool CheckArguments(CommandSource &source, const std::vector ¶ms, ChannelInfo* &ci) - { - const Anope::string &chan = params[0]; - const Anope::string &option = params[1]; - - ci = ChannelInfo::Find(chan); - - if (Anope::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 (option.empty()) - this->OnSyntaxError(source, ""); - else if (!option.equals_ci("ON") && !option.equals_ci("OFF")) - this->OnSyntaxError(source, ""); - else if (!source.AccessFor(ci).HasPriv("SET") && !source.HasPriv("botserv/administration")) - source.Reply(ACCESS_DENIED); - else if (!ci->bi) - source.Reply(BOT_NOT_ASSIGNED); - else - return true; - - return false; - } - - void Process(CommandSource &source, ChannelInfo *ci, const Anope::string ¶m, const Anope::string &ttb, size_t ttb_idx, const Anope::string &optname, KickerData *kd, bool &val) - { - if (param.equals_ci("ON")) - { - if (!ttb.empty()) - { - int16_t i; - - try - { - i = convertTo(ttb); - if (i < 0) - throw ConvertException(); - } - catch (const ConvertException &) - { - source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str()); - return; - } - - kd->ttb[ttb_idx] = i; - } - else - kd->ttb[ttb_idx] = 0; - - val = true; - if (kd->ttb[ttb_idx]) - source.Reply(_("Bot will now kick for \002%s\002, and will place a ban\n" - "after %d kicks for the same user."), optname.c_str(), kd->ttb[ttb_idx]); - else - source.Reply(_("Bot will now kick for \002%s\002."), optname.c_str()); - - bool override = !source.AccessFor(ci).HasPriv("SET"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable the " << optname << " kicker"; - } - else if (param.equals_ci("OFF")) - { - bool override = !source.AccessFor(ci).HasPriv("SET"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable the " << optname << " kicker"; - - val = false; - source.Reply(_("Bot won't kick for \002%s\002 anymore."), optname.c_str()); - } - else - this->OnSyntaxError(source, ""); - } -}; - -class CommandBSKickAMSG final - : public CommandBSKickBase -{ -public: - CommandBSKickAMSG(Module *creator) : CommandBSKickBase(creator, "botserv/kick/amsg", 2, 3) - { - this->SetDesc(_("Configures AMSG kicker")); - this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]")); - } - - void Execute(CommandSource &source, const std::vector ¶ms) override - { - ChannelInfo *ci; - if (CheckArguments(source, params, ci)) - { - KickerData *kd = ci->Require("kickerdata"); - Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_AMSGS, "AMSG", kd, kd->amsgs); - kd->Check(ci); - } - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) override - { - this->SendSyntax(source); - source.Reply(" "); - BotInfo *bi = Config->GetClient("BotServ"); - source.Reply(_("Sets the AMSG kicker on or off. When enabled, the bot will\n" - "kick users who send the same message to multiple channels\n" - "where %s bots are.\n" - " \n" - "\037ttb\037 is the number of times a user can be kicked\n" - "before they get banned. Don't give ttb to disable\n" - "the ban system once activated."), bi ? bi->nick.c_str() : "BotServ"); - return true; - } -}; - -class CommandBSKickBadwords final - : public CommandBSKickBase -{ -public: - CommandBSKickBadwords(Module *creator) : CommandBSKickBase(creator, "botserv/kick/badwords", 2, 3) - { - this->SetDesc(_("Configures badwords kicker")); - this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]")); - } - - void Execute(CommandSource &source, const std::vector ¶ms) override - { - ChannelInfo *ci; - if (CheckArguments(source, params, ci)) - { - KickerData *kd = ci->Require("kickerdata"); - Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_BADWORDS, "badwords", kd, kd->badwords); - kd->Check(ci); - } - - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Sets the bad words kicker on or off. When enabled, this\n" - "option tells the bot to kick users who say certain words\n" - "on the channels.\n" - "You can define bad words for your channel using the\n" - "\002BADWORDS\002 command. Type \002%s%s HELP BADWORDS\002 for\n" - "more information.\n" - " \n" - "\037ttb\037 is the number of times a user can be kicked\n" - "before it gets banned. Don't give ttb to disable\n" - "the ban system once activated."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); - return true; - } -}; - -class CommandBSKickBolds final - : public CommandBSKickBase -{ -public: - CommandBSKickBolds(Module *creator) : CommandBSKickBase(creator, "botserv/kick/bolds", 2, 3) - { - this->SetDesc(_("Configures bolds kicker")); - this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]")); - } - - void Execute(CommandSource &source, const std::vector ¶ms) override - { - ChannelInfo *ci; - if (CheckArguments(source, params, ci)) - { - KickerData *kd = ci->Require("kickerdata"); - Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_BOLDS, "bolds", kd, kd->bolds); - kd->Check(ci); - } - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Sets the bolds kicker on or off. When enabled, this\n" - "option tells the bot to kick users who use bolds.\n" - " \n" - "\037ttb\037 is the number of times a user can be kicked\n" - "before it gets banned. Don't give ttb to disable\n" - "the ban system once activated.")); - return true; - } -}; - -class CommandBSKickCaps final - : public CommandBSKickBase -{ -public: - CommandBSKickCaps(Module *creator) : CommandBSKickBase(creator, "botserv/kick/caps", 2, 5) - { - this->SetDesc(_("Configures caps kicker")); - this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037 [\037min\037 [\037percent\037]]]\002")); - } - - void Execute(CommandSource &source, const std::vector ¶ms) override - { - ChannelInfo *ci; - if (!CheckArguments(source, params, ci)) - return; - - KickerData *kd = ci->Require("kickerdata"); - - if (params[1].equals_ci("ON")) - { - const Anope::string &ttb = params.size() > 2 ? params[2] : "", - &min = params.s