Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/multiaddonmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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;
}

Expand All @@ -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<PendingDownload_t> 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())
Expand Down Expand Up @@ -623,6 +654,7 @@ KHook::Return<void> MultiAddonManager::Hook_GameServerSteamAPIActivated(IServerG
Message("Steam API Activated\n");

m_CallbackDownloadItemResult.Register(this, &MultiAddonManager::OnAddonDownloaded);
m_CallbackSteamServersConnected.Register(this, &MultiAddonManager::OnSteamServersConnected);

RefreshAddons(true);

Expand Down
11 changes: 11 additions & 0 deletions src/multiaddonmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@

#include <ISmmPlugin.h>
#include <igameevents.h>
#include <eiface.h>
#include "khook.hpp"
#include "utlqueue.h"
#include "utlvector.h"
#include <vector>
#include "networksystem/inetworkserializer.h"
#include "steam/steam_api_common.h"
#include "steam/isteamugc.h"
#include "steam/isteamuser.h"
#include "imultiaddonmanager.h"

#ifdef _WIN32
Expand Down Expand Up @@ -126,9 +129,17 @@ class MultiAddonManager : public ISmmPlugin, public IMetamodListener, public IMu
KHook::Function<uint64> m_hookScriptGetAddon;

CUtlVector<PublishedFileId_t> 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<PendingDownload_t> m_PendingDownloads; // Downloads that failed to start because the server wasn't logged on to Steam yet
CUtlQueue<PublishedFileId_t> 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;

Expand Down
Loading