diff options
-rw-r--r-- | include/modules/cap.h | 25 | ||||
-rw-r--r-- | src/modules/m_cap.cpp | 12 |
2 files changed, 36 insertions, 1 deletions
diff --git a/include/modules/cap.h b/include/modules/cap.h index a00089260..1ad2ff2f1 100644 --- a/include/modules/cap.h +++ b/include/modules/cap.h @@ -23,11 +23,24 @@ namespace Cap { - static const unsigned int MAX_CAPS = sizeof(intptr_t) * 8; + static const unsigned int MAX_CAPS = (sizeof(intptr_t) * 8) - 1; + static const intptr_t CAP_302_BIT = (intptr_t)1 << MAX_CAPS; + typedef intptr_t Ext; typedef LocalIntExt ExtItem; class Capability; + enum Protocol + { + /** Supports capability negotiation protocol v3.1, or none + */ + CAP_LEGACY, + + /** Supports capability negotiation v3.2 + */ + CAP_302 + }; + class Manager : public DataProvider { public: @@ -190,6 +203,16 @@ namespace Cap */ bool IsRegistered() const { return (extitem != NULL); } + /** Get the CAP negotiation protocol version of a user. + * The cap must be registered for this to return anything other than CAP_LEGACY. + * @param user User whose negotiation protocol version to query + * @return One of the Capability::Protocol enum indicating the highest supported capability negotiation protocol version + */ + Protocol GetProtocol(LocalUser* user) const + { + return ((IsRegistered() && (extitem->get(user) & CAP_302_BIT)) ? CAP_302 : CAP_LEGACY); + } + /** Called when a user requests to turn this capability on or off. * @param user User requesting to change the state of the cap * @param add True if requesting to turn the cap on, false if requesting to turn it off diff --git a/src/modules/m_cap.cpp b/src/modules/m_cap.cpp index 2b4055e3c..4411306ed 100644 --- a/src/modules/m_cap.cpp +++ b/src/modules/m_cap.cpp @@ -115,6 +115,16 @@ class Cap::ManagerImpl : public Cap::Manager return NULL; } + Protocol GetProtocol(LocalUser* user) const + { + return ((capext.get(user) & CAP_302_BIT) ? CAP_302 : CAP_LEGACY); + } + + void Set302Protocol(LocalUser* user) + { + capext.set(user, capext.get(user) | CAP_302_BIT); + } + bool HandleReq(LocalUser* user, const std::string& reqlist) { Ext usercaps = capext.get(user); @@ -211,6 +221,8 @@ class CommandCap : public SplitCommand else if ((subcommand == "LS") || (subcommand == "LIST")) { const bool is_ls = (subcommand.length() == 2); + if ((is_ls) && (parameters.size() > 1) && (parameters[1] == "302")) + manager.Set302Protocol(user); std::string result = subcommand + " :"; manager.HandleList(result, user, is_ls); |