]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Convert AWAY to use cross-module events and clean up slightly.
authorPeter Powell <petpow@saberuk.com>
Sun, 12 Aug 2018 13:56:27 +0000 (14:56 +0100)
committerPeter Powell <petpow@saberuk.com>
Sun, 12 Aug 2018 14:01:45 +0000 (15:01 +0100)
OnSetAway has been replaced with four events. OnUserPreAway and
OnUserPreBack can be used to deny an away state change and/or
change the away message of a local user. OnUserAway and OnUserBack
allow modules to be notified that a user's away state has changed.

12 files changed:
include/modules.h
include/modules/away.h [new file with mode: 0644]
include/numerics.h
src/coremods/core_user/cmd_away.cpp
src/coremods/core_user/core_user.h
src/modules.cpp
src/modules/m_ircv3.cpp
src/modules/m_spanningtree/away.cpp
src/modules/m_spanningtree/commands.h
src/modules/m_spanningtree/main.cpp
src/modules/m_spanningtree/main.h
src/modules/m_watch.cpp

index 773e3b49fb010a1c5800b1a46a114386291c3fc3..4e5648512c0501b18c1dbe992d6852e45f08bb54 100644 (file)
@@ -223,7 +223,7 @@ enum Implementation
        I_OnChangeLocalUserHost, I_OnPreTopicChange,
        I_OnPostTopicChange, I_OnPostConnect, I_OnPostDeoper,
        I_OnPreChangeRealName, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete,
-       I_OnPostOper, I_OnSetAway, I_OnPostCommand, I_OnPostJoin,
+       I_OnPostOper, I_OnPostCommand, I_OnPostJoin,
        I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass,
        I_OnUserMessage, I_OnPassCompare, I_OnNamesListItem, I_OnNumeric,
        I_OnPreRehash, I_OnModuleRehash, I_OnSendWhoLine, I_OnChangeIdent, I_OnSetUserIP,
@@ -894,16 +894,6 @@ class CoreExport Module : public classbase, public usecountbase
         */
        virtual ModResult OnAcceptConnection(int fd, ListenSocket* sock, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
 
-       /** Called whenever a user sets away or returns from being away.
-        * The away message is available as a parameter, but should not be modified.
-        * At this stage, it has already been copied into the user record.
-        * If awaymsg is empty, the user is returning from away.
-        * @param user The user setting away
-        * @param awaymsg The away message of the user, or empty if returning from away
-        * @return nonzero if the away message should be blocked - should ONLY be nonzero for LOCAL users (IS_LOCAL) (no output is returned by core)
-        */
-       virtual ModResult OnSetAway(User* user, const std::string &awaymsg);
-
        /** Called at intervals for modules to garbage-collect any hashes etc.
         * Certain data types such as hash_map 'leak' buckets, which must be
         * tidied up and freed by copying into a new item every so often. This
diff --git a/include/modules/away.h b/include/modules/away.h
new file mode 100644 (file)
index 0000000..f231f0a
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2016-2017 Peter Powell <petpow@saberuk.com>
+ *
+ * This file is part of InspIRCd.  InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#pragma once
+
+#include "event.h"
+
+namespace Away
+{
+       class EventListener;
+       class EventProvider;
+}
+
+class Away::EventListener
+       : public Events::ModuleEventListener
+{
+ protected:
+       EventListener(Module* mod)
+               : ModuleEventListener(mod, "event/away")
+       {
+       }
+
+ public:
+       /** Called when a user wishes to mark themselves as away.
+        * @param user The user who is going away.
+        * @param message The away message that the user set.
+        * @return Either MOD_RES_ALLOW to allow the user to mark themself as away, MOD_RES_DENY to
+        *         disallow the user to mark themself as away, or MOD_RES_PASSTHRU to let another module
+        *         handle the event.
+        */
+       virtual ModResult OnUserPreAway(LocalUser* user, std::string& message)
+       {
+               return MOD_RES_PASSTHRU;
+       }
+
+       /** Called when a user wishes to mark themselves as back.
+        * @param user The user who is going away.
+        * @param message The away message that the user set.
+        * @return Either MOD_RES_ALLOW to allow the user to mark themself as back, MOD_RES_DENY to
+        *         disallow the user to mark themself as back, or MOD_RES_PASSTHRU to let another module
+        *         handle the event.
+        */
+       virtual ModResult OnUserPreBack(LocalUser* user)
+       {
+               return MOD_RES_PASSTHRU;
+       }
+
+       /** Called when a user has marked themself as away.
+        * @param user The user who has gone away.
+        */
+       virtual void OnUserAway(User* user) = 0;
+
+       /** Called when a user has returned from being away.
+        * @param user The user who has returned from being away.
+        */
+       virtual void OnUserBack(User* user) = 0;
+};
+
+class Away::EventProvider
+       : public Events::ModuleEventProvider
+{
+ public:
+       EventProvider(Module* mod)
+               : ModuleEventProvider(mod, "event/away")
+       {
+       }
+};
index 9e0ee07da6b98731c3498324f28112808d0dc7cb..8c2f0ce11887194c86abfb8ef6f649ce29355b71 100644 (file)
@@ -70,9 +70,6 @@ enum
        RPL_USERHOST                    = 302,
        RPL_ISON                        = 303,
 
