diff --git a/include/modes.h b/include/modes.h index 3052ab00b..865cf6eec 100644 --- a/include/modes.h +++ b/include/modes.h @@ -70,11 +70,6 @@ public: */ Mode(const Anope::string &mname, ModeClass mclass, char mc, ModeType type); virtual ~Mode() = default; - - /** Can a user set this mode, used for mlock - * @param u The user - */ - virtual bool CanSet(User *u) const; }; /** This class is a user mode, all user modes use this/inherit from this @@ -88,6 +83,12 @@ public: * @param mc The mode char */ UserMode(const Anope::string &name, char mc); + + /** Can a user set this mode, used for mlock + * @param source The user who is setting the mode. + * @param target The user the mode is being set on. + */ + virtual bool CanSet(User *source, User *target) const { return true; } }; class CoreExport UserModeParam @@ -122,7 +123,11 @@ public: */ ChannelMode(const Anope::string &name, char mc); - bool CanSet(User *u) const override; + /** Can a user set this mode, used for mlock + * @param u The user who is setting the mode. + * @param c The channel the mode is being set on. + */ + virtual bool CanSet(User *u, Channel *c) const; virtual void Check() { } @@ -270,7 +275,7 @@ class CoreExport UserModeOperOnly public: UserModeOperOnly(const Anope::string &mname, char um) : UserMode(mname, um) { } - bool CanSet(User *u) const override; + bool CanSet(User *source, User *target) const override; }; class CoreExport UserModeNoone @@ -279,7 +284,7 @@ class CoreExport UserModeNoone public: UserModeNoone(const Anope::string &mname, char um) : UserMode(mname, um) { } - bool CanSet(User *u) const override; + bool CanSet(User *source, User *target) const override; }; /** Channel mode +k (key) @@ -302,7 +307,7 @@ public: ChannelModeOperOnly(const Anope::string &mname, char mc) : ChannelMode(mname, mc) { } /* Opers only */ - bool CanSet(User *u) const override; + bool CanSet(User *u, Channel *c) const override; }; /** This class is used for channel modes only servers may set @@ -313,7 +318,7 @@ class CoreExport ChannelModeNoone public: ChannelModeNoone(const Anope::string &mname, char mc) : ChannelMode(mname, mc) { } - bool CanSet(User *u) const override; + bool CanSet(User *u, Channel *c) const override; }; /** This is the mode manager diff --git a/include/modules.h b/include/modules.h index 03f5fe837..c2a0855f5 100644 --- a/include/modules.h +++ b/include/modules.h @@ -1046,9 +1046,10 @@ public: /** Called to determine if a channel mode can be set by a user * @param u The user + * @param c The channel * @param cm The mode */ - virtual EventReturn OnCanSet(User *u, const ChannelMode *cm) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); } + virtual EventReturn OnCanSet(User *u, Channel *c, const ChannelMode *cm) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); } virtual EventReturn OnCheckDelete(Channel *c) ATTR_NOT_NULL(2) { throw NotImplementedException(); } diff --git a/modules/chanserv/chanserv.cpp b/modules/chanserv/chanserv.cpp index 1fdded2d0..55063ae59 100644 --- a/modules/chanserv/chanserv.cpp +++ b/modules/chanserv/chanserv.cpp @@ -330,7 +330,7 @@ public: ci->Extend(def.upper()); } - EventReturn OnCanSet(User *u, const ChannelMode *cm) override + EventReturn OnCanSet(User *u, Channel *c, const ChannelMode *cm) override { if (Config->GetModule(this).Get("nomlock").find(cm->mchar) != Anope::string::npos || Config->GetModule(this).Get("require").find(cm->mchar) != Anope::string::npos) diff --git a/modules/chanserv/cs_mode.cpp b/modules/chanserv/cs_mode.cpp index 14d5d27c3..39009b12b 100644 --- a/modules/chanserv/cs_mode.cpp +++ b/modules/chanserv/cs_mode.cpp @@ -288,7 +288,7 @@ class CommandCSMode final for (auto *ml : mlocks) { ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name); - if (cm && cm->CanSet(source.GetUser())) + if (cm && cm->CanSet(source.GetUser(), ci->c)) modelocks->RemoveMLock(cm, ml->set, ml->param); } } @@ -320,7 +320,7 @@ class CommandCSMode final source.Reply(_("Unknown mode character %c ignored."), mode); break; } - else if (u && !cm->CanSet(u)) + else if (u && !cm->CanSet(u, ci->c)) { source.Reply(_("You may not (un)lock mode %c."), mode); break; @@ -412,7 +412,7 @@ class CommandCSMode final source.Reply(_("Unknown mode character %c ignored."), mode); break; } - else if (u && !cm->CanSet(u)) + else if (u && !cm->CanSet(u, ci->c)) { source.Reply(_("You may not (un)lock mode %c."), mode); break; @@ -508,7 +508,7 @@ class CommandCSMode final { ChannelMode *cm = ModeManager::GetChannelModes()[j]; - if (!u || cm->CanSet(u) || can_override) + if (!u || cm->CanSet(u, ci->c) || can_override) { if (cm->type == MODE_REGULAR || (!adding && cm->type == MODE_PARAM)) { @@ -524,7 +524,7 @@ class CommandCSMode final if (adding == -1) break; ChannelMode *cm = ModeManager::FindChannelModeByChar(mode); - if (!cm || (u && !cm->CanSet(u) && !can_override)) + if (!cm || (u && !cm->CanSet(u, ci->c) && !can_override)) continue; switch (cm->type) { diff --git a/modules/nickserv/ns_set_keepmodes.cpp b/modules/nickserv/ns_set_keepmodes.cpp index 0f376b31c..dd2486bca 100644 --- a/modules/nickserv/ns_set_keepmodes.cpp +++ b/modules/nickserv/ns_set_keepmodes.cpp @@ -227,7 +227,7 @@ public: for (const auto &[last_mode, last_data] : modes) { auto *um = ModeManager::FindUserModeByName(last_mode); - if (um && um->CanSet(nullptr) && norestore.find(um->mchar) == Anope::string::npos) + if (um && um->CanSet(nullptr, u) && norestore.find(um->mchar) == Anope::string::npos) u->SetMode(nullptr, last_mode, last_data); } } diff --git a/modules/protocol/solanum.cpp b/modules/protocol/solanum.cpp index 3c879f263..27e137480 100644 --- a/modules/protocol/solanum.cpp +++ b/modules/protocol/solanum.cpp @@ -23,7 +23,7 @@ class ChannelModeLargeBan final public: ChannelModeLargeBan(const Anope::string &mname, char modeChar) : ChannelMode(mname, modeChar) { } - bool CanSet(User *u) const override + bool CanSet(User *u, Channel *c) const override { return u && u->HasMode("OPER"); } diff --git a/modules/protocol/unrealircd.cpp b/modules/protocol/unrealircd.cpp index 2c4f4ed97..73f606053 100644 --- a/modules/protocol/unrealircd.cpp +++ b/modules/protocol/unrealircd.cpp @@ -749,7 +749,7 @@ public: { } - bool CanSet(User *u) const override + bool CanSet(User *u, Channel *c) const override { return false; } diff --git a/src/modes.cpp b/src/modes.cpp index c68389c2d..31f2768c7 100644 --- a/src/modes.cpp +++ b/src/modes.cpp @@ -113,11 +113,6 @@ Mode::Mode(const Anope::string &mname, ModeClass mcl, char mch, ModeType mt) : n { } -bool Mode::CanSet(User *u) const -{ - return true; -} - UserMode::UserMode(const Anope::string &un, char mch) : Mode(un, MC_USER, mch, MODE_REGULAR) { } @@ -131,10 +126,10 @@ ChannelMode::ChannelMode(const Anope::string &cm, char mch) : Mode(cm, MC_CHANNE { } -bool ChannelMode::CanSet(User *u) const +bool ChannelMode::CanSet(User *u, Channel *c) const { EventReturn MOD_RESULT; - FOREACH_RESULT(OnCanSet, MOD_RESULT, (u, this)); + FOREACH_RESULT(OnCanSet, MOD_RESULT, (u, c, this)); return MOD_RESULT != EVENT_STOP; } @@ -222,12 +217,12 @@ ChannelMode *ChannelModeVirtual::Wrap(Anope::string ¶m) template class ChannelModeVirtual; template class ChannelModeVirtual; -bool UserModeOperOnly::CanSet(User *u) const +bool UserModeOperOnly::CanSet(User *source, User *target) const { - return u && u->HasMode("OPER"); + return source && source->HasMode("OPER"); } -bool UserModeNoone::CanSet(User *u) const +bool UserModeNoone::CanSet(User *source, User *target) const { return false; } @@ -237,12 +232,12 @@ bool ChannelModeKey::IsValid(Anope::string &value) const return !value.empty() && value.find(':') == Anope::string::npos && value.find(',') == Anope::string::npos; } -bool ChannelModeOperOnly::CanSet(User *u) const +bool ChannelModeOperOnly::CanSet(User *u, Channel *c) const { return u && u->HasMode("OPER"); } -bool ChannelModeNoone::CanSet(User *u) const +bool ChannelModeNoone::CanSet(User *u, Channel *c) const { return false; }