From: Peter Powell Date: Sun, 12 Aug 2018 13:56:27 +0000 (+0100) Subject: Convert AWAY to use cross-module events and clean up slightly. X-Git-Url: https://git.netwichtig.de/gitweb/?a=commitdiff_plain;h=ba23c2b115ad3bf2632179d283165c1579332fd8;p=user%2Fhenk%2Fcode%2Finspircd.git Convert AWAY to use cross-module events and clean up slightly. 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. --- diff --git a/include/modules.h b/include/modules.h index 773e3b49f..4e5648512 100644 --- a/include/modules.h +++ b/include/modules.h @@ -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 index 000000000..f231f0a06 --- /dev/null +++ b/include/modules/away.h @@ -0,0 +1,83 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2016-2017 Peter Powell + * + * 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 . + */ + + +#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") + { + } +}; diff --git a/include/numerics.h b/include/numerics.h index 9e0ee07da..8c2f0ce11 100644 --- a/include/numerics.h +++ b/include/numerics.h @@ -70,9 +70,6 @@ enum RPL_USERHOST = 302, RPL_ISON = 303, - RPL_UNAWAY = 305, - RPL_NOWAWAY = 306, - RPL_WHOISSERVER = 312, RPL_ENDOFWHOIS = 318, diff --git a/src/coremods/core_user/cmd_away.cpp b/src/coremods/core_user/cmd_away.cpp index 1b7baceba..50a586392 100644 --- a/src/coremods/core_user/cmd_away.cpp +++ b/src/coremods/core_user/cmd_away.cpp @@ -21,9 +21,18 @@ #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 = "[]"; } @@ -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; diff --git a/src/coremods/core_user/core_user.h b/src/coremods/core_user/core_user.h index f29d2e448..1365cd048 100644 --- a/src/coremods/core_user/core_user.h +++ b/src/coremods/core_user/core_user.h @@ -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. */ diff --git a/src/modules.cpp b/src/modules.cpp index 56ed3c828..8f2d874dc 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -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&) { DetachEvent(I_OnBuildNeighborList); } void Module::OnGarbageCollect() { DetachEvent(I_OnGarbageCollect); } ModResult Module::OnSetConnectClass(LocalUser* user, ConnectClass* myclass) { DetachEvent(I_OnSetConnectClass); return MOD_RES_PASSTHRU; } diff --git a/src/modules/m_ircv3.cpp b/src/modules/m_ircv3.cpp index bbf3d7bc4..92e8a0881 100644 --- a/src/modules/m_ircv3.cpp +++ b/src/modules/m_ircv3.cpp @@ -18,10 +18,14 @@ #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 diff --git a/src/modules/m_spanningtree/away.cpp b/src/modules/m_spanningtree/away.cpp index e65b3099b..282f52a35 100644 --- a/src/modules/m_spanningtree/away.cpp +++ b/src/modules/m_spanningtree/away.cpp @@ -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); } diff --git a/src/modules/m_spanningtree/commands.h b/src/modules/m_spanningtree/commands.h index b98512578..434528e46 100644 --- a/src/modules/m_spanningtree/commands.h +++ b/src/modules/m_spanningtree/commands.h @@ -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 class SpanningTree::CommandAway : public UserOnlyServerCommand { + private: + Away::EventProvider awayevprov; + public: - CommandAway(Module* Creator) : UserOnlyServerCommand(Creator, "AWAY", 0, 2) { } + CommandAway(Module* Creator) + : UserOnlyServerCommand(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); }; }; diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index c7e55c66c..3c9089115 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -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) diff --git a/src/modules/m_spanningtree/main.h b/src/modules/m_spanningtree/main.h index 34b657720..4a65f1c37 100644 --- a/src/modules/m_spanningtree/main.h +++ b/src/modules/m_spanningtree/main.h @@ -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; diff --git a/src/modules/m_watch.cpp b/src/modules/m_watch.cpp index 82cdcb6f8..8b84132b2 100644 --- a/src/modules/m_watch.cpp +++ b/src/modules/m_watch.cpp @@ -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& tokens) CXX11_OVERRIDE