From 45f7640d2aec2a4da13134f6716e07426cdc75be Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Mon, 9 Sep 2024 12:11:05 +0100 Subject: Send an ISupport diff when a user moves to a new connect class. --- src/coremods/core_info/core_info.cpp | 11 +++++++++++ src/coremods/core_info/core_info.h | 7 +++++++ src/coremods/core_info/isupport.cpp | 17 +++++++++++++++++ src/coremods/core_user/core_user.cpp | 5 +++++ 4 files changed, 40 insertions(+) (limited to 'src') diff --git a/src/coremods/core_info/core_info.cpp b/src/coremods/core_info/core_info.cpp index 347850b0d..c6baa71aa 100644 --- a/src/coremods/core_info/core_info.cpp +++ b/src/coremods/core_info/core_info.cpp @@ -169,6 +169,17 @@ public: ServerInstance->AtomicActions.AddAction(new ISupportAction(isupport)); } + void OnChangeConnectClass(LocalUser* user, const std::shared_ptr& klass, bool force) override + { + // TODO: this should be OnPostChangeConnectClass but we need the old + // connect class which isn't exposed to the module interface and we + // can't break the API in a stable release. For now we use this and + // prioritise it to be after core_user checks whether the user needs + // to die. + if (user->IsFullyConnected() && !user->quitting) + isupport.ChangeClass(user, user->GetClass(), klass); + } + void OnUserConnect(LocalUser* user) override { user->WriteNumeric(RPL_WELCOME, INSP_FORMAT("Welcome to the {} IRC Network {}", ServerInstance->Config->Network, user->GetRealMask())); diff --git a/src/coremods/core_info/core_info.h b/src/coremods/core_info/core_info.h index ca5ba8590..9baad8fb0 100644 --- a/src/coremods/core_info/core_info.h +++ b/src/coremods/core_info/core_info.h @@ -59,6 +59,13 @@ public: */ void Build(); + /** Sends an 005 (ISUPPORT) diff from the old class to the new one. + * @param user The user to send the diff to. + * @param oldclass The connect class the user is moving from. + * @param newclass The conenct class the user is moving to. + */ + void ChangeClass(LocalUser* user, const std::shared_ptr& oldclass, const std::shared_ptr& newclass); + /** Send the 005 numerics (ISUPPORT) to a user. * @param user The user to send the ISUPPORT numerics to */ diff --git a/src/coremods/core_info/isupport.cpp b/src/coremods/core_info/isupport.cpp index be9f645af..b9f275ec3 100644 --- a/src/coremods/core_info/isupport.cpp +++ b/src/coremods/core_info/isupport.cpp @@ -160,6 +160,23 @@ void ISupportManager::BuildNumerics(ISupport::TokenMap& tokens, std::vector& oldclass, const std::shared_ptr& newclass) +{ + auto oldtokens = cachedtokens.find(oldclass); + auto newtokens = cachedtokens.find(newclass); + if (oldtokens == cachedtokens.end() || newtokens == cachedtokens.end()) + return; // Should never happen. + + ISupport::TokenMap difftokens; + TokenDifference(difftokens, oldtokens->second, newtokens->second); + + std::vector diffnumerics; + BuildNumerics(difftokens, diffnumerics); + + for (const auto& numeric : diffnumerics) + user->WriteNumeric(numeric); +} + void ISupportManager::SendTo(LocalUser* user) { auto numerics = cachednumerics.find(user->GetClass()); diff --git a/src/coremods/core_user/core_user.cpp b/src/coremods/core_user/core_user.cpp index 20f679862..273c982cb 100644 --- a/src/coremods/core_user/core_user.cpp +++ b/src/coremods/core_user/core_user.cpp @@ -280,6 +280,11 @@ public: const auto& performance = ServerInstance->Config->ConfValue("performance"); clonesonconnect = performance->getBool("clonesonconnect", true); } + + void Prioritize() override + { + ServerInstance->Modules.SetPriority(this, I_OnChangeConnectClass, PRIORITY_FIRST); + } }; MODULE_INIT(CoreModUser) -- cgit v1.3.1-10-gc9f91