diff options
-rw-r--r-- | docs/inspircd.helpop-full.example | 2 | ||||
-rw-r--r-- | docs/inspircd.helpop.example | 2 | ||||
-rw-r--r-- | src/modules/m_autoop.cpp | 58 |
3 files changed, 38 insertions, 24 deletions
diff --git a/docs/inspircd.helpop-full.example b/docs/inspircd.helpop-full.example index 2616241b6..c89756ff3 100644 --- a/docs/inspircd.helpop-full.example +++ b/docs/inspircd.helpop-full.example @@ -844,7 +844,7 @@ Closes all unregistered connections to the local server."> see themselves or themselves and the operators, while operators see all the users (requires auditorium module). - w Adds basic channel access controls of [flag] to + w [flag]:[banmask] Adds basic channel access controls of [flag] to [banmask], via the +w listmode. For example, +w o:R:Brain will op anyone identified to the account 'Brain' on join. diff --git a/docs/inspircd.helpop.example b/docs/inspircd.helpop.example index 5bdfa7b3f..89369a041 100644 --- a/docs/inspircd.helpop.example +++ b/docs/inspircd.helpop.example @@ -164,7 +164,7 @@ LOCKSERV UNLOCKSERV JUMPSERVER"> see themselves or themselves and the operators, while operators see all the users (requires auditorium module). - w Adds basic channel access controls of [flag] to + w [flag]:[banmask] Adds basic channel access controls of [flag] to [banmask], via the +w listmode. For example, +w o:R:Brain will op anyone identified to the account 'Brain' on join. diff --git a/src/modules/m_autoop.cpp b/src/modules/m_autoop.cpp index b96495bf7..427ebfab8 100644 --- a/src/modules/m_autoop.cpp +++ b/src/modules/m_autoop.cpp @@ -26,40 +26,50 @@ class AutoOpList : public ListModeBase levelrequired = OP_VALUE; } + ModeHandler* FindMode(const std::string& mid) + { + if (mid.length() == 1) + return ServerInstance->Modes->FindMode(mid[0], MODETYPE_CHANNEL); + for(char c='A'; c < 'z'; c++) + { + ModeHandler* mh = ServerInstance->Modes->FindMode(c, MODETYPE_CHANNEL); + if (mh && mh->name == mid) + return mh; + } + return NULL; + } + ModResult AccessCheck(User* source, Channel* channel, std::string ¶meter, bool adding) { std::string::size_type pos = parameter.find(':'); if (pos == 0 || pos == std::string::npos) return adding ? MOD_RES_DENY : MOD_RES_PASSTHRU; unsigned int mylevel = channel->GetPrefixValue(source); - while (pos > 0) + std::string mid = parameter.substr(0, pos); + ModeHandler* mh = FindMode(mid); + + if (adding && (!mh || !mh->GetPrefixRank())) { - pos--; - ModeHandler* mh = ServerInstance->Modes->FindMode(parameter[pos], MODETYPE_CHANNEL); - if (adding && (!mh || !mh->GetPrefixRank())) - { - source->WriteNumeric(415, "%s %c :Cannot find prefix mode '%c' for autoop", - source->nick.c_str(), parameter[pos], parameter[pos]); - return MOD_RES_DENY; - } - else if (!mh) - continue; + source->WriteNumeric(415, "%s %s :Cannot find prefix mode '%s' for autoop", + source->nick.c_str(), mid.c_str(), mid.c_str()); + return MOD_RES_DENY; + } + else if (!mh) + return MOD_RES_PASSTHRU; - std::string dummy; - if (mh->AccessCheck(source, channel, dummy, true) == MOD_RES_DENY) - return MOD_RES_DENY; - if (mh->GetLevelRequired() > mylevel) - { - source->WriteNumeric(482, "%s %s :You must be able to set mode '%c' to include it in an autoop", - source->nick.c_str(), channel->name.c_str(), parameter[pos]); - return MOD_RES_DENY; - } + std::string dummy; + if (mh->AccessCheck(source, channel, dummy, true) == MOD_RES_DENY) + return MOD_RES_DENY; + if (mh->GetLevelRequired() > mylevel) + { + source->WriteNumeric(482, "%s %s :You must be able to set mode '%s' to include it in an autoop", + source->nick.c_str(), channel->name.c_str(), mid.c_str()); + return MOD_RES_DENY; } return MOD_RES_PASSTHRU; } }; - class ModuleAutoOp : public Module { AutoOpList mh; @@ -88,7 +98,11 @@ public: if (colon == std::string::npos) continue; if (chan->CheckBan(user, it->mask.substr(colon+1))) - privs += it->mask.substr(0, colon); + { + ModeHandler* given = mh.FindMode(it->mask.substr(0, colon)); + if (given) + privs += given->GetModeChar(); + } } } |