]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Allow maxtargets to be bypassed in LoopCall for JOIN
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Thu, 14 Jan 2010 15:23:24 +0000 (15:23 +0000)
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Thu, 14 Jan 2010 15:23:24 +0000 (15:23 +0000)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@12255 e03df62e-2008-0410-955e-edbf42e46eb7

include/command_parse.h
src/command_parse.cpp
src/commands/cmd_join.cpp

index f374673f26ff0fdd99e88265856d5388d3f958e0..ac401ff6756a6312e7cca3f213b7035e97f0ba75 100644 (file)
@@ -101,33 +101,11 @@ class CoreExport CommandParser
         * @param The number of items in the parameters list
         * @param splithere The first parameter index to split as a comma seperated list
         * @param extra The second parameter index to split as a comma seperated list
+        * @param usemax Limit the command to MaxTargets targets
         * @return This function will return 1 when there are no more parameters to process. When this occurs, its
         * caller should return without doing anything, otherwise it should continue into its main section of code.
         */
-       int LoopCall(User* user, Command* CommandObj, const std::vector<std::string>& parameters, unsigned int splithere, unsigned int extra);
-
-       /** LoopCall is used to call a command classes handler repeatedly based on the contents of a comma seperated list.
-        * There are two overriden versions of this method, one of which takes two potential lists and the other takes one.
-        * We need a version which takes two potential lists for JOIN, because a JOIN may contain two lists of items at once,
-        * the channel names and their keys as follows:
-        *
-        * JOIN #chan1,#chan2,#chan3 key1,,key3
-        *
-        * Therefore, we need to deal with both lists concurrently. The first instance of this method does that by creating
-        * two instances of irc::commasepstream and reading them both together until the first runs out of tokens.
-        * The second version is much simpler and just has the one stream to read, and is used in NAMES, WHOIS, PRIVMSG etc.
-        * Both will only parse until they reach ServerInstance->Config->MaxTargets number of targets, to stop abuse via spam.
-        *
-        * @param user The user who sent the command
-        * @param CommandObj the command object to call for each parameter in the list
-        * @param parameters Parameter list as an array of array of char (that's not a typo).
-        * @param The number of items in the parameters list
-        * @param splithere The first parameter index to split as a comma seperated list
-        * @param extra The second parameter index to split as a comma seperated list
-        * @return This function will return 1 when there are no more parameters to process. When this occurs, its
-        * caller should return without doing anything, otherwise it should continue into its main section of code.
-        */
-       int LoopCall(User* user, Command* CommandObj, const std::vector<std::string>& parameters, unsigned int splithere);
+       int LoopCall(User* user, Command* CommandObj, const std::vector<std::string>& parameters, unsigned int splithere, unsigned int extra = -1, bool usemax = true);
 
        /** Take a raw input buffer from a recvq, and process it on behalf of a user.
         * @param buffer The buffer line to process
index 679f4e9ae8de7a9ea201894a8fca4d53cfda617f..2169817733ff9f2ce5b1f4b709570e06f8169e2f 100644 (file)
@@ -55,11 +55,14 @@ int InspIRCd::PassCompare(Extensible* ex, const std::string &data, const std::st
  * The second version is much simpler and just has the one stream to read, and is used in NAMES, WHOIS, PRIVMSG etc.
  * Both will only parse until they reach ServerInstance->Config->MaxTargets number of targets, to stop abuse via spam.
  */
