]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Add support for setting the unset rank in ModeHandler.
authorPeter Powell <petpow@saberuk.com>
Wed, 18 Oct 2017 02:40:31 +0000 (03:40 +0100)
committerPeter Powell <petpow@saberuk.com>
Mon, 6 Nov 2017 10:55:56 +0000 (10:55 +0000)
14 files changed:
docs/conf/modules.conf.example
include/builtinmodes.h
include/mode.h
src/coremods/core_channel/cmd_kick.cpp
src/mode.cpp
src/modules/m_auditorium.cpp
src/modules/m_autoop.cpp
src/modules/m_customprefix.cpp
src/modules/m_delayjoin.cpp
src/modules/m_delaymsg.cpp
src/modules/m_ojoin.cpp
src/modules/m_operprefix.cpp
src/modules/m_override.cpp
src/modules/m_rmode.cpp

index 3c3978c28018bccb173bade53cbe706341747c00..28450c7e9eae50a0f388c23281a42a5893e420fc 100644 (file)
 # rank       A numeric rank for this prefix, defining what permissions it gives.
 #            The rank of voice, halfop and op is 10000, 20000, and 30000,
 #            respectively.
-# ranktoset  The numeric rank required to set/unset this mode. Defaults to rank.
+# ranktoset  The numeric rank required to set this mode. Defaults to rank.
+# ranktounset The numeric rank required to unset this mode. Defaults to ranktoset.
 # depriv     Can you remove the mode from yourself? Defaults to yes.
 #<customprefix name="founder" letter="q" prefix="~" rank="50000" ranktoset="50000">
 #<customprefix name="admin" letter="a" prefix="&amp;" rank="40000" ranktoset="50000">
index bfb46823fbd7f533b2e162591bef21fdb11a3bd2..922a86f0efe081f6df99bd5e4b87af919f94fb96 100644 (file)
@@ -66,7 +66,7 @@ class ModeChannelOp : public PrefixMode
        ModeChannelOp()
                : PrefixMode(NULL, "op", 'o', OP_VALUE, '@')
        {
-               levelrequired = OP_VALUE;
+               ranktoset = ranktounset = OP_VALUE;
        }
 };
 
@@ -78,7 +78,7 @@ class ModeChannelVoice : public PrefixMode
        ModeChannelVoice()
                : PrefixMode(NULL, "voice", 'v', VOICE_VALUE, '+')
        {
-               levelrequired = HALFOP_VALUE;
+               ranktoset = ranktounset = HALFOP_VALUE;
        }
 };
 
index ec293e4970dbd4701bd5563bb593f36c11ec4251..5cfbe401589df5fcea77dbe9103761e0c15cd7d9 100644 (file)
@@ -148,10 +148,11 @@ class CoreExport ModeHandler : public ServiceProvider
         */
        const Class type_id;
 
-       /** The prefix char needed on channel to use this mode,
-        * only checked for channel modes
-        */
-       int levelrequired;
+       /** The prefix rank required to set this mode on channels. */
+       unsigned int ranktoset;
+
+       /** The prefix rank required to unset this mode on channels. */
+       unsigned int ranktounset;
 
  public:
        /**
@@ -320,7 +321,13 @@ class CoreExport ModeHandler : public ServiceProvider
         */
        virtual void RemoveMode(Channel* channel, Modes::ChangeList& changelist);
 
-       inline unsigned int GetLevelRequired() const { return levelrequired; }
+       /** Retrieves the level required to modify this mode.
+        * @param adding Whether the mode is being added or removed.
+        */
+       inline unsigned int GetLevelRequired(bool adding) const
+       {
+               return adding ? ranktoset : ranktounset;
+       }
 
        friend class ModeParser;
 };
@@ -616,7 +623,7 @@ class CoreExport ModeParser : public fakederef<ModeParser>
 
                /** If this flag is set then the mode change will be subject to access checks.
                 * For more information see the documentation of the PrefixMode class,
-                * ModeHandler::levelrequired and ModeHandler::AccessCheck().
+                * ModeHandler::ranktoset and ModeHandler::AccessCheck().
                 * Modules may explicitly allow a mode change regardless of this flag by returning
                 * MOD_RES_ALLOW from the OnPreMode hook. Only affects channel mode changes.
                 */
