+ bit = 0;
+ extitem = NULL;
+ }
+
+ Ext AddToMask(Ext mask) const { return (mask | GetMask()); }
+ Ext DelFromMask(Ext mask) const { return (mask & (~GetMask())); }
+ Bit GetMask() const { return bit; }
+
+ 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.
+ * @param mod Module providing the cap
+ * @param Name Raw name of the cap as used in the protocol (CAP LS, etc.)
+ */
+ Capability(Module* mod, const std::string& Name)
+ : ServiceProvider(mod, Name, SERVICE_CUSTOM)
+ , active(true)
+ , manager(mod, "capmanager")
+ {
+ Unregister();
+ }
+
+ ~Capability()
+ {
+ SetActive(false);
+ }
+
+ void RegisterService() CXX11_OVERRIDE
+ {
+ manager.SetCaptureHook(this);
+ SetActive(true);
+ }
+
+ /** Check whether a user has the capability turned on.
+ * This method is safe to call if the cap is unregistered and will return false.
+ * @param user User to check
+ * @return True if the user is using this capability, false otherwise
+ */
+ bool get(User* user) const
+ {
+ if (!IsRegistered())
+ return false;
+ Ext caps = extitem->get(user);
+ return (caps & GetMask());
+ }
+
+ /** Turn the capability on/off for a user. If the cap is not registered this method has no effect.
+ * @param user User to turn the cap on/off for
+ * @param val True to turn the cap on, false to turn it off
+ */
+ void set(User* user, bool val)
+ {
+ if (!IsRegistered())
+ return;
+ Ext curr = extitem->get(user);
+ extitem->set(user, (val ? AddToMask(curr) : DelFromMask(curr)));
+ }
+
+ /** Activate or deactivate the capability.
+ * If activating, the cap is marked as active and if the manager is available the cap is registered in the manager.
+ * If deactivating, the cap is marked as inactive and if it is registered, it will be unregistered.
+ * Users who had the cap turned on will have it turned off automatically.
+ * @param activate True to activate the cap, false to deactivate it
+ */
+ void SetActive(bool activate)
+ {
+ active = activate;
+ if (manager)