]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Deduplicate RemoveMode() implementations
authorattilamolnar <attilamolnar@hush.com>
Sun, 26 May 2013 21:23:47 +0000 (23:23 +0200)
committerattilamolnar <attilamolnar@hush.com>
Sun, 26 May 2013 23:07:29 +0000 (01:07 +0200)
The default (core) implementation can now remove prefix modes
The modestacker parameter is now mandatory

include/builtinmodes.h
include/listmode.h
include/mode.h
src/listmode.cpp
src/mode.cpp
src/modes/cmode_k.cpp
src/modes/cmode_o.cpp
src/modes/cmode_v.cpp
src/modules/m_customprefix.cpp
src/modules/m_ojoin.cpp
src/modules/m_spanningtree/fjoin.cpp

index a4a9509221ad0bac156b4df04a145e64dc160f66..46bfe282b9130b44444c52db743b724527b06c3b 100644 (file)
@@ -52,11 +52,9 @@ class ModeChannelKey : public ModeHandler
  public:
        ModeChannelKey();
        ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding);
-       void RemoveMode(Channel* channel, irc::modestacker* stack = NULL);
        void RemoveMode(User* user, irc::modestacker* stack = NULL);
 };
 
-
 /** Channel mode +l
  */
 class ModeChannelLimit : public ParamChannelModeHandler
@@ -96,7 +94,6 @@ class ModeChannelOp : public ModeHandler
        ModeChannelOp();
        ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding);
        unsigned int GetPrefixRank();
-       void RemoveMode(Channel* channel, irc::modestacker* stack = NULL);
        void RemoveMode(User* user, irc::modestacker* stack = NULL);
 };
 
@@ -140,7 +137,6 @@ class ModeChannelVoice : public ModeHandler
        ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding);
        unsigned int GetPrefixRank();
        void RemoveMode(User* user, irc::modestacker* stack = NULL);
-       void RemoveMode(Channel* channel, irc::modestacker* stack = NULL);
 };
 
 /** User mode +i
index 1c6f70d6f483c5b02eeb4016c78f551846d69d40..b4601fcbd310bdd33520cb5d42c62e6331a3de48 100644 (file)
@@ -144,10 +144,13 @@ class CoreExport ListModeBase : public ModeHandler
        virtual void DisplayEmptyList(User* user, Channel* channel);
 
        /** Remove all instances of the mode from a channel.
-        * See mode.h
+        * Populates the given modestack with modes that remove every instance of
+        * this mode from the channel.
+        * See mode.h for more details.
         * @param channel The channel to remove all instances of the mode from
+        * @param stack The mode stack to add the mode change to
         */
-       virtual void RemoveMode(Channel* channel, irc::modestacker* stack);
+       virtual void RemoveMode(Channel* channel, irc::modestacker& stack);
 
        /** Listmodes don't get set on users, no-op
        */
index b2e06257f2971e26791c0a06cf7f45fe5b2ba5c0..6afd00a86a41785765eb9c8764dd9bbfc443db9d 100644 (file)
@@ -100,6 +100,13 @@ enum ParamSpec
  */
 class CoreExport ModeHandler : public ServiceProvider
 {
+       /**
+        * Removes this prefix mode from all users on the given channel
+        * @param channel The channel which the server wants to remove your mode from
+        * @param stack The mode stack to add the mode change to
+        */
+       void RemovePrefixMode(Channel* chan, irc::modestacker& stack);
+
  protected:
        /**
         * The mode parameter translation type
@@ -280,14 +287,15 @@ class CoreExport ModeHandler : public ServiceProvider
 
        /**
         * When a MODETYPE_CHANNEL mode handler is being removed, the server will call this method for every channel on the server.
-        * Your mode handler should remove its user mode from the channel by sending the appropriate server modes using
-        * InspIRCd::SendMode(). The default implementation of this method can remove simple modes which have no parameters,
-        * and can be used when your mode is of this type, otherwise you must implement a more advanced version of it to remove
-        * your mode properly from each channel. Note that in the case of listmodes, you should remove the entire list of items.
+        * The mode handler has to populate the given modestacker with mode changes that remove the mode from the channel.
+        * The default implementation of this method can remove all kinds of channel modes except listmodes.
+        * In the case of listmodes, the entire list of items must be added to the modestacker (which is handled by ListModeBase,
+        * so if you inherit from it or your mode can be removed by the default implementation then you do not have to implement
+        * this function).
         * @param channel The channel which the server wants to remove your mode from
         * @param stack The mode stack to add the mode change to
         */
-       virtual void RemoveMode(Channel* channel, irc::modestacker* stack = NULL);
+       virtual void RemoveMode(Channel* channel, irc::modestacker& stack);
 
        inline unsigned int GetLevelRequired() const { return levelrequired; }
 };
