summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/membership.h2
-rw-r--r--include/mode.h67
-rw-r--r--src/channels.cpp20
-rw-r--r--src/commands/cmd_invite.cpp2
-rw-r--r--src/helperfuncs.cpp2
-rw-r--r--src/mode.cpp57
-rw-r--r--src/modules/m_autoop.cpp14
-rw-r--r--src/modules/m_exemptchanops.cpp8
-rw-r--r--src/modules/m_rmode.cpp7
-rw-r--r--src/modules/m_spanningtree/capab.cpp9
-rw-r--r--src/modules/m_spanningtree/utils.cpp2
11 files changed, 110 insertions, 80 deletions
diff --git a/include/membership.h b/include/membership.h
index 7074566ae..78af85fde 100644
--- a/include/membership.h
+++ b/include/membership.h
@@ -41,7 +41,7 @@ class CoreExport Membership : public Extensible
* @param adding True if adding the prefix, false when removing
* @return True if a change was made
*/
- bool SetPrefix(ModeHandler* mh, bool adding);
+ bool SetPrefix(PrefixMode* mh, bool adding);
};
class CoreExport InviteBase
diff --git a/include/mode.h b/include/mode.h
index 8c3e875f3..e20815549 100644
--- a/include/mode.h
+++ b/include/mode.h
@@ -84,6 +84,8 @@ enum ParamSpec
PARAM_ALWAYS
};
+class PrefixMode;
+
/** Each mode is implemented by ONE ModeHandler class.
* You must derive ModeHandler and add the child class to
* the list of modes handled by the ircd, using
@@ -122,10 +124,6 @@ class CoreExport ModeHandler : public ServiceProvider
*/
char mode;
- /** Mode prefix, or 0
- */
- char prefix;
-
/**
* True if the mode requires oper status
* to set.
@@ -159,11 +157,6 @@ class CoreExport ModeHandler : public ServiceProvider
*/
int levelrequired;
- /** The prefix rank of this mode, used to compare prefix
- * modes
- */
- unsigned int prefixrank;
-
public:
/**
* The constructor for ModeHandler initalizes the mode handler.
@@ -183,20 +176,12 @@ class CoreExport ModeHandler : public ServiceProvider
* Returns true if the mode is a list mode
*/
bool IsListMode() const { return list; }
+
/**
- * Mode prefix or 0. If this is defined, you should
- * also implement GetPrefixRank() to return an integer
- * value for this mode prefix.
- */
- inline char GetPrefix() const { return prefix; }
- /**
- * Get the 'value' of this modes prefix.
- * determines which to display when there are multiple.
- * The mode with the highest value is ranked first. See the
- * PrefixModeValue enum and Channel::GetPrefixValue() for
- * more information.
+ * Returns a PrefixMode* if this mode is a prefix mode, NULL otherwise
*/
- unsigned int GetPrefixRank() const { return prefixrank; }
+ PrefixMode* IsPrefixMode();
+
/**
* Returns the mode's type
*/
@@ -322,6 +307,17 @@ class CoreExport ModeHandler : public ServiceProvider
*/
class PrefixMode : public ModeHandler
{
+ protected:
+ /** The prefix character granted by this mode. '@' for op, '+' for voice, etc.
+ * If 0, this mode does not have a visible prefix character.
+ */
+ char prefix;
+
+ /** The prefix rank of this mode, used to compare prefix
+ * modes
+ */
+ unsigned int prefixrank;
+
public:
/**
* Constructor
@@ -352,6 +348,22 @@ class PrefixMode : public ModeHandler
* @param stack The mode stack to add the mode change to
*/
void RemoveMode(Channel* chan, irc::modestacker& stack);
+
+ /**
+ * Mode prefix or 0. If this is defined, you should
+ * also implement GetPrefixRank() to return an integer
+ * value for this mode prefix.
+ */
+ char GetPrefix() const { return prefix; }
+
+ /**
+ * Get the 'value' of this modes prefix.
+ * determines which to display when there are multiple.
+ * The mode with the highest value is ranked first. See the
+ * PrefixModeValue enum and Channel::GetPrefixValue() for
+ * more information.
+ */
+ unsigned int GetPrefixRank() const { return prefixrank; }
};
/** A prebuilt mode handler which handles a simple user mode, e.g. no parameters, usable by any user, with no extra
@@ -622,12 +634,18 @@ class CoreExport ModeParser
*/
ModeHandler* FindMode(unsigned const char modeletter, ModeType mt);
+ /** Find the mode handler for the given prefix mode
+ * @param modeletter The mode letter to search for
+ * @return A pointer to the PrefixMode or NULL if the mode wasn't found or it isn't a prefix mode
+ */
+ PrefixMode* FindPrefixMode(unsigned char modeletter);
+
/** Find a mode handler by its prefix.
* If there is no mode handler with the given prefix, NULL will be returned.
* @param pfxletter The prefix to find, e.g. '@'
* @return The mode handler which handles this prefix, or NULL if there is none.
*/
- ModeHandler* FindPrefix(unsigned const char pfxletter);
+ PrefixMode* FindPrefix(unsigned const char pfxletter);
/** Returns a list of modes, space seperated by type:
* 1. User modes
@@ -655,3 +673,8 @@ inline const std::string& ModeParser::GetModeListFor004Numeric()
{
return Cached004ModeList;
}
+
+inline PrefixMode* ModeHandler::IsPrefixMode()
+{
+ return (this->type_id == MC_PREFIX ? static_cast<PrefixMode*>(this) : NULL);
+}
diff --git a/src/channels.cpp b/src/channels.cpp
index 91aec6fa5..cf2afbcd6 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -157,7 +157,7 @@ void Channel::SetDefaultModes()
ModeHandler* mode = ServerInstance->Modes->FindMode(*n, MODETYPE_CHANNEL);
if (mode)
{
- if (mode->GetPrefixRank())
+ if (mode->IsPrefixMode())
continue;
if (mode->GetNumParams(true))
@@ -339,8 +339,8 @@ void Channel::ForceJoin(User* user, const std::string* privs, bool bursting, boo
// remote user and his own server set the modes), then set them internally now
for (std::string::const_iterator i = privs->begin(); i != privs->end(); ++i)
{
- ModeHandler* mh = ServerInstance->Modes->FindMode(*i, MODETYPE_CHANNEL);
- if (mh && mh->GetPrefixRank())
+ PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(*i);
+ if (mh)
{
std::string nick = user->nick;
// Set the mode on the user
@@ -588,7 +588,7 @@ void Channel::RawWriteAllExcept(User* user, bool serversource, char status, CULi
unsigned int minrank = 0;
if (status)
{
- ModeHandler* mh = ServerInstance->Modes->FindPrefix(status);
+ PrefixMode* mh = ServerInstance->Modes->FindPrefix(status);
if (mh)
minrank = mh->GetPrefixRank();
}
@@ -737,8 +737,7 @@ const char* Channel::GetPrefixChar(User *user)
{
for(unsigned int i=0; i < m->second->modes.length(); i++)
{
- char mchar = m->second->modes[i];
- ModeHandler* mh = ServerInstance->Modes->FindMode(mchar, MODETYPE_CHANNEL);
+ PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(m->second->modes[i]);
if (mh && mh->GetPrefixRank() > bestrank && mh->GetPrefix())
{
bestrank = mh->GetPrefixRank();
@@ -755,7 +754,7 @@ unsigned int Membership::getRank()
unsigned int rv = 0;
if (mchar)
{
- ModeHandler* mh = ServerInstance->Modes->FindMode(mchar, MODETYPE_CHANNEL);
+ PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(mchar);
if (mh)
rv = mh->GetPrefixRank();
}
@@ -772,8 +771,7 @@ const char* Channel::GetAllPrefixChars(User* user)
{
for(unsigned int i=0; i < m->second->modes.length(); i++)
{
- char mchar = m->second->modes[i];
- ModeHandler* mh = ServerInstance->Modes->FindMode(mchar, MODETYPE_CHANNEL);
+ PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(m->second->modes[i]);
if (mh && mh->GetPrefix())
prefix[ctr++] = mh->GetPrefix();
}
@@ -791,13 +789,13 @@ unsigned int Channel::GetPrefixValue(User* user)
return m->second->getRank();
}
-bool Membership::SetPrefix(ModeHandler* delta_mh, bool adding)
+bool Membership::SetPrefix(PrefixMode* delta_mh, bool adding)
{
char prefix = delta_mh->GetModeChar();
for (unsigned int i = 0; i < modes.length(); i++)
{
char mchar = modes[i];
- ModeHandler* mh = ServerInstance->Modes->FindMode(mchar, MODETYPE_CHANNEL);
+ PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(mchar);
if (mh && mh->GetPrefixRank() <= delta_mh->GetPrefixRank())
{
modes = modes.substr(0,i) +
diff --git a/src/commands/cmd_invite.cpp b/src/commands/cmd_invite.cpp
index 2ed05c550..dabc51aee 100644
--- a/src/commands/cmd_invite.cpp
+++ b/src/commands/cmd_invite.cpp
@@ -131,7 +131,7 @@ CmdResult CommandInvite::Handle (const std::vector<std::string>& parameters, Use
}
case ServerConfig::INVITE_ANNOUNCE_DYNAMIC:
{
- ModeHandler* mh = ServerInstance->Modes->FindMode('h', MODETYPE_CHANNEL);
+ PrefixMode* mh = ServerInstance->Modes->FindPrefixMode('h');
prefix = (mh && mh->name == "halfop" ? mh->GetPrefix() : '@');
break;
}
diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp
index cfbd53c98..1cadc49eb 100644
--- a/src/helperfuncs.cpp
+++ b/src/helperfuncs.cpp
@@ -514,7 +514,7 @@ ModResult OnCheckExemptionHandler::Call(User* user, Channel* chan, const std::st
minmode = current[pos+1];
}
- ModeHandler* mh = ServerInstance->Modes->FindMode(minmode, MODETYPE_CHANNEL);
+ PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(minmode);
if (mh && mypfx >= mh->GetPrefixRank())
return MOD_RES_ALLOW;
if (mh || minmode == '*')
diff --git a/src/mode.cpp b/src/mode.cpp
index aedc8bb85..e89cd72ef 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -28,8 +28,8 @@
ModeHandler::ModeHandler(Module* Creator, const std::string& Name, char modeletter, ParamSpec Params, ModeType type, Class mclass)
: ServiceProvider(Creator, Name, SERVICE_MODE), m_paramtype(TR_TEXT),
- parameters_taken(Params), mode(modeletter), prefix(0), oper(false),
- list(false), m_type(type), type_id(mclass), levelrequired(HALFOP_VALUE), prefixrank(0)
+ parameters_taken(Params), mode(modeletter), oper(false),
+ list(false), m_type(type), type_id(mclass), levelrequired(HALFOP_VALUE)
{
}
@@ -197,6 +197,7 @@ void ModeParser::DisplayCurrentModes(User *user, User* targetuser, Channel* targ
PrefixMode::PrefixMode(Module* Creator, const std::string& Name, char ModeLetter)
: ModeHandler(Creator, Name, ModeLetter, PARAM_ALWAYS, MODETYPE_CHANNEL, MC_PREFIX)
+ , prefix(0), prefixrank(0)
{
list = true;
m_paramtype = TR_NICK;
@@ -254,10 +255,10 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
unsigned int ourrank = chan->GetPrefixValue(user);
if (ourrank < neededrank)
{
- ModeHandler* neededmh = NULL;
+ PrefixMode* neededmh = NULL;
for(char c='A'; c <= 'z'; c++)
{
- ModeHandler *privmh = FindMode(c, MODETYPE_CHANNEL);
+ PrefixMode* privmh = FindPrefixMode(c);
if (privmh && privmh->GetPrefixRank() >= neededrank)
{
// this mode is sufficient to allow this action
@@ -594,18 +595,22 @@ bool ModeParser::AddMode(ModeHandler* mh)
* If they do that, thats their problem, and if i ever EVER see an
* official InspIRCd developer do that, i'll beat them with a paddle!
*/
- if ((mh->GetModeChar() < 'A') || (mh->GetModeChar() > 'z') || (mh->GetPrefix() > 126))
+ if ((mh->GetModeChar() < 'A') || (mh->GetModeChar() > 'z'))
return false;
/* A mode prefix of ',' is not acceptable, it would fuck up server to server.
* A mode prefix of ':' will fuck up both server to server, and client to server.
* A mode prefix of '#' will mess up /whois and /privmsg
*/
- if ((mh->GetPrefix() == ',') || (mh->GetPrefix() == ':') || (mh->GetPrefix() == '#'))
- return false;
+ PrefixMode* pm = mh->IsPrefixMode();
+ if (pm)
+ {
+ if ((pm->GetPrefix() > 126) || (pm->GetPrefix() == ',') || (pm->GetPrefix() == ':') || (pm->GetPrefix() == '#'))
+ return false;
- if (mh->GetPrefix() && FindPrefix(mh->GetPrefix()))
- return false;
+ if (FindPrefix(pm->GetPrefix()))
+ return false;
+ }
mh->GetModeType() == MODETYPE_USER ? mask = MASK_USER : mask = MASK_CHANNEL;
pos = (mh->GetModeChar()-65) | mask;
@@ -686,6 +691,14 @@ ModeHandler* ModeParser::FindMode(unsigned const char modeletter, ModeType mt)
return modehandlers[pos];
}
+PrefixMode* ModeParser::FindPrefixMode(unsigned char modeletter)
+{
+ ModeHandler* mh = FindMode(modeletter, MODETYPE_CHANNEL);
+ if (!mh)
+ return NULL;
+ return mh->IsPrefixMode();
+}
+
std::string ModeParser::CreateModeList(ModeType mt, bool needparam)
{
std::string modestr;
@@ -707,16 +720,13 @@ void ModeParser::RecreateModeListFor004Numeric()
Cached004ModeList = CreateModeList(MODETYPE_USER) + " " + CreateModeList(MODETYPE_CHANNEL) + " " + CreateModeList(MODETYPE_CHANNEL, true);
}
-ModeHandler* ModeParser::FindPrefix(unsigned const char pfxletter)
+PrefixMode* ModeParser::FindPrefix(unsigned const char pfxletter)
{
for (unsigned char mode = 'A'; mode <= 'z'; mode++)
{
- unsigned char pos = (mode-65) | MASK_CHANNEL;
-
- if ((modehandlers[pos]) && (modehandlers[pos]->GetPrefix() == pfxletter))
- {
- return modehandlers[pos];
- }
+ PrefixMode* pm = FindPrefixMode(mode);
+ if ((pm) && (pm->GetPrefix() == pfxletter))
+ return pm;
}
return NULL;
}
@@ -736,7 +746,8 @@ std::string ModeParser::GiveModeList(ModeMasks m)
{
if (modehandlers[pos]->GetNumParams(true))
{
- if ((modehandlers[pos]->IsListMode()) && (!modehandlers[pos]->GetPrefix()))
+ PrefixMode* pm = modehandlers[pos]->IsPrefixMode();
+ if ((modehandlers[pos]->IsListMode()) && ((!pm) || (pm->GetPrefix() == 0)))
{
type1 += modehandlers[pos]->GetModeChar();
}
@@ -746,7 +757,7 @@ std::string ModeParser::GiveModeList(ModeMasks m)
if (modehandlers[pos]->GetNumParams(false))
{
/* But not a list mode */
- if (!modehandlers[pos]->GetPrefix())
+ if (!pm)
{
type2 += modehandlers[pos]->GetModeChar();
}
@@ -776,13 +787,9 @@ std::string ModeParser::BuildPrefixes(bool lettersAndModes)
for (unsigned char mode = 'A'; mode <= 'z'; mode++)
{
- unsigned char pos = (mode-65) | MASK_CHANNEL;
-
- if ((modehandlers[pos]) && (modehandlers[pos]->GetPrefix()))
- {
- prefixes[modehandlers[pos]->GetPrefixRank()] = std::make_pair(
- modehandlers[pos]->GetPrefix(), modehandlers[pos]->GetModeChar());
- }
+ PrefixMode* pm = FindPrefixMode(mode);
+ if (pm && pm->GetPrefix())
+ prefixes[pm->GetPrefixRank()] = std::make_pair(pm->GetPrefix(), pm->GetModeChar());
}
for(std::map<int,std::pair<char,char> >::reverse_iterator n = prefixes.rbegin(); n != prefixes.rend(); n++)
diff --git a/src/modules/m_autoop.cpp b/src/modules/m_autoop.cpp
index 8ecee9578..d195345ca 100644
--- a/src/modules/m_autoop.cpp
+++ b/src/modules/m_autoop.cpp
@@ -32,13 +32,13 @@ class AutoOpList : public ListModeBase
tidy = false;
}
- ModeHandler* FindMode(const std::string& mid)
+ PrefixMode* FindMode(const std::string& mid)
{
if (mid.length() == 1)
- return ServerInstance->Modes->FindMode(mid[0], MODETYPE_CHANNEL);
+ return ServerInstance->Modes->FindPrefixMode(mid[0]);
for(char c='A'; c < 'z'; c++)
{
- ModeHandler* mh = ServerInstance->Modes->FindMode(c, MODETYPE_CHANNEL);
+ PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(c);
if (mh && mh->name == mid)
return mh;
}
@@ -52,9 +52,9 @@ class AutoOpList : public ListModeBase
return adding ? MOD_RES_DENY : MOD_RES_PASSTHRU;
unsigned int mylevel = channel->GetPrefixValue(source);
std::string mid = parameter.substr(0, pos);
- ModeHandler* mh = FindMode(mid);
+ PrefixMode* mh = FindMode(mid);
- if (adding && (!mh || !mh->GetPrefixRank()))
+ if (adding && !mh)
{
source->WriteNumeric(415, "%s %s :Cannot find prefix mode '%s' for autoop",
source->nick.c_str(), mid.c_str(), mid.c_str());
@@ -103,8 +103,8 @@ class ModuleAutoOp : public Module
continue;
if (memb->chan->CheckBan(memb->user, it->mask.substr(colon+1)))
{
- ModeHandler* given = mh.FindMode(it->mask.substr(0, colon));
- if (given && given->GetPrefixRank())
+ PrefixMode* given = mh.FindMode(it->mask.substr(0, colon));
+ if (given)
modeline.push_back(given->GetModeChar());
}
}
diff --git a/src/modules/m_exemptchanops.cpp b/src/modules/m_exemptchanops.cpp
index 068f503c3..5d8958665 100644
--- a/src/modules/m_exemptchanops.cpp
+++ b/src/modules/m_exemptchanops.cpp
@@ -61,13 +61,13 @@ class ExemptHandler : public HandlerBase3<ModResult, User*, Channel*, const std:
ExemptChanOps ec;
ExemptHandler(Module* me) : ec(me) {}
- ModeHandler* FindMode(const std::string& mid)
+ PrefixMode* FindMode(const std::string& mid)
{
if (mid.length() == 1)
- return ServerInstance->Modes->FindMode(mid[0], MODETYPE_CHANNEL);
+ return ServerInstance->Modes->FindPrefixMode(mid[0]);
for(char c='A'; c < 'z'; c++)
{
- ModeHandler* mh = ServerInstance->Modes->FindMode(c, MODETYPE_CHANNEL);
+ PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(c);
if (mh && mh->name == mid)
return mh;
}
@@ -93,7 +93,7 @@ class ExemptHandler : public HandlerBase3<ModResult, User*, Channel*, const std:
}
}
- ModeHandler* mh = FindMode(minmode);
+ PrefixMode* mh = FindMode(minmode);
if (mh && mypfx >= mh->GetPrefixRank())
return MOD_RES_ALLOW;
if (mh || minmode == "*")
diff --git a/src/modules/m_rmode.cpp b/src/modules/m_rmode.cpp
index 1bbbb37bf..6d17820a5 100644
--- a/src/modules/m_rmode.cpp
+++ b/src/modules/m_rmode.cpp
@@ -56,9 +56,8 @@ class CommandRMode : public Command
return CMD_FAILURE;
}
- unsigned int prefixrank;
- char prefixchar;
std::string pattern = parameters.size() > 2 ? parameters[2] : "*";
+ PrefixMode* pm;
ListModeBase* lm;
ListModeBase::ModeList* ml;
irc::modestacker modestack(false);
@@ -68,14 +67,14 @@ class CommandRMode : public Command
if (chan->IsModeSet(mh))
modestack.Push(modeletter);
}
- else if (((prefixrank = mh->GetPrefixRank()) && (prefixchar = mh->GetPrefix())))
+ else if ((pm = mh->IsPrefixMode()))
{
// As user prefix modes don't have a GetList() method, let's iterate through the channel's users.
for (UserMembIter it = chan->userlist.begin(); it != chan->userlist.end(); ++it)
{
if (!InspIRCd::Match(it->first->nick, pattern))
continue;
- if (((strchr(chan->GetAllPrefixChars(user), prefixchar)) != NULL) && !(it->first == user && prefixrank > VOICE_VALUE))
+ if (it->second->hasMode(modeletter) && !((it->first == user) && (pm->GetPrefixRank() > VOICE_VALUE)))
modestack.Push(modeletter, it->first->nick);
}
}
diff --git a/src/modules/m_spanningtree/capab.cpp b/src/modules/m_spanningtree/capab.cpp
index f4f1e1ace..7afcc50e5 100644
--- a/src/modules/m_spanningtree/capab.cpp
+++ b/src/modules/m_spanningtree/capab.cpp
@@ -59,10 +59,13 @@ static std::string BuildModeList(ModeType type)
{
std::string mdesc = mh->name;
mdesc.push_back('=');
- if (mh->GetPrefix())
- mdesc.push_back(mh->GetPrefix());
- if (mh->GetModeChar())
+ PrefixMode* pm = mh->IsPrefixMode();
+ if (pm)
+ {
+ if (pm->GetPrefix())
+ mdesc.push_back(pm->GetPrefix());
mdesc.push_back(mh->GetModeChar());
+ }
modes.push_back(mdesc);
}
}
diff --git a/src/modules/m_spanningtree/utils.cpp b/src/modules/m_spanningtree/utils.cpp
index 0372172f5..6c3ee703c 100644
--- a/src/modules/m_spanningtree/utils.cpp
+++ b/src/modules/m_spanningtree/utils.cpp
@@ -163,7 +163,7 @@ void SpanningTreeUtilities::GetListOfServersForChannel(Channel* c, TreeSocketSet
unsigned int minrank = 0;
if (status)
{
- ModeHandler* mh = ServerInstance->Modes->FindPrefix(status);
+ PrefixMode* mh = ServerInstance->Modes->FindPrefix(status);
if (mh)
minrank = mh->GetPrefixRank();
}