]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/mode.cpp
Search for correct access level for mode changes, remove hardcoded halfop references
[user/henk/code/inspircd.git] / src / mode.cpp
index 441ca520df6b04ab46cd165ec9668b683121bf91..6dea66464914af64c9ee1d173b6fcb644e59b741 100644 (file)
@@ -2,7 +2,7 @@
  *       | Inspire Internet Relay Chat Daemon |
  *       +------------------------------------+
  *
- *  InspIRCd: (C) 2002-2009 InspIRCd Development Team
+ *  InspIRCd: (C) 2002-2010 InspIRCd Development Team
  * See: http://wiki.inspircd.org/Credits
  *
  * This program is free but copyrighted software; see
@@ -46,9 +46,9 @@
 #include "modes/umode_s.h"
 
 ModeHandler::ModeHandler(Module* Creator, const std::string& Name, char modeletter, ParamSpec Params, ModeType type)
-       : providerbase(Creator, Name, type == MODETYPE_CHANNEL ? SERVICE_CMODE : SERVICE_UMODE), m_paramtype(TR_TEXT),
+       : ServiceProvider(Creator, Name, type == MODETYPE_CHANNEL ? SERVICE_CMODE : SERVICE_UMODE), m_paramtype(TR_TEXT),
        parameters_taken(Params), mode(modeletter), prefix(0), oper(false),
-       list(false), m_type(type), count(0), levelrequired(HALFOP_VALUE)
+       list(false), m_type(type), levelrequired(HALFOP_VALUE)
 {
 }
 
@@ -75,17 +75,6 @@ unsigned int ModeHandler::GetPrefixRank()
        return 0;
 }
 
-unsigned int ModeHandler::GetCount()
-{
-       return 0;
-}
-
-void ModeHandler::ChangeCount(int modifier)
-{
-       count += modifier;
-       ServerInstance->Logs->Log("MODE", DEBUG,"Change count for mode %c is now %d", mode, count);
-}
-
 int ModeHandler::GetNumParams(bool adding)
 {
        switch (parameters_taken)
@@ -299,11 +288,23 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
                        unsigned int ourrank = chan->GetPrefixValue(user);
                        if (ourrank < neededrank)
                        {
-                               /* Bog off */
-                               // TODO replace with a real search for the proper prefix
-                               char needed = neededrank > HALFOP_VALUE ? '@' : '%';
-                               user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must have channel privilege %c or above to %sset channel mode %c",
-                                               user->nick.c_str(), chan->name.c_str(), needed, adding ? "" : "un", modechar);
+                               ModeHandler* neededmh = NULL;
+                               for(char c='A'; c <= 'z'; c++)
+                               {
+                                       ModeHandler *privmh = FindMode(modechar, type);
+                                       if (privmh->GetPrefixRank() >= neededrank)
+                                       {
+                                               // this mode is sufficient to allow this action
+                                               if (!neededmh || privmh->GetPrefixRank() < neededmh->GetPrefixRank())
+                                                       neededmh = privmh;
+                                       }
+                               }
+                               if (neededmh)
+                                       user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must have channel %s access or above to %sset channel mode %c",
+                                               user->nick.c_str(), chan->name.c_str(), neededmh->name.c_str(), adding ? "" : "un", modechar);
+                               else
+                                       user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You cannot %sset channel mode %c",
+                                               user->nick.c_str(), chan->name.c_str(), adding ? "" : "un", modechar);
                                return MODEACTION_DENY;
                        }
                }
@@ -353,6 +354,15 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
                return MODEACTION_DENY;
        }
 
+       if (mh->GetPrefixRank() && chan)
+       {
+               User* user_to_prefix = ServerInstance->FindNick(parameter);
+               if (!user_to_prefix)
+                       return MODEACTION_DENY;
+               if (!chan->SetPrefix(user_to_prefix, modechar, adding))
+                       return MODEACTION_DENY;
+       }
+
        /* Call the handler for the mode */
        ModeAction ma = mh->OnModeChange(user, targetuser, chan, parameter, adding);
 
@@ -362,15 +372,6 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
        if (ma != MODEACTION_ALLOW)
                return ma;
 
-       mh->ChangeCount(adding ? 1 : -1);
-
-       if (mh->GetPrefixRank() && chan)
-       {
-               User* user_to_prefix = ServerInstance->FindNick(parameter);
-               if (user_to_prefix)
-                       chan->SetPrefix(user_to_prefix, modechar, adding);
-       }
-
        for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++)
                (*watchers)->AfterMode(user, targetuser, chan, parameter, adding, type);
 
@@ -562,13 +563,11 @@ void ModeParser::DisplayListModes(User* user, Channel* chan, std::string &mode_s
                bool display = true;
                if (!user->HasPrivPermission("channels/auspex") && ServerInstance->Config->HideModeLists[mletter] && (chan->GetPrefixValue(user) < HALFOP_VALUE))
                {
-                       user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :Only half-operators and above may view the +%c list",
+                       user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You do not have access to view the +%c list",
                                user->nick.c_str(), chan->name.c_str(), mletter);
                        display = false;
                }
 
-               /** See below for a description of what craq this is :D
-                */
                unsigned char handler_id = (mletter - 'A') | MASK_CHANNEL;
 
                for(ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++)
@@ -948,7 +947,6 @@ struct builtin_modes
 
        ModeChannelBan b;
        ModeChannelOp o;
-       // halfop is added by configreader
        ModeChannelVoice v;
 
        ModeUserWallops uw;