X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=include%2Fmodules%2Fcap.h;h=6dcb9f3bc4d037d5a9055cfe7472824e8adcb190;hb=79892a727e323dcc4bce7e9c0cf3c99c5fe61706;hp=4ca3911a5512e6bb31f4575231be21373b353ed9;hpb=bc388aa97c1e8ab4ebea729d116e868cff11e137;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/include/modules/cap.h b/include/modules/cap.h index 4ca3911a5..6dcb9f3bc 100644 --- a/include/modules/cap.h +++ b/include/modules/cap.h @@ -23,11 +23,52 @@ 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; + static const unsigned int MAX_VALUE_LENGTH = 100; + typedef intptr_t Ext; - typedef LocalIntExt ExtItem; + class ExtItem : public LocalIntExt + { + public: + ExtItem(Module* mod); + std::string serialize(SerializeFormat format, const Extensible* container, void* item) const CXX11_OVERRIDE; + void unserialize(SerializeFormat format, Extensible* container, const std::string& value) CXX11_OVERRIDE; + }; + class Capability; + enum Protocol + { + /** Supports capability negotiation protocol v3.1, or none + */ + CAP_LEGACY, + + /** Supports capability negotiation v3.2 + */ + CAP_302 + }; + + class EventListener : public Events::ModuleEventListener + { + public: + EventListener(Module* mod) + : ModuleEventListener(mod, "event/cap") + { + } + + /** Called whenever a new client capability becomes available or unavailable + * @param cap Capability being added or removed + * @param add If true, the capability is being added, otherwise its being removed + */ + virtual void OnCapAddDel(Capability* cap, bool add) = 0; + + /** Called whenever the value of a cap changes. + * @param cap Capability whose value changed + */ + virtual void OnCapValueChange(Capability* cap) { } + }; + class Manager : public DataProvider { public: @@ -53,6 +94,11 @@ namespace Cap * @return Capability object pointer if found, NULL otherwise */ virtual Capability* Find(const std::string& name) const = 0; + + /** Notify manager when a value of a cap changed + * @param cap Cap whose value changed + */ + virtual void NotifyValueChange(Capability* cap) = 0; }; /** Represents a client capability. @@ -106,6 +152,16 @@ namespace Cap friend class ManagerImpl; + protected: + /** Notify the manager that the value of the capability changed. + * Must be called if the value of the cap changes for any reason. + */ + void NotifyValueChange() + { + if (IsRegistered()) + manager->NotifyValueChange(this); + } + public: /** Constructor, initializes the capability. * Caps are active by default. @@ -141,7 +197,7 @@ namespace Cap if (!IsRegistered()) return false; Ext caps = extitem->get(user); - return (caps & GetMask()); + return ((caps & GetMask()) != 0); } /** Turn the capability on/off for a user. If the cap is not registered this method has no effect. @@ -190,6 +246,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 @@ -199,5 +265,71 @@ namespace Cap { return true; } + + /** Called when a user requests a list of all capabilities and this capability is about to be included in the list. + * The default behavior always includes the cap in the list. + * @param user User querying a list capabilities + * @return True to add this cap to the list sent to the user, false to not list it + */ + virtual bool OnList(LocalUser* user) + { + return true; + } + + /** Query the value of this capability for a user + * @param user User who will get the value of the capability + * @return Value to show to the user. If NULL, the capability has no value (default). + */ + virtual const std::string* GetValue(LocalUser* user) const + { + return NULL; + } + }; + + /** Reference to a cap. The cap may be provided by another module. + */ + class Reference + { + dynamic_reference_nocheck ref; + + public: + /** Constructor, initializes the capability reference + * @param mod Module creating this object + * @param Name Raw name of the cap as used in the protocol (CAP LS, etc.) + */ + Reference(Module* mod, const std::string& Name) + : ref(mod, "cap/" + Name) + { + } + + /** Check whether a user has the referenced capability turned on. + * @param user User to check + * @return True if the user is using the referenced capability, false otherwise + */ + bool get(LocalUser* user) + { + if (ref) + return ref->get(user); + return false; + } + }; + + class MessageBase : public ClientProtocol::Message + { + public: + MessageBase(const std::string& subcmd) + : ClientProtocol::Message("CAP", ServerInstance->Config->ServerName) + { + PushParamPlaceholder(); + PushParam(subcmd); + } + + void SetUser(LocalUser* user) + { + if (user->registered & REG_NICK) + ReplaceParamRef(0, user->nick); + else + ReplaceParam(0, "*"); + } }; }