diff options
-rw-r--r-- | include/access.h | 4 | ||||
-rw-r--r-- | include/anope.h | 24 | ||||
-rw-r--r-- | modules/commands/cs_access.cpp | 22 | ||||
-rw-r--r-- | src/access.cpp | 11 |
4 files changed, 47 insertions, 14 deletions
diff --git a/include/access.h b/include/access.h index 19b6b3b02..cb24a6030 100644 --- a/include/access.h +++ b/include/access.h @@ -123,8 +123,8 @@ class CoreExport ChanAccess : public Serializable virtual void AccessUnserialize(const Anope::string &data) = 0; /* Comparison operators to other Access entries */ - bool operator>(const ChanAccess &other) const; - bool operator<(const ChanAccess &other) const; + virtual bool operator>(const ChanAccess &other) const; + virtual bool operator<(const ChanAccess &other) const; bool operator>=(const ChanAccess &other) const; bool operator<=(const ChanAccess &other) const; }; diff --git a/include/anope.h b/include/anope.h index 51ece1cd6..07ed29ebf 100644 --- a/include/anope.h +++ b/include/anope.h @@ -762,17 +762,31 @@ template<typename T> inline T convertTo(const Anope::string &s, bool failIfLefto */ #ifdef DEBUG_BUILD # include <typeinfo> -#endif -template<typename T, typename O> inline T anope_dynamic_static_cast(O ptr) + +template<typename T, typename O> inline T anope_dynamic_static_cast(O* ptr) { -#ifdef DEBUG_BUILD T ret = dynamic_cast<T>(ptr); if (ptr != NULL && ret == NULL) - throw CoreException(Anope::string("anope_dynamic_static_cast<") + typeid(T).name() + ">(" + typeid(O).name() + ") fail"); + throw CoreException(Anope::string("anope_dynamic_static_cast<") + typeid(T).name() + ">(" + typeid(O*).name() + ") fail"); return ret; +} + +template<typename T, typename O> inline T anope_dynamic_static_cast(O& ref) +{ + try + { + return dynamic_cast<T>(ref); + } + catch (const std::bad_cast &ex) + { + throw CoreException(Anope::string("std::bad_cast from anope_dynamic_static_cast<") + typeid(T).name() + ">(" + typeid(O&).name() + "): " + ex.what()); + } +} #else +template<typename T, typename O> inline T anope_dynamic_static_cast(O ptr) +{ return static_cast<T>(ptr); -#endif } +#endif #endif // ANOPE_H diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp index 0ecf95106..7a2d1a35b 100644 --- a/modules/commands/cs_access.cpp +++ b/modules/commands/cs_access.cpp @@ -43,13 +43,32 @@ class AccessChanAccess : public ChanAccess { this->level = convertTo<int>(data); } + + bool operator>(const ChanAccess &other) const anope_override + { + if (this->provider != other.provider) + return ChanAccess::operator>(other); + else + return this->level > anope_dynamic_static_cast<const AccessChanAccess &>(other).level; + } + + bool operator<(const ChanAccess &other) const anope_override + { + if (this->provider != other.provider) + return ChanAccess::operator<(other); + else + return this->level < anope_dynamic_static_cast<const AccessChanAccess &>(other).level; + } }; class AccessAccessProvider : public AccessProvider { public: + static AccessAccessProvider *me; + AccessAccessProvider(Module *o) : AccessProvider(o, "access/access") { + me = this; } ChanAccess *Create() anope_override @@ -57,6 +76,7 @@ class AccessAccessProvider : public AccessProvider return new AccessChanAccess(this); } }; +AccessAccessProvider* AccessAccessProvider::me; class CommandCSAccess : public Command { @@ -91,7 +111,7 @@ class CommandCSAccess : public Command AccessGroup u_access = source.AccessFor(ci); const ChanAccess *highest = u_access.Highest(); - AccessChanAccess tmp_access(NULL); + AccessChanAccess tmp_access(AccessAccessProvider::me); tmp_access.ci = ci; tmp_access.level = level; diff --git a/src/access.cpp b/src/access.cpp index 2533f4415..f4b97c21e 100644 --- a/src/access.cpp +++ b/src/access.cpp @@ -363,12 +363,11 @@ bool AccessGroup::HasPriv(const Anope::string &name) const const ChanAccess *AccessGroup::Highest() const { - const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges(); - for (unsigned i = privs.size(); i > 0; --i) - for (unsigned j = this->size(); j > 0; --j) - if (this->at(j - 1)->HasPriv(privs[i - 1].name)) - return this->at(j - 1); - return NULL; + ChanAccess *highest = NULL; + for (unsigned i = 0; i < this->size(); ++i) + if (highest == NULL || *this->at(i) > *highest) + highest = this->at(i); + return highest; } bool AccessGroup::operator>(const AccessGroup &other) const |