From d16a4554002e915f4512dc8b72e4a49073931e63 Mon Sep 17 00:00:00 2001 From: attilamolnar Date: Sun, 26 May 2013 22:40:45 +0200 Subject: Watch mode names with ModeWatchers instead of mode letters --- include/mode.h | 30 ++++++------ src/commands/cmd_lusers.cpp | 2 +- src/mode.cpp | 106 +++++++++++++++++++----------------------- src/modules/m_banredirect.cpp | 6 +-- src/modules/m_operprefix.cpp | 42 ++++++----------- src/modules/m_timedbans.cpp | 2 +- 6 files changed, 82 insertions(+), 106 deletions(-) diff --git a/include/mode.h b/include/mode.h index 32c87d8b0..fc0122788 100644 --- a/include/mode.h +++ b/include/mode.h @@ -342,11 +342,12 @@ class CoreExport ParamChannelModeHandler : public ModeHandler */ class CoreExport ModeWatcher : public classbase { - protected: + private: /** - * The mode letter this class is watching + * The mode name this class is watching */ - char mode; + const std::string mode; + /** * The mode type being watched (user or channel) */ @@ -357,17 +358,18 @@ class CoreExport ModeWatcher : public classbase /** * The constructor initializes the mode and the mode type */ - ModeWatcher(Module* creator, char modeletter, ModeType type); + ModeWatcher(Module* creator, const std::string& modename, ModeType type); /** * The default destructor does nothing. */ virtual ~ModeWatcher(); /** - * Get the mode character being watched - * @return The mode character being watched + * Get the mode name being watched + * @return The mode name being watched */ - char GetModeChar(); + const std::string& GetModeName() const { return mode; } + /** * Get the mode type being watched * @return The mode type being watched (user or channel) @@ -399,7 +401,7 @@ class CoreExport ModeWatcher : public classbase virtual void AfterMode(User* source, User* dest, Channel* channel, const std::string& parameter, bool adding); }; -typedef std::vector::iterator ModeWatchIter; +typedef std::multimap::iterator ModeWatchIter; /** The mode parser handles routing of modes and handling of mode strings. * It marshalls, controls and maintains both ModeWatcher and ModeHandler classes, @@ -415,11 +417,11 @@ class CoreExport ModeParser * or a channel mode, so we have 256 of them not 64. */ ModeHandler* modehandlers[256]; - /** Mode watcher classes arranged in the same way as the - * mode handlers, except for instead of having 256 of them - * we have 256 lists of them. + + /** Mode watcher classes */ - std::vector modewatchers[256]; + std::multimap modewatchermap; + /** Displays the current modes of a channel or user. * Used by ModeParser::Process. */ @@ -512,9 +514,9 @@ class CoreExport ModeParser * triggered. See the documentation of class ModeWatcher for more * information. * @param mw The ModeWatcher you want to add - * @return True if the ModeWatcher was added correctly */ - bool AddModeWatcher(ModeWatcher* mw); + void AddModeWatcher(ModeWatcher* mw); + /** Delete a mode watcher. * A mode watcher is triggered before and after a mode handler is * triggered. See the documentation of class ModeWatcher for more diff --git a/src/commands/cmd_lusers.cpp b/src/commands/cmd_lusers.cpp index d3dde949c..c594a0e24 100644 --- a/src/commands/cmd_lusers.cpp +++ b/src/commands/cmd_lusers.cpp @@ -110,7 +110,7 @@ class InvisibleWatcher : public ModeWatcher unsigned int& invisible; public: InvisibleWatcher(Module* mod, unsigned int& Invisible) - : ModeWatcher(mod, 'i', MODETYPE_USER), invisible(Invisible) + : ModeWatcher(mod, "invisible", MODETYPE_USER), invisible(Invisible) { } diff --git a/src/mode.cpp b/src/mode.cpp index 1fc2af407..c96f25f7f 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -156,8 +156,8 @@ bool ParamChannelModeHandler::ParamValidate(std::string& parameter) return true; } -ModeWatcher::ModeWatcher(Module* Creator, char modeletter, ModeType type) - : mode(modeletter), m_type(type), creator(Creator) +ModeWatcher::ModeWatcher(Module* Creator, const std::string& modename, ModeType type) + : mode(modename), m_type(type), creator(Creator) { } @@ -165,11 +165,6 @@ ModeWatcher::~ModeWatcher() { } -char ModeWatcher::GetModeChar() -{ - return mode; -} - ModeType ModeWatcher::GetModeType() { return m_type; @@ -215,7 +210,6 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool std::string ¶meter, bool SkipACL) { ModeType type = chan ? MODETYPE_CHANNEL : MODETYPE_USER; - unsigned char mask = chan ? MASK_CHANNEL : MASK_USER; ModeHandler *mh = FindMode(modechar, type); int pcnt = mh->GetNumParams(adding); @@ -269,15 +263,20 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool } } - unsigned char handler_id = (modechar - 'A') | mask; - - for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++) + // Ask mode watchers whether this mode change is OK + std::pair itpair = modewatchermap.equal_range(mh->name); + for (ModeWatchIter i = itpair.first; i != itpair.second; ++i) { - if ((*watchers)->BeforeMode(user, targetuser, chan, parameter, adding) == false) - return MODEACTION_DENY; - /* A module whacked the parameter completely, and there was one. abort. */ - if (pcnt && parameter.empty()) - return MODEACTION_DENY; + ModeWatcher* mw = i->second; + if (mw->GetModeType() == type) + { + if (!mw->BeforeMode(user, targetuser, chan, parameter, adding)) + return MODEACTION_DENY; + + // A module whacked the parameter completely, and there was one. Abort. + if (pcnt && parameter.empty()) + return MODEACTION_DENY; + } } if (IS_LOCAL(user) && !user->IsOper()) @@ -331,8 +330,13 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool if (ma != MODEACTION_ALLOW) return ma; - for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++) - (*watchers)->AfterMode(user, targetuser, chan, parameter, adding); + itpair = modewatchermap.equal_range(mh->name); + for (ModeWatchIter i = itpair.first; i != itpair.second; ++i) + { + ModeWatcher* mw = i->second; + if (mw->GetModeType() == type) + mw->AfterMode(user, targetuser, chan, parameter, adding); + } return MODEACTION_ALLOW; } @@ -527,15 +531,24 @@ void ModeParser::DisplayListModes(User* user, Channel* chan, std::string &mode_s display = false; } - unsigned char handler_id = (mletter - 'A') | MASK_CHANNEL; - - for(ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++) + // Ask mode watchers whether it's OK to show the list + std::pair itpair = modewatchermap.equal_range(mh->name); + for (ModeWatchIter i = itpair.first; i != itpair.second; ++i) { - std::string dummyparam; + ModeWatcher* mw = i->second; + if (mw->GetModeType() == MODETYPE_CHANNEL) + { + std::string dummyparam; - if (!((*watchers)->BeforeMode(user, NULL, chan, dummyparam, true))) - display = false; + if (!mw->BeforeMode(user, NULL, chan, dummyparam, true)) + { + // A mode watcher doesn't want us to show the list + display = false; + break; + } + } } + if (display) mh->DisplayList(user, chan); else @@ -793,49 +806,24 @@ std::string ModeParser::BuildPrefixes(bool lettersAndModes) return lettersAndModes ? "(" + mprefixes + ")" + mletters : mletters; } -bool ModeParser::AddModeWatcher(ModeWatcher* mw) +void ModeParser::AddModeWatcher(ModeWatcher* mw) { - unsigned char mask = 0; - unsigned char pos = 0; - - if (!mw) - return false; - - if ((mw->GetModeChar() < 'A') || (mw->GetModeChar() > 'z')) - return false; - - mw->GetModeType() == MODETYPE_USER ? mask = MASK_USER : mask = MASK_CHANNEL; - pos = (mw->GetModeChar()-65) | mask; - - modewatchers[pos].push_back(mw); - - return true; + modewatchermap.insert(std::make_pair(mw->GetModeName(), mw)); } bool ModeParser::DelModeWatcher(ModeWatcher* mw) { - unsigned char mask = 0; - unsigned char pos = 0; - - if (!mw) - return false; - - if ((mw->GetModeChar() < 'A') || (mw->GetModeChar() > 'z')) - return false; - - 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); - - if (a == modewatchers[pos].end()) + std::pair itpair = modewatchermap.equal_range(mw->GetModeName()); + for (ModeWatchIter i = itpair.first; i != itpair.second; ++i) { - return false; + if (i->second == mw) + { + modewatchermap.erase(i); + return true; + } } - modewatchers[pos].erase(a); - - return true; + return false; } void ModeHandler::RemoveMode(User* user) diff --git a/src/modules/m_banredirect.cpp b/src/modules/m_banredirect.cpp index 8e4c5c6e5..c79023ccf 100644 --- a/src/modules/m_banredirect.cpp +++ b/src/modules/m_banredirect.cpp @@ -50,7 +50,7 @@ class BanRedirect : public ModeWatcher public: SimpleExtItem extItem; BanRedirect(Module* parent) - : ModeWatcher(parent, 'b', MODETYPE_CHANNEL) + : ModeWatcher(parent, "ban", MODETYPE_CHANNEL) , ban(parent, "ban") , extItem("banredirect", parent) { @@ -228,9 +228,7 @@ class ModuleBanRedirect : public Module void init() CXX11_OVERRIDE { - if(!ServerInstance->Modes->AddModeWatcher(&re)) - throw ModuleException("Could not add mode watcher"); - + ServerInstance->Modes->AddModeWatcher(&re); ServerInstance->Modules->AddService(re.extItem); Implementation list[] = { I_OnUserPreJoin }; ServerInstance->Modules->Attach(list, this, sizeof(list)/sizeof(Implementation)); diff --git a/src/modules/m_operprefix.cpp b/src/modules/m_operprefix.cpp index b0737cb9a..fbb7e8b50 100644 --- a/src/modules/m_operprefix.cpp +++ b/src/modules/m_operprefix.cpp @@ -64,19 +64,20 @@ class ModuleOperPrefixMode; class HideOperWatcher : public ModeWatcher { ModuleOperPrefixMode* parentmod; + public: - HideOperWatcher(ModuleOperPrefixMode* parent) : ModeWatcher((Module*) parent, 'H', MODETYPE_USER), parentmod(parent) {} + HideOperWatcher(ModuleOperPrefixMode* parent); void AfterMode(User* source, User* dest, Channel* channel, const std::string ¶meter, bool adding); }; class ModuleOperPrefixMode : public Module { OperPrefixMode opm; - bool mw_added; HideOperWatcher hideoperwatcher; + public: ModuleOperPrefixMode() - : opm(this), mw_added(false), hideoperwatcher(this) + : opm(this), hideoperwatcher(this) { } @@ -84,7 +85,7 @@ class ModuleOperPrefixMode : public Module { ServerInstance->Modules->AddService(opm); - Implementation eventlist[] = { I_OnUserPreJoin, I_OnPostOper, I_OnLoadModule, I_OnUnloadModule }; + Implementation eventlist[] = { I_OnUserPreJoin, I_OnPostOper }; ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); /* To give clients a chance to learn about the new prefix we don't give +y to opers @@ -92,19 +93,12 @@ class ModuleOperPrefixMode : public Module * they need to rejoin them in order to get the oper prefix. */ - if (ServerInstance->Modules->Find("m_hideoper.so")) - mw_added = ServerInstance->Modes->AddModeWatcher(&hideoperwatcher); + ServerInstance->Modes->AddModeWatcher(&hideoperwatcher); } ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven) CXX11_OVERRIDE { - /* The user may have the +H umode on himself, but +H does not necessarily correspond - * to the +H of m_hideoper. - * However we only add the modewatcher when m_hideoper is loaded, so these - * conditions (mw_added and the user being +H) together mean the user is a hidden oper. - */ - - if (user->IsOper() && (!mw_added || !user->IsModeSet('H'))) + if ((user->IsOper()) && (user->IsModeSet('H'))) privs.push_back('y'); return MOD_RES_PASSTHRU; } @@ -124,26 +118,14 @@ class ModuleOperPrefixMode : public Module void OnPostOper(User* user, const std::string& opername, const std::string& opertype) CXX11_OVERRIDE { - if (IS_LOCAL(user) && (!mw_added || !user->IsModeSet('H'))) + if (IS_LOCAL(user) && (!user->IsModeSet('H'))) SetOperPrefix(user, true); } - void OnLoadModule(Module* mod) CXX11_OVERRIDE - { - if ((!mw_added) && (mod->ModuleSourceFile == "m_hideoper.so")) - mw_added = ServerInstance->Modes->AddModeWatcher(&hideoperwatcher); - } - - void OnUnloadModule(Module* mod) CXX11_OVERRIDE - { - if ((mw_added) && (mod->ModuleSourceFile == "m_hideoper.so") && (ServerInstance->Modes->DelModeWatcher(&hideoperwatcher))) - mw_added = false; - } ~ModuleOperPrefixMode() { - if (mw_added) - ServerInstance->Modes->DelModeWatcher(&hideoperwatcher); + ServerInstance->Modes->DelModeWatcher(&hideoperwatcher); } Version GetVersion() CXX11_OVERRIDE @@ -159,6 +141,12 @@ class ModuleOperPrefixMode : public Module } }; +HideOperWatcher::HideOperWatcher(ModuleOperPrefixMode* parent) + : ModeWatcher(parent, "hideoper", MODETYPE_USER) + , parentmod(parent) +{ +} + void HideOperWatcher::AfterMode(User* source, User* dest, Channel* channel, const std::string& parameter, bool adding) { if (IS_LOCAL(dest)) diff --git a/src/modules/m_timedbans.cpp b/src/modules/m_timedbans.cpp index 90b8fccdd..a76d89c82 100644 --- a/src/modules/m_timedbans.cpp +++ b/src/modules/m_timedbans.cpp @@ -115,7 +115,7 @@ class BanWatcher : public ModeWatcher { public: BanWatcher(Module* parent) - : ModeWatcher(parent, 'b', MODETYPE_CHANNEL) + : ModeWatcher(parent, "ban", MODETYPE_CHANNEL) { } -- cgit v1.2.3