]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Implement support for multi-prefix on WHOIS.
authorSadie Powell <sadie@witchery.services>
Thu, 25 Feb 2021 20:06:46 +0000 (20:06 +0000)
committerSadie Powell <sadie@witchery.services>
Thu, 25 Feb 2021 20:10:34 +0000 (20:10 +0000)
include/modules/whois.h
src/coremods/core_whois.cpp
src/modules/m_namesx.cpp

index f158f82cc7f0b769ffe9a637b302df6f6480ac21..c081a2b6af4194109b02b9fb4860e236110b7ee8 100644 (file)
@@ -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:
index bd05029980b2cb1ba106d6b9b10b70af04633a40..c1c4777ef24c397b4bcaff5c555ed290a47ce811 100644 (file)
 #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.
index 4f93da21ac16f4e341f0eb400bff98520155a76c..ed983b32dc899eaaf4a28174896c69dbc51ff67c 100644 (file)
 #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)