From f0714a43bb54b629ec7e15345fb0b50a01d09cac Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Fri, 12 Jan 2024 01:26:33 +0100 Subject: [PATCH] CMake: add ReVPK project, standalone VPK tool Standalone VPK tool that does everything the VPK tool implemented in the dedicated server does (pack, unpack), but independent from the game's runtime. --- src/CMakeLists.txt | 1 + src/revpk/CMakeLists.txt | 44 ++++++++++++ src/revpk/revpk.cpp | 150 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 195 insertions(+) create mode 100644 src/revpk/CMakeLists.txt create mode 100644 src/revpk/revpk.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index decaaec8..57f410e4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -49,6 +49,7 @@ set( FOLDER_CONTEXT "Tools" ) add_subdirectory( sdklauncher ) add_subdirectory( netconsole ) add_subdirectory( naveditor ) +add_subdirectory( revpk ) set( FOLDER_CONTEXT "System" ) add_subdirectory( networksystem ) diff --git a/src/revpk/CMakeLists.txt b/src/revpk/CMakeLists.txt new file mode 100644 index 00000000..2ed543c9 --- /dev/null +++ b/src/revpk/CMakeLists.txt @@ -0,0 +1,44 @@ +cmake_minimum_required( VERSION 3.16 ) +add_module( "exe" "revpk" "vpc" ${FOLDER_CONTEXT} TRUE TRUE ) + +start_sources() + +add_sources( SOURCE_GROUP "Private" + "revpk.cpp" + "${ENGINE_SOURCE_DIR}/core/logdef.cpp" + "${ENGINE_SOURCE_DIR}/core/logdef.h" + "${ENGINE_SOURCE_DIR}/core/logger.cpp" + "${ENGINE_SOURCE_DIR}/core/logger.h" + "${ENGINE_SOURCE_DIR}/core/termutil.cpp" + "${ENGINE_SOURCE_DIR}/core/termutil.h" + "${ENGINE_SOURCE_DIR}/tier0/plat_time.cpp" +) + +add_sources( SOURCE_GROUP "Windows" + "${ENGINE_SOURCE_DIR}/windows/console.cpp" + "${ENGINE_SOURCE_DIR}/windows/console.h" +) + +end_sources( "${BUILD_OUTPUT_DIR}/bin/" ) + +set_target_properties( ${PROJECT_NAME} PROPERTIES + VS_DEBUGGER_COMMAND "revpk.exe" + VS_DEBUGGER_WORKING_DIRECTORY "$(ProjectDir)../../../${BUILD_OUTPUT_DIR}/bin/" +) +target_compile_definitions( ${PROJECT_NAME} PRIVATE + "_TOOLS" +) + +target_link_libraries( ${PROJECT_NAME} PRIVATE + "vpc" + "tier0" + "tier1" + "filesystem_std" + "vstdlib" + "mathlib" + "vpklib" + + "libspdlog" + "liblzham" + "Rpcrt4.lib" +) diff --git a/src/revpk/revpk.cpp b/src/revpk/revpk.cpp new file mode 100644 index 00000000..2410c276 --- /dev/null +++ b/src/revpk/revpk.cpp @@ -0,0 +1,150 @@ +//=============================================================================// +// +// Purpose: Standalone VPK tool +// +//=============================================================================// +#include "core/logdef.h" +#include "core/logger.h" +#include "tier0/fasttimer.h" +#include "tier1/cmd.h" +#include "tier1/keyvalues.h" +#include "windows/console.h" +#include "vpklib/packedstore.h" + +#include "vstdlib/keyvaluessystem.h" +#include "filesystem/filesystem_std.h" + +#define PACK_COMMAND "pack" +#define UNPACK_COMMAND "unpack" + +static CKeyValuesSystem s_KeyValuesSystem; +static CFileSystem_Stdio g_FullFileSystem; + +//----------------------------------------------------------------------------- +// Purpose: filesystem singleton accessor +//----------------------------------------------------------------------------- +CFileSystem_Stdio* FileSystem() +{ + return &g_FullFileSystem; +} + +//----------------------------------------------------------------------------- +// Purpose: init +//----------------------------------------------------------------------------- +static void ReVPK_Init() +{ + // Assign global kv accessor to static singleton object as we aren't linked + // to the game!!! + g_pKeyValuesSystem = &s_KeyValuesSystem; + + g_CoreMsgVCallback = EngineLoggerSink; + lzham_enable_fail_exceptions(true); + + Console_Init(true); + SpdLog_Init(true); +} + +//----------------------------------------------------------------------------- +// Purpose: shutdown +//----------------------------------------------------------------------------- +static void ReVPK_Shutdown() +{ + // Must be done to flush all buffers. + SpdLog_Shutdown(); + Console_Shutdown(); +} + +//----------------------------------------------------------------------------- +// Purpose: logs tool's usage +//----------------------------------------------------------------------------- +static void ReVPK_Usage() +{ + Warning(eDLL_T::FS, "Usage:\n"); + Warning(eDLL_T::FS, " revpk " PACK_COMMAND " \n"); + Warning(eDLL_T::FS, " revpk " UNPACK_COMMAND " \n"); +} + +//----------------------------------------------------------------------------- +// Purpose: packs VPK files into 'SHIP' VPK directory +//----------------------------------------------------------------------------- +static void ReVPK_Pack(const CCommand& args) +{ + if (args.ArgC() < 5) + { + ReVPK_Usage(); + return; + } + + VPKPair_t pair(args.Arg(2), args.Arg(3), args.Arg(4), NULL); + CFastTimer timer; + + Msg(eDLL_T::FS, "*** Starting VPK build command for: '%s'\n", pair.m_DirName.Get()); + timer.Start(); + + g_pPackedStore->InitLzCompParams(); + g_pPackedStore->PackWorkspace(pair, "ship/", "vpk/"); + + timer.End(); + Msg(eDLL_T::FS, "*** Time elapsed: '%lf' seconds\n", timer.GetDuration().GetSeconds()); + Msg(eDLL_T::FS, "\n"); +} + +//----------------------------------------------------------------------------- +// Purpose: unpacks VPK files into workspace directory +//----------------------------------------------------------------------------- +static void ReVPK_Unpack(const CCommand& args) +{ + if (args.ArgC() < 3) + { + ReVPK_Usage(); + return; + } + + CUtlString arg = args.Arg(2); + + VPKDir_t vpk(arg, (args.ArgC() > 3)); + CFastTimer timer; + + Msg(eDLL_T::FS, "*** Starting VPK extraction command for: '%s'\n", arg.Get()); + timer.Start(); + + g_pPackedStore->InitLzDecompParams(); + g_pPackedStore->UnpackWorkspace(vpk, "ship/"); + + timer.End(); + Msg(eDLL_T::FS, "*** Time elapsed: '%lf' seconds\n", timer.GetDuration().GetSeconds()); + Msg(eDLL_T::FS, "\n"); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int main(int argc, char* argv[]) +{ + ReVPK_Init(); + + CCommand args; + CUtlString str; + + for (int i = 0; i < argc; i++) + { + str.Append(argv[i]); + str.Append(' '); + } + + args.Tokenize(str.Get(), cmd_source_t::kCommandSrcCode); + + if (!args.ArgC()) + ReVPK_Usage(); + else + { + if (strcmp(args.Arg(1), PACK_COMMAND) == NULL) + ReVPK_Pack(args); + else if (strcmp(args.Arg(1), UNPACK_COMMAND) == NULL) + ReVPK_Unpack(args); + else + ReVPK_Usage(); + } + + ReVPK_Shutdown(); +}