summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/modules.h12
-rw-r--r--include/modules/away.h83
-rw-r--r--include/numerics.h3
-rw-r--r--src/coremods/core_user/cmd_away.cpp41
-rw-r--r--src/coremods/core_user/core_user.h4
-rw-r--r--src/modules.cpp1
-rw-r--r--src/modules/m_ircv3.cpp40
-rw-r--r--src/modules/m_spanningtree/away.cpp16
-rw-r--r--src/modules/m_spanningtree/commands.h11
-rw-r--r--src/modules/m_spanningtree/main.cpp13
-rw-r--r--src/modules/m_spanningtree/main.h8
-rw-r--r--src/modules/m_watch.cpp20
12 files changed, 183 insertions, 69 deletions
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 <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")
+ {
+ }
+};
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 = "[<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;
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<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; }
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<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);
};
};
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<std::string, std::string>& tokens) CXX11_OVERRIDE