index 7f8a8a3291d28d0c445db47e8d34df945917c7b6..420ed2b83ddc2f0e2fb0475f3148ff0792515722 100644 (file)
@@ -104,8 +104,8 @@ CmdResult CommandKick::Handle (const std::vector<std::string>& parameters, User
                        for (std::string::size_type i = 0; i < memb->modes.length(); i++)
                        {
                                ModeHandler* mh = ServerInstance->Modes->FindMode(memb->modes[i], MODETYPE_CHANNEL);
-                               if (mh && mh->GetLevelRequired() > req)
-                                       req = mh->GetLevelRequired();
+                               if (mh && mh->GetLevelRequired(true) > req)
+                                       req = mh->GetLevelRequired(true);
                        }
 
                        if (them < req)
index fd5e307074e2aea1e0ee0bf97f22f2fe3eefdf8b..cff625c4605264069b189832c76fa30382131780 100644 (file)
 #include "builtinmodes.h"
 
 ModeHandler::ModeHandler(Module* Creator, const std::string& Name, char modeletter, ParamSpec Params, ModeType type, Class mclass)
-       : ServiceProvider(Creator, Name, SERVICE_MODE), modeid(ModeParser::MODEID_MAX),
-       parameters_taken(Params), mode(modeletter), oper(false),
-       list(false), m_type(type), type_id(mclass), levelrequired(HALFOP_VALUE)
+       : ServiceProvider(Creator, Name, SERVICE_MODE)
+       , modeid(ModeParser::MODEID_MAX)
+       , parameters_taken(Params)
+       , mode(modeletter)
+       , oper(false)
+       , list(false)
+       , m_type(type)
+       , type_id(mclass)
+       , ranktoset(HALFOP_VALUE)
+       , ranktounset(HALFOP_VALUE)
 {
 }
 
@@ -237,7 +244,7 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, Mode
                        return MODEACTION_DENY;
                if (MOD_RESULT == MOD_RES_PASSTHRU)
                {
-                       unsigned int neededrank = mh->GetLevelRequired();
+                       unsigned int neededrank = mh->GetLevelRequired(adding);
                        /* Compare our rank on the channel against the rank of the required prefix,
                         * allow if >= ours. Because mIRC and xchat throw a tizz if the modes shown
                         * in NAMES(X) are not in rank order, we know the most powerful mode is listed
index 692b3eba4738a01c37ff3914409a577633499f00..7acbd2fff856a11e0ea081dbb60faa17eb9bc553 100644 (file)
@@ -28,7 +28,7 @@ class AuditoriumMode : public SimpleChannelModeHandler
  public:
        AuditoriumMode(Module* Creator) : SimpleChannelModeHandler(Creator, "auditorium", 'u')
        {
-               levelrequired = OP_VALUE;
+               ranktoset = ranktounset = OP_VALUE;
        }
 };
 
index 8c7f300daba11b60cbcbd85d79de719edf69e425..257c3647cbe48fb578ff4958c4f21b6eacec3d45 100644 (file)
@@ -28,7 +28,7 @@ class AutoOpList : public ListModeBase
  public:
        AutoOpList(Module* Creator) : ListModeBase(Creator, "autoop", 'w', "End of Channel Access List", 910, 911, true)
        {
-               levelrequired = OP_VALUE;
+               ranktoset = ranktounset = OP_VALUE;
                tidy = false;
        }
 
@@ -61,7 +61,7 @@ class AutoOpList : public ListModeBase
                std::string dummy;
                if (mh->AccessCheck(source, channel, dummy, true) == MOD_RES_DENY)
                        return MOD_RES_DENY;
-               if (mh->GetLevelRequired() > mylevel)
+               if (mh->GetLevelRequired(true) > mylevel)
                {
                        source->WriteNumeric(ERR_CHANOPRIVSNEEDED, channel->name, InspIRCd::Format("You must be able to set mode '%s' to include it in an autoop", mid.c_str()));
                        return MOD_RES_DENY;
index f6f9a84f691220925fd04342a27b2301b897dc9a..1be9676b592ee68e0d23fec7187cf563c72120b7 100644 (file)
@@ -33,7 +33,8 @@ class CustomPrefixMode : public PrefixMode
                prefix = v.c_str()[0];
                v = tag->getString("letter");
                mode = v.c_str()[0];
-               levelrequired = tag->getInt("ranktoset", prefixrank);
+               ranktoset = tag->getInt("ranktoset", prefixrank, prefixrank, UINT_MAX);
+               ranktounset = tag->getInt("ranktounset", ranktoset, ranktoset, UINT_MAX);
                depriv = tag->getBool("depriv", true);
        }
 
index e864a8289c75e0f8d6be6b174fc7f33f4c65524c..6d125134578fc63a39eaedbbb0663ddba482fc51 100644 (file)
@@ -28,7 +28,7 @@ class DelayJoinMode : public ModeHandler
  public:
        DelayJoinMode(Module* Parent) : ModeHandler(Parent, "delayjoin", 'D', PARAM_NONE, MODETYPE_CHANNEL)
        {
-               levelrequired = OP_VALUE;
+               ranktoset = ranktounset = OP_VALUE;
        }
 
        ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding);
index 1ad41cc57f23395199da3d5efe184b4ba5aca30f..3471c7fd2f2f9c86085483b1a0c93dfda7c828f9 100644 (file)
@@ -27,7 +27,7 @@ class DelayMsgMode : public ParamMode<DelayMsgMode, LocalIntExt>
                : ParamMode<DelayMsgMode, LocalIntExt>(Parent, "delaymsg", 'd')
                , jointime("delaymsg", ExtensionItem::EXT_MEMBERSHIP, Parent)
        {
-               levelrequired = OP_VALUE;
+               ranktoset = ranktounset = OP_VALUE;
        }
 
        bool ResolveModeConflict(std::string &their_param, const std::string &our_param, Channel*)
index 76e66bdc23cbff3d54b128d6253558cce20f42fc..a96e47bc6977743ed250272531459c6305e149c8 100644 (file)
@@ -89,7 +89,7 @@ class NetworkPrefix : public PrefixMode
        NetworkPrefix(Module* parent, char NPrefix)
                : PrefixMode(parent, "official-join", 'Y', NETWORK_VALUE, NPrefix)
        {
-               levelrequired = INT_MAX;
+               ranktoset = ranktounset = UINT_MAX;
        }
 
        ModResult AccessCheck(User* source, Channel* channel, std::string &parameter, bool adding)
index 73155b39473c577fec04b7c8ccfd9d04b92eec70..8b68dbe607a0462fb6ed060fe994a6cd2bf001e7 100644 (file)
@@ -33,7 +33,7 @@ class OperPrefixMode : public PrefixMode
                        : PrefixMode(Creator, "operprefix", 'y', OPERPREFIX_VALUE)
                {
                        prefix = ServerInstance->Config->ConfValue("operprefix")->getString("prefix", "!", 1, 1)[0];
-                       levelrequired = INT_MAX;
+                       ranktoset = ranktounset = UINT_MAX;
                }
 };
 
index fd09dd6ec96178fb283b56c63ac9316f6e1d3347..2094d3c9681312717dac185b8e59e910bceb5ab7 100644 (file)
@@ -42,7 +42,7 @@ class ModuleOverride : public Module
                for (Modes::ChangeList::List::const_iterator i = list.begin(); i != list.end(); ++i)
                {
                        ModeHandler* mh = i->mh;
-                       if (mh->GetLevelRequired() > userlevel)
+                       if (mh->GetLevelRequired(i->adding) > userlevel)
                                return true;
                }
                return false;
index 37c6e62fff3e1ea9ed43601ba5453af41af8973f..7c15247bed10bed49e11e025ae57801e792f4043 100644 (file)
@@ -50,7 +50,7 @@ class CommandRMode : public Command
                        return CMD_FAILURE;
                }
 
-               if (chan->GetPrefixValue(user) < mh->GetLevelRequired())
+               if (chan->GetPrefixValue(user) < mh->GetLevelRequired(false))
                {
                        user->WriteNotice("You do not have access to unset " + ConvToStr(modeletter) + " on " +  chan->name + ".");
                        return CMD_FAILURE;