]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Unset all extensions and the topic when lowering TS on a channel
authorAttila Molnar <attilamolnar@hush.com>
Mon, 6 Jan 2014 12:29:10 +0000 (13:29 +0100)
committerAttila Molnar <attilamolnar@hush.com>
Mon, 6 Jan 2014 12:29:10 +0000 (13:29 +0100)
include/extensible.h
src/base.cpp
src/modules/m_spanningtree/commands.h
src/modules/m_spanningtree/fjoin.cpp

index e062f66a5131aab399d72a6fb219e4370fdb7524..4e6721414219b9237b34a173a536cc8b847e7f10 100644 (file)
@@ -94,6 +94,11 @@ class CoreExport Extensible : public classbase
        virtual CullResult cull();
        virtual ~Extensible();
        void doUnhookExtensions(const std::vector<reference<ExtensionItem> >& toRemove);
+
+       /**
+        * Free all extension items attached to this Extensible
+        */
+       void FreeAllExtItems();
 };
 
 class CoreExport ExtensionManager
index db8d9f3cfe3dfd836314d41a6f1ca7677fc9090b..211dc201508d4de41c73275522dcbf2ef9b594be 100644 (file)
@@ -186,13 +186,18 @@ Extensible::Extensible()
 }
 
 CullResult Extensible::cull()
+{
+       FreeAllExtItems();
+       return classbase::cull();
+}
+
+void Extensible::FreeAllExtItems()
 {
        for(ExtensibleStore::iterator i = extensions.begin(); i != extensions.end(); ++i)
        {
                i->first->free(i->second);
        }
        extensions.clear();
-       return classbase::cull();
 }
 
 Extensible::~Extensible()
index 9690eba46a4ca8d60cbd3cfb927ce6f9c42f4fb4..97322ed99b9db2b85fff89a02dbe2dc3bae9b96e 100644 (file)
@@ -129,6 +129,15 @@ class CommandFJoin : public ServerCommand
         */
        static void RemoveStatus(Channel* c);
        static void ApplyModeStack(User* srcuser, Channel* c, irc::modestacker& stack);
+
+       /**
+        * Lowers the TS on the given channel: removes all modes, unsets all extensions,
+        * clears the topic and removes all pending invites.
+        * @param chan The target channel whose TS to lower
+        * @param TS The new TS to set
+        * @param newname The new name of the channel; must be the same or a case change of the current name
+        */
+       static void LowerTS(Channel* chan, time_t TS, const std::string& newname);
        bool ProcessModeUUIDPair(const std::string& item, TreeSocket* src_socket, Channel* chan, irc::modestacker* modestack);
  public:
        CommandFJoin(Module* Creator) : ServerCommand(Creator, "FJOIN", 3) { }
index 47d8efb82cd47d8baa41bec011c8ba0d1e03afee..d697af63d52f1d93d37b7d35bf14de6887d34d84 100644 (file)
@@ -99,16 +99,8 @@ CmdResult CommandFJoin::Handle(User* srcuser, std::vector<std::string>& params)
                        }
                        else if (ourTS > TS)
                        {
-                               /* Our TS greater than theirs, clear all our modes from the channel, accept theirs. */
-                               if (Utils->AnnounceTSChange)
-                                       chan->WriteChannelWithServ(ServerInstance->Config->ServerName, "NOTICE %s :TS for %s changed from %lu to %lu", chan->name.c_str(), channel.c_str(), (unsigned long) ourTS, (unsigned long) TS);
-
-                               // while the name is equal in case-insensitive compare, it might differ in case; use the remote version
-                               chan->name = channel;
-                               chan->age = TS;
-                               chan->ClearInvites();
-
-                               CommandFJoin::RemoveStatus(chan);
+                               // Our TS is greater than theirs, remove all modes, extensions, etc. from the channel
+                               LowerTS(chan, TS, channel);
 
                                // XXX: If the channel does not exist in the chan hash at this point, create it so the remote modes can be applied on it.
                                // This happens to 0-user permanent channels on the losing side, because those are removed (from the chan hash, then
@@ -248,3 +240,31 @@ void CommandFJoin::ApplyModeStack(User* srcuser, Channel* c, irc::modestacker& s
                stackresult.erase(stackresult.begin() + 1, stackresult.end());
        }
 }
+
+void CommandFJoin::LowerTS(Channel* chan, time_t TS, const std::string& newname)
+{
+       if (Utils->AnnounceTSChange)
+               chan->WriteChannelWithServ(ServerInstance->Config->ServerName, "NOTICE %s :TS for %s changed from %lu to %lu", chan->name.c_str(), newname.c_str(), (unsigned long) chan->age, (unsigned long) TS);
+
+       // While the name is equal in case-insensitive compare, it might differ in case; use the remote version
+       chan->name = newname;
+       chan->age = TS;
+
+       // Remove all pending invites
+       chan->ClearInvites();
+
+       // Clear all modes
+       CommandFJoin::RemoveStatus(chan);
+
+       // Unset all extensions
+       chan->FreeAllExtItems();
+
+       // Clear the topic, if it isn't empty then send a topic change message to local users
+       if (!chan->topic.empty())
+       {
+               chan->topic.clear();
+               chan->WriteChannelWithServ(ServerInstance->Config->ServerName, "TOPIC %s :", chan->name.c_str());
+       }
+       chan->setby.clear();
+       chan->topicset = 0;
+}