X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmode.cpp;h=fd25a9a9ff58b65355c8ac00d7a7f31c82961eaf;hb=8281315255d30d7cad6da4936cf9276b7f58a4dc;hp=3762dc52e14d9a25b537114532d1c58c43402dfe;hpb=b9e11915a976daaf790ebc763aff56e19fd49e0f;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/mode.cpp b/src/mode.cpp index 3762dc52e..fd25a9a9f 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -27,9 +27,16 @@ #include "builtinmodes.h" ModeHandler::ModeHandler(Module* Creator, const std::string& Name, char modeletter, ParamSpec Params, ModeType type, Class mclass) - : ServiceProvider(Creator, Name, SERVICE_MODE), modeid(ModeParser::MODEID_MAX), - parameters_taken(Params), mode(modeletter), oper(false), - list(false), m_type(type), type_id(mclass), levelrequired(HALFOP_VALUE) + : ServiceProvider(Creator, Name, SERVICE_MODE) + , modeid(ModeParser::MODEID_MAX) + , parameters_taken(Params) + , mode(modeletter) + , oper(false) + , list(false) + , m_type(type) + , type_id(mclass) + , ranktoset(HALFOP_VALUE) + , ranktounset(HALFOP_VALUE) { } @@ -44,21 +51,21 @@ ModeHandler::~ModeHandler() { } -int ModeHandler::GetNumParams(bool adding) +bool ModeHandler::NeedsParam(bool adding) const { switch (parameters_taken) { case PARAM_ALWAYS: - return 1; + return true; case PARAM_SETONLY: - return adding ? 1 : 0; + return adding; case PARAM_NONE: break; } - return 0; + return false; } -std::string ModeHandler::GetUserParameter(User* user) +std::string ModeHandler::GetUserParameter(const User* user) const { return ""; } @@ -144,11 +151,6 @@ ModeWatcher::~ModeWatcher() ServerInstance->Modes->DelModeWatcher(this); } -ModeType ModeWatcher::GetModeType() -{ - return m_type; -} - bool ModeWatcher::BeforeMode(User*, User*, Channel*, std::string&, bool) { return true; @@ -160,11 +162,20 @@ void ModeWatcher::AfterMode(User*, User*, Channel*, const std::string&, bool) PrefixMode::PrefixMode(Module* Creator, const std::string& Name, char ModeLetter, unsigned int Rank, char PrefixChar) : ModeHandler(Creator, Name, ModeLetter, PARAM_ALWAYS, MODETYPE_CHANNEL, MC_PREFIX) - , prefix(PrefixChar), prefixrank(Rank) + , prefix(PrefixChar) + , prefixrank(Rank) + , selfremove(true) { list = true; } +ModResult PrefixMode::AccessCheck(User* src, Channel*, std::string& value, bool adding) +{ + if (!adding && src->nick == value && selfremove) + return MOD_RES_ALLOW; + return MOD_RES_PASSTHRU; +} + ModeAction PrefixMode::OnModeChange(User* source, User*, Channel* chan, std::string& parameter, bool adding) { User* target; @@ -219,7 +230,7 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, Mode ModeHandler* mh = mcitem.mh; bool adding = mcitem.adding; - int pcnt = mh->GetNumParams(adding); + const bool needs_param = mh->NeedsParam(adding); std::string& parameter = mcitem.param; // crop mode parameter size to 250 characters @@ -242,7 +253,7 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, Mode return MODEACTION_DENY; if (MOD_RESULT == MOD_RES_PASSTHRU) { - unsigned int neededrank = mh->GetLevelRequired(); + unsigned int neededrank = mh->GetLevelRequired(adding); /* Compare our rank on the channel against the rank of the required prefix, * allow if >= ours. Because mIRC and xchat throw a tizz if the modes shown * in NAMES(X) are not in rank order, we know the most powerful mode is listed @@ -251,11 +262,12 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, Mode unsigned int ourrank = chan->GetPrefixValue(user); if (ourrank < neededrank) { - PrefixMode* neededmh = NULL; - for(char c='A'; c <= 'z'; c++) + const PrefixMode* neededmh = NULL; + const PrefixModeList& prefixmodes = GetPrefixModes(); + for (PrefixModeList::const_iterator i = prefixmodes.begin(); i != prefixmodes.end(); ++i) { - PrefixMode* privmh = FindPrefixMode(c); - if (privmh && privmh->GetPrefixRank() >= neededrank) + const PrefixMode* const privmh = *i; + if (privmh->GetPrefixRank() >= neededrank) { // this mode is sufficient to allow this action if (!neededmh || privmh->GetPrefixRank() < neededmh->GetPrefixRank()) @@ -283,15 +295,15 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, Mode return MODEACTION_DENY; // A module whacked the parameter completely, and there was one. Abort. - if (pcnt && parameter.empty()) + if ((needs_param) && (parameter.empty())) return MODEACTION_DENY; } } if (IS_LOCAL(user) && !user->IsOper()) { - char* disabled = (type == MODETYPE_CHANNEL) ? ServerInstance->Config->DisabledCModes : ServerInstance->Config->DisabledUModes; - if (disabled[modechar - 'A']) + const std::bitset<64>& disabled = (type == MODETYPE_CHANNEL) ? ServerInstance->Config->DisabledCModes : ServerInstance->Config->DisabledUModes; + if (disabled.test(modechar - 'A')) { user->WriteNumeric(ERR_NOPRIVILEGES, InspIRCd::Format("Permission Denied - %s mode %c has been locked by the administrator", type == MODETYPE_CHANNEL ? "channel" : "user", modechar)); @@ -299,7 +311,7 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, Mode } } - if (adding && IS_LOCAL(user) && mh->NeedsOper() && !user->HasModePermission(modechar, type)) + if ((adding) && (IS_LOCAL(user)) && (mh->NeedsOper()) && (!user->HasModePermission(mh))) { /* It's an oper only mode, and they don't have access to it. */ if (user->IsOper()) @@ -318,7 +330,7 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, Mode /* Call the handler for the mode */ ModeAction ma = mh->OnModeChange(user, targetuser, chan, parameter, adding); - if (pcnt && parameter.empty()) + if ((needs_param) && (parameter.empty())) return MODEACTION_DENY; if (ma != MODEACTION_ALLOW) @@ -363,7 +375,7 @@ void ModeParser::ModeParamsToChangeList(User* user, ModeType type, const std::ve } std::string parameter; - if (mh->GetNumParams(adding) && param_at < endindex) + if ((mh->NeedsParam(adding)) && (param_at < endindex)) parameter = parameters[param_at++]; changelist.push(mh, adding, parameter); @@ -432,7 +444,7 @@ unsigned int ModeParser::ProcessSingle(User* user, Channel* targetchannel, User* // If the mode is supposed to have a parameter then we first take a look at item.param // and, if we were asked to, also handle mode merges now - if (mh->GetNumParams(item.adding)) + if (mh->NeedsParam(item.adding)) { // Skip the mode if the parameter does not pass basic validation if (!IsModeParamValid(user, targetchannel, targetuser, item)) @@ -574,11 +586,7 @@ ModeHandler::Id ModeParser::AllocateModeId(ModeType mt) void ModeParser::AddMode(ModeHandler* mh) { - /* Yes, i know, this might let people declare modes like '_' or '^'. - * 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')) + if (!ModeParser::IsModeChar(mh->GetModeChar())) throw ModuleException("Invalid letter for mode " + mh->name); /* A mode prefix of ',' is not acceptable, it would fuck up server to server. @@ -628,7 +636,7 @@ void ModeParser::AddMode(ModeHandler* mh) bool ModeParser::DelMode(ModeHandler* mh) { - if ((mh->GetModeChar() < 'A') || (mh->GetModeChar() > 'z')) + if (!ModeParser::IsModeChar(mh->GetModeChar())) return false; ModeHandlerMap& mhmap = modehandlersbyname[mh->GetModeType()]; @@ -698,7 +706,7 @@ ModeHandler* ModeParser::FindMode(const std::string& modename, ModeType mt) ModeHandler* ModeParser::FindMode(unsigned const char modeletter, ModeType mt) { - if ((modeletter < 'A') || (modeletter > 'z')) + if (!ModeParser::IsModeChar(modeletter)) return NULL; return modehandlers[mt][modeletter-65]; @@ -719,7 +727,7 @@ std::string ModeParser::CreateModeList(ModeType mt, bool needparam) for (unsigned char mode = 'A'; mode <= 'z'; mode++) { ModeHandler* mh = modehandlers[mt][mode-65]; - if ((mh) && ((!needparam) || (mh->GetNumParams(true)))) + if ((mh) && ((!needparam) || (mh->NeedsParam(true)))) modestr.push_back(mode); } @@ -728,7 +736,9 @@ std::string ModeParser::CreateModeList(ModeType mt, bool needparam) void ModeParser::RecreateModeListFor004Numeric() { - Cached004ModeList = CreateModeList(MODETYPE_USER) + " " + CreateModeList(MODETYPE_CHANNEL) + " " + CreateModeList(MODETYPE_CHANNEL, true); + Cached004ModeList[0] = CreateModeList(MODETYPE_USER); + Cached004ModeList[1] = CreateModeList(MODETYPE_CHANNEL); + Cached004ModeList[2] = CreateModeList(MODETYPE_CHANNEL, true); } PrefixMode* ModeParser::FindPrefix(unsigned const char pfxletter) @@ -756,7 +766,7 @@ std::string ModeParser::GiveModeList(ModeType mt) /* One parameter when adding */ if (mh) { - if (mh->GetNumParams(true)) + if (mh->NeedsParam(true)) { PrefixMode* pm = mh->IsPrefixMode(); if ((mh->IsListMode()) && ((!pm) || (pm->GetPrefix() == 0))) @@ -766,7 +776,7 @@ std::string ModeParser::GiveModeList(ModeType mt) else { /* ... and one parameter when removing */ - if (mh->GetNumParams(false)) + if (mh->NeedsParam(false)) { /* But not a list mode */ if (!pm) @@ -858,7 +868,7 @@ void ModeHandler::RemoveMode(Channel* channel, Modes::ChangeList& changelist) { if (channel->IsModeSet(this)) { - if (this->GetNumParams(false)) + if (this->NeedsParam(false)) // Removing this mode requires a parameter changelist.push_remove(this, channel->GetModeParameter(this)); else @@ -871,7 +881,7 @@ void PrefixMode::RemoveMode(Channel* chan, Modes::ChangeList& changelist) const Channel::MemberMap& userlist = chan->GetUsers(); for (Channel::MemberMap::const_iterator i = userlist.begin(); i != userlist.end(); ++i) { - if (i->second->hasMode(this->GetModeChar())) + if (i->second->HasMode(this)) changelist.push_remove(this, i->first->nick); } } @@ -923,6 +933,11 @@ void ModeParser::InitBuiltinModes() static_modes.b.DoRehash(); } +bool ModeParser::IsModeChar(char chr) +{ + return ((chr >= 'A' && chr <= 'Z') || (chr >= 'a' && chr <= 'z')); +} + ModeParser::ModeParser() { /* Clear mode handler list */