index 555f75fa39caa6ded6e871c7215066b9fa294c70..5d54d841745476f626d0840cb9967c1dd4861f2a 100644 (file)
@@ -45,31 +45,14 @@ void ListModeBase::DisplayEmptyList(User* user, Channel* channel)
        user->WriteNumeric(endoflistnumeric, "%s %s :%s", user->nick.c_str(), channel->name.c_str(), endofliststring.c_str());
 }
 
-void ListModeBase::RemoveMode(Channel* channel, irc::modestacker* stack)
+void ListModeBase::RemoveMode(Channel* channel, irc::modestacker& stack)
 {
        ChanData* cd = extItem.get(channel);
        if (cd)
        {
-               irc::modestacker modestack(false);
-
                for (ModeList::iterator it = cd->list.begin(); it != cd->list.end(); it++)
                {
-                       if (stack)
-                               stack->Push(this->GetModeChar(), it->mask);
-                       else
-                               modestack.Push(this->GetModeChar(), it->mask);
-               }
-
-               if (stack)
-                       return;
-
-               std::vector<std::string> stackresult;
-               stackresult.push_back(channel->name);
-               while (modestack.GetStackedLine(stackresult))
-               {
-                       ServerInstance->SendMode(stackresult, ServerInstance->FakeClient);
-                       stackresult.clear();
-                       stackresult.push_back(channel->name);
+                       stack.Push(this->GetModeChar(), it->mask);
                }
        }
 }
index b4bb72c42a9480de52378bfd9e6ceb2e625e0a5d..3d0edb1850a1bd24de4dce21079f4ebd230097c7 100644 (file)
@@ -650,7 +650,17 @@ bool ModeParser::DelMode(ModeHandler* mh)
                                // The channel may not be in the hash after RemoveMode(), see m_permchannels
                                Channel* chan = i->second;
                                ++i;
-                               mh->RemoveMode(chan);
+
+                               irc::modestacker stack(false);
+                               mh->RemoveMode(chan, stack);
+
+                               std::vector<std::string> stackresult;
+                               stackresult.push_back(chan->name);
+                               while (stack.GetStackedLine(stackresult))
+                               {
+                                       ServerInstance->SendMode(stackresult, ServerInstance->FakeClient);
+                                       stackresult.erase(stackresult.begin() + 1, stackresult.end());
+                               }
                        }
                break;
        }
@@ -849,25 +859,29 @@ void ModeHandler::RemoveMode(User* user, irc::modestacker* stack)
        }
 }
 
