]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Construct explicit parameter type list for MODE parameters
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Fri, 6 Mar 2009 22:28:57 +0000 (22:28 +0000)
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Fri, 6 Mar 2009 22:28:57 +0000 (22:28 +0000)
Previously, we used TR_SPACENICKLIST on the parameters. This worked only because
usually, if anything in the list parsed as a nick, then it was a nick. However,
some modes like +k and +g allow free-form text, which could also resolve as a
nick. Add extra parameters to allow modes to specify their TranslateType,
defaulting to TR_TEXT.

This fixes bug #757, found by Taros

git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11180 e03df62e-2008-0410-955e-edbf42e46eb7

15 files changed:
include/command_parse.h
include/ctables.h
include/mode.h
include/modules.h
include/u_listmode.h
src/command_parse.cpp
src/mode.cpp
src/modes/cmode_h.cpp
src/modes/cmode_o.cpp
src/modes/cmode_v.cpp
src/modules.cpp
src/modules/m_chanprotect.cpp
src/modules/m_operprefix.cpp
src/modules/m_spanningtree/main.cpp
src/modules/m_spanningtree/main.h

index b3ae3236addb462a7f0a48bc3e4ff82949b3d33a..21dae89dd91b2bcf9919abe39aca60705dcd9ecd 100644 (file)
@@ -202,6 +202,8 @@ class CoreExport CommandParser : public classbase
         * @return returns the number of substitutions made. Will always be 0 or 1 for TR_TEXT and 0..n for other types.
         */
        int TranslateUIDs(TranslateType to, const std::string &source, std::string &dest);
+
+       int TranslateUIDs(const std::vector<TranslateType> to, const std::string &source, std::string &dest);
 };
 
 /** Command handler class for the RELOAD command.
index 3e10e7c23bcf7d72db09579ad2c11d4a479c0e0e..d7c2a20505062d700c30b68917428444c003b67e 100644 (file)
@@ -33,8 +33,6 @@ enum TranslateType
        TR_END,                 /* End of known parameters, everything after this is TR_TEXT */
        TR_TEXT,                /* Raw text, leave as-is */
        TR_NICK,                /* Nickname, translate to UUID for server->server */
-       TR_NICKLIST,            /* Comma seperated nickname list, translate to UUIDs */
-       TR_SPACENICKLIST,       /* Space seperated nickname list, translate to UUIDs */
        TR_CUSTOM               /* Custom translation handled by EncodeParameter/DecodeParameter */
 };
 
index f78fcda9c3e63d8e1259d99d73967540603cca77..525a262082e371b10cbe6660ee1f2ff00c77da19 100644 (file)
@@ -17,6 +17,7 @@
 /* Forward declarations. */
 class User;
 
+#include "ctables.h"
 #include "channels.h"
 
 /**
@@ -125,6 +126,10 @@ class CoreExport ModeHandler : public Extensible
         * MODETYPE_CHANNEL.
         */
        ModeType m_type;
+       /**
+        * The mode parameter translation type
+        */
+       TranslateType m_paramtype;
        /**
         * True if the mode requires oper status
         * to set.
@@ -161,7 +166,8 @@ class CoreExport ModeHandler : public Extensible
         * and the rank values OP_VALUE, HALFOP_VALUE and VOICE_VALUE respectively. Any prefixes you define should have unique values proportional
         * to these three defaults or proportional to another mode in a module you depend on. See src/cmode_o.cpp as an example.
         */
-       ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix = 0, char prefixrequired = '%');
+       ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly,
+               char mprefix = 0, char prefixrequired = '%', TranslateType translate = TR_TEXT);
        /**
         * The default destructor does nothing
         */
@@ -191,9 +197,13 @@ class CoreExport ModeHandler : public Extensible
         */
        virtual unsigned int GetPrefixRank();
        /**
-        * Returns the modes type
+        * Returns the mode's type
         */
        ModeType GetModeType();
+       /**
+        * Returns the mode's parameter translation type
+        */
+       TranslateType GetTranslateType();
        /**
         * Returns true if the mode can only be set/unset by an oper
         */
index 536313d8fb5ccaf12f8f22aa41c0f99dffbc1b28..90aeb178e3a89c35adcfd766341372e4bea50217 100644 (file)
@@ -739,8 +739,9 @@ class CoreExport Module : public Extensible
         * @param dest The target of the modes (User* or Channel*)
         * @param target_type The type of target (TYPE_USER or TYPE_CHANNEL)
         * @param text The actual modes and their parameters if any
