From 21e7efdadfa685ac1ddcb0a0a515502bc873302b Mon Sep 17 00:00:00 2001 From: Robby Date: Sun, 17 Feb 2019 15:58:31 +0100 Subject: Various text improvements: consistency, syntax, help and doc updates/fixes. --- include/iohook.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/iohook.h b/include/iohook.h index 9ca17d77e..85404b09c 100644 --- a/include/iohook.h +++ b/include/iohook.h @@ -49,7 +49,7 @@ class IOHookProvider : public refcountbase, public ServiceProvider */ bool IsMiddle() const { return middlehook; } - /** Called when the provider should hook an incoming connection and act as being on the server side of the connection. + /** Called when the provider should hook an incoming connection and act as being on the server-side of the connection. * This occurs when a bind block has a hook configured and the listener accepts a connection. * @param sock Socket to hook * @param client Client IP address and port -- cgit v1.3.1-10-gc9f91 From e02c22ff165c7b0dbe39343066a4167e94f5618e Mon Sep 17 00:00:00 2001 From: Matt Schatz Date: Sun, 17 Feb 2019 02:10:26 -0700 Subject: Add a function for displaying human-readable durations. Add InspIRCd::DurationString() to take a time_t and return a string with the duration in a human-readable format (ex: 1y20w2d3h5m9s). --- include/inspircd.h | 6 ++++++ src/helperfuncs.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) (limited to 'include') diff --git a/include/inspircd.h b/include/inspircd.h index f5c7dbafb..0de64b103 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -516,6 +516,12 @@ class CoreExport InspIRCd */ static bool IsValidDuration(const std::string& str); + /** Return a duration in seconds as a human-readable string. + * @param duration The duration in seconds to convert to a human-readable string. + * @return A string representing the given duration. + */ + static std::string DurationString(time_t duration); + /** Attempt to compare a password to a string from the config file. * This will be passed to handling modules which will compare the data * against possible hashed equivalents in the input string. diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp index 94a5240c9..846feab50 100644 --- a/src/helperfuncs.cpp +++ b/src/helperfuncs.cpp @@ -7,6 +7,7 @@ * Copyright (C) 2008 Thomas Stagner * Copyright (C) 2006-2007 Oliver Lupton * Copyright (C) 2007 Dennis Friis + * Copyright (C) 2003-2019 Anope Team * * 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 @@ -429,6 +430,33 @@ bool InspIRCd::IsValidDuration(const std::string& duration) return true; } +std::string InspIRCd::DurationString(time_t duration) +{ + time_t years = duration / 31536000; + time_t weeks = (duration / 604800) % 52; + time_t days = (duration / 86400) % 7; + time_t hours = (duration / 3600) % 24; + time_t minutes = (duration / 60) % 60; + time_t seconds = duration % 60; + + std::string ret; + + if (years) + ret = ConvToStr(years) + "y"; + if (weeks) + ret += ConvToStr(weeks) + "w"; + if (days) + ret += ConvToStr(days) + "d"; + if (hours) + ret += ConvToStr(hours) + "h"; + if (minutes) + ret += ConvToStr(minutes) + "m"; + if (seconds) + ret += ConvToStr(seconds) + "s"; + + return ret; +} + std::string InspIRCd::Format(va_list& vaList, const char* formatString) { static std::vector formatBuffer(1024); -- cgit v1.3.1-10-gc9f91 From f06502606e6e043487d9154ce4127e81e1181549 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Tue, 19 Feb 2019 18:22:00 +0000 Subject: Allow customising ElementComp in flat_{map,multimap,multiset,set}. --- include/flat_map.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/flat_map.h b/include/flat_map.h index bef1404e4..62815168b 100644 --- a/include/flat_map.h +++ b/include/flat_map.h @@ -200,10 +200,10 @@ class flat_map_base } // namespace detail -template > -class flat_set : public detail::flat_map_base +template , typename ElementComp = Comp> +class flat_set : public detail::flat_map_base { - typedef detail::flat_map_base base_t; + typedef detail::flat_map_base base_t; public: typedef typename base_t::iterator iterator; @@ -240,10 +240,10 @@ class flat_set : public detail::flat_map_base } }; -template > -class flat_multiset : public detail::flat_map_base +template , typename ElementComp = Comp> +class flat_multiset : public detail::flat_map_base { - typedef detail::flat_map_base base_t; + typedef detail::flat_map_base base_t; public: typedef typename base_t::iterator iterator; @@ -280,10 +280,10 @@ class flat_multiset : public detail::flat_map_base } }; -template > -class flat_map : public detail::flat_map_base, Comp, T, detail::map_pair_compare, Comp> > +template , typename ElementComp = Comp > +class flat_map : public detail::flat_map_base, Comp, T, detail::map_pair_compare, ElementComp> > { - typedef detail::flat_map_base, Comp, T, detail::map_pair_compare, Comp> > base_t; + typedef detail::flat_map_base, Comp, T, detail::map_pair_compare, ElementComp> > base_t; public: typedef typename base_t::iterator iterator; @@ -333,10 +333,10 @@ class flat_map : public detail::flat_map_base, Comp, T, detail:: } }; -template > -class flat_multimap : public detail::flat_map_base, Comp, T, detail::map_pair_compare, Comp> > +template , typename ElementComp = Comp > +class flat_multimap : public detail::flat_map_base, Comp, T, detail::map_pair_compare, ElementComp> > { - typedef detail::flat_map_base, Comp, T, detail::map_pair_compare, Comp> > base_t; + typedef detail::flat_map_base, Comp, T, detail::map_pair_compare, ElementComp> > base_t; public: typedef typename base_t::iterator iterator; -- cgit v1.3.1-10-gc9f91 From 74136695f88ded34f1413b546ad1b0699404bfe8 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Tue, 19 Feb 2019 18:32:49 +0000 Subject: Fix erasing event subscribers erasing all with the same priority. --- include/event.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/event.h b/include/event.h index 1bcb0a5ed..92bb4ffec 100644 --- a/include/event.h +++ b/include/event.h @@ -39,7 +39,7 @@ class Events::ModuleEventProvider : public ServiceProvider, private dynamic_refe bool operator()(ModuleEventListener* one, ModuleEventListener* two) const; }; - typedef insp::flat_multiset SubscriberList; + typedef insp::flat_multiset > SubscriberList; /** Constructor * @param mod Module providing the event(s) -- cgit v1.3.1-10-gc9f91 From c495b5d9cf8bed4f07c0b77a1f9e98dcc1f62068 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Thu, 6 Sep 2018 10:09:09 +0100 Subject: Implement support for IRCv3 client-to-client tags. --- docs/conf/modules.conf.example | 6 + include/modules/ctctags.h | 135 +++++++++++++ src/coremods/core_serialize_rfc.cpp | 2 +- src/modules/m_delayjoin.cpp | 18 +- src/modules/m_ircv3_ctctags.cpp | 347 ++++++++++++++++++++++++++++++++++ src/modules/m_ircv3_echomessage.cpp | 47 ++++- src/modules/m_spanningtree/compat.cpp | 5 + 7 files changed, 555 insertions(+), 5 deletions(-) create mode 100644 include/modules/ctctags.h create mode 100644 src/modules/m_ircv3_ctctags.cpp (limited to 'include') diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example index 2fa3b5042..3f7e5a9f0 100644 --- a/docs/conf/modules.conf.example +++ b/docs/conf/modules.conf.example @@ -1112,6 +1112,12 @@ # extension will get the chghost message and won't see host cycling. # +#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# +# IRCv3 client-to-client tags module: Provides the message-tags IRCv3 +# extension which allows clients to add extra data to their messages. +# This is used to support new IRCv3 features such as replies and ids. +# + #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # IRCv3 echo-message module: Provides the echo-message IRCv3 # extension which allows capable clients to get an acknowledgement when diff --git a/include/modules/ctctags.h b/include/modules/ctctags.h new file mode 100644 index 000000000..d8798de54 --- /dev/null +++ b/include/modules/ctctags.h @@ -0,0 +1,135 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2019 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 CTCTags +{ + class EventListener; + class TagMessage; + class TagMessageDetails; +} + +class CTCTags::TagMessage : public ClientProtocol::Message +{ + public: + TagMessage(User* source, const Channel* targetchan, const ClientProtocol::TagMap& Tags) + : ClientProtocol::Message("TAGMSG", source) + { + PushParamRef(targetchan->name); + AddTags(Tags); + SetSideEffect(true); + } + + TagMessage(User* source, const User* targetuser, const ClientProtocol::TagMap& Tags) + : ClientProtocol::Message("TAGMSG", source) + { + if (targetuser->registered & REG_NICK) + PushParamRef(targetuser->nick); + else + PushParam("*"); + AddTags(Tags); + SetSideEffect(true); + } + + TagMessage(User* source, const char* targetstr, const ClientProtocol::TagMap& Tags) + : ClientProtocol::Message("TAGMSG", source) + { + PushParam(targetstr); + AddTags(Tags); + SetSideEffect(true); + } +}; + +class CTCTags::TagMessageDetails +{ + public: + /** Whether to echo the tags at all. */ + bool echo; + + /* Whether to send the original tags back to clients with echo-message support. */ + bool echo_original; + + /** The users who are exempted from receiving this message. */ + CUList exemptions; + + /** IRCv3 message tags sent to the server by the user. */ + const ClientProtocol::TagMap tags_in; + + /** IRCv3 message tags sent out to users who get this message. */ + ClientProtocol::TagMap tags_out; + + TagMessageDetails(const ClientProtocol::TagMap& tags) + : echo(true) + , echo_original(false) + , tags_in(tags) + { + } +}; + +class CTCTags::EventListener + : public Events::ModuleEventListener +{ + protected: + EventListener(Module* mod, unsigned int eventprio = DefaultPriority) + : ModuleEventListener(mod, "event/tagmsg", eventprio) + { + } + + public: + /** Called before a user sends a tag message to a channel, a user, or a server glob mask. + * @param user The user sending the message. + * @param target The target of the message. This can either be a channel, a user, or a server + * glob mask. + * @param details Details about the message such as the message tags or whether to echo. See the + * TagMessageDetails class for more information. + * @return MOD_RES_ALLOW to explicitly allow the message, MOD_RES_DENY to explicitly deny the + * message, or MOD_RES_PASSTHRU to let another module handle the event. + */ + virtual ModResult OnUserPreTagMessage(User* user, const MessageTarget& target, TagMessageDetails& details) { return MOD_RES_PASSTHRU; } + + /** Called immediately after a user sends a tag message to a channel, a user, or a server glob mask. + * @param user The user sending the message. + * @param target The target of the message. This can either be a channel, a user, or a server + * glob mask. + * @param details Details about the message such as the message tags or whether to echo. See the + * TagMessageDetails class for more information. + */ + virtual void OnUserPostTagMessage(User* user, const MessageTarget& target, const TagMessageDetails& details) { } + + /** Called immediately before a user sends a tag message to a channel, a user, or a server glob mask. + * @param user The user sending the message. + * @param target The target of the message. This can either be a channel, a user, or a server + * glob mask. + * @param details Details about the message such as the message tags or whether to echo. See the + * TagMessageDetails class for more information. + */ + virtual void OnUserTagMessage(User* user, const MessageTarget& target, const TagMessageDetails& details) { } + + /** Called when a tag message sent by a user to a channel, a user, or a server glob mask is blocked. + * @param user The user sending the message. + * @param target The target of the message. This can either be a channel, a user, or a server + * glob mask. + * @param details Details about the message such as the message tags or whether to echo. See the + * TagMessageDetails class for more information. + */ + virtual void OnUserTagMessageBlocked(User* user, const MessageTarget& target, const TagMessageDetails& details) { } +}; diff --git a/src/coremods/core_serialize_rfc.cpp b/src/coremods/core_serialize_rfc.cpp index 6b693bfb9..b8d075ab6 100644 --- a/src/coremods/core_serialize_rfc.cpp +++ b/src/coremods/core_serialize_rfc.cpp @@ -32,7 +32,7 @@ class RFCSerializer : public ClientProtocol::Serializer static const std::string::size_type MAX_CLIENT_MESSAGE_TAG_LENGTH = 4095; /** The maximum size of server-originated message tags in an outgoing message including the `@`. */ - static const std::string::size_type MAX_SERVER_MESSAGE_TAG_LENGTH = 511; + static const std::string::size_type MAX_SERVER_MESSAGE_TAG_LENGTH = 4095; static void SerializeTags(const ClientProtocol::TagMap& tags, const ClientProtocol::TagSelection& tagwl, std::string& line); diff --git a/src/modules/m_delayjoin.cpp b/src/modules/m_delayjoin.cpp index 8b06f060a..469f33439 100644 --- a/src/modules/m_delayjoin.cpp +++ b/src/modules/m_delayjoin.cpp @@ -21,6 +21,7 @@ #include "inspircd.h" +#include "modules/ctctags.h" class DelayJoinMode : public ModeHandler { @@ -72,7 +73,9 @@ class JoinHook : public ClientProtocol::EventHook } -class ModuleDelayJoin : public Module +class ModuleDelayJoin + : public Module + , public CTCTags::EventListener { public: LocalIntExt unjoined; @@ -80,7 +83,8 @@ class ModuleDelayJoin : public Module DelayJoinMode djm; ModuleDelayJoin() - : unjoined("delayjoin", ExtensionItem::EXT_MEMBERSHIP, this) + : CTCTags::EventListener(this) + , unjoined("delayjoin", ExtensionItem::EXT_MEMBERSHIP, this) , joinhook(this, unjoined) , djm(this, unjoined) { @@ -94,6 +98,7 @@ class ModuleDelayJoin : public Module void OnUserKick(User* source, Membership*, const std::string &reason, CUList&) CXX11_OVERRIDE; void OnBuildNeighborList(User* source, IncludeChanList& include, std::map& exception) CXX11_OVERRIDE; void OnUserMessage(User* user, const MessageTarget& target, const MessageDetails& details) CXX11_OVERRIDE; + void OnUserTagMessage(User* user, const MessageTarget& target, const CTCTags::TagMessageDetails& details) CXX11_OVERRIDE; ModResult OnRawMode(User* user, Channel* channel, ModeHandler* mh, const std::string& param, bool adding) CXX11_OVERRIDE; }; @@ -176,6 +181,15 @@ void ModuleDelayJoin::OnBuildNeighborList(User* source, IncludeChanList& include } } +void ModuleDelayJoin::OnUserTagMessage(User* user, const MessageTarget& target, const CTCTags::TagMessageDetails& details) +{ + if (target.type != MessageTarget::TYPE_CHANNEL) + return; + + Channel* channel = target.Get(); + djm.RevealUser(user, channel); +} + void ModuleDelayJoin::OnUserMessage(User* user, const MessageTarget& target, const MessageDetails& details) { if (target.type != MessageTarget::TYPE_CHANNEL) diff --git a/src/modules/m_ircv3_ctctags.cpp b/src/modules/m_ircv3_ctctags.cpp new file mode 100644 index 000000000..8684642c6 --- /dev/null +++ b/src/modules/m_ircv3_ctctags.cpp @@ -0,0 +1,347 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2019 Peter Powell + * Copyright (C) 2016 Attila Molnar + * + * 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 . + */ + + +#include "inspircd.h" +#include "modules/cap.h" +#include "modules/ctctags.h" + +class CommandTagMsg : public Command +{ + private: + Cap::Capability& cap; + ChanModeReference moderatedmode; + ChanModeReference noextmsgmode; + Events::ModuleEventProvider tagevprov; + ClientProtocol::EventProvider msgevprov; + + bool FirePreEvents(User* source, MessageTarget& msgtarget, CTCTags::TagMessageDetails& msgdetails) + { + // Inform modules that a TAGMSG wants to be sent. + ModResult modres; + FIRST_MOD_RESULT_CUSTOM(tagevprov, CTCTags::EventListener, OnUserPreTagMessage, modres, (source, msgtarget, msgdetails)); + if (modres == MOD_RES_DENY) + { + // Inform modules that a module blocked the TAGMSG. + FOREACH_MOD_CUSTOM(tagevprov, CTCTags::EventListener, OnUserTagMessageBlocked, (source, msgtarget, msgdetails)); + return false; + } + + // Inform modules that a TAGMSG is about to be sent. + FOREACH_MOD_CUSTOM(tagevprov, CTCTags::EventListener, OnUserTagMessage, (source, msgtarget, msgdetails)); + return true; + } + + CmdResult FirePostEvent(User* source, const MessageTarget& msgtarget, const CTCTags::TagMessageDetails& msgdetails) + { + // If the source is local then update its idle time. + LocalUser* lsource = IS_LOCAL(source); + if (lsource) + lsource->idle_lastmsg = ServerInstance->Time(); + + // Inform modules that a TAGMSG was sent. + FOREACH_MOD_CUSTOM(tagevprov, CTCTags::EventListener, OnUserPostTagMessage, (source, msgtarget, msgdetails)); + return CMD_SUCCESS; + } + + CmdResult HandleChannelTarget(User* source, const Params& parameters, const char* target, PrefixMode* pm) + { + Channel* chan = ServerInstance->FindChan(target); + if (!chan) + { + // The target channel does not exist. + source->WriteNumeric(Numerics::NoSuchChannel(parameters[0])); + return CMD_FAILURE; + } + + if (IS_LOCAL(source)) + { + if (chan->IsModeSet(noextmsgmode) && !chan->HasUser(source)) + { + // The noextmsg mode is set and the source is not in the channel. + source->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (no external messages)"); + return CMD_FAILURE; + } + + bool no_chan_priv = chan->GetPrefixValue(source) < VOICE_VALUE; + if (no_chan_priv && chan->IsModeSet(moderatedmode)) + { + // The moderated mode is set and the source has no status rank. + source->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (+m)"); + return CMD_FAILURE; + } + + if (no_chan_priv && ServerInstance->Config->RestrictBannedUsers != ServerConfig::BUT_NORMAL && chan->IsBanned(source)) + { + // The source is banned in the channel and restrictbannedusers is enabled. + if (ServerInstance->Config->RestrictBannedUsers == ServerConfig::BUT_RESTRICT_NOTIFY) + source->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (you're banned)"); + return CMD_FAILURE; + } + } + + // Fire the pre-message events. + MessageTarget msgtarget(chan, pm ? pm->GetPrefix() : 0); + CTCTags::TagMessageDetails msgdetails(parameters.GetTags()); + if (!FirePreEvents(source, msgtarget, msgdetails)) + return CMD_FAILURE; + + unsigned int minrank = pm ? pm->GetPrefixRank() : 0; + CTCTags::TagMessage message(source, chan, parameters.GetTags()); + const Channel::MemberMap& userlist = chan->GetUsers(); + for (Channel::MemberMap::const_iterator iter = userlist.begin(); iter != userlist.end(); ++iter) + { + LocalUser* luser = IS_LOCAL(iter->first); + + // Don't send to remote users or the user who is the source. + if (!luser || luser == source) + continue; + + // Don't send to unprivileged or exempt users. + if (iter->second->getRank() < minrank || msgdetails.exemptions.count(luser)) + continue; + + // Send to users if they have the capability. + if (cap.get(luser)) + luser->Send(msgevprov, message); + } + return FirePostEvent(source, msgtarget, msgdetails); + } + + CmdResult HandleServerTarget(User* source, const Params& parameters) + { + // If the source isn't allowed to mass message users then reject + // the attempt to mass-message users. + if (!source->HasPrivPermission("users/mass-message")) + return CMD_FAILURE; + + // Extract the server glob match from the target parameter. + std::string servername(parameters[0], 1); + + // Fire the pre-message events. + MessageTarget msgtarget(&servername); + CTCTags::TagMessageDetails msgdetails(parameters.GetTags()); + if (!FirePreEvents(source, msgtarget, msgdetails)) + return CMD_FAILURE; + + // If the current server name matches the server name glob then send + // the message out to the local users. + if (InspIRCd::Match(ServerInstance->Config->ServerName, servername)) + { + CTCTags::TagMessage message(source, "$*", parameters.GetTags()); + const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers(); + for (UserManager::LocalList::const_iterator iter = list.begin(); iter != list.end(); ++iter) + { + LocalUser* luser = IS_LOCAL(*iter); + + // Don't send to unregistered users or the user who is the source. + if (luser->registered != REG_ALL || luser == source) + continue; + + // Don't send to exempt users. + if (msgdetails.exemptions.count(luser)) + continue; + + // Send to users if they have the capability. + if (cap.get(luser)) + luser->Send(msgevprov, message); + } + } + + // Fire the post-message event. + return FirePostEvent(source, msgtarget, msgdetails); + } + + CmdResult HandleUserTarget(User* source, const Params& parameters) + { + User* target; + if (IS_LOCAL(source)) + { + // Local sources can specify either a nick or a nick@server mask as the target. + const char* targetserver = strchr(parameters[0].c_str(), '@'); + if (targetserver) + { + // The target is a user on a specific server (e.g. jto@tolsun.oulu.fi). + target = ServerInstance->FindNickOnly(parameters[0].substr(0, targetserver - parameters[0].c_str())); + if (target && strcasecmp(target->server->GetName().c_str(), targetserver + 1)) + target = NULL; + } + else + { + // If the source is a local user then we only look up the target by nick. + target = ServerInstance->FindNickOnly(parameters[0]); + } + } + else + { + // Remote users can only specify a nick or UUID as the target. + target = ServerInstance->FindNick(parameters[0]); + } + + if (!target || target->registered != REG_ALL) + { + // The target user does not exist or is not fully registered. + source->WriteNumeric(Numerics::NoSuchNick(parameters[0])); + return CMD_FAILURE; + } + + // Fire the pre-message events. + MessageTarget msgtarget(target); + CTCTags::TagMessageDetails msgdetails(parameters.GetTags()); + if (!FirePreEvents(source, msgtarget, msgdetails)) + return CMD_FAILURE; + + LocalUser* const localtarget = IS_LOCAL(target); + if (localtarget && cap.get(localtarget)) + { + // Send to the target if they have the capability and are a local user. + CTCTags::TagMessage message(source, localtarget, parameters.GetTags()); + localtarget->Send(msgevprov, message); + } + + // Fire the post-message event. + return FirePostEvent(source, msgtarget, msgdetails); + } + + public: + CommandTagMsg(Module* Creator, Cap::Capability& Cap) + : Command(Creator, "TAGMSG", 1) + , cap(Cap) + , moderatedmode(Creator, "moderated") + , noextmsgmode(Creator, "noextmsg") + , tagevprov(Creator, "event/tagmsg") + , msgevprov(Creator, "TAGMSG") + { + allow_empty_last_param = false; + } + + CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE + { + if (CommandParser::LoopCall(user, this, parameters, 0)) + return CMD_SUCCESS; + + // Check that the source has the message tags capability. + if (IS_LOCAL(user) && !cap.get(user)) + return CMD_FAILURE; + + // The target is a server glob. + if (parameters[0][0] == '$') + return HandleServerTarget(user, parameters); + + // If the message begins with a status character then look it up. + const char* target = parameters[0].c_str(); + PrefixMode* pmh = ServerInstance->Modes->FindPrefix(target[0]); + if (pmh) + target++; + + // The target is a channel name. + if (*target == '#') + return HandleChannelTarget(user, parameters, target, pmh); + + // The target is a nickname. + return HandleUserTarget(user, parameters); + } + + RouteDescriptor GetRouting(User* user, const Params& parameters) CXX11_OVERRIDE + { + return ROUTE_MESSAGE(parameters[0]); + } +}; + +class C2CTags : public ClientProtocol::MessageTagProvider +{ + private: + Cap::Capability& cap; + + public: + C2CTags(Module* Creator, Cap::Capability& Cap) + : ClientProtocol::MessageTagProvider(Creator) + , cap(Cap) + { + } + + ModResult OnProcessTag(User* user, const std::string& tagname, std::string& tagvalue) CXX11_OVERRIDE + { + // A client-only tag is prefixed with a plus sign (+) and otherwise conforms + // to the format specified in IRCv3.2 tags. + if (tagname[0] != '+') + return MOD_RES_PASSTHRU; + + // If the user is local then we check whether they have the message-tags cap + // enabled. If not then we reject all client-only tags originating from them. + LocalUser* lu = IS_LOCAL(user); + if (lu && !cap.get(lu)) + return MOD_RES_DENY; + + // Remote users have their client-only tags checked by their local server. + return MOD_RES_ALLOW; + } + + bool ShouldSendTag(LocalUser* user, const ClientProtocol::MessageTagData& tagdata) CXX11_OVERRIDE + { + return cap.get(user); + } +}; + +class ModuleIRCv3CTCTags + : public Module + , public CTCTags::EventListener +{ + private: + Cap::Capability cap; + CommandTagMsg cmd; + C2CTags c2ctags; + + ModResult CopyClientTags(const ClientProtocol::TagMap& tags_in, ClientProtocol::TagMap& tags_out) + { + for (ClientProtocol::TagMap::const_iterator i = tags_in.begin(); i != tags_in.end(); ++i) + { + const ClientProtocol::MessageTagData& tagdata = i->second; + if (tagdata.tagprov == &c2ctags) + tags_out.insert(*i); + } + return MOD_RES_PASSTHRU; + } + + public: + ModuleIRCv3CTCTags() + : CTCTags::EventListener(this) + , cap(this, "message-tags") + , cmd(this, cap) + , c2ctags(this, cap) + { + } + + ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details) CXX11_OVERRIDE + { + return CopyClientTags(details.tags_in, details.tags_out); + } + + ModResult OnUserPreTagMessage(User* user, const MessageTarget& target, CTCTags::TagMessageDetails& details) CXX11_OVERRIDE + { + return CopyClientTags(details.tags_in, details.tags_out); + } + + Version GetVersion() CXX11_OVERRIDE + { + return Version("Provides the DRAFT message-tags IRCv3 extension", VF_VENDOR | VF_COMMON); + } +}; + +MODULE_INIT(ModuleIRCv3CTCTags) diff --git a/src/modules/m_ircv3_echomessage.cpp b/src/modules/m_ircv3_echomessage.cpp index b407aece4..3ec534e91 100644 --- a/src/modules/m_ircv3_echomessage.cpp +++ b/src/modules/m_ircv3_echomessage.cpp @@ -20,14 +20,21 @@ #include "inspircd.h" #include "modules/cap.h" +#include "modules/ctctags.h" -class ModuleIRCv3EchoMessage : public Module +class ModuleIRCv3EchoMessage + : public Module + , public CTCTags::EventListener { + private: Cap::Capability cap; + ClientProtocol::EventProvider tagmsgprov; public: ModuleIRCv3EchoMessage() - : cap(this, "echo-message") + : CTCTags::EventListener(this) + , cap(this, "echo-message") + , tagmsgprov(this, "TAGMSG") { } @@ -64,6 +71,35 @@ class ModuleIRCv3EchoMessage : public Module } } + void OnUserPostTagMessage(User* user, const MessageTarget& target, const CTCTags::TagMessageDetails& details) CXX11_OVERRIDE + { + if (!cap.get(user) || !details.echo) + return; + + // Caps are only set on local users + LocalUser* const localuser = static_cast(user); + + const ClientProtocol::TagMap& tags = details.echo_original ? details.tags_in : details.tags_out; + if (target.type == MessageTarget::TYPE_USER) + { + User* destuser = target.Get(); + CTCTags::TagMessage message(user, destuser, tags); + localuser->Send(tagmsgprov, message); + } + else if (target.type == MessageTarget::TYPE_CHANNEL) + { + Channel* chan = target.Get(); + CTCTags::TagMessage message(user, chan, tags); + localuser->Send(tagmsgprov, message); + } + else + { + const std::string* servername = target.Get(); + CTCTags::TagMessage message(user, servername->c_str(), tags); + localuser->Send(tagmsgprov, message); + } + } + void OnUserMessageBlocked(User* user, const MessageTarget& target, const MessageDetails& details) CXX11_OVERRIDE { // Prevent spammers from knowing that their spam was blocked. @@ -71,6 +107,13 @@ class ModuleIRCv3EchoMessage : public Module OnUserPostMessage(user, target, details); } + void OnUserTagMessageBlocked(User* user, const MessageTarget& target, const CTCTags::TagMessageDetails& details) CXX11_OVERRIDE + { + // Prevent spammers from knowing that their spam was blocked. + if (details.echo_original) + OnUserPostTagMessage(user, target, details); + } + Version GetVersion() CXX11_OVERRIDE { return Version("Provides the echo-message IRCv3 extension", VF_VENDOR); diff --git a/src/modules/m_spanningtree/compat.cpp b/src/modules/m_spanningtree/compat.cpp index 17bc7cbc6..17b44f896 100644 --- a/src/modules/m_spanningtree/compat.cpp +++ b/src/modules/m_spanningtree/compat.cpp @@ -309,6 +309,11 @@ void TreeSocket::WriteLine(const std::string& original_line) push.append(line, 26, std::string::npos); push.swap(line); } + else if (command == "TAGMSG") + { + // Drop IRCv3 tag messages as v2 has no message tag support. + return; + } } WriteLineNoCompat(line); return; -- cgit v1.3.1-10-gc9f91 From 9b25df31096f889e3653ab100493133014d4fe73 Mon Sep 17 00:00:00 2001 From: Matt Schatz Date: Fri, 22 Feb 2019 06:44:57 -0700 Subject: Improve the handling of config X-lines and filters. (#1583) --- include/xline.h | 7 +++--- src/configreader.cpp | 6 ++++- src/modules/m_filter.cpp | 30 +++++++++++++---------- src/modules/m_xline_db.cpp | 9 +++++-- src/xline.cpp | 59 +++++++++++++++++++++++++++++++--------------- 5 files changed, 73 insertions(+), 38 deletions(-) (limited to 'include') diff --git a/include/xline.h b/include/xline.h index f593c1c97..bc9739f21 100644 --- a/include/xline.h +++ b/include/xline.h @@ -515,8 +515,9 @@ class CoreExport XLineManager /** Expire a line given two iterators which identify it in the main map. * @param container Iterator to the first level of entries the map * @param item Iterator to the second level of entries in the map + * @param silent If true, doesn't send an expiry SNOTICE. */ - void ExpireLine(ContainerIter container, LookupIter item); + void ExpireLine(ContainerIter container, LookupIter item, bool silent = false); /** Apply any new lines that are pending to be applied. * This will only apply lines in the pending_lines list, to save on @@ -533,6 +534,6 @@ class CoreExport XLineManager */ void InvokeStats(const std::string& type, unsigned int numeric, Stats::Context& stats); - /** Clears any XLines which were added by the server configuration. */ - void ClearConfigLines(); + /** Expire X-lines which were added by the server configuration and have been removed. */ + void ExpireRemovedConfigLines(const std::string& type, const insp::flat_set& configlines); }; diff --git a/src/configreader.cpp b/src/configreader.cpp index 00880cfff..0318dd602 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -74,6 +74,8 @@ ServerConfig::~ServerConfig() static void ReadXLine(ServerConfig* conf, const std::string& tag, const std::string& key, XLineFactory* make) { + insp::flat_set configlines; + ConfigTagList tags = conf->ConfTags(tag); for(ConfigIter i = tags.first; i != tags.second; ++i) { @@ -84,9 +86,12 @@ static void ReadXLine(ServerConfig* conf, const std::string& tag, const std::str std::string reason = ctag->getString("reason", ""); XLine* xl = make->Generate(ServerInstance->Time(), 0, "", reason, mask); xl->from_config = true; + configlines.insert(xl->Displayable()); if (!ServerInstance->XLines->AddLine(xl, NULL)) delete xl; } + + ServerInstance->XLines->ExpireRemovedConfigLines(make->GetType(), configlines); } typedef std::map LocalIndex; @@ -405,7 +410,6 @@ void ServerConfig::Fill() SocketEngine::Close(socktest); } - ServerInstance->XLines->ClearConfigLines(); ReadXLine(this, "badip", "ipmask", ServerInstance->XLines->GetFactory("Z")); ReadXLine(this, "badnick", "nick", ServerInstance->XLines->GetFactory("Q")); ReadXLine(this, "badhost", "host", ServerInstance->XLines->GetFactory("K")); diff --git a/src/modules/m_filter.cpp b/src/modules/m_filter.cpp index f49694e81..7a7497d1a 100644 --- a/src/modules/m_filter.cpp +++ b/src/modules/m_filter.cpp @@ -193,7 +193,7 @@ class ModuleFilter : public Module, public ServerEventListener, public Stats::Ev ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details) CXX11_OVERRIDE; FilterResult* FilterMatch(User* user, const std::string &text, int flags); bool DeleteFilter(const std::string& freeform, std::string& reason); - std::pair AddFilter(const std::string& freeform, FilterAction type, const std::string& reason, unsigned long duration, const std::string& flags); + std::pair AddFilter(const std::string& freeform, FilterAction type, const std::string& reason, unsigned long duration, const std::string& flags, bool config = false); void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE; Version GetVersion() CXX11_OVERRIDE; std::string EncodeFilter(FilterResult* filter); @@ -744,7 +744,7 @@ bool ModuleFilter::DeleteFilter(const std::string& freeform, std::string& reason return false; } -std::pair ModuleFilter::AddFilter(const std::string& freeform, FilterAction type, const std::string& reason, unsigned long duration, const std::string& flgs) +std::pair ModuleFilter::AddFilter(const std::string& freeform, FilterAction type, const std::string& reason, unsigned long duration, const std::string& flgs, bool config) { for (std::vector::iterator i = filters.begin(); i != filters.end(); i++) { @@ -756,7 +756,7 @@ std::pair ModuleFilter::AddFilter(const std::string& freeform try { - filters.push_back(FilterResult(RegexEngine, freeform, reason, type, duration, flgs, false)); + filters.push_back(FilterResult(RegexEngine, freeform, reason, type, duration, flgs, config)); } catch (ModuleException &e) { @@ -807,11 +807,13 @@ std::string ModuleFilter::FilterActionToString(FilterAction fa) void ModuleFilter::ReadFilters() { + insp::flat_set removedfilters; + for (std::vector::iterator filter = filters.begin(); filter != filters.end(); ) { if (filter->from_config) { - ServerInstance->SNO->WriteGlobalSno('f', "Removing filter '" + filter->freeform + "' due to config rehash."); + removedfilters.insert(filter->freeform); delete filter->regex; filter = filters.erase(filter); continue; @@ -836,15 +838,17 @@ void ModuleFilter::ReadFilters() if (!StringToFilterAction(action, fa)) fa = FA_NONE; - try - { - filters.push_back(FilterResult(RegexEngine, pattern, reason, fa, duration, flgs, true)); - ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Regular expression %s loaded.", pattern.c_str()); - } - catch (ModuleException &e) - { - ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Error in regular expression '%s': %s", pattern.c_str(), e.GetReason().c_str()); - } + std::pair result = static_cast(this)->AddFilter(pattern, fa, reason, duration, flgs, true); + if (result.first) + removedfilters.erase(pattern); + else + ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Filter '%s' could not be added: %s", pattern.c_str(), result.second.c_str()); + } + + if (!removedfilters.empty()) + { + for (insp::flat_set::const_iterator it = removedfilters.begin(); it != removedfilters.end(); ++it) + ServerInstance->SNO->WriteGlobalSno('f', "Removing filter '" + *(it) + "' due to config rehash."); } } diff --git a/src/modules/m_xline_db.cpp b/src/modules/m_xline_db.cpp index 90f9de9d2..a64dc7071 100644 --- a/src/modules/m_xline_db.cpp +++ b/src/modules/m_xline_db.cpp @@ -51,7 +51,8 @@ class ModuleXLineDB : public Module */ void OnAddLine(User* source, XLine* line) CXX11_OVERRIDE { - dirty = true; + if (!line->from_config) + dirty = true; } /** Called whenever an xline is deleted. @@ -61,7 +62,8 @@ class ModuleXLineDB : public Module */ void OnDelLine(User* source, XLine* line) CXX11_OVERRIDE { - dirty = true; + if (!line->from_config) + dirty = true; } void OnBackgroundTimer(time_t now) CXX11_OVERRIDE @@ -113,6 +115,9 @@ class ModuleXLineDB : public Module for (LookupIter i = lookup->begin(); i != lookup->end(); ++i) { XLine* line = i->second; + if (line->from_config) + continue; + stream << "LINE " << line->type << " " << line->Displayable() << " " << line->source << " " << line->set_time << " " << line->duration << " :" << line->reason << std::endl; diff --git a/src/xline.cpp b/src/xline.cpp index c5b952087..fbb4f0c8b 100644 --- a/src/xline.cpp +++ b/src/xline.cpp @@ -265,12 +265,31 @@ bool XLineManager::AddLine(XLine* line, User* user) LookupIter i = x->second.find(line->Displayable()); if (i != x->second.end()) { - // XLine propagation bug was here, if the line to be added already exists and - // it's expired then expire it and add the new one instead of returning false - if ((!i->second->duration) || (ServerInstance->Time() < i->second->expiry)) - return false; + bool silent = false; - ExpireLine(x, i); + // Allow replacing a config line for an updated config line. + if (i->second->from_config && line->from_config) + { + // Nothing changed, skip adding this one. + if (i->second->reason == line->reason) + return false; + + silent = true; + } + // Allow replacing a non-config line for a new config line. + else if (!line->from_config) + { + // X-line propagation bug was here, if the line to be added already exists and + // it's expired then expire it and add the new one instead of returning false + if ((!i->second->duration) || (ServerInstance->Time() < i->second->expiry)) + return false; + } + else + { + silent = true; + } + + ExpireLine(x, i, silent); } } @@ -403,11 +422,13 @@ XLine* XLineManager::MatchesLine(const std::string &type, const std::string &pat } // removes lines that have expired -void XLineManager::ExpireLine(ContainerIter container, LookupIter item) +void XLineManager::ExpireLine(ContainerIter container, LookupIter item, bool silent) { FOREACH_MOD(OnExpireLine, (item->second)); - item->second->DisplayExpiry(); + if (!silent) + item->second->DisplayExpiry(); + item->second->Unset(); /* TODO: Can we skip this loop by having a 'pending' field in the XLine class, which is set when a line @@ -750,23 +771,23 @@ XLineFactory* XLineManager::GetFactory(const std::string &type) return n->second; } -void XLineManager::ClearConfigLines() +void XLineManager::ExpireRemovedConfigLines(const std::string& type, const insp::flat_set& configlines) { // Nothing to do. if (lookup_lines.empty()) return; - ServerInstance->SNO->WriteToSnoMask('x', "Server rehashing; expiring lines defined in the server config ..."); - for (ContainerIter type = lookup_lines.begin(); type != lookup_lines.end(); ++type) + ContainerIter xlines = lookup_lines.find(type); + if (xlines == lookup_lines.end()) + return; + + for (LookupIter xline = xlines->second.begin(); xline != xlines->second.end(); ) { - for (LookupIter xline = type->second.begin(); xline != type->second.end(); ) - { - // We cache this to avoid iterator invalidation. - LookupIter cachedxline = xline++; - if (cachedxline->second->from_config) - { - ExpireLine(type, cachedxline); - } - } + LookupIter cachedxline = xline++; + if (!cachedxline->second->from_config) + continue; + + if (!configlines.count(cachedxline->second->Displayable())) + ExpireLine(xlines, cachedxline); } } -- cgit v1.3.1-10-gc9f91 From dfb1e0da7823641ad648f9fbd19b43d2e6b0d7ad Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Tue, 12 Mar 2019 09:48:28 -0500 Subject: Add Who::Request::GetFlagIndex to get field index Replaces the dirty logic in m_hideoper and m_namesx --- include/modules/who.h | 11 +++++++++++ src/coremods/core_who.cpp | 22 ++++++++++++++++++++++ src/modules/m_hideoper.cpp | 19 +++---------------- src/modules/m_namesx.cpp | 19 +++---------------- 4 files changed, 39 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/include/modules/who.h b/include/modules/who.h index 4fcbe5f91..8fd2dab08 100644 --- a/include/modules/who.h +++ b/include/modules/who.h @@ -71,6 +71,17 @@ class Who::Request /** A user specified label for the WHOX response. */ std::string whox_querytype; + /** Get the index in the response parameters for the different data fields + * + * The fields 'r' (realname) and 'd' (hops) will always be missing in a non-WHOX + * query, because WHOX splits them to 2 fields, where old WHO has them as one. + * + * @param flag The field name to look for + * @param out The index will be stored in this value + * @return True if the field is available, false otherwise + */ + virtual bool GetFlagIndex(char flag, size_t& out) const = 0; + protected: Request() : fuzzy_match(false) diff --git a/src/coremods/core_who.cpp b/src/coremods/core_who.cpp index bf00b741f..f32ef77b3 100644 --- a/src/coremods/core_who.cpp +++ b/src/coremods/core_who.cpp @@ -34,8 +34,19 @@ enum RPL_WHOSPCRPL = 354 }; +static const char whox_field_order[] = "tcuihsnfdlaor"; +static const char who_field_order[] = "cuhsnf"; + struct WhoData : public Who::Request { + std::string query_flag_order; + + bool GetFlagIndex(char flag, size_t& out) const CXX11_OVERRIDE + { + out = query_flag_order.find(flag); + return out != std::string::npos; + } + WhoData(const CommandBase::Params& parameters) { // Find the matchtext and swap the 0 for a * so we can use InspIRCd::Match on it. @@ -74,6 +85,17 @@ struct WhoData : public Who::Request current_bitset->set(chr); } } + + if (whox) + { + for (const char *c = whox_field_order; c; c++) + { + if (whox_fields[*c]) + query_flag_order.push_back(*c); + } + } + else + query_flag_order = who_field_order; } }; diff --git a/src/modules/m_hideoper.cpp b/src/modules/m_hideoper.cpp index f04d88809..8feb1a852 100644 --- a/src/modules/m_hideoper.cpp +++ b/src/modules/m_hideoper.cpp @@ -123,22 +123,9 @@ class ModuleHideOper if (request.flags['o']) return MOD_RES_DENY; - size_t flag_index = 5; - if (request.whox) - { - // We only need to fiddle with the flags if they are present. - if (!request.whox_fields['f']) - return MOD_RES_PASSTHRU; - - // WHOX makes this a bit tricky as we need to work out the parameter which the flags are in. - flag_index = 0; - static const char* flags = "tcuihsn"; - for (size_t i = 0; i < strlen(flags); ++i) - { - if (request.whox_fields[flags[i]]) - flag_index += 1; - } - } + size_t flag_index; + if (!request.GetFlagIndex('f', flag_index)) + return MOD_RES_PASSTHRU; // hide the "*" that marks the user as an oper from the /WHO line // #chan ident localhost insp22.test nick H@ :0 Attila diff --git a/src/modules/m_namesx.cpp b/src/modules/m_namesx.cpp index defb66b78..1e051e75c 100644 --- a/src/modules/m_namesx.cpp +++ b/src/modules/m_namesx.cpp @@ -84,22 +84,9 @@ class ModuleNamesX if (prefixes.length() <= 1) return MOD_RES_PASSTHRU; - size_t flag_index = 5; - if (request.whox) - { - // We only need to fiddle with the flags if they are present. - if (!request.whox_fields['f']) - return MOD_RES_PASSTHRU; - - // WHOX makes this a bit tricky as we need to work out the parameter which the flags are in. - flag_index = 0; - static const char* flags = "tcuihsn"; - for (size_t i = 0; i < strlen(flags); ++i) - { - if (request.whox_fields[flags[i]]) - flag_index += 1; - } - } + size_t flag_index; + if (!request.GetFlagIndex('f', flag_index)) + return MOD_RES_PASSTHRU; // #chan ident localhost insp22.test nick H@ :0 Attila if (numeric.GetParams().size() <= flag_index) -- cgit v1.3.1-10-gc9f91 From 1003c593bfd455734a8f39f137d4ce68e7e87ca8 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Tue, 12 Mar 2019 12:04:01 -0500 Subject: Rename GetFlagIndex -> GetFieldIndex --- include/modules/who.h | 2 +- src/coremods/core_who.cpp | 2 +- src/modules/m_hideoper.cpp | 2 +- src/modules/m_namesx.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/modules/who.h b/include/modules/who.h index 8fd2dab08..983cece46 100644 --- a/include/modules/who.h +++ b/include/modules/who.h @@ -80,7 +80,7 @@ class Who::Request * @param out The index will be stored in this value * @return True if the field is available, false otherwise */ - virtual bool GetFlagIndex(char flag, size_t& out) const = 0; + virtual bool GetFieldIndex(char flag, size_t& out) const = 0; protected: Request() diff --git a/src/coremods/core_who.cpp b/src/coremods/core_who.cpp index 52af2d2ce..d6df6de20 100644 --- a/src/coremods/core_who.cpp +++ b/src/coremods/core_who.cpp @@ -39,7 +39,7 @@ static const char who_field_order[] = "cuhsnf"; struct WhoData : public Who::Request { - bool GetFlagIndex(char flag, size_t& out) const CXX11_OVERRIDE + bool GetFieldIndex(char flag, size_t& out) const CXX11_OVERRIDE { if (!whox) { diff --git a/src/modules/m_hideoper.cpp b/src/modules/m_hideoper.cpp index 8feb1a852..d78ed538b 100644 --- a/src/modules/m_hideoper.cpp +++ b/src/modules/m_hideoper.cpp @@ -124,7 +124,7 @@ class ModuleHideOper return MOD_RES_DENY; size_t flag_index; - if (!request.GetFlagIndex('f', flag_index)) + if (!request.GetFieldIndex('f', flag_index)) return MOD_RES_PASSTHRU; // hide the "*" that marks the user as an oper from the /WHO line diff --git a/src/modules/m_namesx.cpp b/src/modules/m_namesx.cpp index 1e051e75c..ac15c9723 100644 --- a/src/modules/m_namesx.cpp +++ b/src/modules/m_namesx.cpp @@ -85,7 +85,7 @@ class ModuleNamesX return MOD_RES_PASSTHRU; size_t flag_index; - if (!request.GetFlagIndex('f', flag_index)) + if (!request.GetFieldIndex('f', flag_index)) return MOD_RES_PASSTHRU; // #chan ident localhost insp22.test nick H@ :0 Attila -- cgit v1.3.1-10-gc9f91 From bdded70ac222c997aea8e8fefb029571398c611e Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Sat, 30 Mar 2019 11:53:51 +0000 Subject: Rename OnClientProtocolPopulateTags to OnPopulateTags. --- include/clientprotocol.h | 2 +- include/modules/ircv3.h | 2 +- src/clientprotocol.cpp | 2 +- src/modules/m_botmode.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/clientprotocol.h b/include/clientprotocol.h index ec033e166..44896a3a3 100644 --- a/include/clientprotocol.h +++ b/include/clientprotocol.h @@ -537,7 +537,7 @@ class ClientProtocol::MessageTagProvider : public Events::ModuleEventListener * The default implementation does nothing. * @param msg Message to be populated with tags. */ - virtual void OnClientProtocolPopulateTags(ClientProtocol::Message& msg) + virtual void OnPopulateTags(ClientProtocol::Message& msg) { } diff --git a/include/modules/ircv3.h b/include/modules/ircv3.h index 9729e8ed5..ce2b70da7 100644 --- a/include/modules/ircv3.h +++ b/include/modules/ircv3.h @@ -75,7 +75,7 @@ class IRCv3::CapTag : public ClientProtocol::MessageTagProvider return cap.get(user); } - void OnClientProtocolPopulateTags(ClientProtocol::Message& msg) CXX11_OVERRIDE + void OnPopulateTags(ClientProtocol::Message& msg) CXX11_OVERRIDE { T& tag = static_cast(*this); const std::string* const val = tag.GetValue(msg); diff --git a/src/clientprotocol.cpp b/src/clientprotocol.cpp index 212d65d6b..ee3909fbf 100644 --- a/src/clientprotocol.cpp +++ b/src/clientprotocol.cpp @@ -63,7 +63,7 @@ const ClientProtocol::SerializedMessage& ClientProtocol::Serializer::SerializeFo if (!msg.msginit_done) { msg.msginit_done = true; - FOREACH_MOD_CUSTOM(evprov, MessageTagProvider, OnClientProtocolPopulateTags, (msg)); + FOREACH_MOD_CUSTOM(evprov, MessageTagProvider, OnPopulateTags, (msg)); } return msg.GetSerialized(Message::SerializedInfo(this, MakeTagWhitelist(user, msg.GetTags()))); } diff --git a/src/modules/m_botmode.cpp b/src/modules/m_botmode.cpp index 1007f7ca1..44241e82c 100644 --- a/src/modules/m_botmode.cpp +++ b/src/modules/m_botmode.cpp @@ -43,7 +43,7 @@ class BotTag : public ClientProtocol::MessageTagProvider { } - void OnClientProtocolPopulateTags(ClientProtocol::Message& msg) CXX11_OVERRIDE + void OnPopulateTags(ClientProtocol::Message& msg) CXX11_OVERRIDE { User* const user = msg.GetSourceUser(); if (user && user->IsModeSet(botmode)) -- cgit v1.3.1-10-gc9f91