diff --git a/data/botserv.example.conf b/data/botserv.example.conf index 04a21bb58..15b58a376 100644 --- a/data/botserv.example.conf +++ b/data/botserv.example.conf @@ -352,22 +352,25 @@ module name = "fantasy" /* - * Defines the prefixes for fantasy commands in channels. One of these characters will have to be prepended - * to all fantasy commands. If you choose "!", for example, fantasy commands will be "!kick", - * "!op", etc. This directive is optional, if left out, the default fantasy character is "!". + * Defines the prefixes for fantasy commands in channels. One of these will + * have to be prepended to all fantasy commands. For example, If you choose + * "! ?" as your prefix fantasy commands will be "!kick", "?op", etc. + * + * This directive is optional, it defaults to "!" if not set. */ - #fantasycharacter = "!." + #prefix = "! ?" } command { service = "BotServ"; name = "SET FANTASY"; command = "botserv/set/fantasy"; } /* * Fantasy commands * - * Fantasy commands can be executed in channels that have a BotServ bot by prefixing the - * command with one of the fantasy characters configured in botserv's fantasycharacter - * directive. + * Fantasy commands can be executed in channels that have a BotServ bot assigned + * by prefixing the command with one of the fantasy characters configured in the + * {botserv}:prefix directive. * - * Sane defaults are provided below that do not need to be edited unless you wish to change the default behavior. + * Sane defaults are provided below that do not need to be edited unless you + * wish to change the default behavior. */ fantasy { name = "ACCESS"; command = "chanserv/access"; } fantasy { name = "AKICK"; command = "chanserv/akick"; } diff --git a/language/anope.en_US.po b/language/anope.en_US.po index d05f7d0c8..0bc1ec37f 100644 --- a/language/anope.en_US.po +++ b/language/anope.en_US.po @@ -16,8 +16,8 @@ msgid "" msgstr "" "Project-Id-Version: Anope\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-13 15:06+0000\n" -"PO-Revision-Date: 2025-12-13 15:06+0000\n" +"POT-Creation-Date: 2025-12-14 01:24+0000\n" +"PO-Revision-Date: 2025-12-14 01:24+0000\n" "Last-Translator: Sadie Powell \n" "Language-Team: English\n" "Language: en_US\n" @@ -1436,7 +1436,7 @@ msgid "Additionally, Services Operators with the nickserv/resend permission ca msgstr "" #, c-format -msgid "Additionally, if fantasy is enabled fantasy commands can be executed by prefixing the command name with one of the following characters: %s" +msgid "Additionally, if fantasy is enabled fantasy commands can be executed by prefixing the command name with one of the following fantasy prefixes: %s" msgstr "" #, c-format @@ -2830,7 +2830,7 @@ msgstr "" #, c-format msgid "" -"Enables or disables fantasy mode on a channel. When it is enabled, users will be able to use fantasy commands on a channel when prefixed with one of the following fantasy characters: %s\n" +"Enables or disables fantasy mode on a channel. When it is enabled, users will be able to use fantasy commands on a channel when prefixed with one of the following fantasy prefixes: %s\n" "\n" "Note that users wanting to use fantasy commands MUST have enough access for both the FANTASY privilege and the command they are executing." msgstr "" @@ -3015,7 +3015,7 @@ msgid "Fantasy" msgstr "" #, c-format -msgid "Fantasy commands may be prefixed with one of the following characters: %s" +msgid "Fantasy commands may be prefixed with one of the following fantasy prefixes: %s" msgstr "" #, c-format diff --git a/modules/botserv/botserv.cpp b/modules/botserv/botserv.cpp index eb42675ad..1f6c94bf2 100644 --- a/modules/botserv/botserv.cpp +++ b/modules/botserv/botserv.cpp @@ -147,11 +147,11 @@ public: ), source.service->nick.c_str()); - const Anope::string &fantasycharacters = Config->GetModule("fantasy").Get("fantasycharacter", "!"); + const Anope::string &fantasycharacters = Config->GetModule("fantasy").Get("prefix", "!"); if (!fantasycharacters.empty()) { source.Reply(" "); - source.Reply(_("Fantasy commands may be prefixed with one of the following characters: %s"), + source.Reply(_("Fantasy commands may be prefixed with one of the following fantasy prefixes: %s"), fantasycharacters.c_str()); } source.Reply(" "); @@ -187,13 +187,13 @@ public: source.Reply(_("Bot will join a channel whenever there is at least \002%d\002 user(s) on it."), Config->GetModule(this).Get("minusers")); - const Anope::string &fantasycharacters = Config->GetModule("fantasy").Get("fantasycharacter", "!"); + const Anope::string &fantasycharacters = Config->GetModule("fantasy").Get("prefix", "!"); if (!fantasycharacters.empty()) { source.Reply(_( "Additionally, if fantasy is enabled fantasy commands " "can be executed by prefixing the command name with " - "one of the following characters: %s" + "one of the following fantasy prefixes: %s" ), fantasycharacters.c_str()); } diff --git a/modules/fantasy.cpp b/modules/fantasy.cpp index 4449b0831..12c09123b 100644 --- a/modules/fantasy.cpp +++ b/modules/fantasy.cpp @@ -75,13 +75,13 @@ public: "Enables or disables \002fantasy\002 mode on a channel. " "When it is enabled, users will be able to use " "fantasy commands on a channel when prefixed " - "with one of the following fantasy characters: \002%s\002" + "with one of the following fantasy prefixes: \002%s\002" "\n\n" "Note that users wanting to use fantasy commands " "MUST have enough access for both the FANTASY " "privilege and the command they are executing." ), - Config->GetModule(this->owner).Get("fantasycharacter", "!").c_str()); + Config->GetModule(this->owner).Get("prefix", "!").c_str()); return true; } }; @@ -89,16 +89,26 @@ public: class Fantasy final : public Module { +private: SerializableExtensibleItem fantasy; - CommandBSSetFantasy commandbssetfantasy; + std::vector prefixes; public: - Fantasy(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), - fantasy(this, "BS_FANTASY"), commandbssetfantasy(this) + Fantasy(const Anope::string &modname, const Anope::string &creator) + : Module(modname, creator, VENDOR) + , fantasy(this, "BS_FANTASY") + , commandbssetfantasy(this) { } + void OnReload(Configuration::Conf &conf) override + { + const auto &modconf = conf.GetModule(this); + const auto &prefix = modconf.Get("prefix", "!"); + spacesepstream(prefix).GetTokens(prefixes); + } + void OnPrivmsg(User *u, Channel *c, Anope::string &msg, const Anope::map &tags) override { if (!u || !c || !c->ci || !c->ci->bi || msg.empty() || msg[0] == '\1') @@ -114,23 +124,24 @@ public: return; Anope::string normalized_param0 = Anope::RemoveFormatting(params[0]); - Anope::string fantasy_chars = Config->GetModule(this).Get("fantasycharacter", "!"); - - if (!normalized_param0.find(c->ci->bi->nick)) + if (normalized_param0.find_ci(c->ci->bi->nick) == 0) { params.erase(params.begin()); } - else if (!normalized_param0.find_first_of(fantasy_chars)) + else { - size_t sz = params[0].find_first_of(fantasy_chars); + auto fn = [&normalized_param0](const auto &prefix) { return normalized_param0.find(prefix) == 0; }; + auto it = std::find_if(prefixes.begin(), prefixes.end(), fn); + if (it == prefixes.end()) + return; + + auto sz = params[0].find(*it); if (sz == Anope::string::npos) return; /* normalized_param0 is a subset of params[0] so this can't happen */ - params[0].erase(0, sz + 1); - } - else - { - return; + params[0].erase(0, sz + it->length()); + if (params[0].equals_ci(c->ci->bi->alias)) + params.erase(params.begin()); } if (params.empty())