diff options
author | attilamolnar <attilamolnar@hush.com> | 2013-05-26 23:23:47 +0200 |
---|---|---|
committer | attilamolnar <attilamolnar@hush.com> | 2013-05-27 01:07:29 +0200 |
commit | 9bb24d3f458274b7485554bc95f1274900a69ec2 (patch) | |
tree | 33ab45d74813198ba1377eab83b6a9904a91801e | |
parent | 244a65e8556328642350575c4a94ee8fc1b676b4 (diff) |
Deduplicate RemoveMode() implementations
The default (core) implementation can now remove prefix modes
The modestacker parameter is now mandatory
-rw-r--r-- | include/builtinmodes.h | 4 | ||||
-rw-r--r-- | include/listmode.h | 7 | ||||
-rw-r--r-- | include/mode.h | 18 | ||||
-rw-r--r-- | src/listmode.cpp | 21 | ||||
-rw-r--r-- | src/mode.cpp | 48 | ||||
-rw-r--r-- | src/modes/cmode_k.cpp | 23 | ||||
-rw-r--r-- | src/modes/cmode_o.cpp | 19 | ||||
-rw-r--r-- | src/modes/cmode_v.cpp | 19 | ||||
-rw-r--r-- | src/modules/m_customprefix.cpp | 30 | ||||
-rw-r--r-- | src/modules/m_ojoin.cpp | 30 | ||||
-rw-r--r-- | src/modules/m_spanningtree/fjoin.cpp | 2 |
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 ¶meter, 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 ¶meter, 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 ¶meter, 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); |