summaryrefslogtreecommitdiff
path: root/modules/commands/cs_mode.cpp
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2011-08-19 04:18:13 -0400
committerAdam <Adam@anope.org>2011-09-10 01:52:59 -0400
commit4fcb371bc8813cd647b7769a64d586e3a57d684d (patch)
tree836584fe2392b5ea21115111dbd470dbf04ce47b /modules/commands/cs_mode.cpp
parent6401d93b8e0ec5b6f68bd507dffa360b4d60d335 (diff)
Track what "level" channel status modes are, which allows us to have chanserv/mode determine if a status mode can be set by users better
Diffstat (limited to 'modules/commands/cs_mode.cpp')
-rw-r--r--modules/commands/cs_mode.cpp58
1 files changed, 33 insertions, 25 deletions
diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp
index 36ac60b0f..7c98292d3 100644
--- a/modules/commands/cs_mode.cpp
+++ b/modules/commands/cs_mode.cpp
@@ -15,25 +15,29 @@
class CommandCSMode : public Command
{
- bool CanSet(User *u, ChannelInfo *ci, ChannelModeName mode)
+ bool CanSet(User *u, ChannelInfo *ci, ChannelMode *cm)
{
- switch (mode)
- {
- case CMODE_OWNER:
- return ci->AccessFor(u).HasPriv(CA_OWNER);
- case CMODE_PROTECT:
- return ci->AccessFor(u).HasPriv(CA_PROTECT);
- case CMODE_OP:
- return ci->AccessFor(u).HasPriv(CA_OPDEOP);
- case CMODE_HALFOP:
- return ci->AccessFor(u).HasPriv(CA_HALFOP);
- case CMODE_VOICE:
- return ci->AccessFor(u).HasPriv(CA_VOICE);
- default:
- break;
- }
+ if (!u || !ci || !cm || cm->Type != MODE_STATUS)
+ return false;
- return false;
+ const ChannelAccess accesses[] = { CA_VOICE, CA_HALFOP, CA_OPDEOP, CA_PROTECT, CA_OWNER, CA_SIZE };
+ const ChannelModeName modes[] = { CMODE_VOICE, CMODE_HALFOP, CMODE_OP, CMODE_PROTECT, CMODE_OWNER };
+ ChannelModeStatus *cms = debug_cast<ChannelModeStatus *>(cm);
+ AccessGroup access = ci->AccessFor(u);
+ unsigned short u_level = 0;
+
+ for (int i = 0; accesses[i] != CA_SIZE; ++i)
+ if (access.HasPriv(accesses[i]))
+ {
+ ChannelMode *cm2 = ModeManager::FindChannelModeByName(modes[i]);
+ if (cm2 == NULL || cm2->Type != MODE_STATUS)
+ continue;
+ ChannelModeStatus *cms2 = debug_cast<ChannelModeStatus *>(cm2);
+ if (cms2->Level > u_level)
+ u_level = cms2->Level;
+ }
+
+ return u_level >= cms->Level;
}
void DoLock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
@@ -222,7 +226,7 @@ class CommandCSMode : public Command
if (!sep.GetToken(param))
break;
- if (!this->CanSet(u, ci, cm->Name))
+ if (!this->CanSet(u, ci, cm))
{
source.Reply(_("You do not have access to set mode %c."), cm->ModeChar);
break;
@@ -256,15 +260,19 @@ class CommandCSMode : public Command
else
{
User *target = finduser(param);
- if (target != NULL)
+ if (target == NULL)
{
- AccessGroup targ_access = ci->AccessFor(target);
- if (targ_access > u_access)
- {
- source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str());
- break;
- }
+ source.Reply(NICK_X_NOT_IN_USE, param.c_str());
+ break;
+ }
+
+ AccessGroup targ_access = ci->AccessFor(target);
+ if (targ_access > u_access)
+ {
+ source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str());
+ break;
}
+
if (adding)
ci->c->SetMode(NULL, cm, param);
else