aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Sadie Powell2022-03-24 02:33:45 +0000
committerGravatar Sadie Powell2022-03-25 13:18:42 +0000
commit3bf6454518f4a22a63dec4c5379848df34215a85 (patch)
treeb6d020a15aead6818550b180372ffb3a8b816005
parentFix allowing modules to have a path on Windows. (diff)
Allow modules to handle WHO matching.
-rw-r--r--include/modules/who.h20
-rw-r--r--src/coremods/core_who.cpp13
2 files changed, 32 insertions, 1 deletions
diff --git a/include/modules/who.h b/include/modules/who.h
index d2930f97b..6e8fa024b 100644
--- a/include/modules/who.h
+++ b/include/modules/who.h
@@ -25,6 +25,7 @@
namespace Who
{
class EventListener;
+ class MatchEventListener;
class Request;
}
@@ -48,6 +49,25 @@ class Who::EventListener : public Events::ModuleEventListener
virtual ModResult OnWhoLine(const Request& request, LocalUser* source, User* user, Membership* memb, Numeric::Numeric& numeric) = 0;
};
+class Who::MatchEventListener
+ : public Events::ModuleEventListener
+{
+ public:
+ MatchEventListener(Module* mod)
+ : ModuleEventListener(mod, "event/who-match")
+ {
+ }
+
+ /** Called when a WHO request needs to check if a user matches it.
+ * @param request Details about the WHO request which caused this match attempt.
+ * @param source The user who initiated this WHO request.
+ * @param user The user to attempt to match the WHO request against.
+ * @return MOD_RES_ALLOW to explicitly allow the match, MOD_RES_DENY to explicitly deny the
+ * match, or MOD_RES_PASSTHRU to let another module handle the event.
+ */
+ virtual ModResult OnWhoMatch(const Request& request, LocalUser* source, User* user) = 0;
+};
+
class Who::Request
{
public:
diff --git a/src/coremods/core_who.cpp b/src/coremods/core_who.cpp
index 5dd846595..97920ead9 100644
--- a/src/coremods/core_who.cpp
+++ b/src/coremods/core_who.cpp
@@ -119,6 +119,7 @@ class CommandWho : public SplitCommand
UserModeReference hidechansmode;
UserModeReference invisiblemode;
Events::ModuleEventProvider whoevprov;
+ Events::ModuleEventProvider whomatchevprov;
void BuildOpLevels()
{
@@ -181,7 +182,7 @@ class CommandWho : public SplitCommand
bool MatchChannel(LocalUser* source, Membership* memb, WhoData& data);
/** Determines whether WHO flags match a specific user. */
- static bool MatchUser(LocalUser* source, User* target, WhoData& data);
+ bool MatchUser(LocalUser* source, User* target, WhoData& data);
/** Performs a WHO request on a channel. */
void WhoChannel(LocalUser* source, const std::vector<std::string>& parameters, Channel* c, WhoData& data);
@@ -204,6 +205,7 @@ class CommandWho : public SplitCommand
, hidechansmode(parent, "hidechans")
, invisiblemode(parent, "invisible")
, whoevprov(parent, "event/who")
+ , whomatchevprov(parent, "event/who-match")
{
allow_empty_last_param = false;
syntax = "<server>|<nick>|<channel>|<realname>|<host>|0 [[Aafhilmnoprstux][%acdfhilnorstu] <server>|<nick>|<channel>|<realname>|<host>|0]";
@@ -267,6 +269,15 @@ bool CommandWho::MatchUser(LocalUser* source, User* user, WhoData& data)
if (data.flags['l'] && source_can_see_server && !lu)
return false;
+ // Let a module handle this first if it wants to.
+ ModResult res;
+ FIRST_MOD_RESULT_CUSTOM(whomatchevprov, Who::MatchEventListener, OnWhoMatch, res, (data, source, user));
+ if (res == MOD_RES_ALLOW)
+ return true; // Module explicitly matched.
+
+ else if (res == MOD_RES_DENY)
+ return false; // Module explicitly rejected.
+
// The source wants to match against users' away messages.
bool match = false;
if (data.flags['A'])