X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=include%2Fmodules%2Fcap.h;h=8299d14aeae7634eb6553266c09f1f7492714b22;hb=35b70631f0532a5828b04a8e0c02092a285f331a;hp=9dd44a4aa35e4dd8a1bd0003e125524bacb6d6e8;hpb=259b1113944a01aeb450265f03fb97a283e8ef15;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/include/modules/cap.h b/include/modules/cap.h index 9dd44a4aa..8299d14ae 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. @@ -65,6 +111,8 @@ namespace Cap * * The cap module must be loaded for the capability to work. The IsRegistered() method can be used to query whether the cap is actually online or not. * The capability can be deactivated and reactivated with the SetActive() method. Deactivated caps behave as if they don't exist. + * + * It is possible to implement special behavior by inheriting from this class and overriding some of its methods. */ class Capability : public ServiceProvider, private dynamic_reference_base::CaptureHook { @@ -104,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. @@ -139,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. @@ -187,5 +245,72 @@ namespace Cap * @return True if the cap is registered in the manager, false otherwise */ 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 + * @return True to allow the request, false to reject it + */ + virtual bool OnRequest(LocalUser* user, bool add) + { + 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; + } }; }