]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/clientprotocol.cpp
Rename OnClientProtocolPopulateTags to OnPopulateTags.
[user/henk/code/inspircd.git] / src / clientprotocol.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2016 Attila Molnar <attilamolnar@hush.com>
5  *
6  * This file is part of InspIRCd.  InspIRCd is free software: you can
7  * redistribute it and/or modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation, version 2.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19
20 #include "inspircd.h"
21
22 ClientProtocol::Serializer::Serializer(Module* mod, const char* Name)
23         : DataProvider(mod, std::string("serializer/") + Name)
24         , evprov(mod, "event/messagetag")
25 {
26 }
27
28 bool ClientProtocol::Serializer::HandleTag(LocalUser* user, const std::string& tagname, std::string& tagvalue, TagMap& tags) const
29 {
30         // Catch and block empty tags
31         if (tagname.empty())
32                 return false;
33
34         const ::Events::ModuleEventProvider::SubscriberList& list = evprov.GetSubscribers();
35         for (::Events::ModuleEventProvider::SubscriberList::const_iterator i = list.begin(); i != list.end(); ++i)
36         {
37                 MessageTagProvider* const tagprov = static_cast<MessageTagProvider*>(*i);
38                 const ModResult res = tagprov->OnProcessTag(user, tagname, tagvalue);
39                 if (res == MOD_RES_ALLOW)
40                         return tags.insert(std::make_pair(tagname, MessageTagData(tagprov, tagvalue))).second;
41                 else if (res == MOD_RES_DENY)
42                         break;
43         }
44
45         // No module handles the tag but that's not an error
46         return true;
47 }
48
49 ClientProtocol::TagSelection ClientProtocol::Serializer::MakeTagWhitelist(LocalUser* user, const TagMap& tagmap) const
50 {
51         TagSelection tagwl;
52         for (TagMap::const_iterator i = tagmap.begin(); i != tagmap.end(); ++i)
53         {
54                 const MessageTagData& tagdata = i->second;
55                 if (tagdata.tagprov->ShouldSendTag(user, tagdata))
56                         tagwl.Select(tagmap, i);
57         }
58         return tagwl;
59 }
60
61 const ClientProtocol::SerializedMessage& ClientProtocol::Serializer::SerializeForUser(LocalUser* user, Message& msg)
62 {
63         if (!msg.msginit_done)
64         {
65                 msg.msginit_done = true;
66                 FOREACH_MOD_CUSTOM(evprov, MessageTagProvider, OnPopulateTags, (msg));
67         }
68         return msg.GetSerialized(Message::SerializedInfo(this, MakeTagWhitelist(user, msg.GetTags())));
69 }
70
71 const ClientProtocol::SerializedMessage& ClientProtocol::Message::GetSerialized(const SerializedInfo& serializeinfo) const
72 {
73         // First check if the serialized line they're asking for is in the cache
74         for (SerializedList::const_iterator i = serlist.begin(); i != serlist.end(); ++i)
75         {
76                 const SerializedInfo& curr = i->first;
77                 if (curr == serializeinfo)
78                         return i->second;
79         }
80
81         // Not cached, generate it and put it in the cache for later use
82         serlist.push_back(std::make_pair(serializeinfo, serializeinfo.serializer->Serialize(*this, serializeinfo.tagwl)));
83         return serlist.back().second;
84 }
85
86 void ClientProtocol::Event::GetMessagesForUser(LocalUser* user, MessageList& messagelist)
87 {
88         if (!eventinit_done)
89         {
90                 eventinit_done = true;
91                 FOREACH_MOD_CUSTOM(*event, EventHook, OnEventInit, (*this));
92         }
93
94         // Most of the time there's only a single message but in rare cases there are more
95         if (initialmsg)
96                 messagelist.assign(1, initialmsg);
97         else
98                 messagelist = *initialmsglist;
99
100         // Let modules modify the message list
101         ModResult res;
102         FIRST_MOD_RESULT_CUSTOM(*event, EventHook, OnPreEventSend, res, (user, *this, messagelist));
103         if (res == MOD_RES_DENY)
104                 messagelist.clear();
105 }