]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/mode.cpp
Merge pull request #1193 from Adam-/insp20+banburst
[user/henk/code/inspircd.git] / src / mode.cpp
index 35f64ce00aca616f8f19de4a0871f9d07870bc38..0f5d457834ba33538a28abb713c193751b9f6d71 100644 (file)
@@ -346,10 +346,19 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
                return MODEACTION_DENY;
        }
 
-       if (mh->GetTranslateType() == TR_NICK && !ServerInstance->FindNick(parameter))
+       if (mh->GetTranslateType() == TR_NICK)
        {
-               user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel", user->nick.c_str(), parameter.c_str());
-               return MODEACTION_DENY;
+               User* prefixtarget;
+               if (IS_LOCAL(user))
+                       prefixtarget = ServerInstance->FindNickOnly(parameter);
+               else
+                       prefixtarget = ServerInstance->FindNick(parameter);
+
+               if (!prefixtarget)
+               {
+                       user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel", user->nick.c_str(), parameter.c_str());
+                       return MODEACTION_DENY;
+               }
        }
 
        if (mh->GetPrefixRank() && chan)
@@ -378,16 +387,23 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
 
 void ModeParser::Process(const std::vector<std::string>& parameters, User *user, bool merge)
 {
-       std::string target = parameters[0];
+       const std::string& target = parameters[0];
        Channel* targetchannel = ServerInstance->FindChan(target);
-       User* targetuser  = ServerInstance->FindNick(target);
+       User* targetuser = NULL;
+       if (!targetchannel)
+       {
+               if (IS_LOCAL(user))
+                       targetuser = ServerInstance->FindNickOnly(target);
+               else
+                       targetuser = ServerInstance->FindNick(target);
+       }
        ModeType type = targetchannel ? MODETYPE_CHANNEL : MODETYPE_USER;
 
        LastParse.clear();
        LastParseParams.clear();
        LastParseTranslate.clear();
 
-       if (!targetchannel && !targetuser)
+       if ((!targetchannel) && ((!targetuser) || (IS_SERVER(targetuser))))
        {
                user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(),target.c_str());
                return;
@@ -454,7 +470,7 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user,
                {
                        parameter = parameters[param_at++];
                        /* Make sure the user isn't trying to slip in an invalid parameter */
-                       if ((parameter.find(':') == 0) || (parameter.rfind(' ') != std::string::npos))
+                       if ((parameter.empty()) || (parameter.find(':') == 0) || (parameter.rfind(' ') != std::string::npos))
                                continue;
                        if (merge && targetchannel && targetchannel->IsModeSet(modechar) && !mh->IsListMode())
                        {
@@ -821,11 +837,19 @@ std::string ModeParser::GiveModeList(ModeMasks m)
        return type1 + "," + type2 + "," + type3 + "," + type4;
 }
 
+struct PrefixModeSorter
+{
+       bool operator()(ModeHandler* lhs, ModeHandler* rhs)
+       {
+               return lhs->GetPrefixRank() < rhs->GetPrefixRank();
+       }
+};
+
 std::string ModeParser::BuildPrefixes(bool lettersAndModes)
 {
        std::string mletters;
        std::string mprefixes;
-       std::map<int,std::pair<char,char> > prefixes;
+       std::vector<ModeHandler*> prefixes;
 
        for (unsigned char mode = 'A'; mode <= 'z'; mode++)
        {
@@ -833,15 +857,15 @@ std::string ModeParser::BuildPrefixes(bool lettersAndModes)
 
                if ((modehandlers[pos]) && (modehandlers[pos]->GetPrefix()))
                {
-                       prefixes[modehandlers[pos]->GetPrefixRank()] = std::make_pair(
-                               modehandlers[pos]->GetPrefix(), modehandlers[pos]->GetModeChar());
+                       prefixes.push_back(modehandlers[pos]);
                }
        }
 
-       for(std::map<int,std::pair<char,char> >::reverse_iterator n = prefixes.rbegin(); n != prefixes.rend(); n++)
+       std::sort(prefixes.begin(), prefixes.end(), PrefixModeSorter());
+       for (std::vector<ModeHandler*>::const_reverse_iterator n = prefixes.rbegin(); n != prefixes.rend(); ++n)
        {
-               mletters = mletters + n->second.first;
-               mprefixes = mprefixes + n->second.second;
+               mletters += (*n)->GetPrefix();
+               mprefixes += (*n)->GetModeChar();
        }
 
        return lettersAndModes ? "(" + mprefixes + ")" + mletters : mletters;
@@ -880,7 +904,7 @@ bool ModeParser::DelModeWatcher(ModeWatcher* mw)
        mw->GetModeType() == MODETYPE_USER ? mask = MASK_USER : mask = MASK_CHANNEL;
        pos = (mw->GetModeChar()-65) | mask;
 
-       ModeWatchIter a = find(modewatchers[pos].begin(),modewatchers[pos].end(),mw);
+       ModeWatchIter a = std::find(modewatchers[pos].begin(),modewatchers[pos].end(),mw);
 
        if (a == modewatchers[pos].end())
        {