diff --git a/src/common/global.cpp b/src/common/global.cpp index 7a1768d73..ec4c7bed9 100644 --- a/src/common/global.cpp +++ b/src/common/global.cpp @@ -27,6 +27,7 @@ ConVar* developer = nullptr; ConVar* fps_max = nullptr; ConVar* fps_max_vsync = nullptr; +ConVar* playlist_debug = nullptr; #ifndef DEDICATED ConVar* in_syncRT = nullptr; #endif // !DEDICATED @@ -180,6 +181,7 @@ void ConVar_InitShipped(void) developer = g_pCVar->FindVar("developer"); fps_max = g_pCVar->FindVar("fps_max"); fps_max_vsync = g_pCVar->FindVar("fps_max_vsync"); + playlist_debug = g_pCVar->FindVar("playlist_debug"); base_tickinterval_sp = g_pCVar->FindVar("base_tickinterval_sp"); base_tickinterval_mp = g_pCVar->FindVar("base_tickinterval_mp"); fs_showAllReads = g_pCVar->FindVar("fs_showAllReads"); diff --git a/src/common/global.h b/src/common/global.h index e33bfc5e8..baa485b1a 100644 --- a/src/common/global.h +++ b/src/common/global.h @@ -13,6 +13,8 @@ extern ConVar* developer; extern ConVar* fps_max; extern ConVar* fps_max_vsync; +extern ConVar* playlist_debug; + #ifndef DEDICATED extern ConVar* in_syncRT; #endif // !DEDICATED diff --git a/src/rtech/playlists/playlists.cpp b/src/rtech/playlists/playlists.cpp index 3e31d7615..382564608 100644 --- a/src/rtech/playlists/playlists.cpp +++ b/src/rtech/playlists/playlists.cpp @@ -3,10 +3,14 @@ // Purpose: Playlists system // //===========================================================================// +#include "tier0/commandline.h" #include "engine/sys_dll2.h" #include "engine/cmodel_bsp.h" +#include "pluginsystem/modsystem.h" #include "playlists.h" +#define DEFAULT_PLAYLISTS_FILE_NAME "playlists_r5.txt" + KeyValues** g_pPlaylistKeyValues = nullptr; // The KeyValue for the playlist file. char* g_pPlaylistMapToLoad = nullptr; @@ -45,6 +49,74 @@ void Playlists_SDKInit(void) Mod_GetAllInstalledMaps(); // Parse all installed maps. } +//----------------------------------------------------------------------------- +// Purpose: dumps the merged playlists data to a file on the disk for debugging +// Input : *playlistPath - +//----------------------------------------------------------------------------- +static void Playlists_DumpMerged(const char* const playlistPath) +{ + CUtlBuffer outBuf(0ll, 0, CUtlBuffer::TEXT_BUFFER); + (*g_pPlaylistKeyValues)->RecursiveSaveToFile(outBuf, 0); + + CUtlString finalPath; + finalPath.Format("merged_%s", playlistPath); + + Msg(eDLL_T::RTECH, "%s: Writing merged playlists file \"%s\"\n", __FUNCTION__, finalPath.String()); + + if (!FileSystem()->WriteFile(finalPath.String(), "PLATFORM", outBuf)) + Warning(eDLL_T::RTECH, "%s: Failed to write merged playlists file: '%s'\n", __FUNCTION__, finalPath.String()); +} + +//----------------------------------------------------------------------------- +// Purpose: merges mod playlists deltas into the main playlists +// Input : *szPlaylist - +//----------------------------------------------------------------------------- +static void Playlists_MergeMods() +{ + if (!ModSystem()->IsEnabled()) + return; + + if (!*g_pPlaylistKeyValues) + return; + + ModSystem()->LockModList(); + + const char* playlistPath = nullptr; + bool hasMerges = false; + + // Preload mod paks. + FOR_EACH_VEC(ModSystem()->GetModList(), i) + { + const CModSystem::ModInstance_t* const mod = ModSystem()->GetModList()[i]; + + if (!mod->IsEnabled()) + continue; + + if (!playlistPath) + { + if (!CommandLine()->CheckParm("-playlistFile", &playlistPath) || !playlistPath) + playlistPath = DEFAULT_PLAYLISTS_FILE_NAME; + } + + CUtlString modLookupPath = mod->GetBasePath() + playlistPath; + const char* const pModLookupPath = modLookupPath.String(); + + KeyValues modPlaylists("playlists"); + modPlaylists.UsesEscapeSequences(true); + + if (!modPlaylists.LoadFromFile(FileSystem(), pModLookupPath, "GAME")) + continue; + + (*g_pPlaylistKeyValues)->MergeFrom(&modPlaylists); + hasMerges = true; // Deltas have been applied. + } + + ModSystem()->UnlockModList(); + + if (playlist_debug->GetBool() && hasMerges) + Playlists_DumpMerged(playlistPath); +} + //----------------------------------------------------------------------------- // Purpose: loads the playlists // Input : *szPlaylist - @@ -53,8 +125,9 @@ void Playlists_SDKInit(void) bool Playlists_Load(const char* pszPlaylist) { ThreadJoinServerJob(); - const bool bResults = v_Playlists_Load(pszPlaylist); + + Playlists_MergeMods(); Playlists_SDKInit(); return bResults;