From 1aab85588bef2e4e4f76c78736044d7a1eb44ad6 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Thu, 5 Mar 2026 04:24:54 +0000 Subject: Clean up the abbreviation module and move to standard replies. --- modules/abbreviation.cpp | 67 +++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 29 deletions(-) (limited to 'modules/abbreviation.cpp') diff --git a/modules/abbreviation.cpp b/modules/abbreviation.cpp index 2a6427d7c..48e22463a 100644 --- a/modules/abbreviation.cpp +++ b/modules/abbreviation.cpp @@ -22,19 +22,18 @@ #include "inspircd.h" - -enum -{ - // InspIRCd-specific. - ERR_AMBIGUOUSCOMMAND = 420 -}; +#include "modules/ircv3.h" class ModuleAbbreviation final : public Module { +private: + IRCv3::ReplyCapReference stdrplcap; + public: ModuleAbbreviation() : Module(VF_VENDOR, "Allows commands to be abbreviated by appending a full stop.") + , stdrplcap(this) { } @@ -49,43 +48,53 @@ public: if (validated || command.empty() || command.back() != '.') return MOD_RES_PASSTHRU; - /* Look for any command that starts with the same characters, if it does, replace the command string with it */ - size_t clen = command.length() - 1; + // :irc.example.com FAIL * AMBIGUOUS_ABBREVIATION :BLAH + // :irc.example.com NOTICE nick :*** BLAH + const auto maxlen = ServerInstance->Config->Limits.MaxLine + - ServerInstance->Config->GetServerName().size() + - std::max(user->nick.length() + 4, 22) + - 10; // Some extra just in case. + + auto foundmatch = false; std::string foundcommand; - std::string matchlist; - bool foundmatch = false; - for (const auto& [cmdname, _] : ServerInstance->Parser.GetCommands()) + std::string extracommands; + + const auto cmdlen = command.length() - 1; + for (const auto& [cmdname, cmd] : ServerInstance->Parser.GetCommands()) { - if (!command.compare(0, clen, cmdname, 0, clen)) + // Look for any command that starts with the same characters that + // is usable by the caller. + if (command.compare(0, cmdlen, cmdname, 0, cmdlen) != 0 || !cmd->IsUsableBy(user)) + continue; // No match. + + if (extracommands.length() > maxlen) { - if (matchlist.length() > 450) - { - user->WriteNumeric(ERR_AMBIGUOUSCOMMAND, "Ambiguous abbreviation and too many possible matches."); - return MOD_RES_DENY; - } + IRCv3::WriteReply(Reply::Type::FAIL, user, stdrplcap, nullptr, "AMBIGUOUS_ABBREVIATION", + "Ambiguous abbreviation and too many possible matches."); + return MOD_RES_DENY; + } - if (!foundmatch) - { - /* Found the command */ - foundcommand = cmdname; - foundmatch = true; - } - else - matchlist.append(" ").append(cmdname); + if (!foundmatch) + { + // Found the command. + foundcommand = cmdname; + foundmatch = true; } + else + extracommands.append(" ").append(cmdname); } /* Ambiguous command, list the matches */ - if (!matchlist.empty()) + if (!extracommands.empty()) { - user->WriteNumeric(ERR_AMBIGUOUSCOMMAND, FMT::format("Ambiguous abbreviation, possible matches: {}{}", foundcommand, matchlist)); + IRCv3::WriteReply(Reply::Type::FAIL, user, stdrplcap, nullptr, "AMBIGUOUS_ABBREVIATION", + FMT::format("Ambiguous abbreviation, possible matches: {}{}", foundcommand, extracommands)); return MOD_RES_DENY; } + // Replace the command abbreviation with the found command name. if (!foundcommand.empty()) - { command = foundcommand; - } return MOD_RES_PASSTHRU; } -- cgit v1.3.1-10-gc9f91