]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/mode.cpp
Add s2s backward compatability for protocol changes
[user/henk/code/inspircd.git] / src / mode.cpp
index 1986ed2bbe0b90c8fc7f057c120695dd0d87547f..47d59d85ae314c27e180c83e2eaa1b60eae90e15 100644 (file)
@@ -49,8 +49,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, 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)
+ModeHandler::ModeHandler(InspIRCd* Instance, Module* Creator, 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), creator(Creator)
 {
 }
 
@@ -126,7 +126,7 @@ std::string ModeHandler::GetUserParameter(User* user)
        return "";
 }
 
-ModeAction ModeHandler::OnModeChange(User*, User*, Channel*, std::string&, bool, bool)
+ModeAction ModeHandler::OnModeChange(User*, User*, Channel*, std::string&, bool)
 {
        return MODEACTION_DENY;
 }
@@ -160,23 +160,7 @@ bool ModeHandler::CheckTimeStamp(std::string& theirs, const std::string& ours, C
        return (theirs < ours);
 }
 
-SimpleUserModeHandler::SimpleUserModeHandler(InspIRCd* Instance, char modeletter) : ModeHandler(Instance, modeletter, 0, 0, false, MODETYPE_USER, false)
-{
-}
-
-SimpleUserModeHandler::~SimpleUserModeHandler()
-{
-}
-
-SimpleChannelModeHandler::~SimpleChannelModeHandler()
-{
-}
-
-SimpleChannelModeHandler::SimpleChannelModeHandler(InspIRCd* Instance, char modeletter) : ModeHandler(Instance, modeletter, 0, 0, false, MODETYPE_CHANNEL, false)
-{
-}
-
-ModeAction SimpleUserModeHandler::OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding, bool servermode)
+ModeAction SimpleUserModeHandler::OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
 {
        if (adding)
        {
@@ -199,7 +183,7 @@ ModeAction SimpleUserModeHandler::OnModeChange(User* source, User* dest, Channel
 }
 
 
-ModeAction SimpleChannelModeHandler::OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding, bool servermode)
+ModeAction SimpleChannelModeHandler::OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
 {
        if (adding)
        {
@@ -239,12 +223,12 @@ ModeType ModeWatcher::GetModeType()
        return m_type;
 }
 
-bool ModeWatcher::BeforeMode(User*, User*, Channel*, std::string&, bool, ModeType, bool)
+bool ModeWatcher::BeforeMode(User*, User*, Channel*, std::string&, bool, ModeType)
 {
        return true;
 }
 
-void ModeWatcher::AfterMode(User*, User*, Channel*, const std::string&, bool, ModeType, bool)
+void ModeWatcher::AfterMode(User*, User*, Channel*, const std::string&, bool, ModeType)
 {
 }
 
@@ -335,12 +319,6 @@ void ModeParser::DisplayCurrentModes(User *user, User* targetuser, Channel* targ
        }
        else
        {
-               if (targetuser->Visibility && !targetuser->Visibility->VisibleTo(user))
-               {
-                       user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(), text);
-                       return;
-               }
-
                if (targetuser == user || user->HasPrivPermission("users/auspex"))
                {
                        /* Display user's current mode string */
@@ -351,14 +329,14 @@ void ModeParser::DisplayCurrentModes(User *user, User* targetuser, Channel* targ
                }
                else
                {
-                       user->WriteNumeric(ERR_USERSDONTMATCH, "%s :Can't change mode for other users", user->nick.c_str());
+                       user->WriteNumeric(ERR_USERSDONTMATCH, "%s :Can't view modes for other users", user->nick.c_str());
                        return;
                }
        }
 }
 
 ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool adding, const unsigned char modechar,
-               std::string &parameter, bool servermode, bool SkipACL)
+               std::string &parameter, bool SkipACL)
 {
        ModeType type = chan ? MODETYPE_CHANNEL : MODETYPE_USER;
        unsigned char mask = chan ? MASK_CHANNEL : MASK_USER;
@@ -366,13 +344,13 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
        ModeHandler *mh = FindMode(modechar, type);
        int pcnt = mh->GetNumParams(adding);
 
-       int MOD_RESULT = 0;
-       FOREACH_RESULT(I_OnRawMode, OnRawMode(user, chan, modechar, parameter, adding, pcnt, servermode));
+       ModResult MOD_RESULT;
+       FIRST_MOD_RESULT(ServerInstance, OnRawMode, MOD_RESULT, (user, chan, modechar, parameter, adding, pcnt));
 
-       if (IS_LOCAL(user) && (MOD_RESULT == ACR_DENY))
+       if (IS_LOCAL(user) && (MOD_RESULT == MOD_RES_DENY))
                return MODEACTION_DENY;
 
-       if (chan && !SkipACL && (MOD_RESULT != ACR_ALLOW))
+       if (chan && !SkipACL && (MOD_RESULT != MOD_RES_ALLOW))
        {
                char needed = mh->GetNeededPrefix();
                ModeHandler* prefixmode = FindPrefix(needed);
@@ -413,7 +391,7 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
 
        for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++)
        {
-               if ((*watchers)->BeforeMode(user, targetuser, chan, parameter, adding, type, servermode) == false)
+               if ((*watchers)->BeforeMode(user, targetuser, chan, parameter, adding, type) == false)
                        return MODEACTION_DENY;
                /* A module whacked the parameter completely, and there was one. abort. */
                if (pcnt && parameter.empty())
@@ -448,7 +426,7 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
        }
 
        /* Call the handler for the mode */
-       ModeAction ma = mh->OnModeChange(user, targetuser, chan, parameter, adding, servermode);
+       ModeAction ma = mh->OnModeChange(user, targetuser, chan, parameter, adding);
 
        if (pcnt && parameter.empty())
                return MODEACTION_DENY;
@@ -466,12 +444,12 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
        }
 
        for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++)
