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!
This commit is contained in:
Kawe Mazidjatari 2024-01-13 23:55:01 +01:00
parent 8eb2561fcf
commit 069daff4f0
3 changed files with 44 additions and 34 deletions

View File

@ -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;

View File

@ -161,20 +161,6 @@ static bool ShouldPrune(const CUtlString& filePath, CUtlVector<CUtlString>& 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<VPKKeyValues_t> entryValues;
CUtlVector<VPKEntryBlock_t> 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<uint8_t[]> 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<uint8_t[]> 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<VPKKeyValues_t> entryValues;
CUtlVector<VPKEntryBlock_t> 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 -

View File

@ -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);
};
//-----------------------------------------------------------------------------