summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorattilamolnar <attilamolnar@hush.com>2013-05-26 23:23:47 +0200
committerattilamolnar <attilamolnar@hush.com>2013-05-27 01:07:29 +0200
commit9bb24d3f458274b7485554bc95f1274900a69ec2 (patch)
tree33ab45d74813198ba1377eab83b6a9904a91801e
parent244a65e8556328642350575c4a94ee8fc1b676b4 (diff)
Deduplicate RemoveMode() implementations
The default (core) implementation can now remove prefix modes The modestacker parameter is now mandatory
-rw-r--r--include/builtinmodes.h4
-rw-r--r--include/listmode.h7
-rw-r--r--include/mode.h18
-rw-r--r--src/listmode.cpp21
-rw-r--r--src/mode.cpp48
-rw-r--r--src/modes/cmode_k.cpp23
-rw-r--r--src/modes/cmode_o.cpp19
-rw-r--r--src/modes/cmode_v.cpp19
-rw-r--r--src/modules/m_customprefix.cpp30
-rw-r--r--src/modules/m_ojoin.cpp30
-rw-r--r--src/modules/m_spanningtree/fjoin.cpp2
11 files changed, 52 insertions, 169 deletions
diff --git a/include/builtinmodes.h b/include/builtinmodes.h
index a4a950922..46bfe282b 100644
--- a/include/builtinmodes.h
+++ b/include/builtinmodes.h
@@ -52,11 +52,9 @@ class ModeChannelKey : public ModeHandler
public:
ModeChannelKey();
ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding);
- void RemoveMode(Channel* channel, irc::modestacker* stack = NULL);
void RemoveMode(User* user, irc::modestacker* stack = NULL);
};
-
/** Channel mode +l
*/
class ModeChannelLimit : public ParamChannelModeHandler
@@ -96,7 +94,6 @@ class ModeChannelOp : public ModeHandler
ModeChannelOp();
ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding);
unsigned int GetPrefixRank();
- void RemoveMode(Channel* channel, irc::modestacker* stack = NULL);
void RemoveMode(User* user, irc::modestacker* stack = NULL);
};
@@ -140,7 +137,6 @@ class ModeChannelVoice : public ModeHandler
ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding);
unsigned int GetPrefixRank();
void RemoveMode(User* user, irc::modestacker* stack = NULL);
- void RemoveMode(Channel* channel, irc::modestacker* stack = NULL);
};
/** User mode +i
diff --git a/include/listmode.h b/include/listmode.h
index 1c6f70d6f..b4601fcbd 100644
--- a/include/listmode.h
+++ b/include/listmode.h
@@ -144,10 +144,13 @@ class CoreExport ListModeBase : public ModeHandler
virtual void DisplayEmptyList(User* user, Channel* channel);
/** Remove all instances of the mode from a channel.
- * See mode.h
+ * Populates the given modestack with modes that remove every instance of
+ * this mode from the channel.
+ * See mode.h for more details.
* @param channel The channel to remove all instances of the mode from
+ * @param stack The mode stack to add the mode change to
*/
- virtual void RemoveMode(Channel* channel, irc::modestacker* stack);
+ virtual void RemoveMode(Channel* channel, irc::modestacker& stack);
/** Listmodes don't get set on users, no-op
*/
diff --git a/include/mode.h b/include/mode.h
index b2e06257f..6afd00a86 100644
--- a/include/mode.h
+++ b/include/mode.h
@@ -100,6 +100,13 @@ enum ParamSpec
*/
class CoreExport ModeHandler : public ServiceProvider
{
+ /**
+ * Removes this prefix mode from all users on the given channel
+ * @param channel The channel which the server wants to remove your mode from
+ * @param stack The mode stack to add the mode change to
+ */
+ void RemovePrefixMode(Channel* chan, irc::modestacker& stack);
+
protected:
/**
* The mode parameter translation type
@@ -280,14 +287,15 @@ class CoreExport ModeHandler : public ServiceProvider
/**
* When a MODETYPE_CHANNEL mode handler is being removed, the server will call this method for every channel on the server.
- * Your mode handler should remove its user mode from the channel by sending the appropriate server modes using
- * InspIRCd::SendMode(). The default implementation of this method can remove simple modes which have no parameters,
- * and can be used when your mode is of this type, otherwise you must implement a more advanced version of it to remove
- * your mode properly from each channel. Note that in the case of listmodes, you should remove the entire list of items.
+ * The mode handler has to populate the given modestacker with mode changes that remove the mode from the channel.
+ * The default implementation of this method can remove all kinds of channel modes except listmodes.
+ * In the case of listmodes, the entire list of items must be added to the modestacker (which is handled by ListModeBase,
+ * so if you inherit from it or your mode can be removed by the default implementation then you do not have to implement
+ * this function).
* @param channel The channel which the server wants to remove your mode from
* @param stack The mode stack to add the mode change to
*/
- virtual void RemoveMode(Channel* channel, irc::modestacker* stack = NULL);
+ virtual void RemoveMode(Channel* channel, irc::modestacker& stack);
inline unsigned int GetLevelRequired() const { return levelrequired; }
};
diff --git a/src/listmode.cpp b/src/listmode.cpp
index 555f75fa3..5d54d8417 100644
--- a/src/listmode.cpp
+++ b/src/listmode.cpp
@@ -45,31 +45,14 @@ void ListModeBase::DisplayEmptyList(User* user, Channel* channel)
user->WriteNumeric(endoflistnumeric, "%s %s :%s", user->nick.c_str(), channel->name.c_str(), endofliststring.c_str());
}
-void ListModeBase::RemoveMode(Channel* channel, irc::modestacker* stack)
+void ListModeBase::RemoveMode(Channel* channel, irc::modestacker& stack)
{
ChanData* cd = extItem.get(channel);
if (cd)
{
- irc::modestacker modestack(false);
-
for (ModeList::iterator it = cd->list.begin(); it != cd->list.end(); it++)
{
- if (stack)
- stack->Push(this->GetModeChar(), it->mask);
- else
- modestack.Push(this->GetModeChar(), it->mask);
- }
-
- if (stack)
- return;
-
- std::vector<std::string> stackresult;
- stackresult.push_back(channel->name);
- while (modestack.GetStackedLine(stackresult))
- {
- ServerInstance->SendMode(stackresult, ServerInstance->FakeClient);
- stackresult.clear();
- stackresult.push_back(channel->name);
+ stack.Push(this->GetModeChar(), it->mask);
}
}
}
diff --git a/src/mode.cpp b/src/mode.cpp
index b4bb72c42..3d0edb185 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -650,7 +650,17 @@ bool ModeParser::DelMode(ModeHandler* mh)
// The channel may not be in the hash after RemoveMode(), see m_permchannels
Channel* chan = i->second;
++i;
- mh->RemoveMode(chan);
+
+ irc::modestacker stack(false);
+ mh->RemoveMode(chan, stack);
+
+ std::vector<std::string> stackresult;
+ stackresult.push_back(chan->name);
+ while (stack.GetStackedLine(stackresult))
+ {
+ ServerInstance->SendMode(stackresult, ServerInstance->FakeClient);
+ stackresult.erase(stackresult.begin() + 1, stackresult.end());
+ }
}
break;
}
@@ -849,25 +859,29 @@ void ModeHandler::RemoveMode(User* user, irc::modestacker* stack)
}
}
-/** This default implementation can remove simple channel modes
- * (no parameters)
- */
-void ModeHandler::RemoveMode(Channel* channel, irc::modestacker* stack)
+void ModeHandler::RemoveMode(Channel* channel, irc::modestacker& stack)
{
- if (channel->IsModeSet(this->GetModeChar()))
+ if (this->GetPrefixRank())
{
- if (stack)
- {
- stack->Push(this->GetModeChar());
- }
+ RemovePrefixMode(channel, stack);
+ }
+ else if (channel->IsModeSet(this->GetModeChar()))
+ {
+ if (this->GetNumParams(false))
+ // Removing this mode requires a parameter
+ stack.Push(this->GetModeChar(), channel->GetModeParameter(this->GetModeChar()));
else
- {
- std::vector<std::string> parameters;
- parameters.push_back(channel->name);
- parameters.push_back("-");
- parameters[1].push_back(this->GetModeChar());
- ServerInstance->SendMode(parameters, ServerInstance->FakeClient);
- }
+ stack.Push(this->GetModeChar());
+ }
+}
+
+void ModeHandler::RemovePrefixMode(Channel* chan, irc::modestacker& stack)
+{
+ const UserMembList* userlist = chan->GetUsers();
+ for (UserMembCIter i = userlist->begin(); i != userlist->end(); ++i)
+ {
+ if (i->second->hasMode(this->GetModeChar()))
+ stack.Push(this->GetModeChar(), i->first->nick);
}
}
diff --git a/src/modes/cmode_k.cpp b/src/modes/cmode_k.cpp
index b2d9f34e8..850bc69db 100644
--- a/src/modes/cmode_k.cpp
+++ b/src/modes/cmode_k.cpp
@@ -30,29 +30,6 @@ ModeChannelKey::ModeChannelKey() : ModeHandler(NULL, "key", 'k', PARAM_ALWAYS, M
{
}
-void ModeChannelKey::RemoveMode(Channel* channel, irc::modestacker* stack)
-{
- /** +k needs a parameter when being removed,
- * so we have a special-case RemoveMode here for it
- */
-
- if (channel->IsModeSet('k'))
- {
- if (stack)
- {
- stack->Push('k', channel->GetModeParameter('k'));
- }
- else
- {
- std::vector<std::string> parameters;
- parameters.push_back(channel->name);
- parameters.push_back("-k");
- parameters.push_back(channel->GetModeParameter('k'));
- ServerInstance->SendMode(parameters, ServerInstance->FakeClient);
- }
- }
-}
-
void ModeChannelKey::RemoveMode(User*, irc::modestacker* stack)
{
}
diff --git a/src/modes/cmode_o.cpp b/src/modes/cmode_o.cpp
index ff57e177a..80c768a00 100644
--- a/src/modes/cmode_o.cpp
+++ b/src/modes/cmode_o.cpp
@@ -41,25 +41,6 @@ unsigned int ModeChannelOp::GetPrefixRank()
return OP_VALUE;
}
-void ModeChannelOp::RemoveMode(Channel* channel, irc::modestacker* stack)
-{
- const UserMembList* clist = channel->GetUsers();
-
- for (UserMembCIter i = clist->begin(); i != clist->end(); i++)
- {
- if (stack)
- stack->Push(this->GetModeChar(), i->first->nick);
- else
- {
- std::vector<std::string> parameters;
- parameters.push_back(channel->name);
- parameters.push_back("-o");
- parameters.push_back(i->first->nick);
- ServerInstance->SendMode(parameters, ServerInstance->FakeClient);
- }
- }
-}
-
void ModeChannelOp::RemoveMode(User*, irc::modestacker* stack)
{
}
diff --git a/src/modes/cmode_v.cpp b/src/modes/cmode_v.cpp
index 61387ce83..2371ca2fa 100644
--- a/src/modes/cmode_v.cpp
+++ b/src/modes/cmode_v.cpp
@@ -41,25 +41,6 @@ unsigned int ModeChannelVoice::GetPrefixRank()
return VOICE_VALUE;
}
-void ModeChannelVoice::RemoveMode(Channel* channel, irc::modestacker* stack)
-{
- const UserMembList* clist = channel->GetUsers();
-
- for (UserMembCIter i = clist->begin(); i != clist->end(); i++)
- {
- if (stack)
- stack->Push(this->GetModeChar(), i->first->nick);
- else
- {
- std::vector<std::string> parameters;
- parameters.push_back(channel->name);
- parameters.push_back("-v");
- parameters.push_back(i->first->nick);
- ServerInstance->SendMode(parameters, ServerInstance->FakeClient);
- }
- }
-}
-
void ModeChannelVoice::RemoveMode(User*, irc::modestacker* stack)
{
}
diff --git a/src/modules/m_customprefix.cpp b/src/modules/m_customprefix.cpp
index 48a04d078..6f9f4da28 100644
--- a/src/modules/m_customprefix.cpp
+++ b/src/modules/m_customprefix.cpp
@@ -53,36 +53,6 @@ class CustomPrefixMode : public ModeHandler
return MOD_RES_PASSTHRU;
}
- void RemoveMode(Channel* channel, irc::modestacker* stack)
- {
- const UserMembList* cl = channel->GetUsers();
- std::vector<std::string> mode_junk;
- mode_junk.push_back(channel->name);
- irc::modestacker modestack(false);
- std::vector<std::string> stackresult;
-
- for (UserMembCIter i = cl->begin(); i != cl->end(); i++)
- {
- if (i->second->hasMode(mode))
- {
- if (stack)
- stack->Push(this->GetModeChar(), i->first->nick);
- else
- modestack.Push(this->GetModeChar(), i->first->nick);
- }
- }
-
- if (stack)
- return;
-
- while (modestack.GetStackedLine(stackresult))
- {
- mode_junk.insert(mode_junk.end(), stackresult.begin(), stackresult.end());
- ServerInstance->SendMode(mode_junk, ServerInstance->FakeClient);
- mode_junk.erase(mode_junk.begin() + 1, mode_junk.end());
- }
- }
-
void RemoveMode(User* user, irc::modestacker* stack)
{
}
diff --git a/src/modules/m_ojoin.cpp b/src/modules/m_ojoin.cpp
index 35d90b23e..5b6335580 100644
--- a/src/modules/m_ojoin.cpp
+++ b/src/modules/m_ojoin.cpp
@@ -112,36 +112,6 @@ class NetworkPrefix : public ModeHandler
m_paramtype = TR_NICK;
}
- void RemoveMode(Channel* channel, irc::modestacker* stack)
- {
- const UserMembList* cl = channel->GetUsers();
- std::vector<std::string> mode_junk;
- mode_junk.push_back(channel->name);
- irc::modestacker modestack(false);
- std::vector<std::string> stackresult;
-
- for (UserMembCIter i = cl->begin(); i != cl->end(); i++)
- {
- if (i->second->hasMode('Y'))
- {
- if (stack)
- stack->Push(this->GetModeChar(), i->first->nick);
- else
- modestack.Push(this->GetModeChar(), i->first->nick);
- }
- }
-
- if (stack)
- return;
-
- while (modestack.GetStackedLine(stackresult))
- {
- mode_junk.insert(mode_junk.end(), stackresult.begin(), stackresult.end());
- ServerInstance->SendMode(mode_junk, ServerInstance->FakeClient);
- mode_junk.erase(mode_junk.begin() + 1, mode_junk.end());
- }
- }
-
unsigned int GetPrefixRank()
{
return NETWORK_VALUE;
diff --git a/src/modules/m_spanningtree/fjoin.cpp b/src/modules/m_spanningtree/fjoin.cpp
index f84c101e0..b25444cda 100644
--- a/src/modules/m_spanningtree/fjoin.cpp
+++ b/src/modules/m_spanningtree/fjoin.cpp
@@ -209,7 +209,7 @@ void CommandFJoin::RemoveStatus(Channel* c)
* for this function we require tidyness instead. Fixes bug #493
*/
if (mh)
- mh->RemoveMode(c, &stack);
+ mh->RemoveMode(c, stack);
}
ApplyModeStack(ServerInstance->FakeClient, c, stack);