summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mode.h30
-rw-r--r--src/commands/cmd_lusers.cpp2
-rw-r--r--src/mode.cpp106
-rw-r--r--src/modules/m_banredirect.cpp6
-rw-r--r--src/modules/m_operprefix.cpp42
-rw-r--r--src/modules/m_timedbans.cpp2
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<ModeWatcher*>::iterator ModeWatchIter;
+typedef std::multimap<std::string, ModeWatcher*>::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<ModeWatcher*> modewatchers[256];
+ std::multimap<std::string, ModeWatcher*> 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 &parameter, 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<ModeWatchIter, ModeWatchIter> 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<ModeWatchIter, ModeWatchIter> 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<ModeWatchIter, ModeWatchIter> 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<BanRedirectList> 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 &parameter, 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)
{
}