summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/access.h4
-rw-r--r--include/anope.h24
-rw-r--r--modules/commands/cs_access.cpp22
-rw-r--r--src/access.cpp11
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