From 71277420b37c3a2aef432044207ff5d2178950da Mon Sep 17 00:00:00 2001 From: suarez96 Date: Tue, 20 Oct 2026 21:54:43 -0300 Subject: [PATCH 1/2] Update multiaddonmanager.h --- src/multiaddonmanager.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/multiaddonmanager.h b/src/multiaddonmanager.h index 6bc3f5d..d87f4c7 100644 --- a/src/multiaddonmanager.h +++ b/src/multiaddonmanager.h @@ -21,12 +21,15 @@ #include #include +#include #include "khook.hpp" #include "utlqueue.h" #include "utlvector.h" +#include #include "networksystem/inetworkserializer.h" #include "steam/steam_api_common.h" #include "steam/isteamugc.h" +#include "steam/isteamuser.h" #include "imultiaddonmanager.h" #ifdef _WIN32 @@ -126,9 +129,17 @@ class MultiAddonManager : public ISmmPlugin, public IMetamodListener, public IMu KHook::Function m_hookScriptGetAddon; CUtlVector m_ImportantDownloads; // Important addon downloads that will trigger a map reload when finished + struct PendingDownload_t + { + PublishedFileId_t addon; + bool bImportant; + bool bForce; + }; + std::vector m_PendingDownloads; // Downloads that failed to start because the server wasn't logged on to Steam yet CUtlQueue m_DownloadQueue; // Queue of all addon downloads to print progress STEAM_GAMESERVER_CALLBACK_MANUAL(MultiAddonManager, OnAddonDownloaded, DownloadItemResult_t, m_CallbackDownloadItemResult); + STEAM_GAMESERVER_CALLBACK_MANUAL(MultiAddonManager, OnSteamServersConnected, SteamServersConnected_t, m_CallbackSteamServersConnected); // Used when reloading current map std::string m_sCurrentWorkshopMap; From 1fe4858de1254702dd6f35f453c58de17dd3399b Mon Sep 17 00:00:00 2001 From: suarez96 Date: Tue, 20 Oct 2026 21:54:56 -0300 Subject: [PATCH 2/2] Update multiaddonmanager.cpp --- src/multiaddonmanager.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/multiaddonmanager.cpp b/src/multiaddonmanager.cpp index 6c1a033..c5d6e12 100644 --- a/src/multiaddonmanager.cpp +++ b/src/multiaddonmanager.cpp @@ -344,6 +344,7 @@ bool MultiAddonManager::Load(PluginId id, ISmmAPI *ismm, char *error, size_t max if (g_pEngineServer->IsDedicatedServer()) { m_CallbackDownloadItemResult.Register(this, &MultiAddonManager::OnAddonDownloaded); + m_CallbackSteamServersConnected.Register(this, &MultiAddonManager::OnSteamServersConnected); } } @@ -567,6 +568,16 @@ bool MultiAddonManager::DownloadAddon(const char *pszAddon, bool bImportant, boo if (!GetSteamUGC()->DownloadItem(addon, false)) { Panic("%s: Addon download for %lli failed to start, addon ID is invalid or server is not logged on Steam\n", __func__, addon); + + // Most likely the server hasn't logged on to Steam yet, retry once it does (see OnSteamServersConnected) + bool bPending = false; + for (const auto &pending : m_PendingDownloads) + if (pending.addon == addon) + bPending = true; + + if (!bPending) + m_PendingDownloads.push_back({addon, bImportant, bForce}); + return false; } @@ -580,6 +591,26 @@ bool MultiAddonManager::DownloadAddon(const char *pszAddon, bool bImportant, boo return true; } +// Downloads requested before the server logged on to Steam fail to start, so retry them now +void MultiAddonManager::OnSteamServersConnected(SteamServersConnected_t *pResult) +{ + if (m_PendingDownloads.empty()) + return; + + // Failures get queued again, so work on a copy + std::vector pending; + pending.swap(m_PendingDownloads); + + Message("Logged on to Steam, retrying %i pending addon download(s)\n", (int)pending.size()); + + for (const auto &download : pending) + { + char szAddon[32]; + V_snprintf(szAddon, sizeof(szAddon), "%llu", (unsigned long long)download.addon); + DownloadAddon(szAddon, download.bImportant, download.bForce); + } +} + void MultiAddonManager::RefreshAddons(bool bReloadMap) { if (!GetSteamUGC()) @@ -623,6 +654,7 @@ KHook::Return MultiAddonManager::Hook_GameServerSteamAPIActivated(IServerG Message("Steam API Activated\n"); m_CallbackDownloadItemResult.Register(this, &MultiAddonManager::OnAddonDownloaded); + m_CallbackSteamServersConnected.Register(this, &MultiAddonManager::OnSteamServersConnected); RefreshAddons(true);