]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/mode.cpp
Jason, try this..
[user/henk/code/inspircd.git] / src / mode.cpp
index 6805c348c8629cf7e53167dc978abea91a93d1a9..d73a5d1b8921f94b3153d462c467a436ebde811a 100644 (file)
@@ -149,6 +149,71 @@ bool ModeHandler::CheckTimeStamp(time_t theirs, time_t ours, const std::string&,
        return (ours < theirs);
 }
 
+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)
+{
+       /* Only opers can change other users modes */
+       if (source != dest)
+               return MODEACTION_DENY;
+
+       if (adding)
+       {
+               if (!dest->IsModeSet(this->GetModeChar()))
+               {
+                       dest->SetMode(this->GetModeChar(),true);
+                       return MODEACTION_ALLOW;
+               }
+       }
+       else
+       {
+               if (dest->IsModeSet(this->GetModeChar()))
+               {
+                       dest->SetMode(this->GetModeChar(),false);
+                       return MODEACTION_ALLOW;
+               }
+       }
+
+       return MODEACTION_DENY;
+}
+
+
+ModeAction SimpleChannelModeHandler::OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding, bool servermode)
+{
+       if (adding)
+       {
+               if (!channel->IsModeSet(this->GetModeChar()))
+               {
+                       channel->SetMode(this->GetModeChar(),true);
+                       return MODEACTION_ALLOW;
+               }
+       }
+       else
+       {
+               if (channel->IsModeSet(this->GetModeChar()))
+               {
+                       channel->SetMode(this->GetModeChar(),false);
+                       return MODEACTION_ALLOW;
+               }
+       }
+
+       return MODEACTION_DENY;
+}
+
 ModeWatcher::ModeWatcher(InspIRCd* Instance, char modeletter, ModeType type) : ServerInstance(Instance), mode(modeletter), m_type(type)
 {
 }
@@ -289,7 +354,7 @@ void ModeParser::DisplayCurrentModes(User *user, User* targetuser, Channel* targ
        return;
 }
 