-               (*watchers)->AfterMode(user, targetuser, chan, parameter, adding, type, servermode);
+               (*watchers)->AfterMode(user, targetuser, chan, parameter, adding, type);
 
        return MODEACTION_ALLOW;
 }
 
-void ModeParser::Process(const std::vector<std::string>& parameters, User *user, bool servermode, bool merge)
+void ModeParser::Process(const std::vector<std::string>& parameters, User *user, bool merge)
 {
        std::string target = parameters[0];
        Channel* targetchannel = ServerInstance->FindChan(target);
@@ -497,31 +475,30 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user,
 
        bool SkipAccessChecks = false;
 
-       if (servermode || !IS_LOCAL(user) || ServerInstance->ULine(user->server))
+       if (!IS_LOCAL(user) || ServerInstance->ULine(user->server))
        {
                SkipAccessChecks = true;
        }
-       else if (targetchannel)
+       else
        {
                /* Overall access control hook for mode change */
+               int hook = targetchannel ? AC_GENERAL_MODE : AC_GENERAL_UMODE;
+
                LastParse = mode_sequence;
-               int MOD_RESULT = 0;
-               FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user, NULL, targetchannel, AC_GENERAL_MODE));
+               ModResult MOD_RESULT;
+               FIRST_MOD_RESULT(ServerInstance, OnAccessCheck, MOD_RESULT, (user, targetuser, targetchannel, hook));
                LastParse.clear();
-               if (MOD_RESULT == ACR_DENY)
+               if (MOD_RESULT == MOD_RES_DENY)
                        return;
-               SkipAccessChecks = (MOD_RESULT == ACR_ALLOW);
+               SkipAccessChecks = (MOD_RESULT == MOD_RES_ALLOW);
        }
-       else
+
+       if (targetuser && !SkipAccessChecks && user != targetuser)
        {
-               if (user != targetuser)
-               {
-                       user->WriteNumeric(ERR_USERSDONTMATCH, "%s :Can't change mode for other users", user->nick.c_str());
-                       return;
-               }
+               user->WriteNumeric(ERR_USERSDONTMATCH, "%s :Can't change mode for other users", user->nick.c_str());
+               return;
        }
 
-
        std::string output_mode;
        std::ostringstream output_parameters;
        LastParseParams.push_back(output_mode);
@@ -571,7 +548,7 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user,
                        }
                }
 
