From e1dfd99dcbb3aa0500c75163faddb888312ec922 Mon Sep 17 00:00:00 2001 From: bones_was_here Date: Fri, 13 Jan 2023 09:39:44 +1000 Subject: [PATCH] Unload dlcache packs when changing map or disconnecting Prevents content from the previous server and/or map from interfering with the next Signed-off-by: bones_was_here --- cl_main.c | 8 +++++--- cl_parse.c | 5 ++++- fs.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- fs.h | 3 ++- libcurl.c | 4 ++-- 5 files changed, 60 insertions(+), 12 deletions(-) diff --git a/cl_main.c b/cl_main.c index 45cb43d6..3d6e1b26 100644 --- a/cl_main.c +++ b/cl_main.c @@ -387,11 +387,13 @@ void CL_DisconnectEx(qbool kicked, const char *fmt, ... ) Con_DPrintf("CL_Disconnect\n"); - Cvar_SetValueQuick(&csqc_progcrc, -1); + Cvar_SetValueQuick(&csqc_progcrc, -1); Cvar_SetValueQuick(&csqc_progsize, -1); CL_VM_ShutDown(); -// stop sounds (especially looping!) - S_StopAllSounds (); + // stop sounds (especially looping!) + S_StopAllSounds(); + // prevent dlcache assets from this server from interfering with the next one + FS_UnloadPacks_dlcache(); cl.parsingtextexpectingpingforscores = 0; // just in case no reply has come yet diff --git a/cl_parse.c b/cl_parse.c index 1afbcbe7..4a47a004 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -1690,8 +1690,11 @@ static void CL_ParseServerInfo (void) { SCR_BeginLoadingPlaque(false); S_StopAllSounds(); + // prevent dlcache assets from the previous map from interfering with this one + FS_UnloadPacks_dlcache(); // free q3 shaders so that any newly downloaded shaders will be active - Mod_FreeQ3Shaders(); + // bones_was_here: we free the q3 shaders later in CL_SignonReply + //Mod_FreeQ3Shaders(); } // check memory integrity diff --git a/fs.c b/fs.c index f8266c71..7c5ce33c 100644 --- a/fs.c +++ b/fs.c @@ -321,6 +321,7 @@ typedef struct pack_s int ignorecase; ///< PK3 ignores case int numfiles; qbool vpack; + qbool dlcache; packfile_t *files; } pack_t; //@} @@ -1118,7 +1119,7 @@ FS_AddPack_Fullpath * plain directories. * */ -static qbool FS_AddPack_Fullpath(const char *pakfile, const char *shortname, qbool *already_loaded, qbool keep_plain_dirs) +static qbool FS_AddPack_Fullpath(const char *pakfile, const char *shortname, qbool *already_loaded, qbool keep_plain_dirs, qbool dlcache) { searchpath_t *search; pack_t *pak = NULL; @@ -1194,6 +1195,7 @@ static qbool FS_AddPack_Fullpath(const char *pakfile, const char *shortname, qbo fs_searchpaths = search; } search->pack = pak; + search->pack->dlcache = dlcache; if(pak->vpack) { dpsnprintf(search->filename, sizeof(search->filename), "%s/", pakfile); @@ -1232,7 +1234,7 @@ FS_AddPack * If keep_plain_dirs is set, the pack will be added AFTER the first sequence of * plain directories. */ -qbool FS_AddPack(const char *pakfile, qbool *already_loaded, qbool keep_plain_dirs) +qbool FS_AddPack(const char *pakfile, qbool *already_loaded, qbool keep_plain_dirs, qbool dlcache) { char fullpath[MAX_OSPATH]; int index; @@ -1251,7 +1253,7 @@ qbool FS_AddPack(const char *pakfile, qbool *already_loaded, qbool keep_plain_di dpsnprintf(fullpath, sizeof(fullpath), "%s%s", search->filename, pakfile); - return FS_AddPack_Fullpath(fullpath, pakfile, already_loaded, keep_plain_dirs); + return FS_AddPack_Fullpath(fullpath, pakfile, already_loaded, keep_plain_dirs, dlcache); } @@ -1280,7 +1282,7 @@ static void FS_AddGameDirectory (const char *dir) { if (!strcasecmp(FS_FileExtension(list.strings[i]), "pak")) { - FS_AddPack_Fullpath(list.strings[i], list.strings[i] + strlen(dir), NULL, false); + FS_AddPack_Fullpath(list.strings[i], list.strings[i] + strlen(dir), NULL, false, false); } } @@ -1290,7 +1292,7 @@ static void FS_AddGameDirectory (const char *dir) if (!strcasecmp(FS_FileExtension(list.strings[i]), "pk3") || !strcasecmp(FS_FileExtension(list.strings[i]), "obb") || !strcasecmp(FS_FileExtension(list.strings[i]), "pk3dir") || !strcasecmp(FS_FileExtension(list.strings[i]), "dpk") || !strcasecmp(FS_FileExtension(list.strings[i]), "dpkdir")) { - FS_AddPack_Fullpath(list.strings[i], list.strings[i] + strlen(dir), NULL, false); + FS_AddPack_Fullpath(list.strings[i], list.strings[i] + strlen(dir), NULL, false, false); } } @@ -1399,6 +1401,46 @@ static void FS_ClearSearchPath (void) } } +/* +================ +FS_UnloadPacks_dlcache + +Like FS_ClearSearchPath() but unloads only the packs loaded from dlcache +so we don't need to use a full FS_Rescan() to prevent +content from the previous server and/or map from interfering with the next +================ +*/ +void FS_UnloadPacks_dlcache(void) +{ + searchpath_t *search = fs_searchpaths, *searchprev = fs_searchpaths, *searchnext; + + while (search) + { + searchnext = search->next; + if (search->pack && search->pack->dlcache) + { + Con_DPrintf("Unloading pack: %s\n", search->pack->shortname); + + // remove it from the search path list + if (search == fs_searchpaths) + fs_searchpaths = search->next; + else + searchprev->next = search->next; + + // close the file + FILEDESC_CLOSE(search->pack->handle); + // free any memory associated with it + if (search->pack->files) + Mem_Free(search->pack->files); + Mem_Free(search->pack); + Mem_Free(search); + } + else + searchprev = search; + search = searchnext; + } +} + static void FS_AddSelfPack(void) { if(fs_selfpack) diff --git a/fs.h b/fs.h index b8ada8b9..7b7b18f9 100644 --- a/fs.h +++ b/fs.h @@ -61,7 +61,7 @@ typedef struct vfs_s // IMPORTANT: the file path is automatically prefixed by the current game directory for // each file created by FS_WriteFile, or opened in "write" or "append" mode by FS_OpenRealFile -qbool FS_AddPack(const char *pakfile, qbool *already_loaded, qbool keep_plain_dirs); // already_loaded may be NULL if caller does not care +qbool FS_AddPack(const char *pakfile, qbool *already_loaded, qbool keep_plain_dirs, qbool dlcache); // already_loaded may be NULL if caller does not care const char *FS_WhichPack(const char *filename); void FS_CreatePath (char *path); int FS_SysOpenFD(const char *filepath, const char *mode, qbool nonblocking); // uses absolute path @@ -102,6 +102,7 @@ extern int fs_all_gamedirs_count; qbool FS_ChangeGameDirs(int numgamedirs, char gamedirs[][MAX_QPATH], qbool complain, qbool failmissing); qbool FS_IsRegisteredQuakePack(const char *name); int FS_CRCFile(const char *filename, size_t *filesizepointer); +void FS_UnloadPacks_dlcache(void); void FS_Rescan(void); typedef struct fssearch_s diff --git a/libcurl.c b/libcurl.c index ecc1833c..3ad3c5ff 100644 --- a/libcurl.c +++ b/libcurl.c @@ -583,7 +583,7 @@ static void Curl_EndDownload(downloadinfo *di, CurlStatus status, CURLcode error if(ok && di->loadtype == LOADTYPE_PAK) { - ok = FS_AddPack(di->filename, NULL, true); + ok = FS_AddPack(di->filename, NULL, true, true); if(!ok) CLEAR_AND_RETRY(); } @@ -986,7 +986,7 @@ static qbool Curl_Begin(const char *URL, const char *extraheaders, double maxspe if(loadtype == LOADTYPE_PAK) { qbool already_loaded; - if(FS_AddPack(fn, &already_loaded, true)) + if(FS_AddPack(fn, &already_loaded, true, true)) { Con_DPrintf("%s already exists, not downloading!\n", fn); if(already_loaded) -- 2.39.2