From 889d521e05f2e922683d48c74eb00290e7a2f548 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Wed, 17 Jul 2024 00:06:50 +0100 Subject: Shuffle the modules about a bit. --- modules/ircv3_echomessage.cpp | 168 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 modules/ircv3_echomessage.cpp (limited to 'modules/ircv3_echomessage.cpp') diff --git a/modules/ircv3_echomessage.cpp b/modules/ircv3_echomessage.cpp new file mode 100644 index 000000000..41391dbec --- /dev/null +++ b/modules/ircv3_echomessage.cpp @@ -0,0 +1,168 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2019 linuxdaemon + * Copyright (C) 2018-2024 Sadie Powell + * Copyright (C) 2015, 2018 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 "clientprotocolmsg.h" +#include "modules/cap.h" +#include "modules/ctctags.h" + +class EchoTag final + : public ClientProtocol::MessageTagProvider +{ +private: + CTCTags::CapReference stdrplcap; + +public: + Cap::Capability echomsgcap; + + EchoTag(Module* Creator) + : ClientProtocol::MessageTagProvider(Creator) + , stdrplcap(Creator) + , echomsgcap(Creator, "echo-message") + { + } + + bool ShouldSendTag(LocalUser* user, const ClientProtocol::MessageTagData& tagdata) final + { + return stdrplcap.IsEnabled(user) && echomsgcap.IsEnabled(user); + } +}; + +class ModuleIRCv3EchoMessage final + : public Module + , public CTCTags::EventListener +{ +private: + EchoTag echotag; + ClientProtocol::EventProvider tagmsgprov; + + void AddEchoTag(ClientProtocol::Message& msg) + { + msg.AddTag("inspircd.org/echo", &echotag, ""); + } + +public: + ModuleIRCv3EchoMessage() + : Module(VF_VENDOR, "Provides the IRCv3 echo-message client capability.") + , CTCTags::EventListener(this) + , echotag(this) + , tagmsgprov(this, "TAGMSG") + { + } + + void OnUserPostMessage(User* user, const MessageTarget& target, const MessageDetails& details) override + { + if (!echotag.echomsgcap.IsEnabled(user) || !details.echo) + return; + + // Caps are only set on local users + LocalUser* const localuser = static_cast(user); + + const std::string& text = details.echo_original ? details.original_text : details.text; + const ClientProtocol::TagMap& tags = details.echo_original ? details.tags_in : details.tags_out; + switch (target.type) + { + case MessageTarget::TYPE_USER: + { + const auto* destuser = target.Get(); + ClientProtocol::Messages::Privmsg privmsg(ClientProtocol::Messages::Privmsg::nocopy, user, destuser, text, details.type); + privmsg.AddTags(tags); + AddEchoTag(privmsg); + localuser->Send(ServerInstance->GetRFCEvents().privmsg, privmsg); + break; + } + case MessageTarget::TYPE_CHANNEL: + { + const auto* chan = target.Get(); + const char status = details.echo_original ? target.original_status : target.status; + ClientProtocol::Messages::Privmsg privmsg(ClientProtocol::Messages::Privmsg::nocopy, user, chan, text, details.type, status); + privmsg.AddTags(tags); + AddEchoTag(privmsg); + localuser->Send(ServerInstance->GetRFCEvents().privmsg, privmsg); + break; + } + case MessageTarget::TYPE_SERVER: + { + const auto* servername = target.Get(); + ClientProtocol::Messages::Privmsg privmsg(ClientProtocol::Messages::Privmsg::nocopy, user, *servername, text, details.type); + privmsg.AddTags(tags); + AddEchoTag(privmsg); + localuser->Send(ServerInstance->GetRFCEvents().privmsg, privmsg); + break; + } + } + } + + void OnUserPostTagMessage(User* user, const MessageTarget& target, const CTCTags::TagMessageDetails& details) override + { + if (!echotag.echomsgcap.IsEnabled(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; + switch (target.type) + { + case MessageTarget::TYPE_USER: + { + const auto* destuser = target.Get(); + CTCTags::TagMessage message(user, destuser, tags); + AddEchoTag(message); + localuser->Send(tagmsgprov, message); + break; + } + case MessageTarget::TYPE_CHANNEL: + { + const auto* chan = target.Get(); + const char status = details.echo_original ? target.original_status : target.status; + CTCTags::TagMessage message(user, chan, tags, status); + AddEchoTag(message); + localuser->Send(tagmsgprov, message); + break; + } + case MessageTarget::TYPE_SERVER: + { + const auto* servername = target.Get(); + CTCTags::TagMessage message(user, servername->c_str(), tags); + AddEchoTag(message); + localuser->Send(tagmsgprov, message); + break; + } + } + } + + void OnUserMessageBlocked(User* user, const MessageTarget& target, const MessageDetails& details) override + { + // Prevent spammers from knowing that their spam was blocked. + if (details.echo_original) + OnUserPostMessage(user, target, details); + } + + void OnUserTagMessageBlocked(User* user, const MessageTarget& target, const CTCTags::TagMessageDetails& details) override + { + // Prevent spammers from knowing that their spam was blocked. + if (details.echo_original) + OnUserPostTagMessage(user, target, details); + } +}; + +MODULE_INIT(ModuleIRCv3EchoMessage) -- cgit v1.3.1-10-gc9f91