diff options
Diffstat (limited to 'src/modules')
-rw-r--r-- | src/modules/m_cap.cpp | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/src/modules/m_cap.cpp b/src/modules/m_cap.cpp index e1593e33f..bfce2e68c 100644 --- a/src/modules/m_cap.cpp +++ b/src/modules/m_cap.cpp @@ -25,6 +25,8 @@ namespace Cap class ManagerImpl; } +static Cap::ManagerImpl* managerimpl; + class Cap::ManagerImpl : public Cap::Manager { typedef insp::flat_map<std::string, Capability*, irc::insensitive_swo> CapMap; @@ -62,9 +64,10 @@ class Cap::ManagerImpl : public Cap::Manager public: ManagerImpl(Module* mod, Events::ModuleEventProvider& evprovref) : Cap::Manager(mod) - , capext("caps", ExtensionItem::EXT_USER, mod) + , capext(mod) , evprov(evprovref) { + managerimpl = this; } ~ManagerImpl() @@ -199,6 +202,56 @@ class Cap::ManagerImpl : public Cap::Manager } }; +Cap::ExtItem::ExtItem(Module* mod) + : LocalIntExt("caps", ExtensionItem::EXT_USER, mod) +{ +} + +std::string Cap::ExtItem::serialize(SerializeFormat format, const Extensible* container, void* item) const +{ + std::string ret; + // XXX: Cast away the const because IS_LOCAL() doesn't handle it + LocalUser* user = IS_LOCAL(const_cast<User*>(static_cast<const User*>(container))); + if ((format == FORMAT_NETWORK) || (!user)) + return ret; + + // List requested caps + managerimpl->HandleList(ret, user, false, false); + + // Serialize cap protocol version. If building a human-readable string append a new token, otherwise append only a single character indicating the version. + Protocol protocol = managerimpl->GetProtocol(user); + if (format == FORMAT_USER) + ret.append("capversion=3."); + else if (!ret.empty()) + ret.erase(ret.length()-1); + + if (protocol == CAP_302) + ret.push_back('2'); + else + ret.push_back('1'); + + return ret; +} + +void Cap::ExtItem::unserialize(SerializeFormat format, Extensible* container, const std::string& value) +{ + if (format == FORMAT_NETWORK) + return; + + LocalUser* user = IS_LOCAL(static_cast<User*>(container)); + if (!user) + return; // Can't happen + + // Process the cap protocol version which is a single character at the end of the serialized string + const char verchar = *value.rbegin(); + if (verchar == '2') + managerimpl->Set302Protocol(user); + + // Remove the version indicator from the string passed to HandleReq + std::string caplist(value, 0, value.size()-1); + managerimpl->HandleReq(user, caplist); +} + class CommandCap : public SplitCommand { Events::ModuleEventProvider evprov; |