]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/mode.cpp
Fix an inverted condition in the cgiirc module.
[user/henk/code/inspircd.git] / src / mode.cpp
index e2129b55a46ce03a9466d169b2bed3886c5d082b..0bb97cc9ead29633407cce38333e0c7335fc77ed 100644 (file)
@@ -89,6 +89,11 @@ void ModeHandler::DisplayEmptyList(User*, Channel*)
 
 void ModeHandler::OnParameterMissing(User* user, User* dest, Channel* channel)
 {
+       const std::string message = InspIRCd::Format("You must specify a parameter for the %s mode", name.c_str());
+       if (channel)
+               user->WriteNumeric(Numerics::InvalidModeParameter(channel, this, "*", message));
+       else
+               user->WriteNumeric(Numerics::InvalidModeParameter(dest, this, "*", message));
 }
 
 bool ModeHandler::ResolveModeConflict(std::string& theirs, const std::string& ours, Channel*)
@@ -433,14 +438,9 @@ void ModeParser::Process(User* user, Channel* targetchannel, User* targetuser, M
 
 unsigned int ModeParser::ProcessSingle(User* user, Channel* targetchannel, User* targetuser, Modes::ChangeList& changelist, ModeProcessFlag flags, unsigned int beginindex)
 {
-       LastParse.clear();
        LastChangeList.clear();
 
        unsigned int modes_processed = 0;
-       std::string output_mode;
-       std::string output_parameters;
-
-       char output_pm = '\0'; // current output state, '+' or '-'
        Modes::ChangeList::List& list = changelist.getlist();
        for (Modes::ChangeList::List::iterator i = list.begin()+beginindex; i != list.end(); ++i)
        {
@@ -449,6 +449,12 @@ unsigned int ModeParser::ProcessSingle(User* user, Channel* targetchannel, User*
                Modes::Change& item = *i;
                ModeHandler* mh = item.mh;
 
+               // If a mode change has been given for a mode that does not exist then reject
+               // it. This can happen when core_reloadmodule attempts to restore a mode that
+               // no longer exists.
+               if (!mh)
+                       continue;
+
                // If the mode is supposed to have a parameter then we first take a look at item.param
                // and, if we were asked to, also handle mode merges now
                if (mh->NeedsParam(item.adding))
@@ -467,43 +473,30 @@ unsigned int ModeParser::ProcessSingle(User* user, Channel* targetchannel, User*
                if (ma != MODEACTION_ALLOW)
                        continue;
 
-               char needed_pm = item.adding ? '+' : '-';
-               if (needed_pm != output_pm)
-               {
-                       output_pm = needed_pm;
-                       output_mode.append(1, output_pm);
-               }
-               output_mode.push_back(mh->GetModeChar());
-
-               if (!item.param.empty())
-               {
-                       output_parameters.push_back(' ');
-                       output_parameters.append(item.param);
-               }
                LastChangeList.push(mh, item.adding, item.param);
 
-               if ((output_mode.length() + output_parameters.length() > 450)
-                               || (output_mode.length() > 100)
-                               || (LastChangeList.size() >= ServerInstance->Config->Limits.MaxModes))
+               if (LastChangeList.size() >= ServerInstance->Config->Limits.MaxModes)
                {
                        /* mode sequence is getting too long */
                        break;
                }
        }
 
-       if (!output_mode.empty())
+       if (!LastChangeList.empty())
        {
-               LastParse = targetchannel ? targetchannel->name : targetuser->nick;
-               LastParse.append(" ");
-               LastParse.append(output_mode);
-               LastParse.append(output_parameters);
-
+               ClientProtocol::Events::Mode modeevent(user, targetchannel, targetuser, LastChangeList);
                if (targetchannel)
-                       targetchannel->WriteChannel(user, "MODE " + LastParse);
+               {
+                       targetchannel->Write(modeevent);
+               }
                else
-                       targetuser->WriteFrom(user, "MODE " + LastParse);
+               {
+                       LocalUser* localtarget = IS_LOCAL(targetuser);
+                       if (localtarget)
+                               localtarget->Send(modeevent);
+               }
 
-               FOREACH_MOD(OnMode, (user, targetuser, targetchannel, LastChangeList, flags, output_mode));
+               FOREACH_MOD(OnMode, (user, targetuser, targetchannel, LastChangeList, flags));
        }
 
        return modes_processed;
@@ -637,8 +630,6 @@ void ModeParser::AddMode(ModeHandler* mh)
                mhlist.prefix.push_back(pm);
        else if (mh->IsListModeBase())
                mhlist.list.push_back(mh->IsListModeBase());
-
-       RecreateModeListFor004Numeric();
 }
 
 bool ModeParser::DelMode(ModeHandler* mh)
@@ -696,8 +687,6 @@ bool ModeParser::DelMode(ModeHandler* mh)
                mhlist.prefix.erase(std::find(mhlist.prefix.begin(), mhlist.prefix.end(), mh->IsPrefixMode()));
        else if (mh->IsListModeBase())
                mhlist.list.erase(std::find(mhlist.list.begin(), mhlist.list.end(), mh->IsListModeBase()));
-
-       RecreateModeListFor004Numeric();
        return true;
 }
 
@@ -727,27 +716,6 @@ PrefixMode* ModeParser::FindPrefixMode(unsigned char modeletter)
        return mh->IsPrefixMode();
 }
 
-std::string ModeParser::CreateModeList(ModeType mt, bool needparam)
-{
-       std::string modestr;
-
-       for (unsigned char mode = 'A'; mode <= 'z'; mode++)
-       {
-               ModeHandler* mh = modehandlers[mt][mode-65];
-               if ((mh) && ((!needparam) || (mh->NeedsParam(true))))
-                       modestr.push_back(mode);
-       }
-
-       return modestr;
-}
-
-void ModeParser::RecreateModeListFor004Numeric()
-{
-       Cached004ModeList[0] = CreateModeList(MODETYPE_USER);
-       Cached004ModeList[1] = CreateModeList(MODETYPE_CHANNEL);
-       Cached004ModeList[2] = CreateModeList(MODETYPE_CHANNEL, true);
-}
-
 PrefixMode* ModeParser::FindPrefix(unsigned const char pfxletter)
 {
        const PrefixModeList& list = GetPrefixModes();