summaryrefslogtreecommitdiff
path: root/src/clientprotocol.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/clientprotocol.cpp')
-rw-r--r--src/clientprotocol.cpp105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/clientprotocol.cpp b/src/clientprotocol.cpp
new file mode 100644
index 000000000..a732855a5
--- /dev/null
+++ b/src/clientprotocol.cpp
@@ -0,0 +1,105 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2016 Attila Molnar <attilamolnar@hush.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/>.
+ */
+
+
+#include "inspircd.h"
+
+ClientProtocol::Serializer::Serializer(Module* mod, const char* Name)
+ : DataProvider(mod, std::string("serializer/") + Name)
+ , evprov(mod, "event/messagetag")
+{
+}
+
+bool ClientProtocol::Serializer::HandleTag(LocalUser* user, const std::string& tagname, std::string& tagvalue, TagMap& tags) const
+{
+ // Catch and block empty tags
+ if (tagname.empty())
+ return false;
+
+ const ::Events::ModuleEventProvider::SubscriberList& list = evprov.GetSubscribers();
+ for (::Events::ModuleEventProvider::SubscriberList::const_iterator i = list.begin(); i != list.end(); ++i)
+ {
+ MessageTagProvider* const tagprov = static_cast<MessageTagProvider*>(*i);
+ const ModResult res = tagprov->OnClientProtocolProcessTag(user, tagname, tagvalue);
+ if (res == MOD_RES_ALLOW)
+ return tags.insert(std::make_pair(tagname, MessageTagData(tagprov, tagvalue))).second;
+ else if (res == MOD_RES_DENY)
+ break;
+ }
+
+ // No module handles the tag but that's not an error
+ return true;
+}
+
+ClientProtocol::TagSelection ClientProtocol::Serializer::MakeTagWhitelist(LocalUser* user, const TagMap& tagmap) const
+{
+ TagSelection tagwl;
+ for (TagMap::const_iterator i = tagmap.begin(); i != tagmap.end(); ++i)
+ {
+ const MessageTagData& tagdata = i->second;
+ if (tagdata.tagprov->ShouldSendTag(user, tagdata))
+ tagwl.Select(tagmap, i);
+ }
+ return tagwl;
+}
+
+const ClientProtocol::SerializedMessage& ClientProtocol::Serializer::SerializeForUser(LocalUser* user, Message& msg)
+{
+ if (!msg.msginit_done)
+ {
+ msg.msginit_done = true;
+ FOREACH_MOD_CUSTOM(evprov, MessageTagProvider, OnClientProtocolPopulateTags, (msg));
+ }
+ return msg.GetSerialized(Message::SerializedInfo(this, MakeTagWhitelist(user, msg.GetTags())));
+}
+
+const ClientProtocol::SerializedMessage& ClientProtocol::Message::GetSerialized(const SerializedInfo& serializeinfo) const
+{
+ // First check if the serialized line they're asking for is in the cache
+ for (SerializedList::const_iterator i = serlist.begin(); i != serlist.end(); ++i)
+ {
+ const SerializedInfo& curr = i->first;
+ if (curr == serializeinfo)
+ return i->second;
+ }
+
+ // Not cached, generate it and put it in the cache for later use
+ serlist.push_back(std::make_pair(serializeinfo, serializeinfo.serializer->Serialize(*this, serializeinfo.tagwl)));
+ return serlist.back().second;
+}
+
+void ClientProtocol::Event::GetMessagesForUser(LocalUser* user, MessageList& messagelist)
+{
+ if (!eventinit_done)
+ {
+ eventinit_done = true;
+ FOREACH_MOD_CUSTOM(*event, EventHook, OnEventInit, (*this));
+ }
+
+ // Most of the time there's only a single message but in rare cases there are more
+ if (initialmsg)
+ messagelist.assign(1, initialmsg);
+ else
+ messagelist = *initialmsglist;
+
+ // Let modules modify the message list
+ ModResult res;
+ FIRST_MOD_RESULT_CUSTOM(*event, EventHook, OnPreEventSend, res, (user, *this, messagelist));
+ if (res == MOD_RES_DENY)
+ messagelist.clear();
+}