/* * InspIRCd -- Internet Relay Chat Daemon * * Copyright (C) 2018 Dylan Frank * Copyright (C) 2013-2014 Attila Molnar * Copyright (C) 2013, 2017-2019, 2021-2023 Sadie Powell * * 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 "extension.h" /** The base class for list modes, should be inherited. */ class CoreExport ListModeBase : public ModeHandler { public: /** An item in a listmode's list */ struct ListItem final { std::string setter; std::string mask; time_t time; ListItem(const std::string& Mask, const std::string& Setter, time_t Time) : setter(Setter) , mask(Mask) , time(Time) { } }; /** Items stored in the channel's list */ using ModeList = std::vector; /** The default maximum list size. */ static constexpr size_t DEFAULT_LIST_SIZE = 100; private: class ListData final { public: /* The entries on the list mode list. */ ModeList list; /** The time at which maxitems was last checked. */ time_t maxchecked = 0; /** The maximum number of entries on the list mode list. */ size_t maxentries = 0; }; /** Finds the maximum number of this list mode that can be placed on the * given channel name according to the \ config. * @param channame The channel name to find the limit for. * @return The maximum number of modes of this type that we allow to be se * on the given channel name */ size_t FindLimit(const Channel* chan) const; protected: /** Data relating to a list mode set on a channel */ SimpleExtItem listdata; public: /** Whether the list mode accepts a user mask. */ const bool accepts_mask; /** Numeric to use when outputting the list. */ const unsigned int listnumeric; /** Numeric to indicate end of list. */ const unsigned int endoflistnumeric; /** Constructor. * @param Creator The creator of this class * @param Name Mode name * @param modechar Mode character * @param lnum List numeric * @param eolnum End of list numeric * @param am Whether the list mode accepts a user mask. */ ListModeBase(const WeakModulePtr& Creator, const std::string& Name, char modechar, unsigned int lnum, unsigned int eolnum, bool am = false); /** Compares an entry from this list with the specified value. * @param entry The list entry to compare against. * @param value The value to compare to. * @return If the entries are equivalent then true; otherwise, false. */ virtual bool CompareEntry(const std::string& entry, const std::string& value) const { return entry == value; } /** Get limit of this mode on a channel * @param channel The channel to inspect * @return Maximum number of modes of this type that can be placed on the given channel */ size_t GetLimit(Channel* chan, ListData *data = nullptr); /** Retrieves the list of all modes set on the given channel * @param channel Channel to get the list from * @return A list with all modes of this type set on the given channel, can be NULL */ ModeList* GetList(Channel* channel); /** @copydoc ModeHandler::DisplayList */ void DisplayList(User* user, Channel* channel) override; /** @copydoc ModeHandler::DisplayEmptyList */ void DisplayEmptyList(User* user, Channel* channel) override; /** @copydoc ModeHandler::RemoveMode(Channel*,Modes::ChangeList&) */ void RemoveMode(Channel* channel, Modes::ChangeList& changelist) override; /** @copydoc ModeHandler::OnModeChange */ bool OnModeChange(User* source, User* dest, Channel* channel, Modes::Change& change) override; /** Validate a potential entry for this list mode. This is only for local validation, you * should be prepared to handle malformed entries from remote servers as there is no good * way to prevent them from being set without causing a desync. * @param user The local user which sent the list mode change. * @param channel The channel the mode is being changed on. * @param parameter The parameter that the user specified. * @return True if the parameter is valid; otherwise, false. */ virtual bool ValidateParam(LocalUser* user, Channel* channel, std::string& parameter); /** @copydoc ModeHandler::OnParameterMissing */ void OnParameterMissing(User* user, User* dest, Channel* channel) override; /** Tell the user the list is too long. * Overridden by implementing module. * @param source Source user adding the parameter * @param channel Channel the parameter is being added to * @param parameter The actual parameter being added * @param limit The list limit for the channel. */ virtual void TellListTooLong(LocalUser* source, Channel* channel, const std::string& parameter, size_t limit); /** Tell the user an item is already on the list. * Overridden by implementing module. * @param source Source user adding the parameter * @param channel Channel the parameter is being added to * @param parameter The actual parameter being added */ virtual void TellAlreadyOnList(LocalUser* source, Channel* channel, const std::string& parameter); /** Tell the user that the parameter is not in the list. * Overridden by implementing module. * @param source Source user removing the parameter * @param channel Channel the parameter is being removed from * @param parameter The actual parameter being removed */ virtual void TellNotSet(LocalUser* source, Channel* channel, const std::string& parameter); }; inline ListModeBase::ModeList* ListModeBase::GetList(Channel* channel) { auto* data = listdata.Get(channel); if (!data) return nullptr; return &data->list; }