From d276a8c85066b72963dd0220242b1110af48bc43 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Sun, 17 Nov 2024 14:04:29 +0100 Subject: [PATCH] RTech: rework pak load command API - renamed pak_swap to pak_requestswap. - Installed autocompletion callback for pak_requestswap. - use const where possible. - improved logging on success/failures. - use new reversed types and fields to determine when to skip an asset in Pak_ListTypes_f. - only allow unloading or swapping of a specific pak file if its status is PAK_STATUS_LOADED. --- src/common/completion.cpp | 12 ++++ src/common/completion.h | 1 + src/rtech/pak/pakstate.cpp | 121 ++++++++++++++++++++----------------- 3 files changed, 78 insertions(+), 56 deletions(-) diff --git a/src/common/completion.cpp b/src/common/completion.cpp index fb5487d7..87f9dde7 100644 --- a/src/common/completion.cpp +++ b/src/common/completion.cpp @@ -170,6 +170,18 @@ int RTech_PakUnload_f_CompletionFunc(char const* partial, char commands[COMMAND_ return _Host_Pak_f_CompletionFunc(&s_PakUnloadAutoFileList, partial, commands); } +static CBaseAutoCompleteFileList s_PakSwapAutoFileList("pak_requestswap", "paks/Win64", "rpak"); +//----------------------------------------------------------------------------- +// Purpose: +// Input : *partial - +// **commands - +// Output : int +//----------------------------------------------------------------------------- +int RTech_PakSwap_f_CompletionFunc(char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]) +{ + return _Host_Pak_f_CompletionFunc(&s_PakSwapAutoFileList, partial, commands); +} + static CBaseAutoCompleteFileList s_PakCompress("pak_compress", "paks/Win64_override", "rpak"); //----------------------------------------------------------------------------- // Purpose: diff --git a/src/common/completion.h b/src/common/completion.h index 583394f1..bb83b250 100644 --- a/src/common/completion.h +++ b/src/common/completion.h @@ -11,6 +11,7 @@ int Game_Give_f_CompletionFunc(char const* partial, char commands[COMMAND_COMPLE int RTech_PakLoad_f_CompletionFunc(char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]); int RTech_PakUnload_f_CompletionFunc(char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]); +int RTech_PakSwap_f_CompletionFunc(char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]); int RTech_PakCompress_f_CompletionFunc(char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]); int RTech_PakDecompress_f_CompletionFunc(char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]); diff --git a/src/rtech/pak/pakstate.cpp b/src/rtech/pak/pakstate.cpp index a6c53a7e..c0f78c57 100644 --- a/src/rtech/pak/pakstate.cpp +++ b/src/rtech/pak/pakstate.cpp @@ -20,7 +20,7 @@ static void Pak_ListPaks_f() Msg(eDLL_T::RTECH, "| id | name | status | asset count |\n"); Msg(eDLL_T::RTECH, "|------|----------------------------------------------------|--------------------------------------|-------------|\n"); - uint32_t nTotalLoaded = 0; + uint32_t numLoaded = 0; for (int16_t i = 0, n = g_pakGlobals->loadedPakCount; i < n; ++i) { @@ -29,14 +29,13 @@ static void Pak_ListPaks_f() if (info.status == PakStatus_e::PAK_STATUS_FREED) continue; - const char* szRpakStatus = Pak_StatusToString(info.status); + const char* const pakStatus = Pak_StatusToString(info.status); - // todo: make status into a string from an array/vector - Msg(eDLL_T::RTECH, "| %04i | %-50s | %-36s | %11i |\n", info.handle, info.fileName, szRpakStatus, info.assetCount); - nTotalLoaded++; + Msg(eDLL_T::RTECH, "| %04i | %-50s | %-36s | %11i |\n", info.handle, info.fileName, pakStatus, info.assetCount); + numLoaded++; } Msg(eDLL_T::RTECH, "|------|----------------------------------------------------|--------------------------------------|-------------|\n"); - Msg(eDLL_T::RTECH, "| %18i loaded paks. |\n", nTotalLoaded); + Msg(eDLL_T::RTECH, "| %18i loaded paks. |\n", numLoaded); Msg(eDLL_T::RTECH, "|------|----------------------------------------------------|--------------------------------------|-------------|\n"); } @@ -50,23 +49,23 @@ static void Pak_ListTypes_f() Msg(eDLL_T::RTECH, "| ext | description | version | header size | native size |\n"); Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-------------|-------------|\n"); - uint32_t nRegistered = 0; + uint32_t numRegistered = 0; for (int8_t i = 0; i < PAK_MAX_TRACKED_TYPES; ++i) { - PakAssetBinding_s* type = &g_pakGlobals->assetBindings[i]; + const PakAssetBinding_s& type = g_pakGlobals->assetBindings[i]; - if (!type->description) + if (type.type == PakAssetBinding_s::EType::NONE || type.type == PakAssetBinding_s::EType::STUB) continue; FourCCString_t assetExtension; - FourCCToString(assetExtension, type->extension); + FourCCToString(assetExtension, type.extension); - Msg(eDLL_T::RTECH, "| %-4s | %-25s | %7i | %11i | %11i |\n", assetExtension, type->description, type->version, type->headerSize, type->nativeClassSize); - nRegistered++; + Msg(eDLL_T::RTECH, "| %-4s | %-25s | %7i | %11i | %11i |\n", assetExtension, type.description, type.version, type.headerSize, type.nativeClassSize); + numRegistered++; } Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-------------|-------------|\n"); - Msg(eDLL_T::RTECH, "| %18i registered types. |\n", nRegistered); + Msg(eDLL_T::RTECH, "| %18i registered types. |\n", numRegistered); Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-------------|-------------|\n"); } @@ -82,32 +81,40 @@ static void Pak_RequestUnload_f(const CCommand& args) return; } + const PakLoadedInfo_s* pakInfo = nullptr; + if (args.HasOnlyDigits(1)) { const PakHandle_t pakHandle = atoi(args.Arg(1)); - const PakLoadedInfo_s* const pakInfo = Pak_GetPakInfo(pakHandle); + pakInfo = Pak_GetPakInfo(pakHandle); - if (!pakInfo) + if (pakInfo->status != PAK_STATUS_LOADED) { - Warning(eDLL_T::RTECH, "Found no pak entry for specified handle.\n"); + Warning(eDLL_T::RTECH, "Pak with handle '%d' is currently unavailable; status '%s', cannot unload\n", + pakHandle, Pak_StatusToString(pakInfo->status)); return; } - - Msg(eDLL_T::RTECH, "Requested pak unload for handle '%d'\n", pakHandle); - g_pakLoadApi->UnloadAsync(pakHandle); } else { - const PakLoadedInfo_s* const pakInfo = Pak_GetPakInfo(args.Arg(1)); + const char* const pakName = args.Arg(1); + pakInfo = Pak_GetPakInfo(pakName); + if (!pakInfo) { - Warning(eDLL_T::RTECH, "Found no pak entry for specified name.\n"); + Warning(eDLL_T::RTECH, "Pak with name '%s' not loaded, cannot unload\n", pakName); + return; + } + else if (pakInfo->status != PAK_STATUS_LOADED) + { + Warning(eDLL_T::RTECH, "Pak with name '%s' is currently unavailable; status '%s', cannot unload\n", + pakName, Pak_StatusToString(pakInfo->status)); return; } - - Msg(eDLL_T::RTECH, "Requested pak unload for file '%s'\n", args.Arg(1)); - g_pakLoadApi->UnloadAsync(pakInfo->handle); } + + Msg(eDLL_T::RTECH, "Requested pak unload for file '%s' with handle '%d'\n", pakInfo->fileName, pakInfo->handle); + g_pakLoadApi->UnloadAsync(pakInfo->handle); } /* @@ -117,63 +124,65 @@ Pak_RequestLoad_f */ static void Pak_RequestLoad_f(const CCommand& args) { - g_pakLoadApi->LoadAsync(args.Arg(1), AlignedMemAlloc(), 1, 0); -} + const char* const pakFile = args.Arg(1); + Msg(eDLL_T::RTECH, "Requested pak load for file '%s'\n", pakFile); + g_pakLoadApi->LoadAsync(pakFile, AlignedMemAlloc(), 1, 0); +} /* ===================== -Pak_Swap_f +Pak_RequestSwap_f ===================== */ -static void Pak_Swap_f(const CCommand& args) +static void Pak_RequestSwap_f(const CCommand& args) { if (args.ArgC() < 2) { return; } - const char* pakName = nullptr; - - PakHandle_t pakHandle = PAK_INVALID_HANDLE; const PakLoadedInfo_s* pakInfo = nullptr; if (args.HasOnlyDigits(1)) { - pakHandle = atoi(args.Arg(1)); + const PakHandle_t pakHandle = atoi(args.Arg(1)); pakInfo = Pak_GetPakInfo(pakHandle); - if (!pakInfo) + if (pakInfo->status != PAK_STATUS_LOADED) { - Warning(eDLL_T::RTECH, "Found no pak entry for specified handle.\n"); + Warning(eDLL_T::RTECH, "Pak with handle '%d' is currently unavailable; status '%s', cannot swap\n", + pakHandle, Pak_StatusToString(pakInfo->status)); return; } - - pakName = pakInfo->fileName; } else { - pakName = args.Arg(1); + const char* const pakName = args.Arg(1); pakInfo = Pak_GetPakInfo(pakName); if (!pakInfo) { - Warning(eDLL_T::RTECH, "Found no pak entry for specified name.\n"); + Warning(eDLL_T::RTECH, "Pak with name '%s' not loaded, cannot swap\n", pakName); + return; + } + else if (pakInfo->status != PAK_STATUS_LOADED) + { + Warning(eDLL_T::RTECH, "Pak with name '%s' is currently unavailable; status '%s', cannot swap\n", + pakName, Pak_StatusToString(pakInfo->status)); return; } - - pakHandle = pakInfo->handle; } - Msg(eDLL_T::RTECH, "Requested pak swap for handle '%d'\n", pakHandle); - g_pakLoadApi->UnloadAsyncAndWait(pakHandle); // Wait till this slot gets free'd. + Msg(eDLL_T::RTECH, "Requested pak swap for file '%s' with handle '%d'\n", pakInfo->fileName, pakInfo->handle); - g_pakLoadApi->LoadAsync(pakName, AlignedMemAlloc(), pakInfo->logChannel, 0); + g_pakLoadApi->UnloadAsyncAndWait(pakInfo->handle); // Wait till this slot gets free'd. + g_pakLoadApi->LoadAsync(pakInfo->fileName, AlignedMemAlloc(), pakInfo->logChannel, pakInfo->unkAC); } /* ===================== -RTech_StringToGUID_f +Pak_StringToGUID_f ===================== */ static void Pak_StringToGUID_f(const CCommand& args) @@ -183,7 +192,7 @@ static void Pak_StringToGUID_f(const CCommand& args) return; } - unsigned long long guid = Pak_StringToGuid(args.Arg(1)); + const PakGuid_t guid = Pak_StringToGuid(args.Arg(1)); Msg(eDLL_T::RTECH, "______________________________________________________________\n"); Msg(eDLL_T::RTECH, "] RTECH_HASH ]------------------------------------------------\n"); @@ -192,7 +201,7 @@ static void Pak_StringToGUID_f(const CCommand& args) /* ===================== -RTech_Decompress_f +Pak_Decompress_f Decompresses input RPak file and dumps results to override path @@ -205,8 +214,8 @@ static void Pak_Decompress_f(const CCommand& args) return; } - CFmtStr1024 inPakFile(PAK_PLATFORM_PATH "%s", args.Arg(1)); - CFmtStr1024 outPakFile(PAK_PLATFORM_OVERRIDE_PATH "%s", args.Arg(1)); + const CFmtStr1024 inPakFile(PAK_PLATFORM_PATH "%s", args.Arg(1)); + const CFmtStr1024 outPakFile(PAK_PLATFORM_OVERRIDE_PATH "%s", args.Arg(1)); if (!Pak_DecodePakFile(inPakFile.String(), outPakFile.String())) { @@ -217,7 +226,7 @@ static void Pak_Decompress_f(const CCommand& args) /* ===================== -RTech_Compress_f +Pak_Compress_f Compresses input RPak file and dumps results to base path @@ -230,8 +239,8 @@ static void Pak_Compress_f(const CCommand& args) return; } - CFmtStr1024 inPakFile(PAK_PLATFORM_OVERRIDE_PATH "%s", args.Arg(1)); - CFmtStr1024 outPakFile(PAK_PLATFORM_PATH "%s", args.Arg(1)); + const CFmtStr1024 inPakFile(PAK_PLATFORM_OVERRIDE_PATH "%s", args.Arg(1)); + const CFmtStr1024 outPakFile(PAK_PLATFORM_PATH "%s", args.Arg(1)); // NULL means default compress level const int compressLevel = args.ArgC() > 2 ? atoi(args.Arg(2)) : NULL; @@ -243,18 +252,18 @@ static void Pak_Compress_f(const CCommand& args) } } -static ConCommand pak_stringtoguid("pak_stringtoguid", Pak_StringToGUID_f, "Calculates the GUID from input text", FCVAR_DEVELOPMENTONLY); +static ConCommand pak_stringtoguid("pak_stringtoguid", Pak_StringToGUID_f, "Compute GUID from input text", FCVAR_DEVELOPMENTONLY); static ConCommand pak_compress("pak_compress", Pak_Compress_f, "Compresses specified RPAK file", FCVAR_DEVELOPMENTONLY, RTech_PakCompress_f_CompletionFunc); static ConCommand pak_decompress("pak_decompress", Pak_Decompress_f, "Decompresses specified RPAK file", FCVAR_DEVELOPMENTONLY, RTech_PakDecompress_f_CompletionFunc); static ConCommand pak_requestload("pak_requestload", Pak_RequestLoad_f, "Requests asynchronous load for specified RPAK file", FCVAR_DEVELOPMENTONLY, RTech_PakLoad_f_CompletionFunc); -static ConCommand pak_requestunload("pak_requestunload", Pak_RequestUnload_f, "Requests unload for specified RPAK file or ID", FCVAR_DEVELOPMENTONLY, RTech_PakUnload_f_CompletionFunc); +static ConCommand pak_requestunload("pak_requestunload", Pak_RequestUnload_f, "Requests asynchronous unload for specified RPAK file or ID", FCVAR_DEVELOPMENTONLY, RTech_PakUnload_f_CompletionFunc); -static ConCommand pak_swap("pak_swap", Pak_Swap_f, "Requests swap for specified RPAK file or ID", FCVAR_DEVELOPMENTONLY); +static ConCommand pak_requestswap("pak_requestswap", Pak_RequestSwap_f, "Requests swap for specified RPAK file or ID", FCVAR_DEVELOPMENTONLY, RTech_PakSwap_f_CompletionFunc); -static ConCommand pak_listpaks("pak_listpaks", Pak_ListPaks_f, "Display a list of the loaded Pak files", FCVAR_RELEASE); -static ConCommand pak_listtypes("pak_listtypes", Pak_ListTypes_f, "Display a list of the registered asset types", FCVAR_RELEASE); +static ConCommand pak_listpaks("pak_listpaks", Pak_ListPaks_f, "Display a list of loaded RPAK files", FCVAR_RELEASE); +static ConCommand pak_listtypes("pak_listtypes", Pak_ListTypes_f, "Display a list of registered asset types", FCVAR_RELEASE); // Symbols taken from R2 dll's.