-/** This default implementation can remove simple channel modes
- * (no parameters)
- */
-void ModeHandler::RemoveMode(Channel* channel, irc::modestacker* stack)
+void ModeHandler::RemoveMode(Channel* channel, irc::modestacker& stack)
 {
-       if (channel->IsModeSet(this->GetModeChar()))
+       if (this->GetPrefixRank())
        {
-               if (stack)
-               {
-                       stack->Push(this->GetModeChar());
-               }
+               RemovePrefixMode(channel, stack);
+       }
+       else if (channel->IsModeSet(this->GetModeChar()))
+       {
+               if (this->GetNumParams(false))
+                       // Removing this mode requires a parameter
+                       stack.Push(this->GetModeChar(), channel->GetModeParameter(this->GetModeChar()));
                else
-               {
-                       std::vector<std::string> parameters;
-                       parameters.push_back(channel->name);
-                       parameters.push_back("-");
-                       parameters[1].push_back(this->GetModeChar());
-                       ServerInstance->SendMode(parameters, ServerInstance->FakeClient);
-               }
+                       stack.Push(this->GetModeChar());
+       }
+}
+
+void ModeHandler::RemovePrefixMode(Channel* chan, irc::modestacker& stack)
+{
+       const UserMembList* userlist = chan->GetUsers();
+       for (UserMembCIter i = userlist->begin(); i != userlist->end(); ++i)
+       {
+               if (i->second->hasMode(this->GetModeChar()))
+                       stack.Push(this->GetModeChar(), i->first->nick);
        }
 }
 
index b2d9f34e8874f2a4ee3a11e502e2df38df389713..850bc69db839ff46a4b23d12e1f4d971b75d543c 100644 (file)
@@ -30,29 +30,6 @@ ModeChannelKey::ModeChannelKey() : ModeHandler(NULL, "key", 'k', PARAM_ALWAYS, M
 {
 }
 
-void ModeChannelKey::RemoveMode(Channel* channel, irc::modestacker* stack)
-{
-       /** +k needs a parameter when being removed,
-        * so we have a special-case RemoveMode here for it
-        */
-
-       if (channel->IsModeSet('k'))
-       {
-               if (stack)
-               {
-                       stack->Push('k', channel->GetModeParameter('k'));
-               }
-               else
-               {
-                       std::vector<std::string> parameters;
-                       parameters.push_back(channel->name);
-                       parameters.push_back("-k");
-                       parameters.push_back(channel->GetModeParameter('k'));
-                       ServerInstance->SendMode(parameters, ServerInstance->FakeClient);
-               }
-       }
-}
-
 void ModeChannelKey::RemoveMode(User*, irc::modestacker* stack)
 {
 }
index ff57e177a5a37a9df870fbd29aa4d6370894263e..80c768a00be16f4194111c11e6ff273f0848eea7 100644 (file)
@@ -41,25 +41,6 @@ unsigned int ModeChannelOp::GetPrefixRank()
        return OP_VALUE;
 }
 
-void ModeChannelOp::RemoveMode(Channel* channel, irc::modestacker* stack)
-{
-       const UserMembList* clist = channel->GetUsers();
-
-       for (UserMembCIter i = clist->begin(); i != clist->end(); i++)
-       {
-               if (stack)
-                       stack->Push(this->GetModeChar(), i->first->nick);
-               else
-               {
-                       std::vector<std::string> parameters;
-                       parameters.push_back(channel->name);
-                       parameters.push_back("-o");
-                       parameters.push_back(i->first->nick);
-                       ServerInstance->SendMode(parameters, ServerInstance->FakeClient);
-               }
-       }
-}
-
 void ModeChannelOp::RemoveMode(User*, irc::modestacker* stack)
 {
 }
index 61387ce83e17f17053fc18190f2ae847e16a4fef..2371ca2fabf6db183a029ac53345e0fcbab9d68c 100644 (file)
@@ -41,25 +41,6 @@ unsigned int ModeChannelVoice::GetPrefixRank()
        return VOICE_VALUE;
 }
 
