Move some CPackedStore methods to VPKDir_t

These methods where only used for and by the VPKDir_t structure.
Also renamed variable and method names to reflect new changes regarding the use of KeyValues by creating a structure with all values defined during file lookup rather than doing this during the pack process.
This commit is contained in:
Kawe Mazidjatari 2022-11-23 17:09:48 +01:00
parent 824a9f8bb2
commit 368c4218b4
3 changed files with 298 additions and 282 deletions

View File

@ -51,75 +51,6 @@ void CPackedStore::InitLzDecompParams(void)
m_lzDecompParams.m_struct_size = sizeof(lzham_decompress_params);
}
//-----------------------------------------------------------------------------
// Purpose: gets a directory structure for specified file.
// Input : svPackDirFile -
// bSanitizeName - retrieve the directory file name from block name
// Output : VPKDir_t
//-----------------------------------------------------------------------------
VPKDir_t CPackedStore::GetDirectoryFile(const string& svPackDirFile, bool bSanitizeName) const
{
if (!bSanitizeName)
{
return VPKDir_t(svPackDirFile);
}
std::smatch smRegexMatches;
std::regex_search(svPackDirFile, smRegexMatches, BLOCK_REGEX);
if (smRegexMatches.empty())
{
return VPKDir_t(svPackDirFile);
}
string svSanitizedName = svPackDirFile;
StringReplace(svSanitizedName, smRegexMatches[0], "pak000_dir");
bool bHasLocale = false;
for (const string& svLocale : DIR_LOCALE)
{
if (svSanitizedName.find(svLocale) != string::npos)
{
bHasLocale = true;
break;
}
}
if (!bHasLocale) // Only sanitize if no locale was provided.
{
string svPackDirPrefix;
svPackDirPrefix.append(DIR_LOCALE[0]);
for (const string& svTarget : DIR_TARGET)
{
if (svSanitizedName.find(svTarget) != string::npos)
{
svPackDirPrefix.append(svTarget);
StringReplace(svSanitizedName, svTarget, svPackDirPrefix);
break;
}
}
}
return VPKDir_t(svSanitizedName);
}
//-----------------------------------------------------------------------------
// Purpose: formats pack file path for specific directory file
// Input : &svPackDirFile -
// iPackFileIndex -
// output : string
//-----------------------------------------------------------------------------
string CPackedStore::GetPackFile(const string& svPackDirFile, uint16_t iPackFileIndex) const
{
string svPackChunkFile = StripLocalePrefix(svPackDirFile);
string svPackChunkIndex = fmt::format("{:s}{:03d}", "pak000_", iPackFileIndex);
StringReplace(svPackChunkFile, "pak000_dir", svPackChunkIndex);
return svPackChunkFile;
}
//-----------------------------------------------------------------------------
// Purpose: gets the LZHAM compression level
// output : lzham_compress_level
@ -144,83 +75,83 @@ lzham_compress_level CPackedStore::GetCompressionLevel(void) const
//-----------------------------------------------------------------------------
// Purpose: obtains and returns the entry block to the vector
// Input : hDirectory -
// Input : hDirectoryFile -
// output : vector<VPKEntryBlock_t>
//-----------------------------------------------------------------------------
vector<VPKEntryBlock_t> CPackedStore::GetEntryBlocks(FileHandle_t hDirectory) const
vector<VPKEntryBlock_t> CPackedStore::GetEntryBlocks(FileHandle_t hDirectoryFile) const
{
string svName, svPath, svExtension;
vector<VPKEntryBlock_t> vBlocks;
while (!(svExtension = FileSystem()->ReadString(hDirectory)).empty())
vector<VPKEntryBlock_t> vEntryBlocks;
while (!(svExtension = FileSystem()->ReadString(hDirectoryFile)).empty())
{
while (!(svPath = FileSystem()->ReadString(hDirectory)).empty())
while (!(svPath = FileSystem()->ReadString(hDirectoryFile)).empty())
{
while (!(svName = FileSystem()->ReadString(hDirectory)).empty())
while (!(svName = FileSystem()->ReadString(hDirectoryFile)).empty())
{
const string svFilePath = FormatEntryPath(svPath, svName, svExtension);
vBlocks.push_back(VPKEntryBlock_t(hDirectory, svFilePath));
vEntryBlocks.push_back(VPKEntryBlock_t(hDirectoryFile, svFilePath));
}
}
}
return vBlocks;
return vEntryBlocks;
}
//-----------------------------------------------------------------------------
// Purpose: scans the input directory and returns the paths to the vector
// Input : &svPathIn -
// Output : a vpk keyvalues vector of all existing entry paths
// Input : &svWorkspace -
// Output : vpk keyvalues vector of all existing entry paths
//-----------------------------------------------------------------------------
vector<VPKKeyValues_t> CPackedStore::GetEntryPaths(const string& svPathIn) const
vector<VPKKeyValues_t> CPackedStore::GetEntryValues(const string& svWorkspace) const
{
vector<VPKKeyValues_t> vKeys;
vector<string> vIgnore = GetIgnoreList(svPathIn);
vector<VPKKeyValues_t> vEntryValues;
vector<string> vIgnoredList = GetIgnoreList(svWorkspace);
fs::recursive_directory_iterator dir(svPathIn), end;
fs::recursive_directory_iterator dir(svWorkspace), end;
while (dir != end)
{
const vector<string>::iterator it = std::find(vIgnore.begin(), vIgnore.end(),
const vector<string>::iterator it = std::find(vIgnoredList.begin(), vIgnoredList.end(),
GetExtension(dir->path().filename().u8string(), true, true));
if (it != vIgnore.end())
if (it != vIgnoredList.end())
{
dir.disable_recursion_pending(); // Skip all ignored folders and extensions.
}
else if (dir->file_size() > 0) // Empty files are not supported.
{
const string svPath = dir->path().u8string();
if (!GetExtension(svPath).empty())
const string svEntryPath = dir->path().u8string();
if (!GetExtension(svEntryPath).empty())
{
vKeys.push_back(VPKKeyValues_t(ConvertToUnixPath(svPath)));
vEntryValues.push_back(VPKKeyValues_t(ConvertToUnixPath(svEntryPath)));
}
}
dir++;
}
return vKeys;
return vEntryValues;
}
//-----------------------------------------------------------------------------
// Purpose: scans the input directory and returns the paths to the vector if path exists in manifest
// Input : &svPathIn -
// Purpose: scans the input directory and returns the values to the vector if path exists in manifest
// Input : &svWorkspace -
// *pManifestKV -
// Output : a vpk keyvalues vector of all existing and included entry paths
// Output : vpk keyvalues vector of all existing and included entry paths
//-----------------------------------------------------------------------------
vector<VPKKeyValues_t> CPackedStore::GetEntryPaths(const string& svPathIn, KeyValues* pManifestKV) const
vector<VPKKeyValues_t> CPackedStore::GetEntryValues(const string& svWorkspace, KeyValues* pManifestKV) const
{
vector<VPKKeyValues_t> vKeys;
vector<VPKKeyValues_t> vEntryValues;
if (!pManifestKV)
{
Warning(eDLL_T::FS, "Invalid VPK manifest KV; unable to build entry list\n");
return vKeys;
return vEntryValues;
}
vector<string> vIgnore = GetIgnoreList(svPathIn);
fs::recursive_directory_iterator dir(svPathIn), end;
vector<string> vIgnoredList = GetIgnoreList(svWorkspace);
fs::recursive_directory_iterator dir(svWorkspace), end;
while (dir != end)
{
const vector<string>::iterator it = std::find(vIgnore.begin(), vIgnore.end(),
const vector<string>::iterator it = std::find(vIgnoredList.begin(), vIgnoredList.end(),
GetExtension(dir->path().filename().u8string(), true, true));
if (it != vIgnore.end())
if (it != vIgnoredList.end())
{
dir.disable_recursion_pending(); // Skip all ignored folders and extensions.
}
@ -230,12 +161,12 @@ vector<VPKKeyValues_t> CPackedStore::GetEntryPaths(const string& svPathIn, KeyVa
if (!GetExtension(svFullPath).empty())
{
// Remove workspace path by offsetting it by its size.
const char* pszEntry = (svFullPath.c_str() + svPathIn.length());
const char* pszEntry = (svFullPath.c_str() + svWorkspace.length());
KeyValues* pEntryKV = pManifestKV->FindKey(pszEntry);
if (pEntryKV)
{
vKeys.push_back(VPKKeyValues_t(
vEntryValues.push_back(VPKKeyValues_t(
ConvertToUnixPath(svFullPath),
pEntryKV->GetInt("preloadSize", NULL),
pEntryKV->GetInt("loadFlags", static_cast<uint32_t>(EPackedLoadFlags::LOAD_VISIBLE) | static_cast<uint32_t>(EPackedLoadFlags::LOAD_CACHE)),
@ -248,7 +179,7 @@ vector<VPKKeyValues_t> CPackedStore::GetEntryPaths(const string& svPathIn, KeyVa
}
dir++;
}
return vKeys;
return vEntryValues;
}
//-----------------------------------------------------------------------------
@ -282,7 +213,7 @@ string CPackedStore::GetLevelName(const string& svDirectoryName) const
// Purpose: gets the manifest file associated with the VPK name (must be freed after wards)
// Input : &svWorkspace -
// &svManifestName -
// Output : KeyValues build manifest pointer
// Output : KeyValues (build manifest pointer)
//-----------------------------------------------------------------------------
KeyValues* CPackedStore::GetManifest(const string& svWorkspace, const string& svManifestName) const
{
@ -354,57 +285,10 @@ string CPackedStore::FormatEntryPath(const string& svPath, const string& svName,
return fmt::format("{:s}{:s}{:s}.{:s}", svPath, svPath.empty() ? "" : "/", svName, svExtension);
}
//-----------------------------------------------------------------------------
// Purpose: strips locale prefix from file path
// Input : &svDirectoryFile -
// Output : directory filename without locale prefix
//-----------------------------------------------------------------------------
string CPackedStore::StripLocalePrefix(const string& svDirectoryFile) const
{
fs::path fsDirectoryFile(svDirectoryFile);
string svFileName = fsDirectoryFile.filename().u8string();
for (const string& svLocale : DIR_LOCALE)
{
if (svFileName.find(svLocale) != string::npos)
{
StringReplace(svFileName, svLocale, "");
break;
}
}
return svFileName;
}
//-----------------------------------------------------------------------------
// Purpose: builds a valid file name for the VPK
// Input : svLanguage -
// svTarget -
// &svLevel -
// nPatch -
// Output : a vpk file pair (block and directory file names)
//-----------------------------------------------------------------------------
VPKPair_t CPackedStore::BuildFileName(string svLanguage, string svTarget, const string& svLevel, int nPatch) const
{
if (std::find(DIR_LOCALE.begin(), DIR_LOCALE.end(), svLanguage) == DIR_LOCALE.end())
{
svLanguage = DIR_LOCALE[0];
}
if (std::find(DIR_TARGET.begin(), DIR_TARGET.end(), svTarget) == DIR_TARGET.end())
{
svTarget = DIR_TARGET[0];
}
VPKPair_t vPair;
vPair.m_svBlockName = fmt::format("{:s}_{:s}.bsp.pak000_{:03d}{:s}", svTarget, svLevel, nPatch, ".vpk");
vPair.m_svDirectoryName = fmt::format("{:s}{:s}_{:s}.bsp.pak000_{:s}", svLanguage, svTarget, svLevel, "dir.vpk");
return vPair;
}
//-----------------------------------------------------------------------------
// Purpose: builds the VPK manifest file
// Input : &vBlock -
// &svWorkSpace -
// &svWorkspace -
// &svManifestName -
//-----------------------------------------------------------------------------
void CPackedStore::BuildManifest(const vector<VPKEntryBlock_t>& vBlock, const string& svWorkspace, const string& svManifestName) const
@ -435,7 +319,7 @@ void CPackedStore::BuildManifest(const vector<VPKEntryBlock_t>& vBlock, const st
//-----------------------------------------------------------------------------
// Purpose: validates extraction result with precomputed ADLER32 hash
// Input : &svAssetFile -
// Input : &svAssetPath -
//-----------------------------------------------------------------------------
void CPackedStore::ValidateAdler32PostDecomp(const string& svAssetPath)
{
@ -464,7 +348,7 @@ void CPackedStore::ValidateAdler32PostDecomp(const string& svAssetPath)
//-----------------------------------------------------------------------------
// Purpose: validates extraction result with precomputed CRC32 hash
// Input : &svAssetFile -
// Input : &svAssetPath -
//-----------------------------------------------------------------------------
void CPackedStore::ValidateCRC32PostDecomp(const string& svAssetPath)
{
@ -500,7 +384,7 @@ void CPackedStore::ValidateCRC32PostDecomp(const string& svAssetPath)
//-----------------------------------------------------------------------------
void CPackedStore::PackWorkspace(const VPKPair_t& vPair, const string& svWorkspace, const string& svBuildPath, bool bManifestOnly)
{
const string svPackFilePath = string(svBuildPath + vPair.m_svBlockName).c_str();
const string svPackFilePath = string(svBuildPath + vPair.m_svPackName);
FileHandle_t hPackFile = FileSystem()->Open(svPackFilePath.c_str(), "wb", "GAME");
if (!hPackFile)
@ -509,14 +393,14 @@ void CPackedStore::PackWorkspace(const VPKPair_t& vPair, const string& svWorkspa
return;
}
vector<VPKKeyValues_t> vPaths;
vector<VPKKeyValues_t> vEntryValues;
vector<VPKEntryBlock_t> vEntryBlocks;
KeyValues* pManifestKV = nullptr;
if (bManifestOnly)
{
pManifestKV = GetManifest(svWorkspace, GetLevelName(vPair.m_svDirectoryName));
vPaths = GetEntryPaths(svWorkspace, pManifestKV);
vEntryValues = GetEntryValues(svWorkspace, pManifestKV);
if (pManifestKV)
{
@ -525,23 +409,23 @@ void CPackedStore::PackWorkspace(const VPKPair_t& vPair, const string& svWorkspa
}
else // Pack all files in workspace.
{
vPaths = GetEntryPaths(svWorkspace);
vEntryValues = GetEntryValues(svWorkspace);
}
uint64_t nSharedTotal = NULL;
uint32_t nSharedCount = NULL;
for (size_t i = 0, ps = vPaths.size(); i < ps; i++)
for (size_t i = 0, ps = vEntryValues.size(); i < ps; i++)
{
const VPKKeyValues_t& vKeys = vPaths[i];
FileHandle_t hAsset = FileSystem()->Open(vKeys.m_svEntryPath.c_str(), "rb", "GAME");
const VPKKeyValues_t& vEntryValue = vEntryValues[i];
FileHandle_t hAsset = FileSystem()->Open(vEntryValue.m_svEntryPath.c_str(), "rb", "GAME");
if (!hAsset)
{
Error(eDLL_T::FS, NO_ERROR, "%s - Unable to open '%s' (insufficient rights?)\n", __FUNCTION__, vKeys.m_svEntryPath.c_str());
Error(eDLL_T::FS, NO_ERROR, "%s - Unable to open '%s' (insufficient rights?)\n", __FUNCTION__, vEntryValue.m_svEntryPath.c_str());
continue;
}
const char* szDestPath = (vKeys.m_svEntryPath.c_str() + svWorkspace.length());
const char* szDestPath = (vEntryValue.m_svEntryPath.c_str() + svWorkspace.length());
uint32_t nLen = FileSystem()->Size(hAsset);
uint8_t* pBuf = MemAllocSingleton()->Alloc<uint8_t>(nLen);
@ -549,17 +433,17 @@ void CPackedStore::PackWorkspace(const VPKPair_t& vPair, const string& svWorkspa
FileSystem()->Seek(hAsset, 0, FileSystemSeek_t::FILESYSTEM_SEEK_HEAD);
DevMsg(eDLL_T::FS, "Packing entry '%zu' ('%s')\n", i, szDestPath);
vEntryBlocks.push_back(VPKEntryBlock_t(pBuf, nLen, FileSystem()->Tell(hPackFile), vKeys.m_iPreloadSize, 0, vKeys.m_nLoadFlags, vKeys.m_nTextureFlags, szDestPath));
vEntryBlocks.push_back(VPKEntryBlock_t(pBuf, nLen, FileSystem()->Tell(hPackFile), vEntryValue.m_iPreloadSize, 0, vEntryValue.m_nLoadFlags, vEntryValue.m_nTextureFlags, szDestPath));
VPKEntryBlock_t& vEntry = vEntryBlocks[i];
for (size_t j = 0, es = vEntry.m_vFragments.size(); j < es; j++)
VPKEntryBlock_t& vEntryBlock = vEntryBlocks[i];
for (size_t j = 0, es = vEntryBlock.m_vFragments.size(); j < es; j++)
{
VPKChunkDescriptor_t& vDescriptor = vEntry.m_vFragments[j];
VPKChunkDescriptor_t& vDescriptor = vEntryBlock.m_vFragments[j];
FileSystem()->Read(s_EntryBuf, vDescriptor.m_nCompressedSize, hAsset);
vDescriptor.m_nPackFileOffset = FileSystem()->Tell(hPackFile);
if (vKeys.m_bUseDataSharing)
if (vEntryValue.m_bUseDataSharing)
{
string svEntryHash = sha1(string(reinterpret_cast<char*>(s_EntryBuf), vDescriptor.m_nUncompressedSize));
auto p = m_mChunkHashMap.insert({ svEntryHash, vDescriptor });
@ -576,7 +460,7 @@ void CPackedStore::PackWorkspace(const VPKPair_t& vPair, const string& svWorkspa
}
}
if (vKeys.m_bUseCompression)
if (vEntryValue.m_bUseCompression)
{
m_lzCompStatus = lzham_compress_memory(&m_lzCompParams, s_EntryBuf, &vDescriptor.m_nCompressedSize, s_EntryBuf,
vDescriptor.m_nUncompressedSize, &m_nAdler32_Internal, &m_nCrc32_Internal);
@ -608,31 +492,31 @@ void CPackedStore::PackWorkspace(const VPKPair_t& vPair, const string& svWorkspa
m_mChunkHashMap.clear();
memset(s_EntryBuf, '\0', sizeof(s_EntryBuf));
VPKDir_t vDir = VPKDir_t();
vDir.BuildDirectoryFile(svBuildPath + vPair.m_svDirectoryName, vEntryBlocks);
VPKDir_t vDirectory;
vDirectory.BuildDirectoryFile(svBuildPath + vPair.m_svDirectoryName, vEntryBlocks);
}
//-----------------------------------------------------------------------------
// Purpose: rebuilds manifest and extracts all files from specified VPK file
// Input : &vDir -
// Input : &vDirectory -
// &svWorkspace -
//-----------------------------------------------------------------------------
void CPackedStore::UnpackWorkspace(const VPKDir_t& vDir, const string& svWorkspace)
void CPackedStore::UnpackWorkspace(const VPKDir_t& vDirectory, const string& svWorkspace)
{
if (vDir.m_vHeader.m_nHeaderMarker != VPK_HEADER_MARKER ||
vDir.m_vHeader.m_nMajorVersion != VPK_MAJOR_VERSION ||
vDir.m_vHeader.m_nMinorVersion != VPK_MINOR_VERSION)
if (vDirectory.m_vHeader.m_nHeaderMarker != VPK_HEADER_MARKER ||
vDirectory.m_vHeader.m_nMajorVersion != VPK_MAJOR_VERSION ||
vDirectory.m_vHeader.m_nMinorVersion != VPK_MINOR_VERSION)
{
Error(eDLL_T::FS, NO_ERROR, "Unsupported VPK directory file (invalid header criteria)\n");
return;
}
BuildManifest(vDir.m_vEntryBlocks, svWorkspace, GetLevelName(vDir.m_svDirPath));
const string svPath = RemoveFileName(vDir.m_svDirPath) + '/';
BuildManifest(vDirectory.m_vEntryBlocks, svWorkspace, GetLevelName(vDirectory.m_svDirectoryPath));
const string svPath = RemoveFileName(vDirectory.m_svDirectoryPath) + '/';
for (size_t i = 0, fs = vDir.m_vPackFile.size(); i < fs; i++)
for (size_t i = 0, fs = vDirectory.m_vPackFile.size(); i < fs; i++)
{
const string svPackFile = svPath + vDir.m_vPackFile[i];
const string svPackFile = svPath + vDirectory.m_vPackFile[i];
// Read from each pack file.
FileHandle_t hPackFile = FileSystem()->Open(svPackFile.c_str(), "rb", "GAME");
@ -642,16 +526,16 @@ void CPackedStore::UnpackWorkspace(const VPKDir_t& vDir, const string& svWorkspa
continue;
}
for (size_t j = 0, es = vDir.m_vEntryBlocks.size(); j < es; j++)
for (size_t j = 0, es = vDirectory.m_vEntryBlocks.size(); j < es; j++)
{
const VPKEntryBlock_t& vBlock = vDir.m_vEntryBlocks[j];
if (vBlock.m_iPackFileIndex != static_cast<uint16_t>(i))
const VPKEntryBlock_t& vEntryBlock = vDirectory.m_vEntryBlocks[j];
if (vEntryBlock.m_iPackFileIndex != static_cast<uint16_t>(i))
{
continue;
}
else // Chunk belongs to this block.
{
const string svFilePath = CreateDirectories(svWorkspace + vBlock.m_svEntryPath);
const string svFilePath = CreateDirectories(svWorkspace + vEntryBlock.m_svEntryPath);
FileHandle_t hAsset = FileSystem()->Open(svFilePath.c_str(), "wb", "GAME");
if (!hAsset)
@ -660,10 +544,10 @@ void CPackedStore::UnpackWorkspace(const VPKDir_t& vDir, const string& svWorkspa
continue;
}
DevMsg(eDLL_T::FS, "Unpacking entry '%zu' from block '%zu' ('%s')\n", j, i, vBlock.m_svEntryPath.c_str());
for (size_t k = 0, cs = vBlock.m_vFragments.size(); k < cs; k++)
DevMsg(eDLL_T::FS, "Unpacking entry '%zu' from block '%zu' ('%s')\n", j, i, vEntryBlock.m_svEntryPath.c_str());
for (size_t k = 0, cs = vEntryBlock.m_vFragments.size(); k < cs; k++)
{
const VPKChunkDescriptor_t& vChunk = vBlock.m_vFragments[k];
const VPKChunkDescriptor_t& vChunk = vEntryBlock.m_vFragments[k];
m_nChunkCount++;
FileSystem()->Seek(hPackFile, vChunk.m_nPackFileOffset, FileSystemSeek_t::FILESYSTEM_SEEK_HEAD);
@ -683,7 +567,7 @@ void CPackedStore::UnpackWorkspace(const VPKDir_t& vDir, const string& svWorkspa
if (m_lzDecompStatus != lzham_decompress_status_t::LZHAM_DECOMP_STATUS_SUCCESS)
{
Error(eDLL_T::FS, NO_ERROR, "Status '%d' for chunk '%zu' within entry '%zu' in block '%hu' (chunk not decompressed)\n",
m_lzDecompStatus, m_nChunkCount, i, vBlock.m_iPackFileIndex);
m_lzDecompStatus, m_nChunkCount, i, vEntryBlock.m_iPackFileIndex);
}
else // If successfully decompressed, write to file.
{
@ -697,10 +581,10 @@ void CPackedStore::UnpackWorkspace(const VPKDir_t& vDir, const string& svWorkspa
}
FileSystem()->Close(hAsset);
if (m_nChunkCount == vBlock.m_vFragments.size()) // Only validate after last entry in block had been written.
if (m_nChunkCount == vEntryBlock.m_vFragments.size()) // Only validate after last entry in block had been written.
{
m_nChunkCount = NULL;
m_nCrc32_Internal = vBlock.m_nFileCRC;
m_nCrc32_Internal = vEntryBlock.m_nFileCRC;
ValidateCRC32PostDecomp(svFilePath);
}
@ -733,27 +617,27 @@ VPKKeyValues_t::VPKKeyValues_t(const string& svEntryPath, uint16_t iPreloadSize,
//-----------------------------------------------------------------------------
// Purpose: 'VPKEntryBlock_t' file constructor
// Input : hFile -
// Input : hDirectoryFile -
// &svEntryPath -
//-----------------------------------------------------------------------------
VPKEntryBlock_t::VPKEntryBlock_t(FileHandle_t hFile, const string& svEntryPath)
VPKEntryBlock_t::VPKEntryBlock_t(FileHandle_t hDirectoryFile, const string& svEntryPath)
{
m_svEntryPath = svEntryPath; // Set the entry path.
StringReplace(m_svEntryPath, "\\", "/"); // Flip windows-style backslash to forward slash.
StringReplace(m_svEntryPath, " /", ""); // Remove space character representing VPK root.
FileSystem()->Read(&m_nFileCRC, sizeof(uint32_t), hFile); //
FileSystem()->Read(&m_iPreloadSize, sizeof(uint16_t), hFile); //
FileSystem()->Read(&m_iPackFileIndex, sizeof(uint16_t), hFile); //
FileSystem()->Read(&m_nFileCRC, sizeof(uint32_t), hDirectoryFile); //
FileSystem()->Read(&m_iPreloadSize, sizeof(uint16_t), hDirectoryFile); //
FileSystem()->Read(&m_iPackFileIndex, sizeof(uint16_t), hDirectoryFile); //
uint16_t nMarker = 0;
do // Loop through all chunks in the entry and add to list.
{
VPKChunkDescriptor_t entry(hFile);
VPKChunkDescriptor_t entry(hDirectoryFile);
m_vFragments.push_back(entry);
FileSystem()->Read(&nMarker, sizeof(nMarker), hFile);
FileSystem()->Read(&nMarker, sizeof(nMarker), hDirectoryFile);
} while (nMarker != static_cast<uint16_t>(PACKFILEINDEX_END));
}
@ -761,6 +645,7 @@ VPKEntryBlock_t::VPKEntryBlock_t(FileHandle_t hFile, const string& svEntryPath)
//-----------------------------------------------------------------------------
// Purpose: 'VPKEntryBlock_t' memory constructor
// Input : *pData -
// nLen
// nOffset -
// iPreloadSize -
// iPackFileIndex -
@ -791,15 +676,15 @@ VPKEntryBlock_t::VPKEntryBlock_t(const uint8_t* pData, size_t nLen, int64_t nOff
//-----------------------------------------------------------------------------
// Purpose: 'VPKChunkDescriptor_t' file constructor
// Input : hFile -
// Input : hDirectoryFile -
//-----------------------------------------------------------------------------
VPKChunkDescriptor_t::VPKChunkDescriptor_t(FileHandle_t hFile)
VPKChunkDescriptor_t::VPKChunkDescriptor_t(FileHandle_t hDirectoryFile)
{
FileSystem()->Read(&m_nLoadFlags, sizeof(uint32_t), hFile); //
FileSystem()->Read(&m_nTextureFlags, sizeof(uint16_t), hFile); //
FileSystem()->Read(&m_nPackFileOffset, sizeof(uint64_t), hFile); //
FileSystem()->Read(&m_nCompressedSize, sizeof(uint64_t), hFile); //
FileSystem()->Read(&m_nUncompressedSize, sizeof(uint64_t), hFile); //
FileSystem()->Read(&m_nLoadFlags, sizeof(uint32_t), hDirectoryFile); //
FileSystem()->Read(&m_nTextureFlags, sizeof(uint16_t), hDirectoryFile); //
FileSystem()->Read(&m_nPackFileOffset, sizeof(uint64_t), hDirectoryFile); //
FileSystem()->Read(&m_nCompressedSize, sizeof(uint64_t), hDirectoryFile); //
FileSystem()->Read(&m_nUncompressedSize, sizeof(uint64_t), hDirectoryFile); //
m_bIsCompressed = (m_nCompressedSize != m_nUncompressedSize);
}
@ -812,27 +697,115 @@ VPKChunkDescriptor_t::VPKChunkDescriptor_t(FileHandle_t hFile)
// nUncompressedSize -
//-----------------------------------------------------------------------------
VPKChunkDescriptor_t::VPKChunkDescriptor_t(uint32_t nLoadFlags, uint16_t nTextureFlags,
uint64_t nArchiveOffset, uint64_t nCompressedSize, uint64_t nUncompressedSize)
uint64_t nPackFileOffset, uint64_t nCompressedSize, uint64_t nUncompressedSize)
{
m_nLoadFlags = nLoadFlags;
m_nTextureFlags = nTextureFlags;
m_nPackFileOffset = nArchiveOffset;
m_nPackFileOffset = nPackFileOffset;
m_nCompressedSize = nCompressedSize;
m_nUncompressedSize = nUncompressedSize;
}
//-----------------------------------------------------------------------------
// Purpose: builds a valid file name for the VPK
// Input : svLanguage -
// svTarget -
// &svLevel -
// nPatch -
// Output : a vpk file pair (block and directory file names)
//-----------------------------------------------------------------------------
VPKPair_t::VPKPair_t(string svLanguage, string svTarget, const string& svLevel, int nPatch)
{
if (std::find(DIR_LOCALE.begin(), DIR_LOCALE.end(), svLanguage) == DIR_LOCALE.end())
{
svLanguage = DIR_LOCALE[0];
}
if (std::find(DIR_TARGET.begin(), DIR_TARGET.end(), svTarget) == DIR_TARGET.end())
{
svTarget = DIR_TARGET[0];
}
m_svPackName = fmt::format("{:s}_{:s}.bsp.pak000_{:03d}{:s}", svTarget, svLevel, nPatch, ".vpk");
m_svDirectoryName = fmt::format("{:s}{:s}_{:s}.bsp.pak000_{:s}", svLanguage, svTarget, svLevel, "dir.vpk");
}
//-----------------------------------------------------------------------------
// Purpose: 'VPKDir_t' file constructor
// Input : &svPath -
//-----------------------------------------------------------------------------
VPKDir_t::VPKDir_t(const string& svPath)
VPKDir_t::VPKDir_t(const string& svDirectoryPath)
{
Init(svDirectoryPath);
}
//-----------------------------------------------------------------------------
// Purpose: 'VPKDir_t' file constructor with sanitation
// Input : svDirectoryName -
// bSanitizeName - retrieve the directory file name from block name
// Output : VPKDir_t
//-----------------------------------------------------------------------------
VPKDir_t::VPKDir_t(const string& svDirectoryPath, bool bSanitizeName)
{
if (!bSanitizeName)
{
Init(svDirectoryPath);
return;
}
std::smatch smRegexMatches;
std::regex_search(svDirectoryPath, smRegexMatches, BLOCK_REGEX);
if (smRegexMatches.empty())
{
Init(svDirectoryPath);
return;
}
string svSanitizedName = svDirectoryPath;
StringReplace(svSanitizedName, smRegexMatches[0], "pak000_dir");
bool bHasLocale = false;
for (const string& svLocale : DIR_LOCALE)
{
if (svSanitizedName.find(svLocale) != string::npos)
{
bHasLocale = true;
break;
}
}
if (!bHasLocale) // Only sanitize if no locale was provided.
{
string svPackDirPrefix;
svPackDirPrefix.append(DIR_LOCALE[0]);
for (const string& svTarget : DIR_TARGET)
{
if (svSanitizedName.find(svTarget) != string::npos)
{
svPackDirPrefix.append(svTarget);
StringReplace(svSanitizedName, svTarget, svPackDirPrefix);
break;
}
}
}
Init(svSanitizedName);
}
//-----------------------------------------------------------------------------
// Purpose: 'VPKDir_t' file constructor
// Input : &svDirectoryPath -
//-----------------------------------------------------------------------------
void VPKDir_t::Init(const string& svDirectoryPath)
{
// Create stream to read from each pack file.
FileHandle_t hDirectory = FileSystem()->Open(svPath.c_str(), "rb", "GAME");
FileHandle_t hDirectory = FileSystem()->Open(svDirectoryPath.c_str(), "rb", "GAME");
if (!hDirectory)
{
Error(eDLL_T::FS, NO_ERROR, "%s - Unable to open '%s' (insufficient rights?)\n", __FUNCTION__, svPath.c_str());
Error(eDLL_T::FS, NO_ERROR, "%s - Unable to open '%s' (insufficient rights?)\n", __FUNCTION__, svDirectoryPath.c_str());
return;
}
@ -843,7 +816,7 @@ VPKDir_t::VPKDir_t(const string& svPath)
FileSystem()->Read(&m_vHeader.m_nSignatureSize, sizeof(uint32_t), hDirectory); //
m_vEntryBlocks = g_pPackedStore->GetEntryBlocks(hDirectory);
m_svDirPath = svPath; // Set path to vpk directory file.
m_svDirectoryPath = svDirectoryPath; // Set path to vpk directory file.
m_nPackFileCount = 0;
for (VPKEntryBlock_t vEntry : m_vEntryBlocks)
@ -856,87 +829,122 @@ VPKDir_t::VPKDir_t(const string& svPath)
for (uint16_t i = 0; i < m_nPackFileCount + 1; i++)
{
string svArchivePath = g_pPackedStore->GetPackFile(svPath, i);
m_vPackFile.push_back(svArchivePath);
string svPackPath = GetPackFile(svDirectoryPath, i);
m_vPackFile.push_back(svPackPath);
}
}
//-----------------------------------------------------------------------------
// Purpose: writes the vpk directory header
// Input : pDirectoryFile -
// Purpose: formats pack file path for specific directory file
// Input : &svDirectoryPath -
// iPackFileIndex -
// output : string
//-----------------------------------------------------------------------------
void VPKDir_t::WriteHeader(FileHandle_t pDirectoryFile) const
string VPKDir_t::GetPackFile(const string& svDirectoryPath, uint16_t iPackFileIndex) const
{
FileSystem()->Write(&m_vHeader.m_nHeaderMarker, sizeof(uint32_t), pDirectoryFile);
FileSystem()->Write(&m_vHeader.m_nMajorVersion, sizeof(uint16_t), pDirectoryFile);
FileSystem()->Write(&m_vHeader.m_nMinorVersion, sizeof(uint16_t), pDirectoryFile);
FileSystem()->Write(&m_vHeader.m_nDirectorySize, sizeof(uint32_t), pDirectoryFile);
FileSystem()->Write(&m_vHeader.m_nSignatureSize, sizeof(uint32_t), pDirectoryFile);
string svPackChunkName = StripLocalePrefix(svDirectoryPath);
string svPackChunkIndex = fmt::format("{:s}{:03d}", "pak000_", iPackFileIndex);
StringReplace(svPackChunkName, "pak000_dir", svPackChunkIndex);
return svPackChunkName;
}
//-----------------------------------------------------------------------------
// Purpose: strips locale prefix from file path
// Input : &svDirectoryPath -
// Output : directory filename without locale prefix
//-----------------------------------------------------------------------------
string VPKDir_t::StripLocalePrefix(const string& svDirectoryPath) const
{
string svFileName = GetFileName(svDirectoryPath);
for (const string& svLocale : DIR_LOCALE)
{
if (svFileName.find(svLocale) != string::npos)
{
StringReplace(svFileName, svLocale, "");
break;
}
}
return svFileName;
}
//-----------------------------------------------------------------------------
// Purpose: writes the vpk directory header
// Input : hDirectoryFile -
//-----------------------------------------------------------------------------
void VPKDir_t::WriteHeader(FileHandle_t hDirectoryFile) const
{
FileSystem()->Write(&m_vHeader.m_nHeaderMarker, sizeof(uint32_t), hDirectoryFile);
FileSystem()->Write(&m_vHeader.m_nMajorVersion, sizeof(uint16_t), hDirectoryFile);
FileSystem()->Write(&m_vHeader.m_nMinorVersion, sizeof(uint16_t), hDirectoryFile);
FileSystem()->Write(&m_vHeader.m_nDirectorySize, sizeof(uint32_t), hDirectoryFile);
FileSystem()->Write(&m_vHeader.m_nSignatureSize, sizeof(uint32_t), hDirectoryFile);
}
//-----------------------------------------------------------------------------
// Purpose: writes the directory tree size
// Input : &vEntryBlocks -
// Input : hDirectoryFile -
//-----------------------------------------------------------------------------
void VPKDir_t::WriteTreeSize(FileHandle_t pDirectoryFile) const
void VPKDir_t::WriteTreeSize(FileHandle_t hDirectoryFile) const
{
FileSystem()->Seek(pDirectoryFile, offsetof(VPKDir_t, m_vHeader.m_nDirectorySize), FileSystemSeek_t::FILESYSTEM_SEEK_HEAD);
FileSystem()->Write(&m_vHeader.m_nDirectorySize, sizeof(uint32_t), pDirectoryFile);
FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint32_t), pDirectoryFile);
FileSystem()->Seek(hDirectoryFile, offsetof(VPKDir_t, m_vHeader.m_nDirectorySize), FileSystemSeek_t::FILESYSTEM_SEEK_HEAD);
FileSystem()->Write(&m_vHeader.m_nDirectorySize, sizeof(uint32_t), hDirectoryFile);
FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint32_t), hDirectoryFile);
}
//-----------------------------------------------------------------------------
// Purpose: writes the vpk chunk descriptors
// Input : pDirectoryFile -
// Input : hDirectoryFile -
// &vMap -
// Output : number of descriptors written
//-----------------------------------------------------------------------------
uint64_t VPKDir_t::WriteDescriptor(FileHandle_t pDirectoryFile, std::map<string, std::map<string, std::list<VPKEntryBlock_t>>>& vMap) const
uint64_t VPKDir_t::WriteDescriptor(FileHandle_t hDirectoryFile, std::map<string, std::map<string, std::list<VPKEntryBlock_t>>>& vMap) const
{
uint64_t nDescriptors = NULL;
for (auto& iKeyValue : vMap)
{
FileSystem()->Write(iKeyValue.first.c_str(), (iKeyValue.first.length() + 1), pDirectoryFile);
FileSystem()->Write(iKeyValue.first.c_str(), (iKeyValue.first.length() + 1), hDirectoryFile);
for (auto& jKeyValue : iKeyValue.second)
{
FileSystem()->Write(jKeyValue.first.c_str(), (jKeyValue.first.length() + 1), pDirectoryFile);
FileSystem()->Write(jKeyValue.first.c_str(), (jKeyValue.first.length() + 1), hDirectoryFile);
for (auto& vEntry : jKeyValue.second)
{
string pszEntryPath = GetFileName(vEntry.m_svEntryPath, true);
FileSystem()->Write(pszEntryPath.c_str(), (pszEntryPath.length() + 1), pDirectoryFile);
FileSystem()->Write(pszEntryPath.c_str(), (pszEntryPath.length() + 1), hDirectoryFile);
FileSystem()->Write(&vEntry.m_nFileCRC, sizeof(uint32_t), pDirectoryFile);
FileSystem()->Write(&vEntry.m_iPreloadSize, sizeof(uint16_t), pDirectoryFile);
FileSystem()->Write(&vEntry.m_iPackFileIndex, sizeof(uint16_t), pDirectoryFile);
FileSystem()->Write(&vEntry.m_nFileCRC, sizeof(uint32_t), hDirectoryFile);
FileSystem()->Write(&vEntry.m_iPreloadSize, sizeof(uint16_t), hDirectoryFile);
FileSystem()->Write(&vEntry.m_iPackFileIndex, sizeof(uint16_t), hDirectoryFile);
for (size_t i = 0, nc = vEntry.m_vFragments.size(); i < nc; i++)
{
/*Write chunk descriptor*/
const VPKChunkDescriptor_t* pDescriptor = &vEntry.m_vFragments[i];
FileSystem()->Write(&pDescriptor->m_nLoadFlags, sizeof(uint32_t), pDirectoryFile);
FileSystem()->Write(&pDescriptor->m_nTextureFlags, sizeof(uint16_t), pDirectoryFile);
FileSystem()->Write(&pDescriptor->m_nPackFileOffset, sizeof(uint64_t), pDirectoryFile);
FileSystem()->Write(&pDescriptor->m_nCompressedSize, sizeof(uint64_t), pDirectoryFile);
FileSystem()->Write(&pDescriptor->m_nUncompressedSize, sizeof(uint64_t), pDirectoryFile);
FileSystem()->Write(&pDescriptor->m_nLoadFlags, sizeof(uint32_t), hDirectoryFile);
FileSystem()->Write(&pDescriptor->m_nTextureFlags, sizeof(uint16_t), hDirectoryFile);
FileSystem()->Write(&pDescriptor->m_nPackFileOffset, sizeof(uint64_t), hDirectoryFile);
FileSystem()->Write(&pDescriptor->m_nCompressedSize, sizeof(uint64_t), hDirectoryFile);
FileSystem()->Write(&pDescriptor->m_nUncompressedSize, sizeof(uint64_t), hDirectoryFile);
if (i != (nc - 1))
{
FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint16_t), pDirectoryFile);
FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint16_t), hDirectoryFile);
}
else // Mark end of entry.
{
FileSystem()->Write(&PACKFILEINDEX_END, sizeof(uint16_t), pDirectoryFile);
FileSystem()->Write(&PACKFILEINDEX_END, sizeof(uint16_t), hDirectoryFile);
}
nDescriptors++;
}
}
FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint8_t), pDirectoryFile);
FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint8_t), hDirectoryFile);
}
FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint8_t), pDirectoryFile);
FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint8_t), hDirectoryFile);
}
FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint8_t), pDirectoryFile);
FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint8_t), hDirectoryFile);
return nDescriptors;
}
@ -971,28 +979,28 @@ void VPKDir_t::BuildDirectoryTree(const vector<VPKEntryBlock_t>& vEntryBlocks, s
//-----------------------------------------------------------------------------
// Purpose: builds the vpk directory file
// Input : &svDirectoryFile -
// Input : &svDirectoryPath -
// &vEntryBlocks -
//-----------------------------------------------------------------------------
void VPKDir_t::BuildDirectoryFile(const string& svDirectoryFile, const vector<VPKEntryBlock_t>& vEntryBlocks)
void VPKDir_t::BuildDirectoryFile(const string& svDirectoryPath, const vector<VPKEntryBlock_t>& vEntryBlocks)
{
FileHandle_t pDirectoryFile = FileSystem()->Open(svDirectoryFile.c_str(), "wb", "GAME");
if (!pDirectoryFile)
FileHandle_t hDirectoryFile = FileSystem()->Open(svDirectoryPath.c_str(), "wb", "GAME");
if (!hDirectoryFile)
{
Error(eDLL_T::FS, NO_ERROR, "%s - Unable to write to '%s' (read-only?)\n", __FUNCTION__, svDirectoryFile.c_str());
Error(eDLL_T::FS, NO_ERROR, "%s - Unable to write to '%s' (read-only?)\n", __FUNCTION__, svDirectoryPath.c_str());
return;
}
auto vMap = std::map<string, std::map<string, std::list<VPKEntryBlock_t>>>();
BuildDirectoryTree(vEntryBlocks, vMap);
WriteHeader(pDirectoryFile);
uint64_t nDescriptors = WriteDescriptor(pDirectoryFile, vMap);
WriteHeader(hDirectoryFile);
uint64_t nDescriptors = WriteDescriptor(hDirectoryFile, vMap);
m_vHeader.m_nDirectorySize = static_cast<uint32_t>(FileSystem()->Tell(pDirectoryFile) - sizeof(VPKDirHeader_t));
WriteTreeSize(pDirectoryFile);
m_vHeader.m_nDirectorySize = static_cast<uint32_t>(FileSystem()->Tell(hDirectoryFile) - sizeof(VPKDirHeader_t));
WriteTreeSize(hDirectoryFile);
FileSystem()->Close(pDirectoryFile);
FileSystem()->Close(hDirectoryFile);
DevMsg(eDLL_T::FS, "*** Build directory totaling '%zu' bytes with '%zu' entries and '%zu' descriptors\n",
size_t(sizeof(VPKDirHeader_t) + m_vHeader.m_nDirectorySize), vEntryBlocks.size(), nDescriptors);
}

View File

@ -69,8 +69,8 @@ struct VPKChunkDescriptor_t
bool m_bIsCompressed = false;
VPKChunkDescriptor_t(){};
VPKChunkDescriptor_t(FileHandle_t pFile);
VPKChunkDescriptor_t(uint32_t nEntryFlags, uint16_t nTextureFlags, uint64_t nPackFileOffset, uint64_t nCompressedSize, uint64_t nUncompressedSize);
VPKChunkDescriptor_t(FileHandle_t hDirectoryFile);
VPKChunkDescriptor_t(uint32_t nLoadFlags, uint16_t nTextureFlags, uint64_t nPackFileOffset, uint64_t nCompressedSize, uint64_t nUncompressedSize);
};
struct VPKEntryBlock_t
@ -82,8 +82,8 @@ struct VPKEntryBlock_t
string m_svEntryPath; // Path to entry within vpk.
VPKEntryBlock_t(FileHandle_t pFile, const string& svEntryPath);
VPKEntryBlock_t(const uint8_t* pData, size_t nLen, int64_t nOffset, uint16_t iPreloadSize,
uint16_t iPackFileIndex, uint32_t nEntryFlags, uint16_t nTextureFlags, const string& svEntryPath);
VPKEntryBlock_t(const uint8_t* pData, size_t nLen, int64_t nOffset, uint16_t iPreloadSize,
uint16_t iPackFileIndex, uint32_t nLoadFlags, uint16_t nTextureFlags, const string& svEntryPath);
};
struct VPKDirHeader_t
@ -95,44 +95,54 @@ struct VPKDirHeader_t
uint32_t m_nSignatureSize; // Directory signature.
};
struct VPKPair_t
{
string m_svPackName;
string m_svDirectoryName;
VPKPair_t(string svLanguage, string svTarget, const string& svLevel, int nPatch);
};
struct VPKDir_t
{
VPKDirHeader_t m_vHeader; // Dir header.
vector<VPKEntryBlock_t> m_vEntryBlocks; // Vector of entry blocks.
uint16_t m_nPackFileCount; // Number of pack patches (pack file count-1).
vector<string> m_vPackFile; // Vector of pack file names.
string m_svDirPath; // Path to vpk_dir file.
string m_svDirectoryPath;// Path to vpk_dir file.
VPKDir_t(const string& svPath);
VPKDir_t() { m_vHeader.m_nHeaderMarker = VPK_HEADER_MARKER; m_vHeader.m_nMajorVersion = VPK_MAJOR_VERSION; m_vHeader.m_nMinorVersion = VPK_MINOR_VERSION; };
VPKDir_t()
{
m_vHeader.m_nHeaderMarker = VPK_HEADER_MARKER; m_vHeader.m_nMajorVersion = VPK_MAJOR_VERSION;
m_vHeader.m_nMinorVersion = VPK_MINOR_VERSION; m_vHeader.m_nDirectorySize = NULL, m_vHeader.m_nSignatureSize = NULL;
};
VPKDir_t(const string& svDirectoryFile);
VPKDir_t(const string& svDirectoryFile, bool bSanitizeName);
void WriteHeader(FileHandle_t pDirectoryFile) const;
void WriteTreeSize(FileHandle_t pDirectoryFile) const;
uint64_t WriteDescriptor(FileHandle_t pDirectoryFile, std::map<string, std::map<string, std::list<VPKEntryBlock_t>>>& vMap) const;
void Init(const string& svPath);
string StripLocalePrefix(const string& svDirectoryFile) const;
string GetPackFile(const string& svDirectoryPath, uint16_t iPackFileIndex) const;
void WriteHeader(FileHandle_t hDirectoryFile) const;
void WriteTreeSize(FileHandle_t hDirectoryFile) const;
uint64_t WriteDescriptor(FileHandle_t hDirectoryFile, std::map<string, std::map<string, std::list<VPKEntryBlock_t>>>& vMap) const;
void BuildDirectoryTree(const vector<VPKEntryBlock_t>& vEntryBlocks, std::map<string, std::map<string, std::list<VPKEntryBlock_t>>>& vMap) const;
void BuildDirectoryFile(const string& svDirectoryFile, const vector<VPKEntryBlock_t>& vEntryBlocks);
};
struct VPKPair_t
{
string m_svBlockName;
string m_svDirectoryName;
};
class CPackedStore
{
public:
void InitLzCompParams(void);
void InitLzDecompParams(void);
VPKDir_t GetDirectoryFile(const string& svDirectoryFile, bool bSanitizeName) const;
string GetPackFile(const string& svPackDirFile, uint16_t iPackFileIndex) const;
lzham_compress_level GetCompressionLevel(void) const;
vector<VPKEntryBlock_t> GetEntryBlocks(FileHandle_t pDirectory) const;
vector<VPKKeyValues_t> GetEntryPaths(const string& svPathIn) const;
vector<VPKKeyValues_t> GetEntryPaths(const string& svPathIn, KeyValues* pManifestKeyValues) const;
vector<VPKEntryBlock_t> GetEntryBlocks(FileHandle_t hDirectoryFile) const;
vector<VPKKeyValues_t> GetEntryValues(const string& svWorkspace) const;
vector<VPKKeyValues_t> GetEntryValues(const string& svWorkspace, KeyValues* pManifestKeyValues) const;
string GetNameParts(const string& svDirectoryName, int nCaptureGroup) const;
string GetLevelName(const string& svDirectoryName) const;
@ -140,14 +150,12 @@ public:
KeyValues* GetManifest(const string& svWorkspace, const string& svManifestName) const;
vector<string> GetIgnoreList(const string& svWorkspace) const;
string FormatEntryPath(const string& svName, const string& svPath, const string& svExtension) const;
string StripLocalePrefix(const string& svDirectoryFile) const;
string FormatEntryPath(const string& svPath, const string& svName, const string& svExtension) const;
VPKPair_t BuildFileName(string svLanguage, string svTarget, const string& svLevel, int nPatch) const;
void BuildManifest(const vector<VPKEntryBlock_t>& vBlock, const string& svWorkSpace, const string& svManifestName) const;
void BuildManifest(const vector<VPKEntryBlock_t>& vBlock, const string& svWorkspace, const string& svManifestName) const;
void PackWorkspace(const VPKPair_t& vPair, const string& svWorkspace, const string& svBuildPath, bool bManifestOnly);
void UnpackWorkspace(const VPKDir_t& vDir, const string& svPathOut = "");
void UnpackWorkspace(const VPKDir_t& vDirectory, const string& svWorkspace = "");
void ValidateAdler32PostDecomp(const string& svAssetPath);
void ValidateCRC32PostDecomp(const string& svAssetPath);

View File

@ -533,14 +533,14 @@ void VPK_Pack_f(const CCommand& args)
return;
}
VPKPair_t vPair = g_pPackedStore->BuildFileName(args.Arg(1), args.Arg(2), args.Arg(3), NULL);
VPKPair_t pair(args.Arg(1), args.Arg(2), args.Arg(3), NULL);
CFastTimer timer;
DevMsg(eDLL_T::FS, "*** Starting VPK build command for: '%s'\n", vPair.m_svDirectoryName.c_str());
DevMsg(eDLL_T::FS, "*** Starting VPK build command for: '%s'\n", pair.m_svDirectoryName.c_str());
timer.Start();
g_pPackedStore->InitLzCompParams();
g_pPackedStore->PackWorkspace(vPair, fs_packedstore_workspace->GetString(), "vpk/", (args.ArgC() > 4));
g_pPackedStore->PackWorkspace(pair, fs_packedstore_workspace->GetString(), "vpk/", (args.ArgC() > 4));
timer.End();
DevMsg(eDLL_T::FS, "*** Time elapsed: '%lf' seconds\n", timer.GetDuration().GetSeconds());
@ -563,7 +563,7 @@ void VPK_Unpack_f(const CCommand& args)
}
const char* pArg = args.Arg(1);
VPKDir_t vpk = g_pPackedStore->GetDirectoryFile(pArg, (args.ArgC() > 2));
VPKDir_t vpk(pArg, (args.ArgC() > 2));
CFastTimer timer;
DevMsg(eDLL_T::FS, "*** Starting VPK extraction command for: '%s'\n", pArg);