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 /src/modules/m_namesx.cpp | |
parent | 61225fa14fe0c8335cbfec7a9764cfc3f31936bc (diff) |
Implement support for multi-prefix on WHOIS.
Diffstat (limited to 'src/modules/m_namesx.cpp')
-rw-r--r-- | src/modules/m_namesx.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
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) |