-void ModeChannelVoice::RemoveMode(Channel* channel, irc::modestacker* stack)
-{
-       const UserMembList* clist = channel->GetUsers();
-
-       for (UserMembCIter i = clist->begin(); i != clist->end(); i++)
-       {
-               if (stack)
-                       stack->Push(this->GetModeChar(), i->first->nick);
-               else
-               {
-                       std::vector<std::string> parameters;
-                       parameters.push_back(channel->name);
-                       parameters.push_back("-v");
-                       parameters.push_back(i->first->nick);
-                       ServerInstance->SendMode(parameters, ServerInstance->FakeClient);
-               }
-       }
-}
-
 void ModeChannelVoice::RemoveMode(User*, irc::modestacker* stack)
 {
 }
index 48a04d078edf5c6aa21dc7eadb4cb590479574e5..6f9f4da28635e8e0d8f7aa1847e2a83605291861 100644 (file)
@@ -53,36 +53,6 @@ class CustomPrefixMode : public ModeHandler
                return MOD_RES_PASSTHRU;
        }
 
-       void RemoveMode(Channel* channel, irc::modestacker* stack)
-       {
-               const UserMembList* cl = channel->GetUsers();
-               std::vector<std::string> mode_junk;
-               mode_junk.push_back(channel->name);
-               irc::modestacker modestack(false);
-               std::vector<std::string> stackresult;
-
-               for (UserMembCIter i = cl->begin(); i != cl->end(); i++)
-               {
-                       if (i->second->hasMode(mode))
-                       {
-                               if (stack)
-                                       stack->Push(this->GetModeChar(), i->first->nick);
-                               else
-                                       modestack.Push(this->GetModeChar(), i->first->nick);
-                       }
-               }
-
-               if (stack)
-                       return;
-
-               while (modestack.GetStackedLine(stackresult))
-               {
-                       mode_junk.insert(mode_junk.end(), stackresult.begin(), stackresult.end());
-                       ServerInstance->SendMode(mode_junk, ServerInstance->FakeClient);
-                       mode_junk.erase(mode_junk.begin() + 1, mode_junk.end());
-               }
-       }
-
        void RemoveMode(User* user, irc::modestacker* stack)
        {
        }
index 35d90b23e9c2b1903180d1dbe2cb54761a62a327..5b63355801a598b031703493dbed266960a7291c 100644 (file)
@@ -112,36 +112,6 @@ class NetworkPrefix : public ModeHandler
                m_paramtype = TR_NICK;
        }
 
-       void RemoveMode(Channel* channel, irc::modestacker* stack)
-       {
-               const UserMembList* cl = channel->GetUsers();
-               std::vector<std::string> mode_junk;
-               mode_junk.push_back(channel->name);
-               irc::modestacker modestack(false);
-               std::vector<std::string> stackresult;
-
-               for (UserMembCIter i = cl->begin(); i != cl->end(); i++)
-               {
-                       if (i->second->hasMode('Y'))
-                       {
-                               if (stack)
-                                       stack->Push(this->GetModeChar(), i->first->nick);
-                               else
-                                       modestack.Push(this->GetModeChar(), i->first->nick);
-                       }
-               }
-
-               if (stack)
-                       return;
-
-               while (modestack.GetStackedLine(stackresult))
-               {
-                       mode_junk.insert(mode_junk.end(), stackresult.begin(), stackresult.end());
-                       ServerInstance->SendMode(mode_junk, ServerInstance->FakeClient);
-                       mode_junk.erase(mode_junk.begin() + 1, mode_junk.end());
-               }
-       }
-
        unsigned int GetPrefixRank()
        {
                return NETWORK_VALUE;
index f84c101e052bad0a5f88ca9603faf4048804d651..b25444cdacc657878566c602c4f607e602311eda 100644 (file)
@@ -209,7 +209,7 @@ void CommandFJoin::RemoveStatus(Channel* c)
                 * for this function we require tidyness instead. Fixes bug #493
                 */
                if (mh)
-                       mh->RemoveMode(c, &stack);
+                       mh->RemoveMode(c, stack);
        }
 
        ApplyModeStack(ServerInstance->FakeClient, c, stack);