From aeb0bc3294420e27c8575064236ea3317432a583 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Sun, 16 Jan 2022 01:33:40 +0000 Subject: Make 005 dependent on the connect class. --- src/coremods/core_channel/core_channel.cpp | 13 ++---- src/coremods/core_info/core_info.h | 4 +- src/coremods/core_info/isupport.cpp | 63 ++++++++++++++++++++---------- src/users.cpp | 1 + 4 files changed, 50 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/coremods/core_channel/core_channel.cpp b/src/coremods/core_channel/core_channel.cpp index 5ecae73a3..af8f8a556 100644 --- a/src/coremods/core_channel/core_channel.cpp +++ b/src/coremods/core_channel/core_channel.cpp @@ -223,16 +223,11 @@ class CoreModChannel final std::sort(limits.begin(), limits.end()); tokens["MAXLIST"] = stdalgo::string::join(limits, ','); + } - // Generate the CHANLIMIT token. - unsigned int maxchans = 20; - for (const auto& klass : ServerInstance->Config->Classes) - { - // This cast is safe as we start from 20 above and count down. - if (klass->maxchans < maxchans) - maxchans = static_cast(klass->maxchans); - } - tokens["CHANLIMIT"] = InspIRCd::Format("#:%u", maxchans); + void OnBuildClassISupport(std::shared_ptr klass, ISupport::TokenMap& tokens) override + { + tokens["CHANLIMIT"] = InspIRCd::Format("#:%lu", klass->maxchans); } ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven, bool override) override diff --git a/src/coremods/core_info/core_info.h b/src/coremods/core_info/core_info.h index dddc55f62..10f8e60d0 100644 --- a/src/coremods/core_info/core_info.h +++ b/src/coremods/core_info/core_info.h @@ -28,10 +28,10 @@ class ISupportManager final { private: /** The generated numerics which are sent to clients. */ - std::vector cachednumerics; + SimpleExtItem> cachednumerics; /** The tokens which were generated by the last update. */ - ISupport::TokenMap cachedtokens; + SimpleExtItem cachedtokens; /** Provider for the ISupport::EventListener event. */ ISupport::EventProvider isupportevprov; diff --git a/src/coremods/core_info/isupport.cpp b/src/coremods/core_info/isupport.cpp index 52085441c..de96a45ee 100644 --- a/src/coremods/core_info/isupport.cpp +++ b/src/coremods/core_info/isupport.cpp @@ -44,7 +44,9 @@ namespace } ISupportManager::ISupportManager(Module* mod) - : isupportevprov(mod) + : cachednumerics(mod, "cached-numerics", ExtensionType::CONNECT_CLASS) + , cachedtokens(mod, "cached-tokens", ExtensionType::CONNECT_CLASS) + , isupportevprov(mod) { } @@ -90,29 +92,46 @@ void ISupportManager::Build() }; isupportevprov.Call(&ISupport::EventListener::OnBuildISupport, tokens); - // Transform the map into a list of numerics ready to be sent to clients. - std::vector numerics; - BuildNumerics(tokens, numerics); + insp::flat_map, std::vector> diffnumerics; + for (const auto& klass : ServerInstance->Config->Classes) + { + ISupport::TokenMap classtokens = tokens; + isupportevprov.Call(&ISupport::EventListener::OnBuildClassISupport, klass, classtokens); - // Extract the tokens which have been updated - ISupport::TokenMap difftokens; - TokenDifference(difftokens, cachedtokens, tokens); + // Transform the map into a list of numerics ready to be sent to clients. + std::vector numerics; + BuildNumerics(classtokens, numerics); - // Send the updated numerics to users. - std::vector diffnumerics; - BuildNumerics(difftokens, diffnumerics); - for (LocalUser* user : ServerInstance->Users.GetLocalUsers()) - { - if (user->registered & REG_ALL) + // Extract the tokens which have been updated. + ISupport::TokenMap* oldtokens = cachedtokens.Get(klass.get()); + if (oldtokens) { - for (const auto& diffnumeric : diffnumerics) - user->WriteNumeric(diffnumeric); + // Build the updated numeric diff to send to to existing users. + ISupport::TokenMap difftokens; + TokenDifference(difftokens, *oldtokens, classtokens); + BuildNumerics(difftokens, diffnumerics[klass]); } + + // Apply the new ISUPPORT values. + cachednumerics.Set(klass.get(), numerics); + cachedtokens.Set(klass.get(), classtokens); } - // Apply the new ISUPPORT values. - std::swap(numerics, cachednumerics); - std::swap(tokens, cachedtokens); + if (!diffnumerics.empty()) + { + for (LocalUser* user : ServerInstance->Users.GetLocalUsers()) + { + if (!(user->registered & REG_ALL)) + continue; // User hasn't received 005 yet. + + auto numerics = diffnumerics.find(user->GetClass()); + if (numerics == diffnumerics.end()) + continue; // Should never happen. + + for (const auto& numeric : numerics->second) + user->WriteNumeric(numeric); + } + } } void ISupportManager::BuildNumerics(ISupport::TokenMap& tokens, std::vector& numerics) @@ -137,6 +156,10 @@ void ISupportManager::BuildNumerics(ISupport::TokenMap& tokens, std::vectorWriteNumeric(cachednumeric); + auto numerics = cachednumerics.Get(user->GetClass().get()); + if (!numerics) + return; // Should never happen. + + for (const auto& numeric : *numerics) + user->WriteNumeric(numeric); } diff --git a/src/users.cpp b/src/users.cpp index 43838c17c..4296f442a 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -1300,6 +1300,7 @@ void ConnectClass::Configure(const std::string& classname, std::shared_ptr src) { + ServerInstance->Logs.Log("CONNECTCLASS", LOG_DEBUG, "Updating %s from %s", name.c_str(), src->name.c_str()); commandrate = src->commandrate; config = src->config; fakelag = src->fakelag; -- cgit v1.3.1-10-gc9f91