]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_ircv3_echomessage.cpp
Implement support for IRCv3 client-to-client tags.
[user/henk/code/inspircd.git] / src / modules / m_ircv3_echomessage.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2015 Attila Molnar <attilamolnar@hush.com>
5  *   Copyright (C) 2013-2015 Peter Powell <petpow@saberuk.com>
6  *
7  * This file is part of InspIRCd.  InspIRCd is free software: you can
8  * redistribute it and/or modify it under the terms of the GNU General Public
9  * License as published by the Free Software Foundation, version 2.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20
21 #include "inspircd.h"
22 #include "modules/cap.h"
23 #include "modules/ctctags.h"
24
25 class ModuleIRCv3EchoMessage
26         : public Module
27         , public CTCTags::EventListener
28 {
29  private:
30         Cap::Capability cap;
31         ClientProtocol::EventProvider tagmsgprov;
32
33  public:
34         ModuleIRCv3EchoMessage()
35                 : CTCTags::EventListener(this)
36                 , cap(this, "echo-message")
37                 , tagmsgprov(this, "TAGMSG")
38         {
39         }
40
41         void OnUserPostMessage(User* user, const MessageTarget& target, const MessageDetails& details) CXX11_OVERRIDE
42         {
43                 if (!cap.get(user) || !details.echo)
44                         return;
45
46                 // Caps are only set on local users
47                 LocalUser* const localuser = static_cast<LocalUser*>(user);
48
49                 const std::string& text = details.echo_original ? details.original_text : details.text;
50                 const ClientProtocol::TagMap& tags = details.echo_original ? details.tags_in : details.tags_out;
51                 if (target.type == MessageTarget::TYPE_USER)
52                 {
53                         User* destuser = target.Get<User>();
54                         ClientProtocol::Messages::Privmsg privmsg(ClientProtocol::Messages::Privmsg::nocopy, user, destuser, text, details.type);
55                         privmsg.AddTags(tags);
56                         localuser->Send(ServerInstance->GetRFCEvents().privmsg, privmsg);
57                 }
58                 else if (target.type == MessageTarget::TYPE_CHANNEL)
59                 {
60                         Channel* chan = target.Get<Channel>();
61                         ClientProtocol::Messages::Privmsg privmsg(ClientProtocol::Messages::Privmsg::nocopy, user, chan, text, details.type, target.status);
62                         privmsg.AddTags(tags);
63                         localuser->Send(ServerInstance->GetRFCEvents().privmsg, privmsg);
64                 }
65                 else
66                 {
67                         const std::string* servername = target.Get<std::string>();
68                         ClientProtocol::Messages::Privmsg privmsg(ClientProtocol::Messages::Privmsg::nocopy, user, *servername, text, details.type);
69                         privmsg.AddTags(tags);
70                         localuser->Send(ServerInstance->GetRFCEvents().privmsg, privmsg);
71                 }
72         }
73
74         void OnUserPostTagMessage(User* user, const MessageTarget& target, const CTCTags::TagMessageDetails& details) CXX11_OVERRIDE
75         {
76                 if (!cap.get(user) || !details.echo)
77                         return;
78
79                 // Caps are only set on local users
80                 LocalUser* const localuser = static_cast<LocalUser*>(user);
81
82                 const ClientProtocol::TagMap& tags = details.echo_original ? details.tags_in : details.tags_out;
83                 if (target.type == MessageTarget::TYPE_USER)
84                 {
85                         User* destuser = target.Get<User>();
86                         CTCTags::TagMessage message(user, destuser, tags);
87                         localuser->Send(tagmsgprov, message);
88                 }
89                 else if (target.type == MessageTarget::TYPE_CHANNEL)
90                 {
91                         Channel* chan = target.Get<Channel>();
92                         CTCTags::TagMessage message(user, chan, tags);
93                         localuser->Send(tagmsgprov, message);
94                 }
95                 else
96                 {
97                         const std::string* servername = target.Get<std::string>();
98                         CTCTags::TagMessage message(user, servername->c_str(), tags);
99                         localuser->Send(tagmsgprov, message);
100                 }
101         }
102
103         void OnUserMessageBlocked(User* user, const MessageTarget& target, const MessageDetails& details) CXX11_OVERRIDE
104         {
105                 // Prevent spammers from knowing that their spam was blocked.
106                 if (details.echo_original)
107                         OnUserPostMessage(user, target, details);
108         }
109
110         void OnUserTagMessageBlocked(User* user, const MessageTarget& target, const CTCTags::TagMessageDetails& details) CXX11_OVERRIDE
111         {
112                 // Prevent spammers from knowing that their spam was blocked.
113                 if (details.echo_original)
114                         OnUserPostTagMessage(user, target, details);
115         }
116
117         Version GetVersion() CXX11_OVERRIDE
118         {
119                 return Version("Provides the echo-message IRCv3 extension", VF_VENDOR);
120         }
121 };
122
123 MODULE_INIT(ModuleIRCv3EchoMessage)