From 16398df07d4ce1f1d4a2e43d97bc39043f8d44b5 Mon Sep 17 00:00:00 2001 From: attilamolnar Date: Sun, 1 Sep 2013 14:38:41 +0200 Subject: [PATCH] Move prefix mode specific fields and getters into PrefixMode Add ModeHandler::IsPrefixMode() --- include/membership.h | 2 +- include/mode.h | 67 +++++++++++++++++++--------- src/channels.cpp | 20 ++++----- src/commands/cmd_invite.cpp | 2 +- src/helperfuncs.cpp | 2 +- src/mode.cpp | 57 ++++++++++++----------- src/modules/m_autoop.cpp | 14 +++--- src/modules/m_exemptchanops.cpp | 8 ++-- src/modules/m_rmode.cpp | 7 ++- src/modules/m_spanningtree/capab.cpp | 9 ++-- src/modules/m_spanningtree/utils.cpp | 2 +- 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(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& 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 >::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 HandlerBase3Modes->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= 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(); } -- 2.39.2