-int CommandParser::LoopCall(User* user, Command* CommandObj, const std::vector<std::string>& parameters, unsigned int splithere, unsigned int extra)
+int CommandParser::LoopCall(User* user, Command* CommandObj, const std::vector<std::string>& parameters, unsigned int splithere, unsigned int extra, bool usemax)
 {
        if (splithere >= parameters.size())
                return 0;
 
+       if (extra >= parameters.size())
+               extra = -1;
+
        /* First check if we have more than one item in the list, if we don't we return zero here and the handler
         * which called us just carries on as it was.
         */
@@ -75,7 +78,7 @@ int CommandParser::LoopCall(User* user, Command* CommandObj, const std::vector<s
        /* Create two lists, one for channel names, one for keys
         */
        irc::commasepstream items1(parameters[splithere]);
-       irc::commasepstream items2(parameters[extra]);
+       irc::commasepstream items2(extra >= 0 ? parameters[extra] : "");
        std::string extrastuff;
        std::string item;
        unsigned int max = 0;
@@ -84,72 +87,24 @@ int CommandParser::LoopCall(User* user, Command* CommandObj, const std::vector<s
         * which called us, for every parameter pair until there are
         * no more left to parse.
         */
-       while (items1.GetToken(item) && (max++ < ServerInstance->Config->MaxTargets))
+       while (items1.GetToken(item) && (!usemax || max++ < ServerInstance->Config->MaxTargets))
        {
                if (dupes.find(item.c_str()) == dupes.end())
                {
-                       std::vector<std::string> new_parameters;
-
-                       for (unsigned int t = 0; (t < parameters.size()) && (t < MAXPARAMETERS); t++)
-                               new_parameters.push_back(parameters[t]);
+                       std::vector<std::string> new_parameters(parameters);
 
                        if (!items2.GetToken(extrastuff))
                                extrastuff = "";
 
-                       new_parameters[splithere] = item.c_str();
-                       new_parameters[extra] = extrastuff.c_str();
-
-                       CommandObj->Handle(new_parameters, user);
-
-                       dupes.insert(item.c_str());
-               }
-       }
-       return 1;
-}
-
-int CommandParser::LoopCall(User* user, Command* CommandObj, const std::vector<std::string>& parameters, unsigned int splithere)
-{
-       if (splithere >= parameters.size())
-               return 0;
-
-       /* First check if we have more than one item in the list, if we don't we return zero here and the handler
-        * which called us just carries on as it was.
-        */
-       if (parameters[splithere].find(',') == std::string::npos)
-               return 0;
-
-       std::set<irc::string> dupes;
-
-       /* Only one commasepstream here */
-       irc::commasepstream items1(parameters[splithere]);
-       std::string item;
-       unsigned int max = 0;
+                       new_parameters[splithere] = item;
+                       if (extra >= 0)
+                               new_parameters[extra] = extrastuff;
 
-       /* Parse the commasepstream until there are no tokens remaining.
-        * Each token we parse out, call the command handler that called us
-        * with it
-        */
-       while (items1.GetToken(item) && (max++ < ServerInstance->Config->MaxTargets))
-       {
-               if (dupes.find(item.c_str()) == dupes.end())
-               {
-                       std::vector<std::string> new_parameters;
-
-                       for (unsigned int t = 0; (t < parameters.size()) && (t < MAXPARAMETERS); t++)
-                               new_parameters.push_back(parameters[t]);
-
-                       new_parameters[splithere] = item.c_str();
-
-                       /* Execute the command handler. */
                        CommandObj->Handle(new_parameters, user);
 
                        dupes.insert(item.c_str());
                }
        }
-       /* By returning 1 we tell our caller that nothing is to be done,
-        * as all the previous calls handled the data. This makes the parent
-        * return without doing any processing.
-        */
        return 1;
 }
 
index f3a97d31a505b612f7d1ad3bc0945f83914fa2ba..17a71688a809ec8ac80108bdeafc89b76a7f1f73 100644 (file)
@@ -50,7 +50,7 @@ CmdResult CommandJoin::Handle (const std::vector<std::string>& parameters, User
 {
        if (parameters.size() > 1)
        {
-               if (ServerInstance->Parser->LoopCall(user, this, parameters, 0, 1))
+               if (ServerInstance->Parser->LoopCall(user, this, parameters, 0, 1, false))
                        return CMD_SUCCESS;
 
                if (ServerInstance->IsChannel(parameters[0].c_str(), ServerInstance->Config->Limits.ChanMax))
@@ -61,7 +61,7 @@ CmdResult CommandJoin::Handle (const std::vector<std::string>& parameters, User
        }
        else
        {
-               if (ServerInstance->Parser->LoopCall(user, this, parameters, 0))
+               if (ServerInstance->Parser->LoopCall(user, this, parameters, 0, -1, false))
                        return CMD_SUCCESS;
 
                if (ServerInstance->IsChannel(parameters[0].c_str(), ServerInstance->Config->Limits.ChanMax))