mirror of
https://github.com/inspircd/inspircd.git
synced 2025-03-10 02:59:01 -04:00
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.
This commit is contained in:
parent
f8a9b6ba4a
commit
ba23c2b115
@ -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
|
||||
|
83
include/modules/away.h
Normal file
83
include/modules/away.h
Normal file
@ -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")
|
||||
{
|
||||
}
|
||||
};
|
@ -70,9 +70,6 @@ enum
|
||||
RPL_USERHOST = 302,
|
||||
RPL_ISON = 303,
|
||||
|
||||
RPL_UNAWAY = 305,
|
||||
RPL_NOWAWAY = 306,
|
||||
|
||||
RPL_WHOISSERVER = 312,
|
||||
RPL_ENDOFWHOIS = 318,
|
||||
|
||||
|
@ -21,9 +21,18 @@
|
||||
#include "inspircd.h"
|
||||
#include "core_user.h"
|
||||
|
||||
CommandAway::CommandAway(Module* parent)
|
||||
: Command(parent, "AWAY", 0, 0)
|
||||
enum
|
||||
{
|
||||
// From RFC 1459.
|
||||
RPL_UNAWAY = 305,
|
||||
RPL_NOWAWAY = 306
|
||||
};
|
||||
|
||||
CommandAway::CommandAway(Module* parent)
|
||||
: 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;
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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; }
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user