-               ModeAction ma = TryMode(user, targetuser, targetchannel, adding, modechar, parameter, servermode, SkipAccessChecks);
+               ModeAction ma = TryMode(user, targetuser, targetchannel, adding, modechar, parameter, SkipAccessChecks);
 
                if (ma != MODEACTION_ALLOW)
                        continue;
@@ -609,16 +586,12 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user,
                LastParse.append(output_mode);
                LastParse.append(output_parameters.str());
 
-               if (!user && targetchannel)
-                       targetchannel->WriteChannelWithServ(ServerInstance->Config->ServerName, "MODE %s", LastParse.c_str());
-               else if (!user && targetuser)
-                       targetuser->WriteServ("MODE %s", LastParse.c_str());
-               else if (targetchannel)
+               if (targetchannel)
                {
                        targetchannel->WriteChannel(user, "MODE %s", LastParse.c_str());
                        FOREACH_MOD(I_OnMode,OnMode(user, targetchannel, TYPE_CHANNEL, LastParseParams, LastParseTranslate));
                }
-               else if (targetuser)
+               else
                {
                        targetuser->WriteFrom(user, "MODE %s", LastParse.c_str());
                        FOREACH_MOD(I_OnMode,OnMode(user, targetuser, TYPE_USER, LastParseParams, LastParseTranslate));
@@ -656,9 +629,9 @@ void ModeParser::DisplayListModes(User* user, Channel* chan, std::string &mode_s
                if (!mh || !mh->IsListMode())
                        return;
 
-               int MOD_RESULT = 0;
-               FOREACH_RESULT(I_OnRawMode, OnRawMode(user, chan, mletter, "", true, 0));
-               if (MOD_RESULT == ACR_DENY)
+               ModResult MOD_RESULT;
+               FIRST_MOD_RESULT(ServerInstance, OnRawMode, MOD_RESULT, (user, chan, mletter, "", true, 0));
+               if (MOD_RESULT == MOD_RES_DENY)
                        continue;
 
                bool display = true;
@@ -1049,7 +1022,7 @@ void ModeHandler::RemoveMode(User* user, irc::modestacker* stack)
                        sprintf(moderemove,"-%c",this->GetModeChar());
                        parameters.push_back(user->nick);
                        parameters.push_back(moderemove);
-                       ServerInstance->Modes->Process(parameters, ServerInstance->FakeClient, true);
+                       ServerInstance->Modes->Process(parameters, ServerInstance->FakeClient);
                }
        }
 }
@@ -1086,19 +1059,22 @@ ModeParser::ModeParser(InspIRCd* Instance) : ServerInstance(Instance)
                new ModeChannelPrivate(Instance),
                new ModeChannelModerated(Instance),
                new ModeChannelTopicOps(Instance),
+
                new ModeChannelNoExternal(Instance),
                new ModeChannelInviteOnly(Instance),
                new ModeChannelKey(Instance),
                new ModeChannelLimit(Instance),
+
                new ModeChannelBan(Instance),
                new ModeChannelOp(Instance),
                new ModeChannelHalfOp(Instance),
                new ModeChannelVoice(Instance),
+
                new ModeUserWallops(Instance),
                new ModeUserInvisible(Instance),
                new ModeUserOperator(Instance),
                new ModeUserServerNoticeMask(Instance),
-               NULL
+#define BUILTIN_MODE_COUNT 16
        };
 
        /* Clear mode handler list */
@@ -1108,9 +1084,25 @@ ModeParser::ModeParser(InspIRCd* Instance) : ServerInstance(Instance)
        LastParse.clear();
 
        /* Initialise the RFC mode letters */
-       for (int index = 0; modes[index]; index++)
+       for (int index = 0; index < BUILTIN_MODE_COUNT; index++)
                this->AddMode(modes[index]);
 
        seq = 0;
        memset(&sent, 0, sizeof(sent));
 }
+
+ModeParser::~ModeParser()
+{
+       int count = 0;
+       for(int i=0; i < 256; i++)
+       {
+               ModeHandler* mh = modehandlers[i];
+               if (mh)
+               {
+                       count++;
+                       delete mh;
+               }
+       }
+       if (count != BUILTIN_MODE_COUNT)
+               throw CoreException("Mode handler found non-core modes remaining at deallocation");
+}