-void ModeParser::Process(const char* const* parameters, int pcnt, User *user, bool servermode)
+void ModeParser::Process(const std::vector<std::string>& parameters, User *user, bool servermode)
 {
        std::string target = parameters[0];
        ModeType type = MODETYPE_USER;
@@ -302,15 +367,14 @@ void ModeParser::Process(const char* const* parameters, int pcnt, User *user, bo
        /* Special case for displaying the list for listmodes,
         * e.g. MODE #chan b, or MODE #chan +b without a parameter
         */
-       if ((targetchannel) && (pcnt == 2))
+       if ((targetchannel) && (parameters.size() == 2))
        {
-               const char* mode = parameters[1];
+               const char* mode = parameters[1].c_str();
                int nonlistmodes_found = 0;
-               bool sent[256];
 
-               mask = MASK_CHANNEL;
+               seq++;
 
-               memset(&sent, 0, 256);
+               mask = MASK_CHANNEL;
                
                while (mode && *mode)
                {
@@ -325,9 +389,9 @@ void ModeParser::Process(const char* const* parameters, int pcnt, User *user, bo
                        /* Ensure the user doesnt request the same mode twice,
                         * so they cant flood themselves off out of idiocy.
                         */
-                       if (!sent[mletter])
+                       if (sent[mletter] != seq)
                        {
-                               sent[mletter] = true;
+                               sent[mletter] = seq;
                        }
                        else
                        {
@@ -381,11 +445,11 @@ void ModeParser::Process(const char* const* parameters, int pcnt, User *user, bo
                        return;
        }
 
-       if (pcnt == 1)
+       if (parameters.size() == 1)
        {
-               this->DisplayCurrentModes(user, targetuser, targetchannel, parameters[0]);
+               this->DisplayCurrentModes(user, targetuser, targetchannel, parameters[0].c_str());
        }
-       else if (pcnt > 1)
+       else if (parameters.size() > 1)
        {
                bool SkipAccessChecks = false;
 
@@ -421,7 +485,7 @@ void ModeParser::Process(const char* const* parameters, int pcnt, User *user, bo
                else
                {
                        /* No such nick/channel */
-                       user->WriteNumeric(401, "%s %s :No such nick/channel",user->nick, parameters[0]);
+                       user->WriteNumeric(401, "%s %s :No such nick/channel",user->nick, parameters[0].c_str());
                        return;
                }
 
@@ -431,8 +495,8 @@ void ModeParser::Process(const char* const* parameters, int pcnt, User *user, bo
                std::string output_sequence;
                bool adding = true, state_change = false;
                unsigned char handler_id = 0;
-               int parameter_counter = 2; /* Index of first parameter */
-               int parameter_count = 0;
+               unsigned int parameter_counter = 2; /* Index of first parameter */
+               unsigned int parameter_count = 0;
                bool last_successful_state_change = false;
 
                /* A mode sequence that doesnt start with + or -. Assume +. - Thanks for the suggestion spike (bug#132) */
@@ -495,7 +559,7 @@ void ModeParser::Process(const char* const* parameters, int pcnt, User *user, bo
                                                        if (modehandlers[handler_id]->GetNumParams(adding))
                                                        {
                                                                /* This mode expects a parameter, do we have any parameters left in our list to use? */
-                                                               if (parameter_counter < pcnt)
+                                                               if (parameter_counter < parameters.size())
                                                                {
                                                                        parameter = parameters[parameter_counter++];
 
@@ -577,14 +641,23 @@ void ModeParser::Process(const char* const* parameters, int pcnt, User *user, bo
                                                        /* It's an oper only mode, check if theyre an oper. If they arent,
                                                         * eat any parameter that  came with the mode, and continue to next
                                                         */
-                                                       if ((IS_LOCAL(user)) && (modehandlers[handler_id]->NeedsOper()) && (!user->HasModePermission(modehandlers[handler_id]->GetModeChar(), type)))
+                                                       if (adding && (IS_LOCAL(user)) && (modehandlers[handler_id]->NeedsOper()) && (!user->HasModePermission(modehandlers[handler_id]->GetModeChar(), type)))
                                                        {
-                                                               user->WriteNumeric(481, "%s :Permission Denied - Oper type %s does not have access to %sset %s mode %c",
-                                                                               user->nick,
-                                                                               user->oper,
-                                                                               adding ? "" : "un",
-                                                                               type == MODETYPE_CHANNEL ? "channel" : "user",
-                                                                               modehandlers[handler_id]->GetModeChar());
+                                                               if (IS_OPER(user))
+                                                               {
+                                                                       user->WriteNumeric(481, "%s :Permission Denied - Oper type %s does not have access to set %s mode %c",
+                                                                                       user->nick,
+                                                                                       user->oper,
+                                                                                       type == MODETYPE_CHANNEL ? "channel" : "user",
+                                                                                       modehandlers[handler_id]->GetModeChar());
+                                                               }
+                                                               else
+                                                               {
+                                                                       user->WriteNumeric(481, "%s :Permission Denied - Only operators may set %s mode %c",
+                                                                                       user->nick,
+                                                                                       type == MODETYPE_CHANNEL ? "channel" : "user",
+                                                                                       modehandlers[handler_id]->GetModeChar());
+                                                               }
                                                                continue;
                                                        }
 
@@ -1054,7 +1127,7 @@ bool ModeParser::DelModeWatcher(ModeWatcher* mw)
 void ModeHandler::RemoveMode(User* user, irc::modestacker* stack)
 {
        char moderemove[MAXBUF];
-       const char* parameters[] = { user->nick, moderemove };
+       std::vector<std::string> parameters;
 
        if (user->IsModeSet(this->GetModeChar()))
        {
@@ -1065,7 +1138,9 @@ void ModeHandler::RemoveMode(User* user, irc::modestacker* stack)
                else
                {
                        sprintf(moderemove,"-%c",this->GetModeChar());
-                       ServerInstance->Parser->CallHandler("MODE", parameters, 2, user);
+                       parameters.push_back(user->nick);
+                       parameters.push_back(moderemove);
+                       ServerInstance->Parser->CallHandler("MODE", parameters, user);
                }
        }
 }
@@ -1076,7 +1151,7 @@ void ModeHandler::RemoveMode(User* user, irc::modestacker* stack)
 void ModeHandler::RemoveMode(Channel* channel, irc::modestacker* stack)
 {
        char moderemove[MAXBUF];
-       const char* parameters[] = { channel->name, moderemove };
+       std::vector<std::string> parameters;
 
        if (channel->IsModeSet(this->GetModeChar()))
        {
@@ -1087,7 +1162,9 @@ void ModeHandler::RemoveMode(Channel* channel, irc::modestacker* stack)
                else
                {
                        sprintf(moderemove,"-%c",this->GetModeChar());
-                       ServerInstance->SendMode(parameters, 2, ServerInstance->FakeClient);
+                       parameters.push_back(channel->name);
+                       parameters.push_back(moderemove);
+                       ServerInstance->SendMode(parameters, ServerInstance->FakeClient);
                }
        }
 }
@@ -1116,9 +1193,8 @@ ModeParser::ModeParser(InspIRCd* Instance) : ServerInstance(Instance)
                NULL
        };
 
-       /* Clear mode list */
+       /* Clear mode handler list */
        memset(modehandlers, 0, sizeof(modehandlers));
-       memset(modewatchers, 0, sizeof(modewatchers));
 
        /* Last parse string */
        LastParse.clear();
@@ -1126,4 +1202,7 @@ ModeParser::ModeParser(InspIRCd* Instance) : ServerInstance(Instance)
        /* Initialise the RFC mode letters */
        for (int index = 0; modes[index]; index++)
                this->AddMode(modes[index]);
+
+       seq = 0;
+       memset(&sent, 0, 256);
 }