/* * InspIRCd -- Internet Relay Chat Daemon * * Copyright (C) 2018-2019 Sadie Powell * Copyright (C) 2015 Attila Molnar * * This file is part of InspIRCd. InspIRCd is free software: you can * redistribute it and/or modify it under the terms of the GNU General Public * License as published by the Free Software Foundation, version 2. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "modules/invite.h" namespace Invite { template struct Store { typedef insp::intrusive_list List; /** List of pending Invites */ List invites; }; template class ExtItem; class APIImpl; } extern void RemoveInvite(Invite::Invite* inv, bool remove_user, bool remove_chan); extern void UnserializeInvite(LocalUser* user, const std::string& value); template class Invite::ExtItem : public ExtensionItem { private: static std::string ToString(void* item, bool human) { std::string ret; Store* store = static_cast*>(item); for (typename insp::intrusive_list::iterator i = store->invites.begin(); i != store->invites.end(); ++i) { Invite* inv = *i; inv->Serialize(human, (ExtType == ExtensionItem::EXT_USER), ret); } if (!ret.empty()) ret.erase(ret.length()-1); return ret; } public: ExtItem(Module* owner, const char* extname) : ExtensionItem(extname, ExtType, owner) { } Store* get(Extensible* ext, bool create = false) { Store* store = static_cast*>(get_raw(ext)); if ((create) && (!store)) { store = new Store; set_raw(ext, store); } return store; } void unset(Extensible* ext) { void* store = unset_raw(ext); if (store) free(ext, store); } void free(Extensible* container, void* item) CXX11_OVERRIDE { Store* store = static_cast*>(item); for (typename Store::List::iterator i = store->invites.begin(); i != store->invites.end(); ) { Invite* inv = *i; // Destructing the Invite invalidates the iterator, so move it now ++i; RemoveInvite(inv, (ExtType != ExtensionItem::EXT_USER), (ExtType == ExtensionItem::EXT_USER)); } delete store; } std::string ToHuman(const Extensible* container, void* item) const CXX11_OVERRIDE { return ToString(item, true); } std::string ToInternal(const Extensible* container, void* item) const CXX11_OVERRIDE { return ToString(item, false); } void FromInternal(Extensible* container, const std::string& value) CXX11_OVERRIDE { if (ExtType != ExtensionItem::EXT_CHANNEL) UnserializeInvite(static_cast(container), value); } }; class Invite::APIImpl : public APIBase { ExtItem userext; ExtItem chanext; public: APIImpl(Module* owner); void Create(LocalUser* user, Channel* chan, time_t timeout) CXX11_OVERRIDE; Invite* Find(LocalUser* user, Channel* chan) CXX11_OVERRIDE; bool Remove(LocalUser* user, Channel* chan) CXX11_OVERRIDE; const List* GetList(LocalUser* user) CXX11_OVERRIDE; void RemoveAll(LocalUser* user) { userext.unset(user); } void RemoveAll(Channel* chan) { chanext.unset(chan); } void Destruct(Invite* inv, bool remove_chan = true, bool remove_user = true); void Unserialize(LocalUser* user, const std::string& value); };