+        * @param translate The translation types of the mode parameters
         */
-       virtual void OnMode(User* user, void* dest, int target_type, const std::string &text);
+       virtual void OnMode(User* user, void* dest, int target_type, const std::string &text, const std::vector<TranslateType> &translate);
 
        /** Allows modules to alter or create server descriptions
         * Whenever a module requires a server description, for example for display in
@@ -847,8 +848,9 @@ class CoreExport Module : public Extensible
         * @param target_type The type of item to decode data for, TYPE_USER or TYPE_CHANNEL
         * @param target The Channel* or User* that modes should be sent for
         * @param modeline The modes and parameters to be sent
+        * @param translate The translation types of the mode parameters
         */
-       virtual void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::string &modeline);
+       virtual void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::string &modeline, const std::vector<TranslateType> &translate);
 
        /** Implemented by modules which provide the ability to link servers.
         * These modules will implement this method, which allows metadata (extra data added to
index b08ad8d4dc82ec131cc8f20c9fc8b3877168688e..88b5fb3eea17c66a4643903147af900f1a9da925 100644 (file)
@@ -423,18 +423,21 @@ class ListModeBase : public ModeHandler
                chan->GetExt(infokey, mlist);
                irc::modestacker modestack(ServerInstance, true);
                std::deque<std::string> stackresult;
+               std::vector<TranslateType> types;
+               types.push_back(TR_TEXT);
                if (mlist)
                {
                        for (modelist::iterator it = mlist->begin(); it != mlist->end(); it++)
                        {
                                modestack.Push(std::string(1, mode)[0], it->mask);
+                               types.push_back(this->GetTranslateType());
                        }
                }
                while (modestack.GetStackedLine(stackresult))
                {
                        irc::stringjoiner mode_join(" ", stackresult, 0, stackresult.size() - 1);
                        std::string line = mode_join.GetJoined();
-                       proto->ProtoSendMode(opaque, TYPE_CHANNEL, chan, line);
+                       proto->ProtoSendMode(opaque, TYPE_CHANNEL, chan, line, types);
                }
        }
 
index 7c18c8ab19cd8cb772bac95d3eddeecc479f34ca..d0b1148165815f494225d1dcff3986643876f7d6 100644 (file)
@@ -609,32 +609,24 @@ void CommandParser::SetupCommandTable()
                this->CreateCommand(new CommandReload(ServerInstance));
 }
 
-int CommandParser::TranslateUIDs(TranslateType to, const std::string &source, std::string &dest)
+int CommandParser::TranslateUIDs(const std::vector<TranslateType> to, const std::string &source, std::string &dest)
 {
+       irc::spacesepstream items(source);
+       std::vector<TranslateType>::const_iterator types = to.begin();
        User* user = NULL;
        std::string item;
        int translations = 0;
        dest.clear();
 
-       switch (to)
+       while (items.GetToken(item))
        {
-               case TR_NICK:
-                       /* Translate single nickname */
-                       user = ServerInstance->FindNick(source);
-                       if (user)
-                       {
-                               dest = user->uuid;
-                               translations++;
-                       }
-                       else
-                               dest = source;
-               break;
-               case TR_NICKLIST:
+               TranslateType t = *types;
+               types++;
+
+               switch (t)
                {
-                       /* Translate comma seperated list of nicknames */
-                       irc::commasepstream items(source);
-                       while (items.GetToken(item))
-                       {
+                       case TR_NICK:
+                               /* Translate single nickname */
                                user = ServerInstance->FindNick(item);
                                if (user)
                                {
@@ -643,31 +635,42 @@ int CommandParser::TranslateUIDs(TranslateType to, const std::string &source, st
                                }
                                else
                                        dest.append(item);
-                               dest.append(",");
-                       }
-                       if (!dest.empty())
-                               dest.erase(dest.end() - 1);
+                       break;
+                       break;
+                       case TR_END:
+                       case TR_TEXT:
+                       default:
+                               /* Do nothing */
+                               dest.append(item);
+                       break;
                }
-               break;
-               case TR_SPACENICKLIST:
-               {
-                       /* Translate space seperated list of nicknames */
-                       irc::spacesepstream items(source);
-                       while (items.GetToken(item))
+               dest.append(" ");
+       }
+
+       if (!dest.empty())
+               dest.erase(dest.end() - 1);
+       return translations;
+}
+
+int CommandParser::TranslateUIDs(TranslateType to, const std::string &source, std::string &dest)
+{
+       User* user = NULL;
+       std::string item;
+       int translations = 0;
+       dest.clear();
+
+       switch (to)
+       {
+               case TR_NICK:
+                       /* Translate single nickname */
+                       user = ServerInstance->FindNick(source);
+                       if (user)
                        {
-                               user = ServerInstance->FindNick(item);
-                               if (user)
-                               {
-                                       dest.append(user->uuid);
-                                       translations++;
-                               }
-                               else
-                                       dest.append(item);
-                               dest.append(" ");
+                               dest = user->uuid;
+                               translations++;
                        }
-                       if (!dest.empty())
-                               dest.erase(dest.end() - 1);
-               }
+                       else
+                               dest = source;
                break;
                case TR_END:
                case TR_TEXT:
index e7f918e62dad0c4f80ae53f1c3a25dacf7dfb249..da8f10294ff89149f9e8f445774b7dc7f17db028 100644 (file)
@@ -52,8 +52,8 @@
 /* +s (server notice masks) */
 #include "modes/umode_s.h"
 
-ModeHandler::ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix, char prefixrequired)
-       : ServerInstance(Instance), mode(modeletter), n_params_on(parameters_on), n_params_off(parameters_off), list(listmode), m_type(type), oper(operonly), prefix(mprefix), count(0), prefixneeded(prefixrequired)
+ModeHandler::ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix, char prefixrequired, TranslateType translate)
+       : ServerInstance(Instance), mode(modeletter), n_params_on(parameters_on), n_params_off(parameters_off), list(listmode), m_type(type), m_paramtype(translate), oper(operonly), prefix(mprefix), count(0), prefixneeded(prefixrequired)
 {
 }
 
