]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Fix the chanhistory module being inconsistent across servers.
authorPeter Powell <petpow@saberuk.com>
Sat, 29 Sep 2018 15:19:26 +0000 (16:19 +0100)
committerPeter Powell <petpow@saberuk.com>
Mon, 1 Oct 2018 11:34:47 +0000 (12:34 +0100)
Closes #331.

include/modules/server.h
src/modules/m_chanhistory.cpp
src/modules/m_spanningtree/utils.cpp

index 99bd2ee1d26ecb44f2b6f8c2826fb45802016a36..54ea5d58cca3fd2cc89896a12746de020c087e43 100644 (file)
@@ -29,6 +29,14 @@ class ServerEventListener : public Events::ModuleEventListener
        {
        }
 
+       /** Fired when a channel message is being broadcast across the network.
+        * @param channel The channel which is having a message sent to it.
+        * @param server The server which might have a message broadcast to it.
+        * @return Either MOD_RES_ALLOW to always send the message to the server, MOD_RES_DENY to never
+        *         send the message to the server or MOD_RES_PASSTHRU if no module handled the event.
+        */
+       virtual ModResult OnBroadcastMessage(Channel* channel, const Server* server) { return MOD_RES_PASSTHRU; }
+
        /** Fired when a server finishes burst
         * @param server Server that recently linked and finished burst
         */
index fe4bd94777374897551940fef5c0b058e43d4b0b..06840744b1e7269ad7d9806bee8079def89720e6 100644 (file)
@@ -20,6 +20,7 @@
 #include "inspircd.h"
 #include "modules/ircv3_servertime.h"
 #include "modules/ircv3_batch.h"
+#include "modules/server.h"
 
 struct HistoryItem
 {
@@ -118,7 +119,9 @@ class HistoryMode : public ParamMode<HistoryMode, SimpleExtItem<HistoryList> >
        }
 };
 
-class ModuleChanHistory : public Module
+class ModuleChanHistory
+       : public Module
+       , public ServerEventListener
 {
        HistoryMode m;
        bool sendnotice;
@@ -131,7 +134,8 @@ class ModuleChanHistory : public Module
 
  public:
        ModuleChanHistory()
-               : m(this)
+               : ServerEventListener(this)
+               , m(this)
                , botmode(this, "bot")
                , batchcap(this)
                , batchmanager(this)
@@ -148,6 +152,11 @@ class ModuleChanHistory : public Module
                dobots = tag->getBool("bots", true);
        }
 
+       ModResult OnBroadcastMessage(Channel* channel, const Server* server) CXX11_OVERRIDE
+       {
+               return channel->IsModeSet(m) ? MOD_RES_ALLOW : MOD_RES_PASSTHRU;
+       }
+
        void OnUserPostMessage(User* user, const MessageTarget& target, const MessageDetails& details) CXX11_OVERRIDE
        {
                if ((target.type == MessageTarget::TYPE_CHANNEL) && (target.status == 0) && (details.type == MSG_PRIVMSG))
index cde627e21af47aa26b4be649d911a307b71f1e21..61a6868b36a51553d06501ede17252fbbc62de88 100644 (file)
@@ -28,6 +28,7 @@
 #include "treesocket.h"
 #include "resolvers.h"
 #include "commandbuilder.h"
+#include "modules/server.h"
 
 SpanningTreeUtilities* Utils = NULL;
 
@@ -144,6 +145,7 @@ void SpanningTreeUtilities::GetListOfServersForChannel(Channel* c, TreeSocketSet
                        minrank = mh->GetPrefixRank();
        }
 
+       TreeServer::ChildServers children = TreeRoot->GetChildren();
        const Channel::MemberMap& ulist = c->GetUsers();
        for (Channel::MemberMap::const_iterator i = ulist.begin(); i != ulist.end(); ++i)
        {
@@ -157,9 +159,22 @@ void SpanningTreeUtilities::GetListOfServersForChannel(Channel* c, TreeSocketSet
                {
                        TreeServer* best = TreeServer::Get(i->first);
                        list.insert(best->GetSocket());
+
+                       TreeServer::ChildServers::iterator citer = std::find(children.begin(), children.end(), best);
+                       if (citer != children.end())
+                               children.erase(citer);
                }
        }
-       return;
+
+       // Check whether the servers which do not have users in the channel might need this message. This
+       // is used to keep the chanhistory module synchronised between servers.
+       for (TreeServer::ChildServers::const_iterator i = children.begin(); i != children.end(); ++i)
+       {
+               ModResult result;
+               FIRST_MOD_RESULT_CUSTOM(Creator->GetEventProvider(), ServerEventListener, OnBroadcastMessage, result, (c, *i));
+               if (result == MOD_RES_ALLOW)
+                       list.insert((*i)->GetSocket());
+       }
 }
 
 void SpanningTreeUtilities::DoOneToAllButSender(const CmdBuilder& params, TreeServer* omitroute)