diff options
| author | 2024-07-17 00:06:50 +0100 | |
|---|---|---|
| committer | 2024-07-17 00:06:50 +0100 | |
| commit | 889d521e05f2e922683d48c74eb00290e7a2f548 (patch) | |
| tree | b4c56bd4cdf0881601c7e4d6ff571e491af10bf4 /src/modules/m_hidemode.cpp | |
| parent | Use std::endian from C++20 in the sha1 module. (diff) | |
| download | inspircd++-889d521e05f2e922683d48c74eb00290e7a2f548.tar.gz inspircd++-889d521e05f2e922683d48c74eb00290e7a2f548.tar.bz2 inspircd++-889d521e05f2e922683d48c74eb00290e7a2f548.zip | |
Shuffle the modules about a bit.
Diffstat (limited to 'src/modules/m_hidemode.cpp')
| -rw-r--r-- | src/modules/m_hidemode.cpp | 205 |
1 files changed, 0 insertions, 205 deletions
diff --git a/src/modules/m_hidemode.cpp b/src/modules/m_hidemode.cpp deleted file mode 100644 index c3bd0b175..000000000 --- a/src/modules/m_hidemode.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - * InspIRCd -- Internet Relay Chat Daemon - * - * Copyright (C) 2019 Matt Schatz <genius3000@g3k.solutions> - * Copyright (C) 2018-2023 Sadie Powell <sadie@witchery.services> - * Copyright (C) 2018 linuxdaemon <linuxdaemon.irc@gmail.com> - * Copyright (C) 2018 Attila Molnar <attilamolnar@hush.com> - * - * 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 <http://www.gnu.org/licenses/>. - */ - - -#include "inspircd.h" -#include "clientprotocolevent.h" - -namespace -{ -class Settings final -{ - typedef insp::flat_map<std::string, ModeHandler::Rank> RanksToSeeMap; - RanksToSeeMap rankstosee; - -public: - ModeHandler::Rank GetRequiredRank(const ModeHandler& mh) const - { - RanksToSeeMap::const_iterator it = rankstosee.find(mh.name); - if (it != rankstosee.end()) - return it->second; - return 0; - } - - void Load(const Module* mod) - { - RanksToSeeMap newranks; - - for (const auto& [_, tag] : ServerInstance->Config->ConfTags("hidemode")) - { - const std::string modename = tag->getString("mode"); - if (modename.empty()) - throw ModuleException(mod, "<hidemode:mode> is empty at " + tag->source.str()); - - ModeHandler::Rank rank = tag->getNum<ModeHandler::Rank>("rank", 0); - if (!rank) - throw ModuleException(mod, "<hidemode:rank> must be greater than 0 at " + tag->source.str()); - - ServerInstance->Logs.Debug(MODNAME, "Hiding the {} mode from users below rank {}", modename, rank); - newranks.emplace(modename, rank); - } - rankstosee.swap(newranks); - } -}; - -class ModeHook final - : public ClientProtocol::EventHook -{ - typedef insp::flat_map<ModeHandler::Rank, const ClientProtocol::MessageList*> FilteredModeMap; - - std::vector<Modes::ChangeList> modechangelists; - std::list<ClientProtocol::Messages::Mode> filteredmodelist; - std::list<ClientProtocol::MessageList> filteredmsgplists; - FilteredModeMap cache; - - static ModResult HandleResult(const ClientProtocol::MessageList* filteredmessagelist, ClientProtocol::MessageList& messagelist) - { - // Deny if member isn't allowed to see even a single mode change from this mode event - if (!filteredmessagelist) - return MOD_RES_DENY; - - // Member is allowed to see at least one mode change, replace list - if (filteredmessagelist != &messagelist) - messagelist = *filteredmessagelist; - - return MOD_RES_PASSTHRU; - } - - Modes::ChangeList* FilterModeChangeList(const ClientProtocol::Events::Mode& mode, ModeHandler::Rank rank) - { - Modes::ChangeList* modechangelist = nullptr; - for (Modes::ChangeList::List::const_iterator i = mode.GetChangeList().getlist().begin(); i != mode.GetChangeList().getlist().end(); ++i) - { - const Modes::Change& curr = *i; - if (settings.GetRequiredRank(*curr.mh) <= rank) - { - // No restriction on who can see this mode or there is one but the member's rank is sufficient - if (modechangelist) - modechangelist->push(curr); - - continue; - } - - // Member cannot see the current mode change - - if (!modechangelist) - { - // Create new mode change list or reuse the last one if it's empty - if ((modechangelists.empty()) || (!modechangelists.back().empty())) - modechangelists.emplace_back(); - - // Add all modes to it which we've accepted so far - modechangelists.back().push(mode.GetChangeList().getlist().begin(), i); - modechangelist = &modechangelists.back(); - } - } - return modechangelist; - } - - void OnEventInit(const ClientProtocol::Event& ev) override - { - cache.clear(); - filteredmsgplists.clear(); - filteredmodelist.clear(); - modechangelists.clear(); - - // Ensure no reallocations will happen - const size_t numprefixmodes = ServerInstance->Modes.GetPrefixModes().size(); - modechangelists.reserve(numprefixmodes); - } - - ModResult OnPreEventSend(LocalUser* user, const ClientProtocol::Event& ev, ClientProtocol::MessageList& messagelist) override - { - const ClientProtocol::Events::Mode& mode = static_cast<const ClientProtocol::Events::Mode&>(ev); - Channel* const chan = mode.GetMessages().front().GetChanTarget(); - if (!chan) - return MOD_RES_PASSTHRU; - - if (user->HasPrivPermission("channels/auspex")) - return MOD_RES_PASSTHRU; - - Membership* const memb = chan->GetUser(user); - if (!memb) - return MOD_RES_PASSTHRU; - - // Check cache first - const FilteredModeMap::const_iterator it = cache.find(memb->GetRank()); - if (it != cache.end()) - return HandleResult(it->second, messagelist); - - // Message for this rank isn't cached, generate it now - const Modes::ChangeList* const filteredchangelist = FilterModeChangeList(mode, memb->GetRank()); - - // If no new change list was generated (above method returned NULL) it means the member and everyone else - // with the same rank can see everything in the original change list. - ClientProtocol::MessageList* finalmsgplist = &messagelist; - if (filteredchangelist) - { - if (filteredchangelist->empty()) - { - // This rank cannot see any mode changes in the original change list - finalmsgplist = nullptr; - } - else - { - // This rank can see some of the mode changes in the filtered mode change list. - // Create and store a new protocol message from it. - filteredmsgplists.emplace_back(); - ClientProtocol::Events::Mode::BuildMessages(mode.GetMessages().front().GetSourceUser(), chan, nullptr, *filteredchangelist, filteredmodelist, filteredmsgplists.back()); - finalmsgplist = &filteredmsgplists.back(); - } - } - - // Cache the result in all cases so it can be reused for further members with the same rank - cache.emplace(memb->GetRank(), finalmsgplist); - return HandleResult(finalmsgplist, messagelist); - } - -public: - Settings settings; - - ModeHook(Module* mod) - : ClientProtocol::EventHook(mod, "MODE", 10) - { - } -}; -} - -class ModuleHideMode final - : public Module -{ -private: - ModeHook modehook; - -public: - ModuleHideMode() - : Module(VF_VENDOR, "Allows mode changes to be hidden from users without a prefix mode ranked equal to or higher than a defined level.") - , modehook(this) - { - } - - void ReadConfig(ConfigStatus& status) override - { - modehook.settings.Load(this); - } -}; - -MODULE_INIT(ModuleHideMode) |
