From 069daff4f08a3f6690fa27f4455baa19b1fe7bf7 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Sat, 13 Jan 2024 23:55:01 +0100 Subject: [PATCH] VpkLib: check for manifest file first before opening the pack file We do this as if we happen to not have any manifest whatsoever, but already opened the block file, and the block file already existed and was still valid, it would be emptied out. Only open it if we are actually going to write into it! --- src/public/ipackedstore.h | 6 ++++ src/vpklib/packedstore.cpp | 70 ++++++++++++++++++++------------------ src/vpklib/packedstore.h | 2 ++ 3 files changed, 44 insertions(+), 34 deletions(-) diff --git a/src/public/ipackedstore.h b/src/public/ipackedstore.h index 4e26ea44..6686028b 100644 --- a/src/public/ipackedstore.h +++ b/src/public/ipackedstore.h @@ -18,6 +18,12 @@ enum EPackedTextureFlags TEXTURE_ENVIRONMENT_MAP = 1 << 10, }; +enum EPackedStoreTargets +{ + STORE_TARGET_SERVER, + STORE_TARGET_CLIENT +}; + struct FileHandleTracker_t { int m_nFileNumber; diff --git a/src/vpklib/packedstore.cpp b/src/vpklib/packedstore.cpp index 24e1f636..a7856e67 100644 --- a/src/vpklib/packedstore.cpp +++ b/src/vpklib/packedstore.cpp @@ -161,20 +161,6 @@ static bool ShouldPrune(const CUtlString& filePath, CUtlVector& igno return false; } -//----------------------------------------------------------------------------- -// Purpose: gets the parts of the directory file name -// Input : &dirFileName - -// nCaptureGroup - (1 = locale + target, 2 = level) -// Output : part of directory file name as string -//----------------------------------------------------------------------------- -//static CUtlString GetNameParts(const CUtlString& dirFileName, int nCaptureGroup) -//{ -// std::cmatch regexMatches; -// std::regex_search(dirFileName.Get(), regexMatches, s_DirFileRegex); -// -// return regexMatches[nCaptureGroup].str().c_str(); -//} - //----------------------------------------------------------------------------- // Purpose: gets the level name from the directory file name // Input : &dirFileName - @@ -443,6 +429,26 @@ void CPackedStoreBuilder::PackStore(const VPKPair_t& vpkPair, const char* worksp workspacePath.AppendSlash(); workspacePath.FixSlashes('/'); + CUtlVector entryValues; + CUtlVector entryBlocks; + + // NOTE: we get the entry values prior to opening the file, because if we + // don't have a valid manifest file, we won't be able to build the store. + // If we had already opened the block file, and a one already existed, it + // would be emptied out ("wb" flag) which we want to avoid here. + if (!GetEntryValues(entryValues, workspacePath, vpkPair.m_DirName)) + { + return; + } + + std::unique_ptr pEntryBuffer(new uint8_t[ENTRY_MAX_LEN]); + + if (!pEntryBuffer) + { + Error(eDLL_T::FS, NO_ERROR, "%s - Unable to allocate memory for entry buffer!\n", __FUNCTION__); + return; + } + CUtlString packFilePath; CUtlString dirFilePath; @@ -457,24 +463,6 @@ void CPackedStoreBuilder::PackStore(const VPKPair_t& vpkPair, const char* worksp return; } - std::unique_ptr pEntryBuffer(new uint8_t[ENTRY_MAX_LEN]); - - if (!pEntryBuffer) - { - Error(eDLL_T::FS, NO_ERROR, "%s - Unable to allocate memory for entry buffer!\n", __FUNCTION__); - FileSystem()->Close(hPackFile); - return; - } - - CUtlVector entryValues; - CUtlVector entryBlocks; - - if (!GetEntryValues(entryValues, workspacePath, vpkPair.m_DirName)) - { - FileSystem()->Close(hPackFile); - return; - } - size_t nSharedTotal = NULL; size_t nSharedCount = NULL; @@ -828,14 +816,28 @@ VPKPair_t::VPKPair_t(const char* pLocale, const char* pTarget, const char* pLeve if (!bFoundTarget) { - Warning(eDLL_T::FS, "Target '%s' not supported; using default '%s'\n", pTarget, DIR_TARGET[0]); - pTarget = DIR_TARGET[0]; + Warning(eDLL_T::FS, "Target '%s' not supported; using default '%s'\n", pTarget, DIR_TARGET[STORE_TARGET_SERVER]); + pTarget = DIR_TARGET[STORE_TARGET_SERVER]; } m_PackName.Format("%s_%s.bsp.pak000_%03d.vpk", pTarget, pLevel, nPatch); m_DirName.Format("%s%s_%s.bsp.pak000_dir.vpk", pLocale, pTarget, pLevel); } +//----------------------------------------------------------------------------- +// Purpose: gets the parts of the directory file name +// Input : &dirFileName - +// nCaptureGroup - (1 = locale + target, 2 = level) +// Output : part of directory file name as string +//----------------------------------------------------------------------------- +CUtlString VPKPair_t::GetNameParts(const int nCaptureGroup) +{ + std::cmatch regexMatches; + std::regex_search(m_DirName.Get(), regexMatches, s_DirFileRegex); + + return regexMatches[nCaptureGroup].str().c_str(); +} + //----------------------------------------------------------------------------- // Purpose: 'VPKDir_t' file constructor // Input : &dirFilePath - diff --git a/src/vpklib/packedstore.h b/src/vpklib/packedstore.h index 6533554e..658f34a5 100644 --- a/src/vpklib/packedstore.h +++ b/src/vpklib/packedstore.h @@ -8,6 +8,7 @@ * ██║ ██║ ██║ ╚████╔╝ ██║ ██║ ██╗ ███████╗██║██████╔╝ * * ╚═╝ ╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝╚═════╝ * *******************************************************************/ +#include "public/ipackedstore.h" #include "public/ifilesystem.h" #include "public/tier1/strtools.h" #include "public/tier1/utlvector.h" @@ -188,6 +189,7 @@ struct VPKPair_t CUtlString m_DirName; VPKPair_t(const char* svLocale, const char* svTarget, const char* svLevel, int nPatch); + CUtlString GetNameParts(const int nCaptureGroup); }; //-----------------------------------------------------------------------------