diff options
-rw-r--r-- | include/access.h | 3 | ||||
-rw-r--r-- | src/access.cpp | 13 | ||||
-rw-r--r-- | src/channels.cpp | 29 | ||||
-rw-r--r-- | src/regchannel.cpp | 9 |
4 files changed, 30 insertions, 24 deletions
diff --git a/include/access.h b/include/access.h index 7caee6e5c..01d0616d4 100644 --- a/include/access.h +++ b/include/access.h @@ -78,7 +78,8 @@ class CoreExport ChanAccess class AccessGroup : public std::vector<ChanAccess *> { public: - bool SuperAdmin; + ChannelInfo *ci; + bool SuperAdmin, Founder; AccessGroup(); bool HasPriv(ChannelAccess priv) const; ChanAccess *Highest() const; diff --git a/src/access.cpp b/src/access.cpp index 07e82159c..61536ed81 100644 --- a/src/access.cpp +++ b/src/access.cpp @@ -13,6 +13,12 @@ #include "modules.h" #include "access.h" +enum +{ + ACCESS_INVALID = -10000, + ACCESS_FOUNDER = 10001 +}; + AccessProvider::AccessProvider(Module *o, const Anope::string &n) : Service(o, n) { } @@ -75,13 +81,18 @@ bool ChanAccess::operator<=(ChanAccess &other) AccessGroup::AccessGroup() : std::vector<ChanAccess *>() { - this->SuperAdmin = false; + this->ci = NULL; + this->SuperAdmin = this->Founder = false; } bool AccessGroup::HasPriv(ChannelAccess priv) const { if (this->SuperAdmin) return true; + else if (ci->levels[priv] == ACCESS_INVALID) + return false; + else if (this->Founder) + return true; for (unsigned i = this->size(); i > 0; --i) { ChanAccess *access = this->at(i - 1); diff --git a/src/channels.cpp b/src/channels.cpp index 35f74c57e..273a0a0db 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -1060,17 +1060,6 @@ void do_cmode(const Anope::string &source, const Anope::string &channel, const A /*************************************************************************/ -enum -{ - ACCESS_INVALID = -10000, - ACCESS_FOUNDER = 10001 -}; - -static inline bool ShouldSet(AccessGroup &u_access, User *u, ChannelInfo *ci, ChannelAccess priv) -{ - return u_access.HasPriv(priv) || (IsFounder(u, ci) && ci->levels[priv] != ACCESS_INVALID); -} - /** * Set the correct modes, or remove the ones granted without permission, * for the specified user on ths specified channel. This doesn't give @@ -1102,31 +1091,31 @@ void chan_set_correct_modes(User *user, Channel *c, int give_modes) if (give_modes && (!user->Account() || user->Account()->HasFlag(NI_AUTOOP))) { - if (owner && ShouldSet(u_access, user, ci, CA_AUTOOWNER)) + if (owner && u_access.HasPriv(CA_AUTOOWNER)) c->SetMode(NULL, CMODE_OWNER, user->nick); - else if (admin && ShouldSet(u_access, user, ci, CA_AUTOPROTECT)) + else if (admin && u_access.HasPriv(CA_AUTOPROTECT)) c->SetMode(NULL, CMODE_PROTECT, user->nick); - if (op && ShouldSet(u_access, user, ci, CA_AUTOOP)) + if (op && u_access.HasPriv(CA_AUTOOP)) c->SetMode(NULL, CMODE_OP, user->nick); - else if (halfop && ShouldSet(u_access, user, ci, CA_AUTOHALFOP)) + else if (halfop && u_access.HasPriv(CA_AUTOHALFOP)) c->SetMode(NULL, CMODE_HALFOP, user->nick); - else if (voice && ShouldSet(u_access, user, ci, CA_AUTOVOICE)) + else if (voice && u_access.HasPriv(CA_AUTOVOICE)) c->SetMode(NULL, CMODE_VOICE, user->nick); } /* If this channel has secureops or the channel is syncing and they are not ulined, check to remove modes */ if ((ci->HasFlag(CI_SECUREOPS) || (c->HasFlag(CH_SYNCING) && user->server->IsSynced())) && !user->server->IsULined()) { - if (owner && !ShouldSet(u_access, user, ci, CA_AUTOOWNER) && !ShouldSet(u_access, user, ci, CA_OWNERME)) + if (owner && !u_access.HasPriv(CA_AUTOOWNER) && !u_access.HasPriv(CA_OWNERME)) c->RemoveMode(NULL, CMODE_OWNER, user->nick); - if (admin && !ShouldSet(u_access, user, ci, CA_AUTOPROTECT) && !ShouldSet(u_access, user, ci, CA_PROTECTME)) + if (admin && !u_access.HasPriv(CA_AUTOPROTECT) && !u_access.HasPriv(CA_PROTECTME)) c->RemoveMode(NULL, CMODE_PROTECT, user->nick); - if (op && c->HasUserStatus(user, CMODE_OP) && !ShouldSet(u_access, user, ci, CA_AUTOOP) && !ShouldSet(u_access, user, ci, CA_OPDEOPME)) + if (op && c->HasUserStatus(user, CMODE_OP) && !u_access.HasPriv(CA_AUTOOP) && !u_access.HasPriv(CA_OPDEOPME)) c->RemoveMode(NULL, CMODE_OP, user->nick); - if (halfop && !ShouldSet(u_access, user, ci, CA_AUTOHALFOP) && !ShouldSet(u_access, user, ci, CA_HALFOPME)) + if (halfop && !u_access.HasPriv(CA_AUTOHALFOP) && !u_access.HasPriv(CA_HALFOPME)) c->RemoveMode(NULL, CMODE_HALFOP, user->nick); } diff --git a/src/regchannel.cpp b/src/regchannel.cpp index ce5bef71c..3b246fece 100644 --- a/src/regchannel.cpp +++ b/src/regchannel.cpp @@ -258,12 +258,14 @@ AccessGroup ChannelInfo::AccessFor(User *u) AccessGroup group; + group.SuperAdmin = u->SuperAdmin; + group.Founder = IsFounder(u, this); + group.ci = this; + for (unsigned i = 0, end = this->access.size(); i < end; ++i) if (this->access[i]->Matches(u, nc)) group.push_back(this->access[i]); - group.SuperAdmin = u->SuperAdmin; - return group; } @@ -271,6 +273,9 @@ AccessGroup ChannelInfo::AccessFor(NickCore *nc) { AccessGroup group; + group.Founder = (this->founder && this->founder == nc); + group.ci = this; + for (unsigned i = 0, end = this->access.size(); i < end; ++i) if (this->access[i]->Matches(NULL, nc)) group.push_back(this->access[i]); |