summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/modules/m_autoop.cpp12
-rw-r--r--src/modules/m_banredirect.cpp20
-rw-r--r--src/modules/m_channames.cpp11
-rw-r--r--src/modules/m_messageflood.cpp8
-rw-r--r--src/modules/m_ojoin.cpp17
-rw-r--r--src/modules/m_operprefix.cpp12
-rw-r--r--src/modules/m_repeat.cpp8
-rw-r--r--src/modules/m_rmode.cpp17
-rw-r--r--src/modules/m_spanningtree/commands.h2
-rw-r--r--src/modules/m_spanningtree/fjoin.cpp36
-rw-r--r--src/modules/m_timedbans.cpp17
-rw-r--r--src/users.cpp12
12 files changed, 60 insertions, 112 deletions
diff --git a/src/modules/m_autoop.cpp b/src/modules/m_autoop.cpp
index 828bef14c..801cf6c74 100644
--- a/src/modules/m_autoop.cpp
+++ b/src/modules/m_autoop.cpp
@@ -89,9 +89,7 @@ class ModuleAutoOp : public Module
ListModeBase::ModeList* list = mh.GetList(memb->chan);
if (list)
{
- std::string modeline("+");
- std::vector<std::string> modechange;
- modechange.push_back(memb->chan->name);
+ Modes::ChangeList changelist;
for (ListModeBase::ModeList::iterator it = list->begin(); it != list->end(); it++)
{
std::string::size_type colon = it->mask.find(':');
@@ -101,14 +99,10 @@ class ModuleAutoOp : public Module
{
PrefixMode* given = mh.FindMode(it->mask.substr(0, colon));
if (given)
- modeline.push_back(given->GetModeChar());
+ changelist.push_add(given, memb->user->nick);
}
}
- modechange.push_back(modeline);
- for(std::string::size_type i = modeline.length(); i > 1; --i) // we use "i > 1" instead of "i" so we skip the +
- modechange.push_back(memb->user->nick);
- if(modechange.size() >= 3)
- ServerInstance->Modes->Process(modechange, ServerInstance->FakeClient);
+ ServerInstance->Modes->Process(ServerInstance->FakeClient, memb->chan, NULL, changelist);
}
}
diff --git a/src/modules/m_banredirect.cpp b/src/modules/m_banredirect.cpp
index 1a123e580..d82b8473c 100644
--- a/src/modules/m_banredirect.cpp
+++ b/src/modules/m_banredirect.cpp
@@ -238,26 +238,16 @@ class ModuleBanRedirect : public Module
if(redirects)
{
- irc::modestacker modestack(false);
+ ModeHandler* ban = ServerInstance->Modes->FindMode('b', MODETYPE_CHANNEL);
+ Modes::ChangeList changelist;
for(BanRedirectList::iterator i = redirects->begin(); i != redirects->end(); i++)
- {
- modestack.Push('b', i->targetchan.insert(0, i->banmask));
- }
+ changelist.push_remove(ban, i->targetchan.insert(0, i->banmask));
for(BanRedirectList::iterator i = redirects->begin(); i != redirects->end(); i++)
- {
- modestack.PushPlus();
- modestack.Push('b', i->banmask);
- }
+ changelist.push_add(ban, i->banmask);
- std::vector<std::string> stackresult;
- stackresult.push_back(chan->name);
- while (modestack.GetStackedLine(stackresult))
- {
- ServerInstance->Modes->Process(stackresult, ServerInstance->FakeClient, ModeParser::MODE_LOCALONLY);
- stackresult.erase(stackresult.begin() + 1, stackresult.end());
- }
+ ServerInstance->Modes->Process(ServerInstance->FakeClient, chan, NULL, changelist, ModeParser::MODE_LOCALONLY);
}
}
}
diff --git a/src/modules/m_channames.cpp b/src/modules/m_channames.cpp
index 1fb5b2a40..7513cb33a 100644
--- a/src/modules/m_channames.cpp
+++ b/src/modules/m_channames.cpp
@@ -64,6 +64,8 @@ class ModuleChannelNames : public Module
void ValidateChans()
{
+ Modes::ChangeList removepermchan;
+
badchan = true;
const chan_hash& chans = ServerInstance->GetChans();
for (chan_hash::const_iterator i = chans.begin(); i != chans.end(); )
@@ -76,12 +78,11 @@ class ModuleChannelNames : public Module
if (c->IsModeSet(permchannelmode) && c->GetUserCounter())
{
- std::vector<std::string> modes;
- modes.push_back(c->name);
- modes.push_back(std::string("-") + permchannelmode->GetModeChar());
-
- ServerInstance->Modes->Process(modes, ServerInstance->FakeClient);
+ removepermchan.clear();
+ removepermchan.push_remove(*permchannelmode);
+ ServerInstance->Modes->Process(ServerInstance->FakeClient, c, NULL, removepermchan);
}
+
Channel::MemberMap& users = c->userlist;
for (Channel::MemberMap::iterator j = users.begin(); j != users.end(); )
{
diff --git a/src/modules/m_messageflood.cpp b/src/modules/m_messageflood.cpp
index 92d67b9ab..3cebd2a5f 100644
--- a/src/modules/m_messageflood.cpp
+++ b/src/modules/m_messageflood.cpp
@@ -137,11 +137,9 @@ class ModuleMsgFlood : public Module
f->clear(user);
if (f->ban)
{
- std::vector<std::string> parameters;
- parameters.push_back(dest->name);
- parameters.push_back("+b");
- parameters.push_back("*!*@" + user->dhost);
- ServerInstance->Modes->Process(parameters, ServerInstance->FakeClient);
+ Modes::ChangeList changelist;
+ changelist.push_add(ServerInstance->Modes->FindMode('b', MODETYPE_CHANNEL), "*!*@" + user->dhost);
+ ServerInstance->Modes->Process(ServerInstance->FakeClient, dest, NULL, changelist);
}
const std::string kickMessage = "Channel flood triggered (limit is " + ConvToStr(f->lines) +
diff --git a/src/modules/m_ojoin.cpp b/src/modules/m_ojoin.cpp
index 3710757aa..1444f93ad 100644
--- a/src/modules/m_ojoin.cpp
+++ b/src/modules/m_ojoin.cpp
@@ -65,18 +65,17 @@ class CommandOjoin : public SplitCommand
}
else
{
+ channel = ServerInstance->FindChan(parameters[0]);
+ if (!channel)
+ return CMD_FAILURE;
+
ServerInstance->SNO->WriteGlobalSno('a', user->nick+" used OJOIN in "+parameters[0]);
// they're already in the channel
- std::vector<std::string> modes;
- modes.push_back(parameters[0]);
- modes.push_back(std::string("+") + npmh->GetModeChar());
+ Modes::ChangeList changelist;
+ changelist.push_add(npmh, user->nick);
if (op)
- {
- modes[1].push_back('o');
- modes.push_back(user->nick);
- }
- modes.push_back(user->nick);
- ServerInstance->Modes->Process(modes, ServerInstance->FakeClient);
+ changelist.push_add(ServerInstance->Modes->FindMode('o', MODETYPE_CHANNEL), user->nick);
+ ServerInstance->Modes->Process(ServerInstance->FakeClient, channel, NULL, changelist);
}
return CMD_SUCCESS;
}
diff --git a/src/modules/m_operprefix.cpp b/src/modules/m_operprefix.cpp
index 262c034db..4c63e53d1 100644
--- a/src/modules/m_operprefix.cpp
+++ b/src/modules/m_operprefix.cpp
@@ -74,16 +74,10 @@ class ModuleOperPrefixMode : public Module
void SetOperPrefix(User* user, bool add)
{
- std::vector<std::string> modechange;
- modechange.push_back("");
- modechange.push_back(add ? "+" : "-");
- modechange[1].push_back(opm.GetModeChar());
- modechange.push_back(user->nick);
+ Modes::ChangeList changelist;
+ changelist.push(&opm, add, user->nick);
for (User::ChanList::iterator v = user->chans.begin(); v != user->chans.end(); v++)
- {
- modechange[0] = (*v)->chan->name;
- ServerInstance->Modes->Process(modechange, ServerInstance->FakeClient);
- }
+ ServerInstance->Modes->Process(ServerInstance->FakeClient, (*v)->chan, NULL, changelist);
}
void OnPostOper(User* user, const std::string& opername, const std::string& opertype) CXX11_OVERRIDE
diff --git a/src/modules/m_repeat.cpp b/src/modules/m_repeat.cpp
index b992fe0f4..ca6955040 100644
--- a/src/modules/m_repeat.cpp
+++ b/src/modules/m_repeat.cpp
@@ -376,11 +376,9 @@ class RepeatModule : public Module
if (settings->Action == ChannelSettings::ACT_BAN)
{
- std::vector<std::string> parameters;
- parameters.push_back(memb->chan->name);
- parameters.push_back("+b");
- parameters.push_back("*!*@" + user->dhost);
- ServerInstance->Modes->Process(parameters, ServerInstance->FakeClient);
+ Modes::ChangeList changelist;
+ changelist.push_add(ServerInstance->Modes->FindMode('b', MODETYPE_CHANNEL), "*!*@" + user->dhost);
+ ServerInstance->Modes->Process(ServerInstance->FakeClient, chan, NULL, changelist);
}
memb->chan->KickUser(ServerInstance->FakeClient, user, "Repeat flood");
diff --git a/src/modules/m_rmode.cpp b/src/modules/m_rmode.cpp
index c81fbd7e7..feb17383d 100644
--- a/src/modules/m_rmode.cpp
+++ b/src/modules/m_rmode.cpp
@@ -60,7 +60,7 @@ class CommandRMode : public Command
PrefixMode* pm;
ListModeBase* lm;
ListModeBase::ModeList* ml;
- irc::modestacker modestack(false);
+ Modes::ChangeList changelist;
if ((pm = mh->IsPrefixMode()))
{
@@ -71,7 +71,7 @@ class CommandRMode : public Command
if (!InspIRCd::Match(it->first->nick, pattern))
continue;
if (it->second->hasMode(modeletter) && !((it->first == user) && (pm->GetPrefixRank() > VOICE_VALUE)))
- modestack.Push(modeletter, it->first->nick);
+ changelist.push_remove(mh, it->first->nick);
}
}
else if ((lm = mh->IsListModeBase()) && ((ml = lm->GetList(chan)) != NULL))
@@ -80,23 +80,16 @@ class CommandRMode : public Command
{
if (!InspIRCd::Match(it->mask, pattern))
continue;
- modestack.Push(modeletter, it->mask);
+ changelist.push_remove(mh, it->mask);
}
}
else
{
if (chan->IsModeSet(mh))
- modestack.Push(modeletter);
- }
-
- parameterlist stackresult;
- stackresult.push_back(chan->name);
- while (modestack.GetStackedLine(stackresult))
- {
- ServerInstance->Modes->Process(stackresult, user);
- stackresult.erase(stackresult.begin() + 1, stackresult.end());
+ changelist.push_remove(mh);
}
+ ServerInstance->Modes->Process(user, chan, NULL, changelist);
return CMD_SUCCESS;
}
};
diff --git a/src/modules/m_spanningtree/commands.h b/src/modules/m_spanningtree/commands.h
index c26d5d7ae..1766ee067 100644
--- a/src/modules/m_spanningtree/commands.h
+++ b/src/modules/m_spanningtree/commands.h
@@ -130,7 +130,7 @@ class CommandFJoin : public ServerCommand
* @param newname The new name of the channel; must be the same or a case change of the current name
*/
static void LowerTS(Channel* chan, time_t TS, const std::string& newname);
- void ProcessModeUUIDPair(const std::string& item, TreeServer* sourceserver, Channel* chan, irc::modestacker* modestack);
+ void ProcessModeUUIDPair(const std::string& item, TreeServer* sourceserver, Channel* chan, Modes::ChangeList* modechangelist);
public:
CommandFJoin(Module* Creator) : ServerCommand(Creator, "FJOIN", 3) { }
CmdResult Handle(User* user, std::vector<std::string>& params);
diff --git a/src/modules/m_spanningtree/fjoin.cpp b/src/modules/m_spanningtree/fjoin.cpp
index 6263237a3..cb1126ac7 100644
--- a/src/modules/m_spanningtree/fjoin.cpp
+++ b/src/modules/m_spanningtree/fjoin.cpp
@@ -113,10 +113,9 @@ CmdResult CommandFJoin::Handle(User* srcuser, std::vector<std::string>& params)
}
/* First up, apply their channel modes if they won the TS war */
+ Modes::ChangeList modechangelist;
if (apply_other_sides_modes)
{
- // 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)
@@ -132,41 +131,33 @@ CmdResult CommandFJoin::Handle(User* srcuser, std::vector<std::string>& params)
++paramit;
}
- stack.Push(*i, modeparam);
+ modechangelist.push_add(mh, modeparam);
}
- std::vector<std::string> modelist;
-
- // Mode parser needs to know what channel to act on.
- modelist.push_back(params[0]);
-
- while (stack.GetStackedLine(modelist))
- {
- ServerInstance->Modes->Process(modelist, srcuser, ModeParser::MODE_LOCALONLY | ModeParser::MODE_MERGE);
- modelist.erase(modelist.begin() + 1, modelist.end());
- }
+ ServerInstance->Modes->Process(srcuser, chan, NULL, modechangelist, ModeParser::MODE_LOCALONLY | ModeParser::MODE_MERGE);
+ // Reuse for prefix modes
+ modechangelist.clear();
}
- irc::modestacker modestack(true);
TreeServer* const sourceserver = TreeServer::Get(srcuser);
/* Now, process every 'modes,uuid' pair */
irc::tokenstream users(params.back());
std::string item;
- irc::modestacker* modestackptr = (apply_other_sides_modes ? &modestack : NULL);
+ Modes::ChangeList* modechangelistptr = (apply_other_sides_modes ? &modechangelist : NULL);
while (users.GetToken(item))
{
- ProcessModeUUIDPair(item, sourceserver, chan, modestackptr);
+ ProcessModeUUIDPair(item, sourceserver, chan, modechangelistptr);
}
- /* Flush mode stacker if we lost the FJOIN or had equal TS */
+ // Set prefix modes on their users if we lost the FJOIN or had equal TS
if (apply_other_sides_modes)
- CommandFJoin::ApplyModeStack(srcuser, chan, modestack);
+ ServerInstance->Modes->Process(srcuser, chan, NULL, modechangelist, ModeParser::MODE_LOCALONLY);
return CMD_SUCCESS;
}
-void CommandFJoin::ProcessModeUUIDPair(const std::string& item, TreeServer* sourceserver, Channel* chan, irc::modestacker* modestack)
+void CommandFJoin::ProcessModeUUIDPair(const std::string& item, TreeServer* sourceserver, Channel* chan, Modes::ChangeList* modechangelist)
{
std::string::size_type comma = item.find(',');
@@ -189,17 +180,18 @@ void CommandFJoin::ProcessModeUUIDPair(const std::string& item, TreeServer* sour
}
/* Check if the user received at least one mode */
- if ((modestack) && (comma > 0) && (comma != std::string::npos))
+ if ((modechangelist) && (comma > 0) && (comma != std::string::npos))
{
/* Iterate through the modes and see if they are valid here, if so, apply */
std::string::const_iterator commait = item.begin()+comma;
for (std::string::const_iterator i = item.begin(); i != commait; ++i)
{
- if (!ServerInstance->Modes->FindMode(*i, MODETYPE_CHANNEL))
+ ModeHandler* mh = ServerInstance->Modes->FindMode(*i, MODETYPE_CHANNEL);
+ if (!mh)
throw ProtocolException("Unrecognised mode '" + std::string(1, *i) + "'");
/* Add any modes this user had to the mode stack */
- modestack->Push(*i, who->nick);
+ modechangelist->push_add(mh, who->nick);
}
}
diff --git a/src/modules/m_timedbans.cpp b/src/modules/m_timedbans.cpp
index e3a938336..803156446 100644
--- a/src/modules/m_timedbans.cpp
+++ b/src/modules/m_timedbans.cpp
@@ -71,17 +71,15 @@ class CommandTban : public Command
return CMD_FAILURE;
}
std::string mask = parameters[2];
- std::vector<std::string> setban;
- setban.push_back(parameters[0]);
- setban.push_back("+b");
bool isextban = ((mask.size() > 2) && (mask[1] == ':'));
if (!isextban && !InspIRCd::IsValidMask(mask))
mask.append("!*@*");
- setban.push_back(mask);
+ Modes::ChangeList setban;
+ setban.push_add(ServerInstance->Modes->FindMode('b', MODETYPE_CHANNEL), mask);
// Pass the user (instead of ServerInstance->FakeClient) to ModeHandler::Process() to
// make it so that the user sets the mode themselves
- ServerInstance->Modes->Process(setban, user);
+ ServerInstance->Modes->Process(user, channel, NULL, setban);
if (ServerInstance->Modes->GetLastParse().empty())
{
user->WriteNotice("Invalid ban mask");
@@ -169,17 +167,14 @@ class ModuleTimedBans : public Module
Channel* cr = ServerInstance->FindChan(chan);
if (cr)
{
- std::vector<std::string> setban;
- setban.push_back(chan);
- setban.push_back("-b");
- setban.push_back(mask);
-
CUList empty;
std::string expiry = "*** Timed ban on " + chan + " expired.";
cr->WriteAllExcept(ServerInstance->FakeClient, true, '@', empty, "NOTICE %s :%s", cr->name.c_str(), expiry.c_str());
ServerInstance->PI->SendChannelNotice(cr, '@', expiry);
- ServerInstance->Modes->Process(setban, ServerInstance->FakeClient);
+ Modes::ChangeList setban;
+ setban.push_remove(ServerInstance->Modes->FindMode('b', MODETYPE_CHANNEL), mask);
+ ServerInstance->Modes->Process(ServerInstance->FakeClient, cr, NULL, setban);
}
}
}
diff --git a/src/users.cpp b/src/users.cpp
index 5f0f1a344..4f9b6c945 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -449,21 +449,15 @@ void User::UnOper()
/* Remove all oper only modes from the user when the deoper - Bug #466*/
- std::string moderemove("-");
-
+ Modes::ChangeList changelist;
for (unsigned char letter = 'A'; letter <= 'z'; letter++)
{
ModeHandler* mh = ServerInstance->Modes->FindMode(letter, MODETYPE_USER);
if (mh && mh->NeedsOper())
- moderemove += letter;
+ changelist.push_remove(mh);
}
-
- std::vector<std::string> parameters;
- parameters.push_back(this->nick);
- parameters.push_back(moderemove);
-
- ServerInstance->Modes->Process(parameters, this);
+ ServerInstance->Modes->Process(this, NULL, this, changelist);
// Remove the user from the oper list
stdalgo::vector::swaperase(ServerInstance->Users->all_opers, this);