-       RPL_UNAWAY                      = 305,
-       RPL_NOWAWAY                     = 306,
-
        RPL_WHOISSERVER                 = 312,
        RPL_ENDOFWHOIS                  = 318,
 
index 1b7bacebaa3d31eae28767f16941a903688f844e..50a586392b4a2d4a4e58ac73c02fa5b4eab0e901 100644 (file)
 #include "inspircd.h"
 #include "core_user.h"
 
+enum
+{
+       // From RFC 1459.
+       RPL_UNAWAY = 305,
+       RPL_NOWAWAY = 306
+};
+
 CommandAway::CommandAway(Module* parent)
-       : Command(parent, "AWAY", 0, 0)
+       : Command(parent, "AWAY", 0, 1)
+       , awayevprov(parent)
 {
+       allow_empty_last_param = false;
        syntax = "[<message>]";
 }
 
@@ -31,29 +40,37 @@ CommandAway::CommandAway(Module* parent)
  */
 CmdResult CommandAway::Handle(User* user, const Params& parameters)
 {
+       LocalUser* luser = IS_LOCAL(user);
        ModResult MOD_RESULT;
 
-       if ((!parameters.empty()) && (!parameters[0].empty()))
+       if (!parameters.empty())
        {
-               FIRST_MOD_RESULT(OnSetAway, MOD_RESULT, (user, parameters[0]));
-
-               if (MOD_RESULT == MOD_RES_DENY && IS_LOCAL(user))
-                       return CMD_FAILURE;
+               std::string message(parameters[0]);
+               if (luser)
+               {
+                       FIRST_MOD_RESULT_CUSTOM(awayevprov, Away::EventListener, OnUserPreAway, MOD_RESULT, (luser, message));
+                       if (MOD_RESULT == MOD_RES_DENY)
+                               return CMD_FAILURE;
+               }
 
                user->awaytime = ServerInstance->Time();
-               user->awaymsg.assign(parameters[0], 0, ServerInstance->Config->Limits.MaxAway);
-
+               user->awaymsg.assign(message, 0, ServerInstance->Config->Limits.MaxAway);
                user->WriteNumeric(RPL_NOWAWAY, "You have been marked as being away");
+               FOREACH_MOD_CUSTOM(awayevprov, Away::EventListener, OnUserAway, (user));
        }
        else
        {
-               FIRST_MOD_RESULT(OnSetAway, MOD_RESULT, (user, ""));
-
-               if (MOD_RESULT == MOD_RES_DENY && IS_LOCAL(user))
-                       return CMD_FAILURE;
+               if (luser)
+               {
+                       FIRST_MOD_RESULT_CUSTOM(awayevprov, Away::EventListener, OnUserPreBack, MOD_RESULT, (luser));
+                       if (MOD_RESULT == MOD_RES_DENY)
+                               return CMD_FAILURE;
+               }
 
+               user->awaytime = 0;
                user->awaymsg.clear();
                user->WriteNumeric(RPL_UNAWAY, "You are no longer marked as being away");
+               FOREACH_MOD_CUSTOM(awayevprov, Away::EventListener, OnUserBack, (user));
        }
 
        return CMD_SUCCESS;
index f29d2e448b8b962e323a49f8c3c9c51e83df04d0..1365cd048de8c9184bfff9567d603c25e48451ca 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "inspircd.h"
 #include "listmode.h"
+#include "modules/away.h"
 
 class MessageWrapper
 {
@@ -53,6 +54,9 @@ class MessageWrapper
  */
 class CommandAway : public Command
 {
+ private:
+       Away::EventProvider awayevprov;
+
  public:
        /** Constructor for away.
         */
index 56ed3c828da36fad7561fb1b8b2df77817da91a2..8f2d874dcbc0d9e34ae3d470d0660a1ca025ce82 100644 (file)
@@ -127,7 +127,6 @@ void                Module::OnExpireLine(XLine*) { DetachEvent(I_OnExpireLine); }
 void           Module::OnCleanup(ExtensionItem::ExtensibleType, Extensible*) { }
 ModResult      Module::OnChannelPreDelete(Channel*) { DetachEvent(I_OnChannelPreDelete); return MOD_RES_PASSTHRU; }
 void           Module::OnChannelDelete(Channel*) { DetachEvent(I_OnChannelDelete); }
-ModResult      Module::OnSetAway(User*, const std::string &) { DetachEvent(I_OnSetAway); return MOD_RES_PASSTHRU; }
 void           Module::OnBuildNeighborList(User*, IncludeChanList&, std::map<User*,bool>&) { DetachEvent(I_OnBuildNeighborList); }
 void           Module::OnGarbageCollect() { DetachEvent(I_OnGarbageCollect); }
 ModResult      Module::OnSetConnectClass(LocalUser* user, ConnectClass* myclass) { DetachEvent(I_OnSetConnectClass); return MOD_RES_PASSTHRU; }
index bbf3d7bc4bb22dc30c582d16c63a20d1f06ce3b5..92e8a088150402e13168d716a9e85ff169969404 100644 (file)
 
 #include "inspircd.h"
 #include "modules/account.h"
+#include "modules/away.h"
 #include "modules/cap.h"
 #include "modules/ircv3.h"
 
-class ModuleIRCv3 : public Module, public AccountEventListener
+class ModuleIRCv3
+       : public Module
+       , public AccountEventListener
+       , public Away::EventListener
 {
        Cap::Capability cap_accountnotify;
        Cap::Capability cap_awaynotify;
@@ -32,9 +36,10 @@ class ModuleIRCv3 : public Module, public AccountEventListener
  public:
        ModuleIRCv3()
                : AccountEventListener(this)
-               , cap_accountnotify(this, "account-notify"),
-                                       cap_awaynotify(this, "away-notify"),
-                                       cap_extendedjoin(this, "extended-join")
+               , Away::EventListener(this)
+               , cap_accountnotify(this, "account-notify")
+               , cap_awaynotify(this, "away-notify")
+               , cap_extendedjoin(this, "extended-join")
        {
        }
 
@@ -133,19 +138,24 @@ class ModuleIRCv3 : public Module, public AccountEventListener
                }
        }
 
-       ModResult OnSetAway(User* user, const std::string &awaymsg) CXX11_OVERRIDE
+       void OnUserAway(User* user) CXX11_OVERRIDE
        {
-               if (cap_awaynotify.IsActive())
-               {
-                       // Going away: n!u@h AWAY :reason
-                       // Back from away: n!u@h AWAY
-                       std::string line = ":" + user->GetFullHost() + " AWAY";
-                       if (!awaymsg.empty())
-                               line += " :" + awaymsg;
+               if (!cap_awaynotify.IsActive())
+                       return;
 
-                       IRCv3::WriteNeighborsWithCap(user, line, cap_awaynotify);
-               }
-               return MOD_RES_PASSTHRU;
+               // Going away: n!u@h AWAY :reason
+               const std::string line = ":" + user->GetFullHost() + " AWAY :" + user->awaymsg;
+               IRCv3::WriteNeighborsWithCap(user, line, cap_awaynotify);
+       }
+
+       void OnUserBack(User* user) CXX11_OVERRIDE
+       {
+               if (!cap_awaynotify.IsActive())
+                       return;
+
+               // Back from away: n!u@h AWAY
+               const std::string line = ":" + user->GetFullHost() + " AWAY";
+               IRCv3::WriteNeighborsWithCap(user, line, cap_awaynotify);
        }
 
        void OnPostJoin(Membership *memb) CXX11_OVERRIDE
index e65b3099b92aa5317c7a61fe985530a35614fb2f..282f52a35b99eed394d8e6e2afbac1d406dcb3ee 100644 (file)
@@ -27,19 +27,19 @@ CmdResult CommandAway::HandleRemote(::RemoteUser* u, Params& params)
 {
        if (!params.empty())
        {
-               FOREACH_MOD(OnSetAway, (u, params.back()));
-
                if (params.size() > 1)
                        u->awaytime = ConvToInt(params[0]);
                else
                        u->awaytime = ServerInstance->Time();
 
                u->awaymsg = params.back();
+               FOREACH_MOD_CUSTOM(awayevprov, Away::EventListener, OnUserAway, (u));
        }
        else
        {
-               FOREACH_MOD(OnSetAway, (u, ""));
+               u->awaytime = 0;
                u->awaymsg.clear();
+               FOREACH_MOD_CUSTOM(awayevprov, Away::EventListener, OnUserBack, (u));
        }
        return CMD_SUCCESS;
 }
@@ -47,12 +47,6 @@ CmdResult CommandAway::HandleRemote(::RemoteUser* u, Params& params)
 CommandAway::Builder::Builder(User* user)
        : CmdBuilder(user, "AWAY")
 {
-       push_int(user->awaytime).push_last(user->awaymsg);
-}
-
-CommandAway::Builder::Builder(User* user, const std::string& msg)
-       : CmdBuilder(user, "AWAY")
-{
-       if (!msg.empty())
-               push_int(ServerInstance->Time()).push_last(msg);
+       if (user->awaymsg.empty())
+               push_int(user->awaytime).push_last(user->awaymsg);
 }
index b98512578338de743f20a2da0caf55e72d6bd27f..434528e4601b74840655969a4b9de8675b06a7c6 100644 (file)
@@ -22,6 +22,7 @@
 #include "servercommand.h"
 #include "commandbuilder.h"
 #include "remoteuser.h"
+#include "modules/away.h"
 
 namespace SpanningTree
 {
@@ -241,15 +242,21 @@ class CommandResync : public ServerOnlyServerCommand<CommandResync>
 
 class SpanningTree::CommandAway : public UserOnlyServerCommand<SpanningTree::CommandAway>
 {
+ private:
+       Away::EventProvider awayevprov;
+
  public:
-       CommandAway(Module* Creator) : UserOnlyServerCommand<SpanningTree::CommandAway>(Creator, "AWAY", 0, 2) { }
+       CommandAway(Module* Creator)
+               : UserOnlyServerCommand<SpanningTree::CommandAway>(Creator, "AWAY", 0, 2)
+               , awayevprov(Creator)
+       {
+       }
        CmdResult HandleRemote(::RemoteUser* user, Params& parameters);
 
        class Builder : public CmdBuilder
        {
         public:
                Builder(User* user);
-               Builder(User* user, const std::string& msg);
        };
 };
 
index c7e55c66cf3259e784969b03c4b4e956f74675db..3c90891156153fe5a9ca25dd4f41a4305e5f13d6 100644 (file)
@@ -37,7 +37,8 @@
 #include "translate.h"
 
 ModuleSpanningTree::ModuleSpanningTree()
-       : Stats::EventListener(this)
+       : Away::EventListener(this)
+       , Stats::EventListener(this)
        , rconnect(this)
        , rsquit(this)
        , map(this)
@@ -718,12 +719,16 @@ void ModuleSpanningTree::OnDelLine(User* user, XLine *x)
        params.Broadcast();
 }
 
-ModResult ModuleSpanningTree::OnSetAway(User* user, const std::string &awaymsg)
+void ModuleSpanningTree::OnUserAway(User* user)
 {
        if (IS_LOCAL(user))
-               CommandAway::Builder(user, awaymsg).Broadcast();
+               CommandAway::Builder(user).Broadcast();
+}
 
-       return MOD_RES_PASSTHRU;
+void ModuleSpanningTree::OnUserBack(User* user)
+{
+       if (IS_LOCAL(user))
+               CommandAway::Builder(user).Broadcast();
 }
 
 void ModuleSpanningTree::OnMode(User* source, User* u, Channel* c, const Modes::ChangeList& modes, ModeParser::ModeProcessFlag processflags, const std::string& output_mode)
index 34b65772059d703f934e2f429279e4a20c3d5e63..4a65f1c37850f56b36ffb7ae46f46ca6820146cb 100644 (file)
@@ -53,7 +53,10 @@ class Autoconnect;
 
 /** This is the main class for the spanningtree module
  */
-class ModuleSpanningTree : public Module, public Stats::EventListener
+class ModuleSpanningTree
+       : public Module
+       , public Away::EventListener
+       , public Stats::EventListener
 {
        /** Client to server commands, registered in the core
         */
@@ -164,7 +167,8 @@ class ModuleSpanningTree : public Module, public Stats::EventListener
        void OnAddLine(User *u, XLine *x) CXX11_OVERRIDE;
        void OnDelLine(User *u, XLine *x) CXX11_OVERRIDE;
        ModResult OnStats(Stats::Context& stats) CXX11_OVERRIDE;
-       ModResult OnSetAway(User* user, const std::string &awaymsg) CXX11_OVERRIDE;
+       void OnUserAway(User* user) CXX11_OVERRIDE;
+       void OnUserBack(User* user) CXX11_OVERRIDE;
        void OnLoadModule(Module* mod) CXX11_OVERRIDE;
        void OnUnloadModule(Module* mod) CXX11_OVERRIDE;
        ModResult OnAcceptConnection(int newsock, ListenSocket* from, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) CXX11_OVERRIDE;
index 82cdcb6f820fe19a012c8712bb833a1eb3ed9abe..8b84132b23838dc43b5e852a684a9b2df8748b0f 100644 (file)
@@ -18,6 +18,7 @@
 
 
 #include "inspircd.h"
+#include "modules/away.h"
 
 #define INSPIRCD_MONITOR_MANAGER_ONLY
 #include "m_monitor.cpp"
@@ -179,7 +180,9 @@ class CommandWatch : public SplitCommand
        }
 };
 
-class ModuleWatch : public Module
+class ModuleWatch
+       : public Module
+       , public Away::EventListener
 {
        IRCv3::Monitor::Manager manager;
        CommandWatch cmd;
@@ -211,7 +214,8 @@ class ModuleWatch : public Module
 
  public:
        ModuleWatch()
-               : manager(this, "watch")
+               : Away::EventListener(this)
+               , manager(this, "watch")
                , cmd(this, manager)
        {
        }
@@ -245,14 +249,14 @@ class ModuleWatch : public Module
                Offline(user, user->nick);
        }
 
-       ModResult OnSetAway(User* user, const std::string& awaymsg) CXX11_OVERRIDE
+       void OnUserAway(User* user) CXX11_OVERRIDE
        {
-               if (awaymsg.empty())
-                       SendAlert(user, user->nick, RPL_NOTAWAY, "is no longer away", ServerInstance->Time());
-               else
-                       SendAlert(user, user->nick, RPL_GONEAWAY, awaymsg.c_str(), user->awaytime);
+               SendAlert(user, user->nick, RPL_GONEAWAY, user->awaymsg.c_str(), user->awaytime);
+       }
 
-               return MOD_RES_PASSTHRU;
+       void OnUserBack(User* user) CXX11_OVERRIDE
+       {
+               SendAlert(user, user->nick, RPL_NOTAWAY, "is no longer away", ServerInstance->Time());
        }
 
        void On005Numeric(std::map<std::string, std::string>& tokens) CXX11_OVERRIDE