]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/mode.cpp
Move depriv from m_customprefix into PrefixMode.
[user/henk/code/inspircd.git] / src / mode.cpp
index b7a7b7d41b4b243633135bd7fa8755297c908e8b..fd25a9a9ff58b65355c8ac00d7a7f31c82961eaf 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)
 {
 }
 
@@ -58,7 +65,7 @@ bool ModeHandler::NeedsParam(bool adding) const
        return false;
 }
 
-std::string ModeHandler::GetUserParameter(User* user)
+std::string ModeHandler::GetUserParameter(const User* user) const
 {
        return "";
 }
@@ -155,11 +162,20 @@ void ModeWatcher::AfterMode(User*, User*, Channel*, const std::string&, bool)
 
 PrefixMode::PrefixMode(Module* Creator, const std::string& Name, char ModeLetter, unsigned int Rank, char PrefixChar)
        : ModeHandler(Creator, Name, ModeLetter, PARAM_ALWAYS, MODETYPE_CHANNEL, MC_PREFIX)
-       , prefix(PrefixChar), prefixrank(Rank)
+       , prefix(PrefixChar)
+       , prefixrank(Rank)
+       , selfremove(true)
 {
        list = true;
 }
 
+ModResult PrefixMode::AccessCheck(User* src, Channel*, std::string& value, bool adding)
+{
+       if (!adding && src->nick == value && selfremove)
+               return MOD_RES_ALLOW;
+       return MOD_RES_PASSTHRU;
+}
+
 ModeAction PrefixMode::OnModeChange(User* source, User*, Channel* chan, std::string& parameter, bool adding)
 {
        User* target;
@@ -237,7 +253,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
@@ -246,11 +262,12 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, Mode
                        unsigned int ourrank = chan->GetPrefixValue(user);
                        if (ourrank < neededrank)
                        {
-                               PrefixMode* neededmh = NULL;
-                               for(char c='A'; c <= 'z'; c++)
+                               const PrefixMode* neededmh = NULL;
+                               const PrefixModeList& prefixmodes = GetPrefixModes();
+                               for (PrefixModeList::const_iterator i = prefixmodes.begin(); i != prefixmodes.end(); ++i)
                                {
-                                       PrefixMode* privmh = FindPrefixMode(c);
-                                       if (privmh && privmh->GetPrefixRank() >= neededrank)
+                                       const PrefixMode* const privmh = *i;
+                                       if (privmh->GetPrefixRank() >= neededrank)
                                        {
                                                // this mode is sufficient to allow this action
                                                if (!neededmh || privmh->GetPrefixRank() < neededmh->GetPrefixRank())
@@ -285,8 +302,8 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, Mode
 
        if (IS_LOCAL(user) && !user->IsOper())
        {
-               char* disabled = (type == MODETYPE_CHANNEL) ? ServerInstance->Config->DisabledCModes : ServerInstance->Config->DisabledUModes;
-               if (disabled[modechar - 'A'])
+               const std::bitset<64>& disabled = (type == MODETYPE_CHANNEL) ? ServerInstance->Config->DisabledCModes : ServerInstance->Config->DisabledUModes;
+               if (disabled.test(modechar - 'A'))
                {
                        user->WriteNumeric(ERR_NOPRIVILEGES, InspIRCd::Format("Permission Denied - %s mode %c has been locked by the administrator",
                                type == MODETYPE_CHANNEL ? "channel" : "user", modechar));
@@ -569,11 +586,7 @@ ModeHandler::Id ModeParser::AllocateModeId(ModeType mt)
 
 void ModeParser::AddMode(ModeHandler* mh)
 {
-       /* Yes, i know, this might let people declare modes like '_' or '^'.
-        * If they do that, thats their problem, and if i ever EVER see an
-        * official InspIRCd developer do that, i'll beat them with a paddle!
-        */
-       if ((mh->GetModeChar() < 'A') || (mh->GetModeChar() > 'z'))
+       if (!ModeParser::IsModeChar(mh->GetModeChar()))
                throw ModuleException("Invalid letter for mode " + mh->name);
 
        /* A mode prefix of ',' is not acceptable, it would fuck up server to server.
@@ -623,7 +636,7 @@ void ModeParser::AddMode(ModeHandler* mh)
 
 bool ModeParser::DelMode(ModeHandler* mh)
 {
-       if ((mh->GetModeChar() < 'A') || (mh->GetModeChar() > 'z'))
+       if (!ModeParser::IsModeChar(mh->GetModeChar()))
                return false;
 
        ModeHandlerMap& mhmap = modehandlersbyname[mh->GetModeType()];
@@ -693,7 +706,7 @@ ModeHandler* ModeParser::FindMode(const std::string& modename, ModeType mt)
 
 ModeHandler* ModeParser::FindMode(unsigned const char modeletter, ModeType mt)
 {
-       if ((modeletter < 'A') || (modeletter > 'z'))
+       if (!ModeParser::IsModeChar(modeletter))
                return NULL;
 
        return modehandlers[mt][modeletter-65];
@@ -723,7 +736,9 @@ std::string ModeParser::CreateModeList(ModeType mt, bool needparam)
 
 void ModeParser::RecreateModeListFor004Numeric()
 {
-       Cached004ModeList = CreateModeList(MODETYPE_USER) + " " + CreateModeList(MODETYPE_CHANNEL) + " " + CreateModeList(MODETYPE_CHANNEL, true);
+       Cached004ModeList[0] = CreateModeList(MODETYPE_USER);
+       Cached004ModeList[1] = CreateModeList(MODETYPE_CHANNEL);
+       Cached004ModeList[2] = CreateModeList(MODETYPE_CHANNEL, true);
 }
 
 PrefixMode* ModeParser::FindPrefix(unsigned const char pfxletter)
@@ -866,7 +881,7 @@ void PrefixMode::RemoveMode(Channel* chan, Modes::ChangeList& changelist)
        const Channel::MemberMap& userlist = chan->GetUsers();
        for (Channel::MemberMap::const_iterator i = userlist.begin(); i != userlist.end(); ++i)
        {
-               if (i->second->hasMode(this->GetModeChar()))
+               if (i->second->HasMode(this))
                        changelist.push_remove(this, i->first->nick);
        }
 }
@@ -918,6 +933,11 @@ void ModeParser::InitBuiltinModes()
        static_modes.b.DoRehash();
 }
 
+bool ModeParser::IsModeChar(char chr)
+{
+       return ((chr >= 'A' && chr <= 'Z') || (chr >= 'a' && chr <= 'z'));
+}
+
 ModeParser::ModeParser()
 {
        /* Clear mode handler list */