mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
CPackedStore: fix directory file name sanitizer
The sanitizer can retrieve the directory file name from the block file name if this is passed instead. This was broken in the previous system. Sanitization can be opted out if the 3rd parameter of the 'fs_vpk_unpack' command is omitted.
This commit is contained in:
parent
addf815873
commit
142c0d1de5
@ -43,41 +43,68 @@ void CPackedStore::InitLzDecompParams(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose: gets a directory structure for specified file
|
// Purpose: gets a directory structure for specified file.
|
||||||
// Input : svPackDirFile -
|
// Input : svPackDirFile -
|
||||||
|
// bSanitizeName - retrieve the directory file name from block name
|
||||||
// Output : VPKDir_t
|
// Output : VPKDir_t
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
VPKDir_t CPackedStore::GetDirectoryFile(string svPackDirFile) const
|
VPKDir_t CPackedStore::GetDirectoryFile(string svPackDirFile, bool bSanitizeName) const
|
||||||
{
|
{
|
||||||
/*| PACKDIRFILE |||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/
|
/*| PACKDIRFILE |||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/
|
||||||
std::regex rgArchiveRegex("pak000_([0-9]{3})");
|
|
||||||
std::smatch smRegexMatches;
|
std::smatch smRegexMatches;
|
||||||
|
|
||||||
std::regex_search(svPackDirFile, smRegexMatches, rgArchiveRegex);
|
if (!bSanitizeName)
|
||||||
|
return VPKDir_t(svPackDirFile);
|
||||||
|
|
||||||
|
std::regex_search(svPackDirFile, smRegexMatches, BLOCK_REGEX);
|
||||||
|
if (smRegexMatches.empty())
|
||||||
|
return VPKDir_t(svPackDirFile);
|
||||||
|
|
||||||
if (smRegexMatches.size() != 0)
|
|
||||||
{
|
|
||||||
StringReplace(svPackDirFile, smRegexMatches[0], "pak000_dir");
|
StringReplace(svPackDirFile, smRegexMatches[0], "pak000_dir");
|
||||||
|
|
||||||
for (const string& svLocale : DIR_LOCALE)
|
bool bHasLocale = false;
|
||||||
|
bool bHasContext = false;
|
||||||
|
string svPackDirPrefix;
|
||||||
|
|
||||||
|
size_t nLocaleIndex = 0; // Default to ENGLISH;
|
||||||
|
size_t nContextIndex = 0; // Default to SERVER;
|
||||||
|
|
||||||
|
for (size_t i = 0, nl = DIR_LOCALE.size(); i < nl; i++)
|
||||||
{
|
{
|
||||||
|
const string& svLocale = DIR_LOCALE[i];
|
||||||
if (svPackDirFile.find(svLocale) != string::npos)
|
if (svPackDirFile.find(svLocale) != string::npos)
|
||||||
{
|
{
|
||||||
for (const string& svContext : DIR_CONTEXT)
|
svPackDirPrefix.append(svLocale);
|
||||||
{
|
nLocaleIndex = i;
|
||||||
if (svPackDirFile.find(svContext) != string::npos)
|
bHasLocale = true;
|
||||||
{
|
|
||||||
const string svPackDirPrefix = svContext + svContext;
|
|
||||||
StringReplace(svPackDirFile, svContext, svPackDirPrefix);
|
|
||||||
goto escape;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}escape:;
|
|
||||||
}
|
|
||||||
|
|
||||||
VPKDir_t vDir(svPackDirFile);
|
if (svPackDirPrefix.empty()) // No locale found.
|
||||||
return vDir;
|
{
|
||||||
|
svPackDirPrefix.append(DIR_LOCALE[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bHasLocale)
|
||||||
|
{
|
||||||
|
for (size_t i = 0, nc = DIR_CONTEXT.size(); i < nc; i++)
|
||||||
|
{
|
||||||
|
const string& svContext = DIR_CONTEXT[i];
|
||||||
|
if (svPackDirFile.find(svContext) != string::npos)
|
||||||
|
{
|
||||||
|
svPackDirPrefix.append(svContext);
|
||||||
|
nContextIndex = i;
|
||||||
|
bHasContext = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bHasContext) // Context is required for this to work.
|
||||||
|
{
|
||||||
|
StringReplace(svPackDirFile, DIR_CONTEXT[nContextIndex], svPackDirPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
return VPKDir_t(svPackDirFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -148,7 +175,7 @@ vector<VPKEntryBlock_t> CPackedStore::GetEntryBlocks(CIOStream* pReader) const
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose: scans the input directory and returns the paths to the vector
|
// Purpose: scans the input directory and returns the paths to the vector
|
||||||
// Input : &svPathIn -
|
// Input : &svPathIn -
|
||||||
// Output : vector<string>
|
// Output : a string vector of all included entry paths
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
vector<string> CPackedStore::GetEntryPaths(const string& svPathIn) const
|
vector<string> CPackedStore::GetEntryPaths(const string& svPathIn) const
|
||||||
{
|
{
|
||||||
@ -181,7 +208,7 @@ vector<string> CPackedStore::GetEntryPaths(const string& svPathIn) const
|
|||||||
// Purpose: scans the input directory and returns the paths to the vector if path exists in manifest
|
// Purpose: scans the input directory and returns the paths to the vector if path exists in manifest
|
||||||
// Input : &svPathIn -
|
// Input : &svPathIn -
|
||||||
// &jManifest -
|
// &jManifest -
|
||||||
// Output : vector<string>
|
// Output : a string vector of all included entry paths
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
vector<string> CPackedStore::GetEntryPaths(const string& svPathIn, const nlohmann::json& jManifest) const
|
vector<string> CPackedStore::GetEntryPaths(const string& svPathIn, const nlohmann::json& jManifest) const
|
||||||
{
|
{
|
||||||
@ -225,15 +252,15 @@ vector<string> CPackedStore::GetEntryPaths(const string& svPathIn, const nlohman
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose: gets the parts of the directory file name (1 = locale + context, 2 = levelname)
|
// Purpose: gets the parts of the directory file name
|
||||||
// Input : &svDirectoryName -
|
// Input : &svDirectoryName -
|
||||||
// nCaptureGroup -
|
// nCaptureGroup - (1 = locale + context, 2 = levelname)
|
||||||
// Output : string
|
// Output : part of directory file name as string
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
string CPackedStore::GetNameParts(const string& svDirectoryName, int nCaptureGroup) const
|
string CPackedStore::GetNameParts(const string& svDirectoryName, int nCaptureGroup) const
|
||||||
{
|
{
|
||||||
std::smatch smRegexMatches;
|
std::smatch smRegexMatches;
|
||||||
std::regex_search(svDirectoryName, smRegexMatches, BLOCK_REGEX);
|
std::regex_search(svDirectoryName, smRegexMatches, DIR_REGEX);
|
||||||
|
|
||||||
return smRegexMatches[nCaptureGroup].str();
|
return smRegexMatches[nCaptureGroup].str();
|
||||||
}
|
}
|
||||||
@ -241,12 +268,12 @@ string CPackedStore::GetNameParts(const string& svDirectoryName, int nCaptureGro
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose: gets the source of the directory file name
|
// Purpose: gets the source of the directory file name
|
||||||
// Input : &svDirectoryName -
|
// Input : &svDirectoryName -
|
||||||
// Output : string
|
// Output : source name as string (e.g. "mp_rr_box")
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
string CPackedStore::GetSourceName(const string& svDirectoryName) const
|
string CPackedStore::GetSourceName(const string& svDirectoryName) const
|
||||||
{
|
{
|
||||||
std::smatch smRegexMatches;
|
std::smatch smRegexMatches;
|
||||||
std::regex_search(svDirectoryName, smRegexMatches, BLOCK_REGEX);
|
std::regex_search(svDirectoryName, smRegexMatches, DIR_REGEX);
|
||||||
|
|
||||||
return smRegexMatches[1].str() + smRegexMatches[2].str();
|
return smRegexMatches[1].str() + smRegexMatches[2].str();
|
||||||
}
|
}
|
||||||
@ -285,7 +312,7 @@ nlohmann::json CPackedStore::GetManifest(const string& svWorkSpace, const string
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose: gets the contents from the global ignore list (.vpkignore)
|
// Purpose: gets the contents from the global ignore list (.vpkignore)
|
||||||
// Input : &svWorkSpace -
|
// Input : &svWorkSpace -
|
||||||
// Output : vector<string>
|
// Output : a string vector of ignored directories/files
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
vector<string> CPackedStore::GetIgnoreList(const string& svWorkSpace) const
|
vector<string> CPackedStore::GetIgnoreList(const string& svWorkSpace) const
|
||||||
{
|
{
|
||||||
@ -317,7 +344,7 @@ vector<string> CPackedStore::GetIgnoreList(const string& svWorkSpace) const
|
|||||||
// Input : svPath -
|
// Input : svPath -
|
||||||
// &svName -
|
// &svName -
|
||||||
// &svExtension -
|
// &svExtension -
|
||||||
// Output : string
|
// Output : formatted entry path
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
string CPackedStore::FormatEntryPath(string svPath, const string& svName, const string& svExtension) const
|
string CPackedStore::FormatEntryPath(string svPath, const string& svName, const string& svExtension) const
|
||||||
{
|
{
|
||||||
@ -331,7 +358,7 @@ string CPackedStore::FormatEntryPath(string svPath, const string& svName, const
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose: strips locale prefix from file path
|
// Purpose: strips locale prefix from file path
|
||||||
// Input : &svDirectoryFile -
|
// Input : &svDirectoryFile -
|
||||||
// Output : string
|
// Output : directory filename without locale prefix
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
string CPackedStore::StripLocalePrefix(const string& svDirectoryFile) const
|
string CPackedStore::StripLocalePrefix(const string& svDirectoryFile) const
|
||||||
{
|
{
|
||||||
@ -355,7 +382,7 @@ string CPackedStore::StripLocalePrefix(const string& svDirectoryFile) const
|
|||||||
// svContext -
|
// svContext -
|
||||||
// &svPakName -
|
// &svPakName -
|
||||||
// nPatch -
|
// nPatch -
|
||||||
// Output : VPKPair_t
|
// Output : a vpk file pair (block and directory file names)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
VPKPair_t CPackedStore::BuildFileName(string svLanguage, string svContext, const string& svPakName, int nPatch) const
|
VPKPair_t CPackedStore::BuildFileName(string svLanguage, string svContext, const string& svPakName, int nPatch) const
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,8 @@ constexpr unsigned int VPK_MINOR_VERSION = 3;
|
|||||||
constexpr unsigned int VPK_DICT_SIZE = 20;
|
constexpr unsigned int VPK_DICT_SIZE = 20;
|
||||||
constexpr int ENTRY_MAX_LEN = 1024 * 1024;
|
constexpr int ENTRY_MAX_LEN = 1024 * 1024;
|
||||||
|
|
||||||
static const std::regex BLOCK_REGEX{ R"((?:.*\/)?([^_]*_)(.*)(.bsp.pak000_dir).*)" };
|
static const std::regex BLOCK_REGEX{ R"(pak000_([0-9]{3}))" };
|
||||||
|
static const std::regex DIR_REGEX{ R"((?:.*\/)?([^_]*_)(.*)(.bsp.pak000_dir).*)" };
|
||||||
|
|
||||||
static const vector<string> DIR_CONTEXT =
|
static const vector<string> DIR_CONTEXT =
|
||||||
{
|
{
|
||||||
@ -142,7 +143,7 @@ public:
|
|||||||
void InitLzCompParams(void);
|
void InitLzCompParams(void);
|
||||||
void InitLzDecompParams(void);
|
void InitLzDecompParams(void);
|
||||||
|
|
||||||
VPKDir_t GetDirectoryFile(string svDirectoryFile) const;
|
VPKDir_t GetDirectoryFile(string svDirectoryFile, bool bSanitizeName) const;
|
||||||
string GetPackFile(const string& svPackDirFile, uint16_t iArchiveIndex) const;
|
string GetPackFile(const string& svPackDirFile, uint16_t iArchiveIndex) const;
|
||||||
lzham_compress_level GetCompressionLevel(void) const;
|
lzham_compress_level GetCompressionLevel(void) const;
|
||||||
|
|
||||||
|
@ -261,20 +261,20 @@ void Pak_RequestUnload_f(const CCommand& args)
|
|||||||
{
|
{
|
||||||
if (args.HasOnlyDigits(1))
|
if (args.HasOnlyDigits(1))
|
||||||
{
|
{
|
||||||
RPakHandle_t pakHandle = std::stoi(args.Arg(1));
|
const RPakHandle_t pakHandle = std::stoi(args.Arg(1));
|
||||||
RPakLoadedInfo_t* pakInfo = g_pRTech->GetPakLoadedInfo(pakHandle);
|
const RPakLoadedInfo_t* pakInfo = g_pRTech->GetPakLoadedInfo(pakHandle);
|
||||||
if (!pakInfo)
|
if (!pakInfo)
|
||||||
{
|
{
|
||||||
throw std::exception("Found no pak entry for specified handle.");
|
throw std::exception("Found no pak entry for specified handle.");
|
||||||
}
|
}
|
||||||
|
|
||||||
string pakName = pakInfo->m_pszFileName;
|
const string pakName = pakInfo->m_pszFileName;
|
||||||
!pakName.empty() ? DevMsg(eDLL_T::RTECH, "Requested pak unload for file '%s'\n", pakName.c_str()) : DevMsg(eDLL_T::RTECH, "Requested pak unload for handle '%d'\n", pakHandle);
|
!pakName.empty() ? DevMsg(eDLL_T::RTECH, "Requested pak unload for file '%s'\n", pakName.c_str()) : DevMsg(eDLL_T::RTECH, "Requested pak unload for handle '%d'\n", pakHandle);
|
||||||
g_pakLoadApi->UnloadPak(pakHandle);
|
g_pakLoadApi->UnloadPak(pakHandle);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RPakLoadedInfo_t* pakInfo = g_pRTech->GetPakLoadedInfo(args.Arg(1));
|
const RPakLoadedInfo_t* pakInfo = g_pRTech->GetPakLoadedInfo(args.Arg(1));
|
||||||
if (!pakInfo)
|
if (!pakInfo)
|
||||||
{
|
{
|
||||||
throw std::exception("Found no pak entry for specified name.");
|
throw std::exception("Found no pak entry for specified name.");
|
||||||
@ -537,7 +537,7 @@ void VPK_Unpack_f(const CCommand& args)
|
|||||||
|
|
||||||
DevMsg(eDLL_T::FS, "*** Starting VPK extraction command for: '%s'\n", pArg);
|
DevMsg(eDLL_T::FS, "*** Starting VPK extraction command for: '%s'\n", pArg);
|
||||||
|
|
||||||
VPKDir_t vpk = g_pPackedStore->GetDirectoryFile(pArg);
|
VPKDir_t vpk = g_pPackedStore->GetDirectoryFile(pArg, (args.ArgC() > 2));
|
||||||
g_pPackedStore->InitLzDecompParams();
|
g_pPackedStore->InitLzDecompParams();
|
||||||
|
|
||||||
std::thread th([&] { g_pPackedStore->UnpackAll(vpk, ConvertToWinPath(fs_packedstore_workspace->GetString())); });
|
std::thread th([&] { g_pPackedStore->UnpackAll(vpk, ConvertToWinPath(fs_packedstore_workspace->GetString())); });
|
||||||
|
Loading…
x
Reference in New Issue
Block a user