diff options
author | Sadie Powell <sadie@witchery.services> | 2021-02-25 20:06:46 +0000 |
---|---|---|
committer | Sadie Powell <sadie@witchery.services> | 2021-02-25 20:10:34 +0000 |
commit | 0db24252fd119cafee34f1bfa023763fcdd7ebf5 (patch) | |
tree | c71033314cc0d94c226eb087b1e535709019878c | |
parent | 61225fa14fe0c8335cbfec7a9764cfc3f31936bc (diff) |
Implement support for multi-prefix on WHOIS.
-rw-r--r-- | include/modules/whois.h | 16 | ||||
-rw-r--r-- | src/coremods/core_whois.cpp | 16 | ||||
-rw-r--r-- | src/modules/m_namesx.cpp | 47 |
3 files changed, 63 insertions, 16 deletions
diff --git a/include/modules/whois.h b/include/modules/whois.h index f158f82cc..c081a2b6a 100644 --- a/include/modules/whois.h +++ b/include/modules/whois.h @@ -28,6 +28,22 @@ namespace Whois class Context; } +enum +{ + // From RFC 1459. + RPL_WHOISUSER = 311, + RPL_WHOISOPERATOR = 313, + RPL_WHOISIDLE = 317, + RPL_WHOISCHANNELS = 319, + + // From UnrealIRCd. + RPL_WHOISHOST = 378, + RPL_WHOISMODES = 379, + + // InspIRCd-specific. + RPL_CHANNELSMSG = 651 +}; + class Whois::EventListener : public Events::ModuleEventListener { public: diff --git a/src/coremods/core_whois.cpp b/src/coremods/core_whois.cpp index bd0502998..c1c4777ef 100644 --- a/src/coremods/core_whois.cpp +++ b/src/coremods/core_whois.cpp @@ -30,22 +30,6 @@ #include "inspircd.h" #include "modules/whois.h" -enum -{ - // From RFC 1459. - RPL_WHOISUSER = 311, - RPL_WHOISOPERATOR = 313, - RPL_WHOISIDLE = 317, - RPL_WHOISCHANNELS = 319, - - // From UnrealIRCd. - RPL_WHOISHOST = 378, - RPL_WHOISMODES = 379, - - // InspIRCd-specific. - RPL_CHANNELSMSG = 651 -}; - enum SplitWhoisState { // Don't split private/secret channels into a separate RPL_WHOISCHANNELS numeric. diff --git a/src/modules/m_namesx.cpp b/src/modules/m_namesx.cpp index 4f93da21a..ed983b32d 100644 --- a/src/modules/m_namesx.cpp +++ b/src/modules/m_namesx.cpp @@ -27,11 +27,13 @@ #include "modules/cap.h" #include "modules/names.h" #include "modules/who.h" +#include "modules/whois.h" class ModuleNamesX : public Module , public Names::EventListener , public Who::EventListener + , public Whois::LineEventListener { private: Cap::Capability cap; @@ -40,6 +42,7 @@ class ModuleNamesX ModuleNamesX() : Names::EventListener(this) , Who::EventListener(this) + , Whois::LineEventListener(this) , cap(this, "multi-prefix") { } @@ -104,6 +107,50 @@ class ModuleNamesX numeric.GetParams()[flag_index].append(prefixes, 1, std::string::npos); return MOD_RES_PASSTHRU; } + + ModResult OnWhoisLine(Whois::Context& whois, Numeric::Numeric& numeric) CXX11_OVERRIDE + { + if (numeric.GetNumeric() != RPL_WHOISCHANNELS || !cap.get(whois.GetSource())) + return MOD_RES_PASSTHRU; + + // :testnet.inspircd.org 319 test Sadie :#test ~#inspircd + if (numeric.GetParams().size() < 2 || numeric.GetParams().back().empty()) + return MOD_RES_PASSTHRU; + + std::stringstream newchannels; + irc::spacesepstream channelstream(numeric.GetParams().back()); + for (std::string channel; channelstream.GetToken(channel); ) + { + size_t hashpos = channel.find('#'); + if (!hashpos || hashpos == std::string::npos) + { + // The entry is malformed or the user has no privs. + newchannels << channel << ' '; + continue; + } + + Channel* chan = ServerInstance->FindChan(channel.substr(hashpos)); + if (!chan) + { + // Should never happen. + newchannels << channel << ' '; + continue; + } + + Membership* memb = chan->GetUser(whois.GetTarget()); + if (!memb) + { + // Should never happen. + newchannels << channel << ' '; + continue; + } + + newchannels << memb->GetAllPrefixChars() << chan->name << ' '; + } + + numeric.GetParams().back() = newchannels.str(); + return MOD_RES_PASSTHRU; + } }; MODULE_INIT(ModuleNamesX) |