From 2bc570800ba714c5e5c50368c6e07847ebd674da Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Wed, 23 Nov 2022 12:27:57 +0100 Subject: [PATCH] Split 'VPKDir_t::Build' into multiple methods Each process of writing out a VPK directory is now within its own method. --- r5dev/vpklib/packedstore.cpp | 178 +++++++++++++++++++++-------------- r5dev/vpklib/packedstore.h | 7 +- 2 files changed, 114 insertions(+), 71 deletions(-) diff --git a/r5dev/vpklib/packedstore.cpp b/r5dev/vpklib/packedstore.cpp index 6e855525..e66aeb1f 100644 --- a/r5dev/vpklib/packedstore.cpp +++ b/r5dev/vpklib/packedstore.cpp @@ -609,7 +609,7 @@ void CPackedStore::PackWorkspace(const VPKPair_t& vPair, const string& svWorkspa memset(s_EntryBuf, '\0', sizeof(s_EntryBuf)); VPKDir_t vDir = VPKDir_t(); - vDir.Build(svBuildPath + vPair.m_svDirectoryName, vEntryBlocks); + vDir.BuildDirectoryFile(svBuildPath + vPair.m_svDirectoryName, vEntryBlocks); } //----------------------------------------------------------------------------- @@ -862,28 +862,92 @@ VPKDir_t::VPKDir_t(const string& svPath) } //----------------------------------------------------------------------------- -// Purpose: builds the vpk directory file -// Input : &svDirectoryFile - -// &vEntryBlocks - +// Purpose: writes the vpk directory header +// Input : pDirectoryFile - //----------------------------------------------------------------------------- -void VPKDir_t::Build(const string& svDirectoryFile, const vector<VPKEntryBlock_t>& vEntryBlocks) +void VPKDir_t::WriteHeader(FileHandle_t pDirectoryFile) const { - FileHandle_t hDirectoryFile = FileSystem()->Open(svDirectoryFile.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()); - return; - } + 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); +} - auto vMap = std::map<string, std::map<string, std::list<VPKEntryBlock_t>>>(); +//----------------------------------------------------------------------------- +// Purpose: writes the directory tree size +// Input : &vEntryBlocks - +//----------------------------------------------------------------------------- +void VPKDir_t::WriteTreeSize(FileHandle_t pDirectoryFile) 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); +} + +//----------------------------------------------------------------------------- +// Purpose: writes the vpk chunk descriptors +// Input : pDirectoryFile - +// &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 nDescriptors = NULL; - 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); + for (auto& iKeyValue : vMap) + { + FileSystem()->Write(iKeyValue.first.c_str(), (iKeyValue.first.length() + 1), pDirectoryFile); + for (auto& jKeyValue : iKeyValue.second) + { + FileSystem()->Write(jKeyValue.first.c_str(), (jKeyValue.first.length() + 1), pDirectoryFile); + for (auto& vEntry : jKeyValue.second) + { + string pszEntryPath = GetFileName(vEntry.m_svEntryPath, true); + FileSystem()->Write(pszEntryPath.c_str(), (pszEntryPath.length() + 1), pDirectoryFile); + 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); + + 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); + + if (i != (nc - 1)) + { + FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint16_t), pDirectoryFile); + } + else // Mark end of entry. + { + FileSystem()->Write(&PACKFILEINDEX_END, sizeof(uint16_t), pDirectoryFile); + } + nDescriptors++; + } + } + FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint8_t), pDirectoryFile); + } + FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint8_t), pDirectoryFile); + } + FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint8_t), pDirectoryFile); + + return nDescriptors; +} + +//----------------------------------------------------------------------------- +// Purpose: builds the vpk directory tree +// Input : &vEntryBlocks - +// &vMap - +//----------------------------------------------------------------------------- +void VPKDir_t::BuildDirectoryTree(const vector<VPKEntryBlock_t>& vEntryBlocks, std::map<string, std::map<string, std::list<VPKEntryBlock_t>>>& vMap) const +{ for (const VPKEntryBlock_t& vBlock : vEntryBlocks) { string svExtension = GetExtension(vBlock.m_svEntryPath); @@ -903,61 +967,35 @@ void VPKDir_t::Build(const string& svDirectoryFile, const vector<VPKEntryBlock_t } vMap[svExtension][svFilePath].push_back(vBlock); } - - for (auto& iKeyValue : vMap) - { - 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), hDirectoryFile); - for (auto& vEntry : jKeyValue.second) - { - string pszEntryPath = GetFileName(vEntry.m_svEntryPath, true); - FileSystem()->Write(pszEntryPath.c_str(), (pszEntryPath.length() + 1), hDirectoryFile); - - 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), 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), hDirectoryFile); - } - else // Mark end of entry. - { - FileSystem()->Write(&PACKFILEINDEX_END, sizeof(uint16_t), hDirectoryFile); - } - nDescriptors++; - } - } - FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint8_t), hDirectoryFile); - } - FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint8_t), hDirectoryFile); - } - FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint8_t), hDirectoryFile); - m_vHeader.m_nDirectorySize = static_cast<uint32_t>(FileSystem()->Tell(hDirectoryFile) - sizeof(VPKDirHeader_t)); - - 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); - - 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); } +//----------------------------------------------------------------------------- +// Purpose: builds the vpk directory file +// Input : &svDirectoryFile - +// &vEntryBlocks - +//----------------------------------------------------------------------------- +void VPKDir_t::BuildDirectoryFile(const string& svDirectoryFile, const vector<VPKEntryBlock_t>& vEntryBlocks) +{ + FileHandle_t pDirectoryFile = FileSystem()->Open(svDirectoryFile.c_str(), "wb", "GAME"); + if (!pDirectoryFile) + { + Error(eDLL_T::FS, NO_ERROR, "%s - Unable to write to '%s' (read-only?)\n", __FUNCTION__, svDirectoryFile.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); + + m_vHeader.m_nDirectorySize = static_cast<uint32_t>(FileSystem()->Tell(pDirectoryFile) - sizeof(VPKDirHeader_t)); + WriteTreeSize(pDirectoryFile); + + FileSystem()->Close(pDirectoryFile); + 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); +} //----------------------------------------------------------------------------- // Singleton //----------------------------------------------------------------------------- diff --git a/r5dev/vpklib/packedstore.h b/r5dev/vpklib/packedstore.h index 8c5b58fd..6c58281d 100644 --- a/r5dev/vpklib/packedstore.h +++ b/r5dev/vpklib/packedstore.h @@ -106,7 +106,12 @@ struct VPKDir_t 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; }; - void Build(const string& svDirectoryFile, const vector<VPKEntryBlock_t>& vEntryBlocks); + 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 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