@@ -97,6 +97,11 @@ ModeType ModeHandler::GetModeType()
        return m_type;
 }
 
+TranslateType ModeHandler::GetTranslateType()
+{
+       return m_paramtype;
+}
+
 bool ModeHandler::NeedsOper()
 {
        return oper;
@@ -498,6 +503,8 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user,
                std::string mode_sequence = parameters[1];
                std::string parameter;
                std::ostringstream parameter_list;
+               std::vector<TranslateType> parameter_xlate;
+               parameter_xlate.push_back(TR_TEXT);
                std::string output_sequence;
                bool adding = true, state_change = false;
                unsigned char handler_id = 0;
@@ -710,6 +717,7 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user,
                                                                if ((modehandlers[handler_id]->GetNumParams(adding)) && (!parameter.empty()))
                                                                {
                                                                        parameter_list << " " << parameter;
+                                                                       parameter_xlate.push_back(modehandlers[handler_id]->GetTranslateType());
                                                                        parameter_count++;
                                                                        /* Does this mode have a prefix? */
                                                                        if (modehandlers[handler_id]->GetPrefix() && targetchannel)
@@ -768,13 +776,13 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user,
                                if (type == MODETYPE_CHANNEL)
                                {
                                        targetchannel->WriteChannel(user, "MODE %s %s%s", targetchannel->name.c_str(), output_sequence.c_str(), parameter_list.str().c_str());
-                                       FOREACH_MOD(I_OnMode,OnMode(user, targetchannel, TYPE_CHANNEL, output_sequence + parameter_list.str()));
+                                       FOREACH_MOD(I_OnMode,OnMode(user, targetchannel, TYPE_CHANNEL, output_sequence + parameter_list.str(), parameter_xlate));
                                        this->LastParse = targetchannel->name;
                                }
                                else
                                {
                                        user->WriteTo(targetuser, "MODE %s %s%s", targetuser->nick.c_str(), output_sequence.c_str(), parameter_list.str().c_str());
-                                       FOREACH_MOD(I_OnMode,OnMode(user, targetuser, TYPE_USER, output_sequence + parameter_list.str()));
+                                       FOREACH_MOD(I_OnMode,OnMode(user, targetuser, TYPE_USER, output_sequence + parameter_list.str(), parameter_xlate));
                                        this->LastParse = targetuser->nick;
                                }
                        }
index c3bb92576e05ddd85172614821c7373a85294c26..0d6da2778422dd5b52ef39de5d7cb4d42fa0c910 100644 (file)
@@ -19,7 +19,7 @@
 #include "modules.h"
 #include "modes/cmode_h.h"
 
-ModeChannelHalfOp::ModeChannelHalfOp(InspIRCd* Instance) : ModeHandler(Instance, 'h', 1, 1, true, MODETYPE_CHANNEL, false, '%', '@')
+ModeChannelHalfOp::ModeChannelHalfOp(InspIRCd* Instance) : ModeHandler(Instance, 'h', 1, 1, true, MODETYPE_CHANNEL, false, '%', '@', TR_NICK)
 {
 }
 
index 7b27788fcd3bcd94c8e345d9e8f3ad779c0162d5..16ea2ffb726b11e7c891f04356c201deb85e4676 100644 (file)
@@ -19,7 +19,7 @@
 #include "modules.h"
 #include "modes/cmode_o.h"
 
-ModeChannelOp::ModeChannelOp(InspIRCd* Instance) : ModeHandler(Instance, 'o', 1, 1, true, MODETYPE_CHANNEL, false, '@', '@')
+ModeChannelOp::ModeChannelOp(InspIRCd* Instance) : ModeHandler(Instance, 'o', 1, 1, true, MODETYPE_CHANNEL, false, '@', '@', TR_NICK)
 {
 }
 
index a89f5705f2fa65d3458be8b7bf533cb98ad16b8d..47befbac99449d809d0e6f59dfb1be326aea7320 100644 (file)
@@ -20,7 +20,7 @@
 #include "modules.h"
 #include "modes/cmode_v.h"
 
-ModeChannelVoice::ModeChannelVoice(InspIRCd* Instance) : ModeHandler(Instance, 'v', 1, 1, true, MODETYPE_CHANNEL, false, '+')
+ModeChannelVoice::ModeChannelVoice(InspIRCd* Instance) : ModeHandler(Instance, 'v', 1, 1, true, MODETYPE_CHANNEL, false, '+', '%', TR_NICK)
 {
 }
 
index db14fd1e656cb38fbc6aa956f513fc6eb7617a2a..2d8c9387f5cbd49db8a50116d983772b669a76d4 100644 (file)
@@ -116,7 +116,7 @@ void                Module::OnPostJoin(User*, Channel*) { }
 void           Module::OnUserPart(User*, Channel*, std::string&, bool&) { }
 void           Module::OnRehash(User*, const std::string&) { }
 int            Module::OnUserPreJoin(User*, Channel*, const char*, std::string&, const std::string&) { return 0; }
-void           Module::OnMode(User*, void*, int, const std::string&) { }
+void           Module::OnMode(User*, void*, int, const std::string&, const std::vector<TranslateType>&) { }
 Version                Module::GetVersion() { return Version("Misconfigured", VF_VENDOR, -1); }
 void           Module::OnOper(User*, const std::string&) { }
 void           Module::OnPostOper(User*, const std::string&, const std::string &) { }
@@ -170,7 +170,7 @@ void                Module::OnPostLocalTopicChange(User*, Channel*, const std::string&) { }
 void           Module::OnGetServerDescription(const std::string&, std::string&) { }
 void           Module::OnSyncUser(User*, Module*, void*) { }
 void           Module::OnSyncChannel(Channel*, Module*, void*) { }
-void           Module::ProtoSendMode(void*, TargetTypeFlags, void*, const std::string&) { }
+void           Module::ProtoSendMode(void*, TargetTypeFlags, void*, const std::string&, const std::vector<TranslateType>&) { }
 void           Module::OnSyncChannelMetaData(Channel*, Module*, void*, const std::string&, bool) { }
 void           Module::OnSyncUserMetaData(User*, Module*, void*, const std::string&, bool) { }
 void           Module::OnSyncOtherMetaData(Module*, void*, bool) { }
index 85c8660a25c8ecced6d663f3c23d16a0bc20ab27..627857175962ca6d2f40a51520d2c230222adb22 100644 (file)
@@ -159,7 +159,7 @@ class ChanFounder : public ModeHandler, public FounderProtectBase
 {
  public:
        ChanFounder(InspIRCd* Instance, char my_prefix, bool &depriv_self, bool &depriv_others)
-               : ModeHandler(Instance, 'q', 1, 1, true, MODETYPE_CHANNEL, false, my_prefix, 0),
+               : ModeHandler(Instance, 'q', 1, 1, true, MODETYPE_CHANNEL, false, my_prefix, 0, TR_NICK),
                  FounderProtectBase(Instance, "cm_founder_", "founder", 386, 387, depriv_self, depriv_others) { }
 
        unsigned int GetPrefixRank()
@@ -235,7 +235,7 @@ class ChanProtect : public ModeHandler, public FounderProtectBase
 {
  public:
        ChanProtect(InspIRCd* Instance, char my_prefix, bool &depriv_self, bool &depriv_others)
-               : ModeHandler(Instance, 'a', 1, 1, true, MODETYPE_CHANNEL, false, my_prefix, 0),
+               : ModeHandler(Instance, 'a', 1, 1, true, MODETYPE_CHANNEL, false, my_prefix, 0, TR_NICK),
                  FounderProtectBase(Instance,"cm_protect_","protected user", 388, 389, depriv_self, depriv_others) { }
 
        unsigned int GetPrefixRank()
index 0dd762878a590c134af58fdb62c1b4079fb9859f..7fda38bb33bb4776556e79da3ef68cf2a0f17e99 100644 (file)
@@ -51,7 +51,7 @@ void AddPrefixChan(User* user, Channel* channel)
 class OperPrefixMode : public ModeHandler
 {
        public:
-               OperPrefixMode(InspIRCd* Instance, char pfx) : ModeHandler(Instance, 'y', 1, 1, true, MODETYPE_CHANNEL, false, pfx) { }
+               OperPrefixMode(InspIRCd* Instance, char pfx) : ModeHandler(Instance, 'y', 1, 1, true, MODETYPE_CHANNEL, false, pfx, pfx, TR_NICK) { }
 
                unsigned int GetPrefixRank()
                {
index da393858cf487eb6cef9112e1ec2bd4499ab7e48..51a9eb025535e215c8df936d50f267e82bc430f5 100644 (file)
@@ -800,7 +800,7 @@ void ModuleSpanningTree::OnDelLine(User* user, XLine *x)
        }
 }
 
-void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const std::string &text)
+void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const std::string &text, const std::vector<TranslateType> &translate)
 {
        if ((IS_LOCAL(user)) && (user->registered == REG_ALL))
        {
@@ -808,7 +808,7 @@ void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const s
                std::string command;
                std::string output_text;
 
-               ServerInstance->Parser->TranslateUIDs(TR_SPACENICKLIST, text, output_text);
+               ServerInstance->Parser->TranslateUIDs(translate, text, output_text);
 
                if (target_type == TYPE_USER)
                {
@@ -851,19 +851,19 @@ int ModuleSpanningTree::OnSetAway(User* user, const std::string &awaymsg)
        return 0;
 }
 
-void ModuleSpanningTree::ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::string &modeline)
+void ModuleSpanningTree::ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::string &modeline, const std::vector<TranslateType> &translate)
 {
        TreeSocket* s = (TreeSocket*)opaque;
        std::string output_text;
 
-       ServerInstance->Parser->TranslateUIDs(TR_SPACENICKLIST, modeline, output_text);
+       ServerInstance->Parser->TranslateUIDs(translate, modeline, output_text);
 
        if (target)
        {
                if (target_type == TYPE_USER)
                {
                        User* u = (User*)target;
-                       s->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" FMODE "+u->uuid+" "+ConvToStr(u->age)+" "+output_text);
+                       s->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" MODE "+u->uuid+" "+output_text);
                }
                else if (target_type == TYPE_CHANNEL)
                {
index 1dd7692c186d93f0b3a1aa965efa468111a4e9d5..19ec2d43c026475fb8be2fee773773ba8842f17b 100644 (file)
@@ -174,10 +174,10 @@ class ModuleSpanningTree : public Module
        void OnLine(User* source, const std::string &host, bool adding, char linetype, long duration, const std::string &reason);
        virtual void OnAddLine(User *u, XLine *x);
        virtual void OnDelLine(User *u, XLine *x);
-       virtual void OnMode(User* user, void* dest, int target_type, const std::string &text);
+       virtual void OnMode(User* user, void* dest, int target_type, const std::string &text, const std::vector<TranslateType> &translate);
        virtual int OnStats(char statschar, User* user, string_list &results);
        virtual int OnSetAway(User* user, const std::string &awaymsg);
-       virtual void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::string &modeline);
+       virtual void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::string &modeline, const std::vector<TranslateType> &translate);
        virtual void ProtoSendMetaData(void* opaque, TargetTypeFlags target_type, void* target, const std::string &extname, const std::string &extdata);
        virtual void OnEvent(Event* event);
        virtual void OnLoadModule(Module* mod,const std::string &name);