]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Split out ModeParser::ProcessSingle() from Process()
authorAttila Molnar <attilamolnar@hush.com>
Wed, 3 Sep 2014 12:47:13 +0000 (14:47 +0200)
committerAttila Molnar <attilamolnar@hush.com>
Wed, 3 Sep 2014 12:47:13 +0000 (14:47 +0200)
This applies up to one MODE line's worth of mode changes from a Modes::ChangeList

include/mode.h
src/mode.cpp

index 3d8f0c9404155205faeaff772000e7dc8bbee193..2833d75a2cd8504c19661ea8c5f02bb9f1e81f6f 100644 (file)
@@ -542,7 +542,7 @@ class CoreExport ModeParser : public fakederef<ModeParser>
        /**
         * Attempts to apply a mode change to a user or channel
         */
-       ModeAction TryMode(User* user, User* targu, Channel* targc, bool adding, unsigned char mode, std::string &param, bool SkipACL);
+       ModeAction TryMode(User* user, User* targu, Channel* targc, Modes::Change& mcitem, bool SkipACL);
 
        /** Returns a list of user or channel mode characters.
         * Used for constructing the parts of the mode list in the 004 numeric.
@@ -680,6 +680,18 @@ class CoreExport ModeParser : public fakederef<ModeParser>
         */
        void Process(const std::vector<std::string>& parameters, User* user, ModeProcessFlag flags = MODE_NONE);
 
+       /** Process a single MODE line's worth of mode changes, taking max modes and line length limits
+        * into consideration.
+        * @param user The source of the mode change, can be a server user.
+        * @param targetchannel Channel to apply the mode change on. NULL if changing modes on a channel.
+        * @param targetuser User to apply the mode change on. NULL if changing modes on a user.
+        * @param changelist Modes to change in form of a Modes::ChangeList. May not process
+        * the entire list due to MODE line length and max modes limitations.
+        * @param flags Optional flags controlling how the mode change is processed,
+        * defaults to MODE_NONE.
+        */
+       void ProcessSingle(User* user, Channel* targetchannel, User* targetuser, Modes::ChangeList& changelist, ModeProcessFlag flags = MODE_NONE);
+
        /** Find the mode handler for a given mode name and type.
         * @param modename The mode name to search for.
         * @param mt Type of mode to search for, user or channel.
index 4fac34f788e9e8f8a6cfd478a104a2177d6d094c..3facc75222296b7770deb536b20172182b35eb9c 100644 (file)
@@ -237,14 +237,15 @@ ModeAction ParamModeBase::OnModeChange(User* source, User*, Channel* chan, std::
        return MODEACTION_ALLOW;
 }
 
-ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool adding, const unsigned char modechar,
-               std::string &parameter, bool SkipACL)
+ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, Modes::Change& mcitem, bool SkipACL)
 {
        ModeType type = chan ? MODETYPE_CHANNEL : MODETYPE_USER;
 
-       ModeHandler *mh = FindMode(modechar, type);
+       ModeHandler* mh = mcitem.mh;
+       bool adding = mcitem.adding;
        int pcnt = mh->GetNumParams(adding);
 
+       std::string& parameter = mcitem.param;
        // crop mode parameter size to 250 characters
        if (parameter.length() > 250 && adding)
                parameter = parameter.substr(0, 250);
@@ -255,6 +256,8 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
        if (IS_LOCAL(user) && (MOD_RESULT == MOD_RES_DENY))
                return MODEACTION_DENY;
 
+       const char modechar = mh->GetModeChar();
+
        if (chan && !SkipACL && (MOD_RESULT != MOD_RES_ALLOW))
        {
                MOD_RESULT = mh->AccessCheck(user, chan, parameter, adding);
@@ -385,6 +388,9 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User* user,
                return;
        }
 
+       // Populate a temporary Modes::ChangeList with the parameters
+       Modes::ChangeList changelist;
+
        ModResult MOD_RESULT;
        FIRST_MOD_RESULT(OnPreMode, MOD_RESULT, (user, targetuser, targetchannel, parameters));
 
@@ -409,11 +415,7 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User* user,
 
        const std::string& mode_sequence = parameters[1];
 
-       std::string output_mode;
-       std::string output_parameters;
-
        bool adding = true;
-       char output_pm = '\0'; // current output state, '+' or '-'
        unsigned int param_at = 2;
 
        for (std::string::const_iterator letter = mode_sequence.begin(); letter != mode_sequence.end(); letter++)
@@ -456,25 +458,53 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User* user,
                        }
                }
 
+               changelist.push(mh, adding, parameter);
+       }
+
+       ProcessSingle(user, targetchannel, targetuser, changelist, flags);
+
+       if ((LastParse.empty()) && (targetchannel) && (parameters.size() == 2))
+       {
+               /* Special case for displaying the list for listmodes,
+                * e.g. MODE #chan b, or MODE #chan +b without a parameter
+                */
+               this->DisplayListModes(user, targetchannel, mode_sequence);
+       }
+}
+
+void ModeParser::ProcessSingle(User* user, Channel* targetchannel, User* targetuser, Modes::ChangeList& changelist, ModeProcessFlag flags)
+{
+       LastParse.clear();
+       LastChangeList.clear();
+
+       std::string output_mode;
+       std::string output_parameters;
+
+       char output_pm = '\0'; // current output state, '+' or '-'
+       Modes::ChangeList::List& list = changelist.getlist();
+       for (Modes::ChangeList::List::iterator i = list.begin(); i != list.end(); ++i)
+       {
+               Modes::Change& item = *i;
+               ModeHandler* mh = item.mh;
                ModeAction ma = TryMode(user, targetuser, targetchannel, adding, modechar, parameter, (!(flags & MODE_CHECKACCESS)));
 
                if (ma != MODEACTION_ALLOW)
                        continue;
 
-               char needed_pm = adding ? '+' : '-';
+               char needed_pm = item.adding ? '+' : '-';
                if (needed_pm != output_pm)
                {
                        output_pm = needed_pm;
                        output_mode.append(1, output_pm);
                }
-               output_mode.append(1, modechar);
+               output_mode.push_back(mh->GetModeChar());
 
-               if (pcnt)
+               if (!item.param.empty())
                {
                        output_parameters.push_back(' ');
-                       output_parameters.append(parameter);
+                       output_parameters.append(item.param);
                }
-               LastChangeList.push(mh, adding, parameter);
+               LastChangeList.push(mh, item.adding, item.param);
 
                if ((output_mode.length() + output_parameters.length() > 450)
                                || (output_mode.length() > 100)
@@ -499,13 +529,6 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User* user,
 
                FOREACH_MOD(OnMode, (user, targetuser, targetchannel, LastChangeList, flags, output_mode));
        }
-       else if (targetchannel && parameters.size() == 2)
-       {
-               /* Special case for displaying the list for listmodes,
-                * e.g. MODE #chan b, or MODE #chan +b without a parameter
-                */
-               this->DisplayListModes(user, targetchannel, mode_sequence);
-       }
 }
 
 void ModeParser::DisplayListModes(User* user, Channel* chan, const std::string& mode_sequence)