]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_spanningtree/fjoin.cpp
m_ssl_gnutls Fix feature testing and cipher suite related errors on older GnuTLS...
[user/henk/code/inspircd.git] / src / modules / m_spanningtree / fjoin.cpp
index 71d837b2840b4bf0b150029ac935fd12a484115e..ee18c8e8742dd02021ce2c978a447e8fb8ef1f51 100644 (file)
@@ -106,6 +106,14 @@ CmdResult CommandFJoin::Handle(const std::vector<std::string>& params, User *src
                        chan->ClearInvites();
                        param_list.push_back(channel);
                        this->RemoveStatus(ServerInstance->FakeClient, param_list);
+
+                       // XXX: If the channel does not exist in the chan hash at this point, create it so the remote modes can be applied on it.
+                       // This happens to 0-user permanent channels on the losing side, because those are removed (from the chan hash, then
+                       // deleted later) as soon as the permchan mode is removed from them.
+                       if (ServerInstance->FindChan(channel) == NULL)
+                       {
+                               chan = new Channel(channel, TS);
+                       }
                }
                // The silent case here is ourTS == TS, we don't need to remove modes here, just to merge them later on.
        }
@@ -113,19 +121,38 @@ CmdResult CommandFJoin::Handle(const std::vector<std::string>& params, User *src
        /* First up, apply their modes if they won the TS war */
        if (apply_other_sides_modes)
        {
-               unsigned int idx = 2;
+               // Need to use a modestacker here due to maxmodes
+               irc::modestacker stack(true);
+               std::vector<std::string>::const_iterator paramit = params.begin() + 3;
+               const std::vector<std::string>::const_iterator lastparamit = ((params.size() > 3) ? (params.end() - 1) : params.end());
+               for (std::string::const_iterator i = params[2].begin(); i != params[2].end(); ++i)
+               {
+                       ModeHandler* mh = ServerInstance->Modes->FindMode(*i, MODETYPE_CHANNEL);
+                       if (!mh)
+                               continue;
+
+                       std::string modeparam;
+                       if ((paramit != lastparamit) && (mh->GetNumParams(true)))
+                       {
+                               modeparam = *paramit;
+                               ++paramit;
+                       }
+
+                       stack.Push(*i, modeparam);
+               }
+
                std::vector<std::string> modelist;
 
                // Mode parser needs to know what channel to act on.
                modelist.push_back(params[0]);
 
-               /* Remember, params[params.size() - 1] is nicklist, and we don't want to apply *that* */
-               for (idx = 2; idx != (params.size() - 1); idx++)
+               while (stack.GetStackedLine(modelist))
                {
-                       modelist.push_back(params[idx]);
+                       ServerInstance->Modes->Process(modelist, srcuser, true);
+                       modelist.erase(modelist.begin() + 1, modelist.end());
                }
 
-               ServerInstance->SendMode(modelist, srcuser);
+               ServerInstance->Modes->Process(modelist, srcuser, true);
        }
 
        /* Now, process every 'modes,nick' pair */