Add new RPak types and rename existing

Rename to enforce consistency.
This commit is contained in:
Kawe Mazidjatari 2023-09-19 20:43:01 +02:00
parent 156e31404e
commit 37ab1cfad5
8 changed files with 413 additions and 343 deletions

View File

@ -291,15 +291,15 @@ void Pak_ListPaks_f(const CCommand& args)
for (int16_t i = 0, n = *g_pLoadedPakCount; i < n; ++i) for (int16_t i = 0, n = *g_pLoadedPakCount; i < n; ++i)
{ {
const RPakLoadedInfo_t& info = g_pLoadedPakInfo[i]; const PakLoadedInfo_t& info = g_pLoadedPakInfo[i];
if (info.m_nStatus == RPakStatus_t::PAK_STATUS_FREED) if (info.m_status == EPakStatus::PAK_STATUS_FREED)
continue; continue;
const char* szRpakStatus = g_pRTech->PakStatusToString(info.m_nStatus); const char* szRpakStatus = g_pRTech->PakStatusToString(info.m_status);
// todo: make status into a string from an array/vector // todo: make status into a string from an array/vector
Msg(eDLL_T::RTECH, "| %04i | %-50s | %-36s | %11i |\n", info.m_nHandle, info.m_pszFileName, szRpakStatus, info.m_nAssetCount); Msg(eDLL_T::RTECH, "| %04i | %-50s | %-36s | %11i |\n", info.m_handle, info.m_fileName, szRpakStatus, info.m_assetCount);
nTotalLoaded++; nTotalLoaded++;
} }
Msg(eDLL_T::RTECH, "|------|----------------------------------------------------|--------------------------------------|-------------|\n"); Msg(eDLL_T::RTECH, "|------|----------------------------------------------------|--------------------------------------|-------------|\n");
@ -321,12 +321,12 @@ void Pak_ListTypes_f(const CCommand& args)
for (int8_t i = 0; i < PAK_MAX_TYPES; ++i) for (int8_t i = 0; i < PAK_MAX_TYPES; ++i)
{ {
RPakAssetBinding_t* type = &g_pPakGlobals->m_nAssetBindings[i]; PakAssetBinding_t* type = &g_pPakGlobals->m_assetBindings[i];
if (!type->m_szDescription) if (!type->m_description)
continue; continue;
Msg(eDLL_T::RTECH, "| %-4s | %-25s | %7i | %11i | %11i |\n", FourCCToString(type->m_nExtension).c_str(), type->m_szDescription, type->m_iVersion, type->m_iSubHeaderSize, type->m_iNativeClassSize); Msg(eDLL_T::RTECH, "| %-4s | %-25s | %7i | %11i | %11i |\n", FourCCToString(type->m_extension).c_str(), type->m_description, type->m_version, type->m_subHeaderSize, type->m_nativeClassSize);
nRegistered++; nRegistered++;
} }
Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-------------|-------------|\n"); Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-------------|-------------|\n");
@ -350,27 +350,27 @@ void Pak_RequestUnload_f(const CCommand& args)
{ {
if (args.HasOnlyDigits(1)) if (args.HasOnlyDigits(1))
{ {
const RPakHandle_t pakHandle = atoi(args.Arg(1)); const PakHandle_t pakHandle = atoi(args.Arg(1));
const RPakLoadedInfo_t* pakInfo = g_pRTech->GetPakLoadedInfo(pakHandle); const PakLoadedInfo_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.");
} }
const string pakName = pakInfo->m_pszFileName; const string pakName = pakInfo->m_fileName;
!pakName.empty() ? Msg(eDLL_T::RTECH, "Requested pak unload for file '%s'\n", pakName.c_str()) : Msg(eDLL_T::RTECH, "Requested pak unload for handle '%d'\n", pakHandle); !pakName.empty() ? Msg(eDLL_T::RTECH, "Requested pak unload for file '%s'\n", pakName.c_str()) : Msg(eDLL_T::RTECH, "Requested pak unload for handle '%d'\n", pakHandle);
g_pakLoadApi->UnloadPak(pakHandle); g_pakLoadApi->UnloadPak(pakHandle);
} }
else else
{ {
const RPakLoadedInfo_t* pakInfo = g_pRTech->GetPakLoadedInfo(args.Arg(1)); const PakLoadedInfo_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.");
} }
Msg(eDLL_T::RTECH, "Requested pak unload for file '%s'\n", args.Arg(1)); Msg(eDLL_T::RTECH, "Requested pak unload for file '%s'\n", args.Arg(1));
g_pakLoadApi->UnloadPak(pakInfo->m_nHandle); g_pakLoadApi->UnloadPak(pakInfo->m_handle);
} }
} }
catch (const std::exception& e) catch (const std::exception& e)
@ -401,8 +401,8 @@ void Pak_Swap_f(const CCommand& args)
try try
{ {
string pakName; string pakName;
RPakHandle_t pakHandle = 0; PakHandle_t pakHandle = 0;
RPakLoadedInfo_t* pakInfo = nullptr; PakLoadedInfo_t* pakInfo = nullptr;
if (args.HasOnlyDigits(1)) if (args.HasOnlyDigits(1))
{ {
@ -413,7 +413,7 @@ void Pak_Swap_f(const CCommand& args)
throw std::exception("Found no pak entry for specified handle."); throw std::exception("Found no pak entry for specified handle.");
} }
pakName = pakInfo->m_pszFileName; pakName = pakInfo->m_fileName;
} }
else else
{ {
@ -424,14 +424,14 @@ void Pak_Swap_f(const CCommand& args)
throw std::exception("Found no pak entry for specified name."); throw std::exception("Found no pak entry for specified name.");
} }
pakHandle = pakInfo->m_nHandle; pakHandle = pakInfo->m_handle;
} }
!pakName.empty() ? Msg(eDLL_T::RTECH, "Requested pak swap for file '%s'\n", pakName.c_str()) : Msg(eDLL_T::RTECH, "Requested pak swap for handle '%d'\n", pakHandle); !pakName.empty() ? Msg(eDLL_T::RTECH, "Requested pak swap for file '%s'\n", pakName.c_str()) : Msg(eDLL_T::RTECH, "Requested pak swap for handle '%d'\n", pakHandle);
g_pakLoadApi->UnloadPak(pakHandle); g_pakLoadApi->UnloadPak(pakHandle);
while (pakInfo->m_nStatus != RPakStatus_t::PAK_STATUS_FREED) // Wait till this slot gets free'd. while (pakInfo->m_status != EPakStatus::PAK_STATUS_FREED) // Wait till this slot gets free'd.
std::this_thread::sleep_for(std::chrono::seconds(1)); std::this_thread::sleep_for(std::chrono::seconds(1));
g_pakLoadApi->LoadAsync(pakName.c_str(), AlignedMemAlloc(), NULL, 0); g_pakLoadApi->LoadAsync(pakName.c_str(), AlignedMemAlloc(), NULL, 0);
@ -511,33 +511,33 @@ void RTech_Decompress_f(const CCommand& args)
FileSystem()->Read(pPakBuf, nPakLen, hPakFile); FileSystem()->Read(pPakBuf, nPakLen, hPakFile);
FileSystem()->Close(hPakFile); FileSystem()->Close(hPakFile);
RPakHeader_t* pHeader = reinterpret_cast<RPakHeader_t*>(pPakBuf); PakFileHeader_t* pHeader = reinterpret_cast<PakFileHeader_t*>(pPakBuf);
uint16_t flags = (pHeader->m_nFlags[0] << 8) | pHeader->m_nFlags[1]; uint16_t flags = (pHeader->m_flags[0] << 8) | pHeader->m_flags[1];
SYSTEMTIME systemTime; SYSTEMTIME systemTime;
FileTimeToSystemTime(&pHeader->m_nFileTime, &systemTime); FileTimeToSystemTime(&pHeader->m_fileTime, &systemTime);
Msg(eDLL_T::RTECH, " | |-+ Header ------------------------------------------------\n"); Msg(eDLL_T::RTECH, " | |-+ Header ------------------------------------------------\n");
Msg(eDLL_T::RTECH, " | |-- Magic : '0x%08X'\n", pHeader->m_nMagic); Msg(eDLL_T::RTECH, " | |-- Magic : '0x%08X'\n", pHeader->m_magic);
Msg(eDLL_T::RTECH, " | |-- Version : '%hu'\n", pHeader->m_nVersion); Msg(eDLL_T::RTECH, " | |-- Version : '%hu'\n", pHeader->m_version);
Msg(eDLL_T::RTECH, " | |-- Flags : '0x%04hX'\n", flags); Msg(eDLL_T::RTECH, " | |-- Flags : '0x%04hX'\n", flags);
Msg(eDLL_T::RTECH, " | |-- Time : '%hu-%hu-%hu/%hu %hu:%hu:%hu.%hu'\n", Msg(eDLL_T::RTECH, " | |-- Time : '%hu-%hu-%hu/%hu %hu:%hu:%hu.%hu'\n",
systemTime.wYear,systemTime.wMonth,systemTime.wDay, systemTime.wDayOfWeek, systemTime.wYear,systemTime.wMonth,systemTime.wDay, systemTime.wDayOfWeek,
systemTime.wHour, systemTime.wMinute, systemTime.wSecond, systemTime.wMilliseconds); systemTime.wHour, systemTime.wMinute, systemTime.wSecond, systemTime.wMilliseconds);
Msg(eDLL_T::RTECH, " | |-- Hash : '0x%08llX'\n", pHeader->m_nHash); Msg(eDLL_T::RTECH, " | |-- Hash : '0x%08llX'\n", pHeader->m_checksum);
Msg(eDLL_T::RTECH, " | |-- Entries : '%u'\n", pHeader->m_nAssetEntryCount); Msg(eDLL_T::RTECH, " | |-- Entries : '%u'\n", pHeader->m_assetEntryCount);
Msg(eDLL_T::RTECH, " | |-+ Compression -----------------------------------------\n"); Msg(eDLL_T::RTECH, " | |-+ Compression -----------------------------------------\n");
Msg(eDLL_T::RTECH, " | |-- Size comp: '%zu'\n", pHeader->m_nSizeDisk); Msg(eDLL_T::RTECH, " | |-- Size comp: '%zu'\n", pHeader->m_compressedSize);
Msg(eDLL_T::RTECH, " | |-- Size decp: '%zu'\n", pHeader->m_nSizeMemory); Msg(eDLL_T::RTECH, " | |-- Size decp: '%zu'\n", pHeader->m_decompressedSize);
if (pHeader->m_nMagic != PAK_HEADER_MAGIC) if (pHeader->m_magic != PAK_HEADER_MAGIC)
{ {
Error(eDLL_T::RTECH, NO_ERROR, "%s - pak file '%s' has invalid magic!\n", Error(eDLL_T::RTECH, NO_ERROR, "%s - pak file '%s' has invalid magic!\n",
__FUNCTION__, inPakFile.String()); __FUNCTION__, inPakFile.String());
return; return;
} }
if ((pHeader->m_nFlags[1] & 1) != 1) if ((pHeader->m_flags[1] & 1) != 1)
{ {
Error(eDLL_T::RTECH, NO_ERROR, "%s - pak file '%s' already decompressed!\n", Error(eDLL_T::RTECH, NO_ERROR, "%s - pak file '%s' already decompressed!\n",
__FUNCTION__, inPakFile.String()); __FUNCTION__, inPakFile.String());
@ -547,21 +547,21 @@ void RTech_Decompress_f(const CCommand& args)
const size_t unsignedPakLen = static_cast<size_t>(nPakLen); const size_t unsignedPakLen = static_cast<size_t>(nPakLen);
if (pHeader->m_nSizeDisk != unsignedPakLen) if (pHeader->m_compressedSize != unsignedPakLen)
{ {
Error(eDLL_T::RTECH, NO_ERROR, "%s - pak file '%s' decompressed size '%zu' doesn't match expected size '%zu'!\n", Error(eDLL_T::RTECH, NO_ERROR, "%s - pak file '%s' decompressed size '%zu' doesn't match expected size '%zu'!\n",
__FUNCTION__, inPakFile.String(), unsignedPakLen, pHeader->m_nSizeMemory); __FUNCTION__, inPakFile.String(), unsignedPakLen, pHeader->m_decompressedSize);
return; return;
} }
RPakDecompState_t decompState; PakDecompState_t decompState;
const uint64_t nDecompSize = g_pRTech->DecompressPakFileInit(&decompState, pPakBuf, unsignedPakLen, NULL, sizeof(RPakHeader_t)); const uint64_t nDecompSize = g_pRTech->DecompressPakFileInit(&decompState, pPakBuf, unsignedPakLen, NULL, sizeof(PakFileHeader_t));
if (nDecompSize == pHeader->m_nSizeDisk) if (nDecompSize == pHeader->m_compressedSize)
{ {
Error(eDLL_T::RTECH, NO_ERROR, "%s - calculated size: '%llu' expected: '%llu'!\n", Error(eDLL_T::RTECH, NO_ERROR, "%s - calculated size: '%llu' expected: '%llu'!\n",
__FUNCTION__, nDecompSize, pHeader->m_nSizeMemory); __FUNCTION__, nDecompSize, pHeader->m_decompressedSize);
return; return;
} }
@ -570,24 +570,24 @@ void RTech_Decompress_f(const CCommand& args)
Msg(eDLL_T::RTECH, " | |-- Size calc: '%llu'\n", nDecompSize); Msg(eDLL_T::RTECH, " | |-- Size calc: '%llu'\n", nDecompSize);
} }
Msg(eDLL_T::RTECH, " | |-- Ratio : '%.02f'\n", (pHeader->m_nSizeDisk * 100.f) / pHeader->m_nSizeMemory); Msg(eDLL_T::RTECH, " | |-- Ratio : '%.02f'\n", (pHeader->m_compressedSize * 100.f) / pHeader->m_decompressedSize);
std::unique_ptr<uint8_t[]> pDecompBufContainer(new uint8_t[nPakLen]); std::unique_ptr<uint8_t[]> pDecompBufContainer(new uint8_t[nPakLen]);
uint8_t* const pDecompBuf = pDecompBufContainer.get(); uint8_t* const pDecompBuf = pDecompBufContainer.get();
decompState.m_nOutMask = UINT64_MAX; decompState.m_outputMask = UINT64_MAX;
decompState.m_nOut = uint64_t(pDecompBuf); decompState.m_outputBuf = uint64_t(pDecompBuf);
uint8_t nDecompResult = g_pRTech->DecompressPakFile(&decompState, unsignedPakLen, pHeader->m_nSizeMemory); uint8_t nDecompResult = g_pRTech->DecompressPakFile(&decompState, unsignedPakLen, pHeader->m_decompressedSize);
if (nDecompResult != 1) if (nDecompResult != 1)
{ {
Error(eDLL_T::RTECH, NO_ERROR, "%s - decompression failed for '%s' return value: '%hu'!\n", Error(eDLL_T::RTECH, NO_ERROR, "%s - decompression failed for '%s' return value: '%hu'!\n",
__FUNCTION__, inPakFile.String(), nDecompResult); __FUNCTION__, inPakFile.String(), nDecompResult);
} }
pHeader->m_nFlags[1] = 0x0; // Set compressed flag to false for the decompressed pak file. pHeader->m_flags[1] = 0x0; // Set compressed flag to false for the decompressed pak file.
pHeader->m_nSizeDisk = pHeader->m_nSizeMemory; // Equal compressed size with decompressed. pHeader->m_compressedSize = pHeader->m_decompressedSize; // Equal compressed size with decompressed.
FileSystem()->CreateDirHierarchy(PLATFORM_PAK_OVERRIDE_PATH, "GAME"); FileSystem()->CreateDirHierarchy(PLATFORM_PAK_OVERRIDE_PATH, "GAME");
FileHandle_t hDecompFile = FileSystem()->Open(outPakFile.String(), "wb", "GAME"); FileHandle_t hDecompFile = FileSystem()->Open(outPakFile.String(), "wb", "GAME");
@ -600,25 +600,25 @@ void RTech_Decompress_f(const CCommand& args)
return; return;
} }
if (pHeader->m_nPatchIndex > 0) // Check if its an patch rpak. if (pHeader->m_patchIndex > 0) // Check if its an patch rpak.
{ {
// Loop through all the structs and patch their compress size. // Loop through all the structs and patch their compress size.
for (uint32_t i = 1, nPatchOffset = (sizeof(RPakHeader_t) + sizeof(uint64_t)); for (uint32_t i = 1, nPatchOffset = (sizeof(PakFileHeader_t) + sizeof(uint64_t));
i <= pHeader->m_nPatchIndex; i++, nPatchOffset += sizeof(RPakPatchCompressedHeader_t)) i <= pHeader->m_patchIndex; i++, nPatchOffset += sizeof(PakPatchFileHeader_t))
{ {
RPakPatchCompressedHeader_t* pPatchHeader = reinterpret_cast<RPakPatchCompressedHeader_t*>(pDecompBuf + nPatchOffset); PakPatchFileHeader_t* pPatchHeader = reinterpret_cast<PakPatchFileHeader_t*>(pDecompBuf + nPatchOffset);
Msg(eDLL_T::RTECH, " | |-+ Patch #%02u -----------------------------------------\n", i); Msg(eDLL_T::RTECH, " | |-+ Patch #%02u -----------------------------------------\n", i);
Msg(eDLL_T::RTECH, " | %s |-- Size comp: '%llu'\n", i < pHeader->m_nPatchIndex ? "|" : " ", pPatchHeader->m_nSizeDisk); Msg(eDLL_T::RTECH, " | %s |-- Size comp: '%llu'\n", i < pHeader->m_patchIndex ? "|" : " ", pPatchHeader->sizeDisk);
Msg(eDLL_T::RTECH, " | %s |-- Size decp: '%llu'\n", i < pHeader->m_nPatchIndex ? "|" : " ", pPatchHeader->m_nSizeMemory); Msg(eDLL_T::RTECH, " | %s |-- Size decp: '%llu'\n", i < pHeader->m_patchIndex ? "|" : " ", pPatchHeader->sizeMemory);
pPatchHeader->m_nSizeDisk = pPatchHeader->m_nSizeMemory; // Fix size for decompress. pPatchHeader->sizeDisk = pPatchHeader->sizeMemory; // Fix size for decompress.
} }
} }
memcpy_s(pDecompBuf, sizeof(RPakHeader_t), pPakBuf, sizeof(RPakHeader_t));// Overwrite first 0x80 bytes which are NULL with the header data. memcpy_s(pDecompBuf, sizeof(PakFileHeader_t), pPakBuf, sizeof(PakFileHeader_t));// Overwrite first 0x80 bytes which are NULL with the header data.
FileSystem()->Write(pDecompBuf, decompState.m_nDecompSize, hDecompFile); FileSystem()->Write(pDecompBuf, decompState.m_decompSize, hDecompFile);
Msg(eDLL_T::RTECH, " |-- Checksum : '0x%08X'\n", crc32::update(NULL, pDecompBuf, decompState.m_nDecompSize)); Msg(eDLL_T::RTECH, " |-- Checksum : '0x%08X'\n", crc32::update(NULL, pDecompBuf, decompState.m_decompSize));
Msg(eDLL_T::RTECH, "-+ Decompressed pak file to: '%s'\n", outPakFile.String()); Msg(eDLL_T::RTECH, "-+ Decompressed pak file to: '%s'\n", outPakFile.String());
Msg(eDLL_T::RTECH, "--------------------------------------------------------------\n"); Msg(eDLL_T::RTECH, "--------------------------------------------------------------\n");

View File

@ -240,28 +240,28 @@ void Mod_ProcessPakQueue()
{ {
// SDK pak files must be unloaded before the engine pak files, // SDK pak files must be unloaded before the engine pak files,
// as we reference assets within engine pak files. // as we reference assets within engine pak files.
const RPakLoadedInfo_t* pLoadedPakInfo = g_pRTech->GetPakLoadedInfo(*(RPakHandle_t*)v10); const PakLoadedInfo_t* pLoadedPakInfo = g_pRTech->GetPakLoadedInfo(*(PakHandle_t*)v10);
if (pLoadedPakInfo) if (pLoadedPakInfo)
{ {
const char* pszLoadedPakName = pLoadedPakInfo->m_pszFileName; const char* pszLoadedPakName = pLoadedPakInfo->m_fileName;
if (strcmp(pszLoadedPakName, "common_mp.rpak") == 0 || if (strcmp(pszLoadedPakName, "common_mp.rpak") == 0 ||
strcmp(pszLoadedPakName, "common_sp.rpak") == 0 || strcmp(pszLoadedPakName, "common_sp.rpak") == 0 ||
strcmp(pszLoadedPakName, "common_pve.rpak") == 0) strcmp(pszLoadedPakName, "common_pve.rpak") == 0)
{ {
const RPakLoadedInfo_t* pLoadedSdkPak = g_pRTech->GetPakLoadedInfo("common_sdk.rpak"); const PakLoadedInfo_t* pLoadedSdkPak = g_pRTech->GetPakLoadedInfo("common_sdk.rpak");
if (pLoadedSdkPak) // Only unload if sdk pak file is loaded. if (pLoadedSdkPak) // Only unload if sdk pak file is loaded.
g_pakLoadApi->UnloadPak(pLoadedSdkPak->m_nHandle); g_pakLoadApi->UnloadPak(pLoadedSdkPak->m_handle);
} }
#ifndef DEDICATED #ifndef DEDICATED
else if (strcmp(pszLoadedPakName, "ui_mp.rpak") == 0) else if (strcmp(pszLoadedPakName, "ui_mp.rpak") == 0)
{ {
const RPakLoadedInfo_t* pLoadedSdkPak = g_pRTech->GetPakLoadedInfo("ui_sdk.rpak"); const PakLoadedInfo_t* pLoadedSdkPak = g_pRTech->GetPakLoadedInfo("ui_sdk.rpak");
if (pLoadedSdkPak) // Only unload if sdk pak file is loaded. if (pLoadedSdkPak) // Only unload if sdk pak file is loaded.
g_pakLoadApi->UnloadPak(pLoadedSdkPak->m_nHandle); g_pakLoadApi->UnloadPak(pLoadedSdkPak->m_handle);
} }
#endif // !DEDICATED #endif // !DEDICATED
} }
@ -278,7 +278,7 @@ void Mod_ProcessPakQueue()
if (old_gather_props->GetBool()) if (old_gather_props->GetBool())
old_gather_props->SetValue(false); old_gather_props->SetValue(false);
g_pakLoadApi->UnloadPak(*(RPakHandle_t*)v10); g_pakLoadApi->UnloadPak(*(PakHandle_t*)v10);
Mod_UnloadPakFile(); // Unload mod pak files. Mod_UnloadPakFile(); // Unload mod pak files.
if (s_pLevelSetKV) if (s_pLevelSetKV)
@ -455,7 +455,7 @@ void Mod_PreloadLevelPaks(const char* pszLevelName)
continue; continue;
snprintf(szPathBuffer, sizeof(szPathBuffer), "%s.rpak", pSubKey->GetName()); snprintf(szPathBuffer, sizeof(szPathBuffer), "%s.rpak", pSubKey->GetName());
RPakHandle_t nPakId = g_pakLoadApi->LoadAsync(szPathBuffer, AlignedMemAlloc(), 4, 0); PakHandle_t nPakId = g_pakLoadApi->LoadAsync(szPathBuffer, AlignedMemAlloc(), 4, 0);
if (nPakId == INVALID_PAK_HANDLE) if (nPakId == INVALID_PAK_HANDLE)
Error(eDLL_T::ENGINE, NO_ERROR, "%s: unable to load pak '%s' results '%d'\n", __FUNCTION__, szPathBuffer, nPakId); Error(eDLL_T::ENGINE, NO_ERROR, "%s: unable to load pak '%s' results '%d'\n", __FUNCTION__, szPathBuffer, nPakId);
@ -469,7 +469,7 @@ void Mod_PreloadLevelPaks(const char* pszLevelName)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Mod_UnloadPakFile(void) void Mod_UnloadPakFile(void)
{ {
for (const RPakHandle_t& it : g_vLoadedPakHandle) for (const PakHandle_t& it : g_vLoadedPakHandle)
{ {
if (it >= 0) if (it >= 0)
{ {

View File

@ -22,7 +22,7 @@ InitReturnVal_t CMaterialSystem::Init(CMaterialSystem* thisptr)
#ifdef MATERIALSYSTEM_NODX #ifdef MATERIALSYSTEM_NODX
// Only load the 'startup.rpak' file, as 'common_early.rpak' has assets // Only load the 'startup.rpak' file, as 'common_early.rpak' has assets
// that references assets in 'startup.rpak'. // that references assets in 'startup.rpak'.
RPakHandle_t pakHandle = g_pakLoadApi->LoadAsync("startup.rpak", AlignedMemAlloc(), 5, 0); PakHandle_t pakHandle = g_pakLoadApi->LoadAsync("startup.rpak", AlignedMemAlloc(), 5, 0);
g_pakLoadApi->WaitAsync(pakHandle, nullptr); g_pakLoadApi->WaitAsync(pakHandle, nullptr);
// Trick: return INIT_FAILED to disable the loading of hardware // Trick: return INIT_FAILED to disable the loading of hardware

View File

@ -9,9 +9,14 @@
#define PAK_MAX_TYPES 64 #define PAK_MAX_TYPES 64
#define PAK_HEADER_MAGIC (('k'<<24)+('a'<<16)+('P'<<8)+'R') #define PAK_HEADER_MAGIC (('k'<<24)+('a'<<16)+('P'<<8)+'R')
typedef int RPakHandle_t; //-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
struct PakFile_t;
enum class RPakStatus_t : int32_t typedef int PakHandle_t;
enum class EPakStatus : int32_t
{ {
PAK_STATUS_FREED = 0, PAK_STATUS_FREED = 0,
PAK_STATUS_LOAD_PENDING = 1, PAK_STATUS_LOAD_PENDING = 1,
@ -31,134 +36,147 @@ enum class RPakStatus_t : int32_t
PAK_STATUS_BUSY = 15 PAK_STATUS_BUSY = 15
}; };
struct RPakAssetBinding_t struct PakAssetBinding_t
{ {
uint32_t m_nExtension; // For example '0x6C74616D' for the material asset. uint32_t m_extension; // For example '0x6C74616D' for the material asset.
int m_iVersion; int m_version;
const char* m_szDescription; // Description/Name of asset. const char* m_description; // Description/Name of asset.
void* m_pLoadAssetFunction; void* m_loadAssetFunction;
void* m_pUnloadAssetFunction; void* m_unloadAssetFunction;
void* m_pReplaceAssetFunction; void* m_replaceAssetFunction;
void* m_pAllocAssetFunctions; void* m_allocAssetFunctions;
int m_iSubHeaderSize; int m_subHeaderSize;
int m_iNativeClassSize; // Native class size, for 'material' it would be CMaterialGlue full size. int m_nativeClassSize; // Native class size, for 'material' it would be CMaterialGlue full size.
uint32_t m_HeaderAlignment; uint32_t m_headerAlignment;
int unk3; int unk3;
// [ PIXIE ]: Should be the full size across Season 0-3. // [ PIXIE ]: Should be the full size across Season 0-3.
}; };
struct RPakAssetEntry_t struct PakAsset_t
{ {
uint64_t m_Guid; uint64_t m_guid;
uint64_t m_Padding; uint64_t m_padding;
uint32_t m_nHeadPageIdx; uint32_t m_headPageIdx;
uint32_t m_nHeadPageOffset; uint32_t m_headPageOffset;
uint32_t m_nCpuPageIdx; uint32_t m_cpuPageIdx;
uint32_t m_nCpuPageOffset; uint32_t m_cpuPageOffset;
uint64_t m_nStarpakOffset; uint64_t m_starpakOffset;
uint64_t m_nStarpakOptOffset; uint64_t m_starpakOptOffset;
uint16_t m_nPageEnd; uint16_t m_pageEnd;
uint16_t unk1; uint16_t unk1;
uint32_t m_nRelationsStartIdx; uint32_t m_relationsStartIdx;
uint32_t m_nUsesStartIdx; uint32_t m_usesStartIdx;
uint32_t m_nRelationsCount; uint32_t m_relationsCount;
uint32_t m_nUsesCount; uint32_t m_usesCount;
uint32_t m_nAssetHeaderSize; uint32_t m_assetHeaderSize;
uint32_t m_nVersion; uint32_t m_version;
uint32_t m_nMagic; uint32_t m_magic;
}; };
struct RPakAssetEntryShort struct PakAssetShort_t
{ {
uint64_t m_Guid; uint64_t m_guid;
uint64_t m_Padding; uint64_t m_padding;
void* m_pHead; void* m_head;
void* m_pCpu; void* m_cpu;
}; };
struct RPakGlobals_t struct PakGlobals_t
{ {
RPakAssetBinding_t m_nAssetBindings[64]; // [ PIXIE ]: Max possible registered assets on Season 3, 0-2 I did not check yet. PakAssetBinding_t m_assetBindings[64]; // [ PIXIE ]: Max possible registered assets on Season 3, 0-2 I did not check yet.
RPakAssetEntryShort m_Assets[0x40000]; PakAssetShort_t m_assets[0x40000];
// End size unknown. // End size unknown.
}; };
struct RPakHeader_t struct PakFileHeader_t
{ {
uint32_t m_nMagic; // 'RPak' uint32_t m_magic; // 'RPak'
uint16_t m_nVersion; // R2 = '7' R5 = '8' uint16_t m_version; // R2 = '7' R5 = '8'
uint8_t m_nFlags[0x2]; // uint8_t m_flags[0x2]; //
FILETIME m_nFileTime; // FILETIME m_fileTime; //
uint64_t m_nHash; // uint64_t m_checksum; //
uint64_t m_nSizeDisk; // Compressed size uint64_t m_compressedSize; // Compressed size
uint64_t m_nEmbeddedStarpakOffset; // uint64_t m_embeddedStarpakOffset; //
uint8_t unk0[0x8]; // uint8_t unk0[0x8]; //
uint64_t m_nSizeMemory; // Decompressed size uint64_t m_decompressedSize; // Decompressed size
uint64_t m_nEmbeddedStarpakSize; // uint64_t m_embeddedStarpakSize; //
uint8_t unk1[0x8]; // uint8_t unk1[0x8]; //
uint16_t m_nStarpakReferenceSize; // uint16_t m_starpakReferenceSize; //
uint16_t m_nStarpakOptReferenceSize; // uint16_t m_starpakOptReferenceSize; //
uint16_t m_nVirtualSegmentCount; // * 0x10 uint16_t m_virtualSegmentCount; // * 0x10
uint16_t m_nMemPageCount; // * 0xC uint16_t m_memPageCount; // * 0xC
uint32_t m_nPatchIndex; // uint32_t m_patchIndex; //
uint32_t m_nDescriptorCount; // uint32_t m_descriptorCount; //
uint32_t m_nAssetEntryCount; // File entry count uint32_t m_assetEntryCount; // File entry count
uint32_t m_nGuidDescriptorCount; // uint32_t m_guidDescriptorCount; //
uint32_t m_nRelationsCounts; // uint32_t m_relationsCounts; //
uint8_t unk2[0x10]; // uint8_t unk2[0x10]; //
uint32_t m_nMemPageOffset; // Size not verified. Offsets every page by x amount, if not 0 start of first page has data corresponding for 'patching some page' uint32_t m_memPageOffset; // Size not verified. Offsets every page by x amount, if not 0 start of first page has data corresponding for 'patching some page'
uint8_t unk3[0x8]; // uint8_t unk3[0x8]; //
}; };
struct RPakPatchCompressedHeader_t struct PakPatchFileHeader_t
{ {
uint64_t m_nSizeDisk; size_t m_sizeDisk;
uint64_t m_nSizeMemory; size_t m_sizeMemory;
}; };
struct RPakDecompState_t struct PakPatchDataHeader_t
{ {
uint64_t m_nInputBuf; int m_editStreamSize;
uint64_t m_nOut; int m_pageCount;
uint64_t m_nMask; };
uint64_t m_nOutMask;
uint64_t m_nTotalFileLen; struct PakSegmentHeader_t
uint64_t m_nDecompSize; {
uint64_t m_nInvMaskIn; int m_flags;
uint64_t m_nInvMaskOut; int m_align;
uint32_t m_nHeaderOffset; size_t m_size;
};
struct PakDecompState_t
{
uint64_t m_inputBuf;
uint64_t m_outputBuf;
uint64_t m_inputMask;
uint64_t m_outputMask;
uint64_t m_fileSize;
uint64_t m_decompSize;
uint64_t m_inputInvMask;
uint64_t m_outputInvMask;
uint32_t m_headerOffset;
uint32_t dword44; uint32_t dword44;
uint64_t m_nInputBytePos; uint64_t m_fileBytePosition;
uint64_t m_nDecompPosition; uint64_t m_decompBytePosition;
uint64_t m_nLengthNeeded; uint64_t m_bufferSizeNeeded;
uint64_t byte; uint64_t m_currentByte;
uint32_t m_nByteBitOffset; uint32_t m_currentByteBit;
uint32_t dword6C; uint32_t dword6C;
uint64_t qword70; uint64_t qword70;
uint64_t m_nCompressedStreamSize; uint64_t m_compressedStreamSize;
uint64_t m_nDecompStreamSize; uint64_t m_decompStreamSize;
}; };
class RPakLoadedInfo_t class PakLoadedInfo_t
{ {
public: public:
RPakHandle_t m_nHandle; //0x0000 PakHandle_t m_handle; //0x0000
RPakStatus_t m_nStatus; //0x0004 EPakStatus m_status; //0x0004
uint64_t m_nUnk1; //0x0008 uint64_t m_nUnk1; //0x0008
uint32_t m_nUnk2; //0x0010 uint32_t m_nUnk2; //0x0010
uint32_t m_nAssetCount; //0x0014 uint32_t m_assetCount; //0x0014
char* m_pszFileName; //0x0018 char* m_fileName; //0x0018
void* m_pMalloc; //0x0020 void* m_allocator; //0x0020
uint64_t* m_pAssetGuids; //0x0028 size of the array is m_nAssetCount uint64_t* m_assetGuids; //0x0028 size of the array is m_nAssetCount
#if defined (GAMEDLL_S3) #if defined (GAMEDLL_S3)
void* m_pVSegBuffers[4]; //0x0030 void* m_virtualSegmentBuffers[4]; //0x0030
char pad_0050[16]; //0x0050 char pad_0050[16]; //0x0050
void* m_pPakInfo; //0x0060 void* m_pakInfo; //0x0060
RPakLoadedInfo_t* m_pUnknownLoadedPakInfo; //0x0068 PakLoadedInfo_t* m_pUnknownLoadedPakInfo; //0x0068
char pad_0070[4]; //0x0070 char pad_0070[4]; //0x0070
int8_t m_nUnk3; //0x0074 int8_t m_nUnk3; //0x0074
char pad_0075[51]; //0x0075 char pad_0075[51]; //0x0075
@ -172,76 +190,128 @@ public:
uint64_t m_nUnkEnd; //0x00B0/0x00E8 uint64_t m_nUnkEnd; //0x00B0/0x00E8
}; //Size: 0x00B8/0x00E8 }; //Size: 0x00B8/0x00E8
struct RPakDescriptor_t struct PakPage_t
{ {
uint32_t m_Index; uint32_t m_index;
uint32_t m_Offset; uint32_t m_offset;
}; };
struct RPakMemPageInfo_t struct PakPageHeader_t
{ {
uint32_t m_nVirtualSegmentIndex; uint32_t m_virtualSegmentIndex;
uint32_t m_nPageAlignment; uint32_t m_pageAlignment;
uint32_t m_nDataSize; uint32_t m_dataSize;
}; };
struct RPakVirtualSegment_t struct PakFileStream_t
{ {
uint32_t m_nFlags; _QWORD qword0;
uint32_t m_nAlignment; _QWORD qword8;
uint64_t m_nDataSize; _DWORD fileHandle;
_DWORD gap14[32];
_BYTE gap94[32];
unsigned int unsigned_intB4;
_DWORD dwordB8;
_BYTE byteBC;
_BYTE byteBD;
_BYTE gapBE;
_BYTE byteBF;
_BYTE gapC0[256];
uint8_t* buffer;
_QWORD qword1C8;
_QWORD qword1D0;
}; };
struct PakFile_t // !TODO: Map out on S1 and S2! #pragma pack(push, 4)
struct RBitRead // TODO: move to own file?
{ {
int m_nDescCount; uint64_t m_dataBuf;
int m_nProcessedAssetCount; int m_bitsRemaining;
int m_nPageEnd; };
int m_nPageStart; #pragma pack(pop)
uint32_t m_nPatchIndex_maybe;
struct PakMemoryData_t
{
uint64_t m_processedPatchedDataSize;
char* m_patchData;
uint64_t m_patchDataPtr;
RBitRead m_bitBuf;
uint32_t m_patchDataOffset;
_BYTE patchCommands[64];
_BYTE PATCH_field_68[64];
_BYTE PATCH_unk2[256];
_BYTE PATCH_unk3[256];
_QWORD field_2A8;
size_t m_patchSrcSize;
char* m_patchDstPtr;
__int64 m_numBytesToProcess_maybe;
unsigned __int8(__fastcall* patchFunc)(PakFile_t*, unsigned __int64*);
uint64_t qword2D0;
uint64_t qword2D8;
int* qword2E0;
uint8_t** m_pagePointers;
PakPatchFileHeader_t* m_patchHeaders;
uint64_t UnkPatchIndexes;
char* m_streamingFilePaths;
char* m_optStreamingFilePaths;
PakSegmentHeader_t* m_segmentHeaders;
PakPageHeader_t* m_pageHeaders;
PakPage_t* m_virtualPointers;
PakAsset_t* m_assetEntries;
PakPage_t* m_guidDescriptors;
uint32_t* m_fileRelations;
char gap5E0[32];
PakPatchDataHeader_t* m_patchDataHeader;
PakAsset_t** m_ppAssetEntries;
_BYTE gap370[520];
const char* m_fileName;
PakFileHeader_t m_pakHeader;
};
struct PakFile_t
{
int m_numPointers;
int m_numAssets;
int m_pageCount;
int m_pageStart;
uint32_t m_patchCount;
uint32_t dword14; uint32_t dword14;
char gap18[184];
PakFileStream_t* m_fileStream;
size_t m_compressSize;
int m_fileHandle;
_BYTE gap2c[164];
uint32_t unsigned_intD0; uint32_t unsigned_intD0;
char gapD4[284]; char gapD4[284];
uint64_t m_nInputBytePos; uint64_t m_inputBytePos;
uint8_t byte1F8; uint8_t byte1F8;
char gap1F9[4]; char gap1F9[4];
uint8_t byte1FD; uint8_t byte1FD;
uint8_t byte1FE; short flags_1FE;
uint8_t byte200; PakDecompState_t m_pakDecompState;
RPakDecompState_t m_PakDecompState; void* m_decompBuffer;
uint64_t qword288; size_t m_maxCopySize;
uint64_t qword290;
uint64_t qword298; uint64_t qword298;
uint64_t qword2A0;
char* m_PatchData; PakMemoryData_t m_memoryData;
char gap2B0[696];
unsigned __int8(__fastcall* pfunc568)(__int64, LARGE_INTEGER*, unsigned __int64);
uint64_t qword570;
uint64_t qword578;
int* qword580;
uint8_t** m_ppPagePointers;
void* m_pPatchCompressPairs;
uint64_t qword598;
char* m_pszStreamingFilePaths;
char* m_pszOptStreamingFilePaths;
void* m_pVirtualSegments;
RPakMemPageInfo_t* m_pMemPages;
RPakDescriptor_t* m_pVirtualPointers;
RPakAssetEntry_t* m_pAssetEntries;
RPakDescriptor_t* m_pGuidDescriptors;
uint32_t* m_pFileRelations;
char gap5E0[40];
RPakAssetEntry_t** m_ppAssetEntries;
char gap610[256];
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) // TODO: needs to be checked.
char gap710[256];
#if !defined (GAMEDLL_S2)
char gap810[8];
#endif // !(GAMEDLL_S0) || !(GAMEDLL_S1) || !(GAMEDLL_S2)
#endif
const char* m_pszFileName;
RPakHeader_t m_PakHdr;
}; };
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) #if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
@ -254,7 +324,7 @@ static_assert(sizeof(PakFile_t) == 2200); // S2
static_assert(sizeof(PakFile_t) == 1944); // S0/S1 static_assert(sizeof(PakFile_t) == 1944); // S0/S1
#endif // !GAMEDLL_S0 && !GAMEDLL_S1 #endif // !GAMEDLL_S0 && !GAMEDLL_S1
static_assert(sizeof(RPakDecompState_t) == 136); static_assert(sizeof(PakDecompState_t) == 136);
static_assert(sizeof(RPakPatchCompressedHeader_t) == 16); static_assert(sizeof(PakPatchFileHeader_t) == 16);
#endif // RTECH_IPACKFILE_H #endif // RTECH_IPACKFILE_H

View File

@ -14,7 +14,7 @@
// from within the level settings KV (located in // from within the level settings KV (located in
// scripts/levels/settings/*.kv). On level unload, // scripts/levels/settings/*.kv). On level unload,
// each pak listed in this vector gets unloaded. // each pak listed in this vector gets unloaded.
CUtlVector<RPakHandle_t> g_vLoadedPakHandle; CUtlVector<PakHandle_t> g_vLoadedPakHandle;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: load user-requested pak files on-demand // Purpose: load user-requested pak files on-demand
@ -24,9 +24,9 @@ CUtlVector<RPakHandle_t> g_vLoadedPakHandle;
// bUnk - // bUnk -
// Output : pak file handle on success, INVALID_PAK_HANDLE on failure // Output : pak file handle on success, INVALID_PAK_HANDLE on failure
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
RPakHandle_t Pak_LoadAsync(const char* szPakFileName, CAlignedMemAlloc* pMalloc, int nIdx, bool bUnk) PakHandle_t Pak_LoadAsync(const char* szPakFileName, CAlignedMemAlloc* pMalloc, int nIdx, bool bUnk)
{ {
RPakHandle_t pakHandle = INVALID_PAK_HANDLE; PakHandle_t pakHandle = INVALID_PAK_HANDLE;
CUtlString pakBasePath; CUtlString pakBasePath;
CUtlString pakOverridePath; CUtlString pakOverridePath;
@ -56,15 +56,15 @@ RPakHandle_t Pak_LoadAsync(const char* szPakFileName, CAlignedMemAlloc* pMalloc,
// Purpose: unloads loaded pak files // Purpose: unloads loaded pak files
// Input : handle - // Input : handle -
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Pak_UnloadPak(RPakHandle_t handle) void Pak_UnloadPak(PakHandle_t handle)
{ {
RPakLoadedInfo_t* pakInfo = g_pRTech->GetPakLoadedInfo(handle); PakLoadedInfo_t* pakInfo = g_pRTech->GetPakLoadedInfo(handle);
if (pakInfo && pakInfo->m_pszFileName) if (pakInfo && pakInfo->m_fileName)
{ {
Msg(eDLL_T::RTECH, "Unloading pak file: '%s'\n", pakInfo->m_pszFileName); Msg(eDLL_T::RTECH, "Unloading pak file: '%s'\n", pakInfo->m_fileName);
if (strcmp(pakInfo->m_pszFileName, "mp_lobby.rpak") == 0) if (strcmp(pakInfo->m_fileName, "mp_lobby.rpak") == 0)
s_bBasePaksInitialized = false; s_bBasePaksInitialized = false;
} }

View File

@ -5,34 +5,34 @@
/* ==== RTECH_GAME ====================================================================================================================================================== */ /* ==== RTECH_GAME ====================================================================================================================================================== */
inline CMemory p_Pak_LoadAsync; inline CMemory p_Pak_LoadAsync;
inline RPakHandle_t(*v_Pak_LoadAsync)(const char* szPakFileName, CAlignedMemAlloc* pMalloc, int nIdx, bool bUnk); inline PakHandle_t(*v_Pak_LoadAsync)(const char* szPakFileName, CAlignedMemAlloc* pMalloc, int nIdx, bool bUnk);
inline CMemory p_Pak_WaitAsync; inline CMemory p_Pak_WaitAsync;
inline RPakStatus_t(*v_Pak_WaitAsync)(RPakHandle_t handle, void* pFinishCallback); inline EPakStatus(*v_Pak_WaitAsync)(PakHandle_t handle, void* pFinishCallback);
inline CMemory p_Pak_LoadPak; inline CMemory p_Pak_LoadPak;
inline unsigned int (*v_Pak_LoadPak)(void* thisptr, void* a2, uint64_t a3); inline unsigned int (*v_Pak_LoadPak)(void* thisptr, void* a2, uint64_t a3);
inline CMemory p_Pak_UnloadPak; inline CMemory p_Pak_UnloadPak;
inline void(*v_Pak_UnloadPak)(RPakHandle_t handle); inline void(*v_Pak_UnloadPak)(PakHandle_t handle);
inline CMemory p_Pak_OpenFileOffset; // Offset to inlined 'Pak_OpenFile'. inline CMemory p_Pak_OpenFileOffset; // Offset to inlined 'Pak_OpenFile'.
inline RPakStatus_t WaitAsync(RPakHandle_t handle, void* pFinishCallback = nullptr) { return v_Pak_WaitAsync(handle, pFinishCallback); } inline EPakStatus WaitAsync(PakHandle_t handle, void* pFinishCallback = nullptr) { return v_Pak_WaitAsync(handle, pFinishCallback); }
typedef struct PakLoadFuncs_s typedef struct PakLoadFuncs_s
{ {
void* LoadPatches; void* LoadPatches;
void* RegisterAsset; void* RegisterAsset;
char unknown0[8]; char unknown0[8];
RPakHandle_t (*LoadAsync)(const char* pakFileName, CAlignedMemAlloc* allocator, int nIdx, bool bUnk); PakHandle_t (*LoadAsync)(const char* pakFileName, CAlignedMemAlloc* allocator, int nIdx, bool bUnk);
void* Func4; void* Func4;
void (*UnloadPak)(RPakHandle_t handle); void (*UnloadPak)(PakHandle_t handle);
void* Func6; void* Func6;
char unknown2[16]; char unknown2[16];
void* Func7; void* Func7;
void* Func8; void* Func8;
RPakStatus_t(*WaitAsync)(RPakHandle_t handle, void* pFinishCallback); EPakStatus(*WaitAsync)(PakHandle_t handle, void* pFinishCallback);
void* Func10; void* Func10;
void* Func11; void* Func11;
void* FindByGUID; void* FindByGUID;
@ -62,7 +62,7 @@ typedef struct PakLoadFuncs_s
} PakLoadFuncs_t; } PakLoadFuncs_t;
extern PakLoadFuncs_t* g_pakLoadApi; extern PakLoadFuncs_t* g_pakLoadApi;
extern CUtlVector<RPakHandle_t> g_vLoadedPakHandle; extern CUtlVector<PakHandle_t> g_vLoadedPakHandle;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
class V_RTechGame : public IDetour class V_RTechGame : public IDetour
@ -79,16 +79,16 @@ class V_RTechGame : public IDetour
virtual void GetFun(void) const virtual void GetFun(void) const
{ {
p_Pak_LoadAsync = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 89 03 8B 0B").FollowNearCallSelf(); p_Pak_LoadAsync = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 89 03 8B 0B").FollowNearCallSelf();
v_Pak_LoadAsync = p_Pak_LoadAsync.RCast<RPakHandle_t(*)(const char*, CAlignedMemAlloc*, int, bool)>(); v_Pak_LoadAsync = p_Pak_LoadAsync.RCast<PakHandle_t(*)(const char*, CAlignedMemAlloc*, int, bool)>();
p_Pak_WaitAsync = g_GameDll.FindPatternSIMD("40 53 55 48 83 EC 38 48 89 74 24 ??"); p_Pak_WaitAsync = g_GameDll.FindPatternSIMD("40 53 55 48 83 EC 38 48 89 74 24 ??");
v_Pak_WaitAsync = p_Pak_WaitAsync.RCast<RPakStatus_t(*)(RPakHandle_t, void*)>(); v_Pak_WaitAsync = p_Pak_WaitAsync.RCast<EPakStatus(*)(PakHandle_t, void*)>();
p_Pak_LoadPak = g_GameDll.FindPatternSIMD("48 89 4C 24 ?? 56 41 55 48 81 EC ?? ?? ?? ?? 4C"); p_Pak_LoadPak = g_GameDll.FindPatternSIMD("48 89 4C 24 ?? 56 41 55 48 81 EC ?? ?? ?? ?? 4C");
v_Pak_LoadPak = p_Pak_LoadPak.RCast<unsigned int (*)(void*, void*, uint64_t)>(); v_Pak_LoadPak = p_Pak_LoadPak.RCast<unsigned int (*)(void*, void*, uint64_t)>();
p_Pak_UnloadPak = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 85 FF 74 0C").FollowNearCallSelf(); p_Pak_UnloadPak = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 85 FF 74 0C").FollowNearCallSelf();
v_Pak_UnloadPak = p_Pak_UnloadPak.RCast<void (*)(RPakHandle_t)>(); v_Pak_UnloadPak = p_Pak_UnloadPak.RCast<void (*)(PakHandle_t)>();
} }
virtual void GetVar(void) const virtual void GetVar(void) const
{ {

View File

@ -68,7 +68,7 @@ uint64_t __fastcall RTech::StringToGuid(const char* pData)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: calculate 'decompressed' size and commit parameters // Purpose: calculate 'decompressed' size and commit parameters
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uint64_t __fastcall RTech::DecompressPakFileInit(RPakDecompState_t* state, uint8_t* fileBuffer, uint64_t fileSize, uint64_t offNoHeader, uint64_t headerSize) uint64_t __fastcall RTech::DecompressPakFileInit(PakDecompState_t* state, uint8_t* fileBuffer, uint64_t fileSize, uint64_t offNoHeader, uint64_t headerSize)
{ {
int64_t input_byte_pos_init; // r9 int64_t input_byte_pos_init; // r9
uint64_t byte_init; // r11 uint64_t byte_init; // r11
@ -95,65 +95,65 @@ uint64_t __fastcall RTech::DecompressPakFileInit(RPakDecompState_t* state, uint8
const uintptr_t mask = UINT64_MAX; const uintptr_t mask = UINT64_MAX;
const uintptr_t file_buf = uintptr_t(fileBuffer); const uintptr_t file_buf = uintptr_t(fileBuffer);
state->m_nInputBuf = file_buf; state->m_inputBuf = file_buf;
state->m_nOut = 0i64; state->m_outputBuf = 0i64;
state->m_nOutMask = 0i64; state->m_outputMask = 0i64;
state->dword44 = 0; state->dword44 = 0;
state->m_nTotalFileLen = fileSize + offNoHeader; state->m_fileSize = fileSize + offNoHeader;
state->m_nMask = mask; state->m_inputMask = mask;
input_byte_pos_init = offNoHeader + headerSize + 8; input_byte_pos_init = offNoHeader + headerSize + 8;
byte_init = *(uint64_t*)((mask & (offNoHeader + headerSize)) + file_buf); byte_init = *(uint64_t*)((mask & (offNoHeader + headerSize)) + file_buf);
state->m_nDecompPosition = headerSize; state->m_decompBytePosition = headerSize;
decompressed_size_bits = byte_init & 0x3F; decompressed_size_bits = byte_init & 0x3F;
byte_init >>= 6; byte_init >>= 6;
state->m_nInputBytePos = input_byte_pos_init; state->m_fileBytePosition = input_byte_pos_init;
state->m_nDecompSize = (byte_init & ((1i64 << decompressed_size_bits) - 1)) | (1i64 << decompressed_size_bits); state->m_decompSize = (byte_init & ((1i64 << decompressed_size_bits) - 1)) | (1i64 << decompressed_size_bits);
byte_1_low = *(uint64_t*)((mask & input_byte_pos_init) + file_buf) << (64 byte_1_low = *(uint64_t*)((mask & input_byte_pos_init) + file_buf) << (64
- ((uint8_t)decompressed_size_bits - ((uint8_t)decompressed_size_bits
+ 6)); + 6));
input_byte_pos_1 = input_byte_pos_init + ((uint64_t)(uint32_t)(decompressed_size_bits + 6) >> 3); input_byte_pos_1 = input_byte_pos_init + ((uint64_t)(uint32_t)(decompressed_size_bits + 6) >> 3);
state->m_nInputBytePos = input_byte_pos_1; state->m_fileBytePosition = input_byte_pos_1;
bit_pos_final = ((decompressed_size_bits + 6) & 7) + 13; bit_pos_final = ((decompressed_size_bits + 6) & 7) + 13;
byte_1 = (0xFFFFFFFFFFFFFFFFui64 >> ((decompressed_size_bits + 6) & 7)) & ((byte_init >> decompressed_size_bits) | byte_1_low); byte_1 = (0xFFFFFFFFFFFFFFFFui64 >> ((decompressed_size_bits + 6) & 7)) & ((byte_init >> decompressed_size_bits) | byte_1_low);
brih_bits = (((uint8_t)byte_1 - 1) & 0x3F) + 1; brih_bits = (((uint8_t)byte_1 - 1) & 0x3F) + 1;
inv_mask_in = 0xFFFFFFFFFFFFFFFFui64 >> (64 - (uint8_t)brih_bits); inv_mask_in = 0xFFFFFFFFFFFFFFFFui64 >> (64 - (uint8_t)brih_bits);
state->m_nInvMaskIn = inv_mask_in; state->m_inputInvMask = inv_mask_in;
state->m_nInvMaskOut = 0xFFFFFFFFFFFFFFFFui64 >> (63 - (((byte_1 >> 6) - 1) & 0x3F)); state->m_outputInvMask = 0xFFFFFFFFFFFFFFFFui64 >> (63 - (((byte_1 >> 6) - 1) & 0x3F));
byte_final_full = (byte_1 >> 13) | (*(uint64_t*)((mask & input_byte_pos_1) + file_buf) << (64 byte_final_full = (byte_1 >> 13) | (*(uint64_t*)((mask & input_byte_pos_1) + file_buf) << (64
- (uint8_t)bit_pos_final)); - (uint8_t)bit_pos_final));
bit_pos_final_1 = bit_pos_final; bit_pos_final_1 = bit_pos_final;
byte_bit_offset_final = bit_pos_final & 7; byte_bit_offset_final = bit_pos_final & 7;
input_byte_pos_final = (bit_pos_final_1 >> 3) + input_byte_pos_1; input_byte_pos_final = (bit_pos_final_1 >> 3) + input_byte_pos_1;
byte_final = (0xFFFFFFFFFFFFFFFFui64 >> byte_bit_offset_final) & byte_final_full; byte_final = (0xFFFFFFFFFFFFFFFFui64 >> byte_bit_offset_final) & byte_final_full;
state->m_nInputBytePos = input_byte_pos_final; state->m_fileBytePosition = input_byte_pos_final;
if (inv_mask_in == -1i64) if (inv_mask_in == -1i64)
{ {
state->m_nHeaderOffset = 0; state->m_headerOffset = 0;
stream_len_needed = fileSize; stream_len_needed = fileSize;
} }
else else
{ {
brih_bytes = brih_bits >> 3; brih_bytes = brih_bits >> 3;
state->m_nHeaderOffset = brih_bytes + 1; state->m_headerOffset = brih_bytes + 1;
byte_tmp = *(uint64_t*)((mask & input_byte_pos_final) + file_buf); byte_tmp = *(uint64_t*)((mask & input_byte_pos_final) + file_buf);
state->m_nInputBytePos = input_byte_pos_final + brih_bytes + 1; state->m_fileBytePosition = input_byte_pos_final + brih_bytes + 1;
stream_len_needed = byte_tmp & ((1i64 << (8 * ((uint8_t)brih_bytes + 1))) - 1); stream_len_needed = byte_tmp & ((1i64 << (8 * ((uint8_t)brih_bytes + 1))) - 1);
} }
result = state->m_nDecompSize; result = state->m_decompSize;
inv_mask_out = state->m_nInvMaskOut; inv_mask_out = state->m_outputInvMask;
qw70 = offNoHeader + state->m_nInvMaskIn - 6i64; qw70 = offNoHeader + state->m_inputInvMask - 6i64;
state->m_nLengthNeeded = stream_len_needed + offNoHeader; state->m_bufferSizeNeeded = stream_len_needed + offNoHeader;
state->qword70 = qw70; state->qword70 = qw70;
state->byte = byte_final; state->m_currentByte = byte_final;
state->m_nByteBitOffset = byte_bit_offset_final; state->m_currentByteBit = byte_bit_offset_final;
state->dword6C = 0; state->dword6C = 0;
state->m_nCompressedStreamSize = stream_len_needed + offNoHeader; state->m_compressedStreamSize = stream_len_needed + offNoHeader;
state->m_nDecompStreamSize = result; state->m_decompStreamSize = result;
if (result - 1 > inv_mask_out) if (result - 1 > inv_mask_out)
{ {
stream_compressed_size_new = stream_len_needed + offNoHeader - state->m_nHeaderOffset; stream_compressed_size_new = stream_len_needed + offNoHeader - state->m_headerOffset;
state->m_nDecompStreamSize = inv_mask_out + 1; state->m_decompStreamSize = inv_mask_out + 1;
state->m_nCompressedStreamSize = stream_compressed_size_new; state->m_compressedStreamSize = stream_compressed_size_new;
} }
return result; return result;
@ -280,7 +280,7 @@ static const unsigned char /*unk_141313180*/ s_PakFileCompressionLUT[0x720] =
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: decompress input data // Purpose: decompress input data
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, uint64_t inLen, uint64_t outLen) uint8_t __fastcall RTech::DecompressPakFile(PakDecompState_t* state, uint64_t inLen, uint64_t outLen)
{ {
char result; // al char result; // al
uint64_t v5; // r15 uint64_t v5; // r15
@ -352,26 +352,26 @@ uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, uint64_t i
uint32_t v71; // [rsp+60h] [rbp+8h] uint32_t v71; // [rsp+60h] [rbp+8h]
uint64_t v74; // [rsp+78h] [rbp+20h] uint64_t v74; // [rsp+78h] [rbp+20h]
if (inLen < state->m_nLengthNeeded) if (inLen < state->m_bufferSizeNeeded)
return 0; return 0;
v5 = state->m_nDecompPosition; v5 = state->m_decompBytePosition;
if (outLen < state->m_nInvMaskOut + (v5 & ~state->m_nInvMaskOut) + 1 && outLen < state->m_nDecompSize) if (outLen < state->m_outputInvMask + (v5 & ~state->m_outputInvMask) + 1 && outLen < state->m_decompSize)
return 0; return 0;
v6 = state->m_nOut; v6 = state->m_outputBuf;
v7 = state->m_nByteBitOffset; v7 = state->m_currentByteBit;
v8 = state->byte; v8 = state->m_currentByte;
v9 = state->m_nInputBytePos; v9 = state->m_fileBytePosition;
v10 = state->qword70; v10 = state->qword70;
v11 = state->m_nInputBuf; v11 = state->m_inputBuf;
if (state->m_nCompressedStreamSize < v10) if (state->m_compressedStreamSize < v10)
v10 = state->m_nCompressedStreamSize; v10 = state->m_compressedStreamSize;
v12 = state->dword6C; v12 = state->dword6C;
v74 = v11; v74 = v11;
v70 = v6; v70 = v6;
v71 = v12; v71 = v12;
if (!v7) if (!v7)
goto LABEL_11; goto LABEL_11;
v13 = (*(_QWORD*)((v9 & state->m_nMask) + v11) << (64 - (unsigned __int8)v7)) | v8; v13 = (*(_QWORD*)((v9 & state->m_inputMask) + v11) << (64 - (unsigned __int8)v7)) | v8;
for (i = v7; ; i = v7) for (i = v7; ; i = v7)
{ {
v7 &= 7u; v7 &= 7u;
@ -389,12 +389,12 @@ uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, uint64_t i
if (*((char*)&s_PakFileCompressionLUT + v18) < 0) if (*((char*)&s_PakFileCompressionLUT + v18) < 0)
{ {
v56 = -(int)v20; v56 = -(int)v20;
v57 = (__int64*)(v11 + (v9 & state->m_nMask)); v57 = (__int64*)(v11 + (v9 & state->m_inputMask));
v71 = 1; v71 = 1;
v58 = (__int64*)(v6 + (v5 & state->m_nOutMask)); v58 = (__int64*)(v6 + (v5 & state->m_outputMask));
if (v56 == *((unsigned __int8*)&s_PakFileCompressionLUT + v16 + 1248)) if (v56 == *((unsigned __int8*)&s_PakFileCompressionLUT + v16 + 1248))
{ {
if ((~v9 & state->m_nInvMaskIn) < 0xF || (state->m_nInvMaskOut & ~v5) < 15 || state->m_nDecompSize - v5 < 0x10) if ((~v9 & state->m_inputInvMask) < 0xF || (state->m_outputInvMask & ~v5) < 15 || state->m_decompSize - v5 < 0x10)
v56 = 1; v56 = 1;
v59 = char(v19); v59 = char(v19);
v60 = v19 >> 3; v60 = v19 >> 3;
@ -453,7 +453,7 @@ uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, uint64_t i
v22 = ((unsigned __int64)(unsigned int)v19 >> (((unsigned int)(v21 - 31) >> 3) & 6)) & 0x3F; v22 = ((unsigned __int64)(unsigned int)v19 >> (((unsigned int)(v21 - 31) >> 3) & 6)) & 0x3F;
v23 = 1 << (v21 + ((v19 >> 4) & ((24 * (((unsigned int)(v21 - 31) >> 3) & 2)) >> 4))); v23 = 1 << (v21 + ((v19 >> 4) & ((24 * (((unsigned int)(v21 - 31) >> 3) & 2)) >> 4)));
v7 += (((unsigned int)(v21 - 31) >> 3) & 6) + *((unsigned __int8*)&s_PakFileCompressionLUT + v22 + 1088) + v21 + ((v19 >> 4) & ((24 * (((unsigned int)(v21 - 31) >> 3) & 2)) >> 4)); v7 += (((unsigned int)(v21 - 31) >> 3) & 6) + *((unsigned __int8*)&s_PakFileCompressionLUT + v22 + 1088) + v21 + ((v19 >> 4) & ((24 * (((unsigned int)(v21 - 31) >> 3) & 2)) >> 4));
v24 = state->m_nOutMask; v24 = state->m_outputMask;
v25 = 16 * (v23 + ((v23 - 1) & (v19 >> ((((unsigned int)(v21 - 31) >> 3) & 6) + *((_BYTE*)&s_PakFileCompressionLUT + v22 + 1088))))); v25 = 16 * (v23 + ((v23 - 1) & (v19 >> ((((unsigned int)(v21 - 31) >> 3) & 6) + *((_BYTE*)&s_PakFileCompressionLUT + v22 + 1088)))));
v19 >>= (((unsigned int)(v21 - 31) >> 3) & 6) + *((_BYTE*)&s_PakFileCompressionLUT + v22 + 1088) + v21 + ((v19 >> 4) & ((24 * (((unsigned int)(v21 - 31) >> 3) & 2)) >> 4)); v19 >>= (((unsigned int)(v21 - 31) >> 3) & 6) + *((_BYTE*)&s_PakFileCompressionLUT + v22 + 1088) + v21 + ((v19 >> 4) & ((24 * (((unsigned int)(v21 - 31) >> 3) & 2)) >> 4));
v26 = v25 + *((unsigned __int8*)&s_PakFileCompressionLUT + v22 + 1024) - 16; v26 = v25 + *((unsigned __int8*)&s_PakFileCompressionLUT + v22 + 1024) - 16;
@ -480,7 +480,7 @@ uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, uint64_t i
v45 = *((_BYTE*)&s_PakFileCompressionLUT + v46 + 1216); v45 = *((_BYTE*)&s_PakFileCompressionLUT + v46 + 1216);
if (v74 && v7 + v45 >= 61) if (v74 && v7 + v45 >= 61)
{ {
v47 = v9++ & state->m_nMask; v47 = v9++ & state->m_inputMask;
v43 |= (unsigned __int64)*(unsigned __int8*)(v47 + v74) << (61 - (unsigned __int8)v7); v43 |= (unsigned __int64)*(unsigned __int8*)(v47 + v74) << (61 - (unsigned __int8)v7);
v7 -= 8; v7 -= 8;
} }
@ -536,18 +536,18 @@ uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, uint64_t i
break; break;
LABEL_29: LABEL_29:
v6 = v70; v6 = v70;
v13 = (*(_QWORD*)((v9 & state->m_nMask) + v11) << (64 - (unsigned __int8)v7)) | v19; v13 = (*(_QWORD*)((v9 & state->m_inputMask) + v11) << (64 - (unsigned __int8)v7)) | v19;
} }
if (v5 != state->m_nDecompStreamSize) if (v5 != state->m_decompStreamSize)
goto LABEL_25; goto LABEL_25;
v30 = state->m_nDecompSize; v30 = state->m_decompSize;
if (v5 == v30) if (v5 == v30)
{ {
result = 1; result = 1;
goto LABEL_69; goto LABEL_69;
} }
v31 = state->m_nInvMaskIn; v31 = state->m_inputInvMask;
v32 = state->m_nHeaderOffset; v32 = state->m_headerOffset;
v33 = v31 & -(__int64)v9; v33 = v31 & -(__int64)v9;
v19 >>= 1; v19 >>= 1;
++v7; ++v7;
@ -558,32 +558,32 @@ uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, uint64_t i
if (v9 > v34) if (v9 > v34)
state->qword70 = v31 + v34 + 1; state->qword70 = v31 + v34 + 1;
} }
v35 = v9 & state->m_nMask; v35 = v9 & state->m_inputMask;
v9 += v32; v9 += v32;
v36 = v5 + state->m_nInvMaskOut + 1; v36 = v5 + state->m_outputInvMask + 1;
v37 = *(_QWORD*)(v35 + v11) & ((1i64 << (8 * (unsigned __int8)v32)) - 1); v37 = *(_QWORD*)(v35 + v11) & ((1i64 << (8 * (unsigned __int8)v32)) - 1);
v38 = v37 + state->m_nLengthNeeded; v38 = v37 + state->m_bufferSizeNeeded;
v39 = v37 + state->m_nCompressedStreamSize; v39 = v37 + state->m_compressedStreamSize;
state->m_nLengthNeeded = v38; state->m_bufferSizeNeeded = v38;
state->m_nCompressedStreamSize = v39; state->m_compressedStreamSize = v39;
if (v36 >= v30) if (v36 >= v30)
{ {
v36 = v30; v36 = v30;
state->m_nCompressedStreamSize = v32 + v39; state->m_compressedStreamSize = v32 + v39;
} }
state->m_nDecompStreamSize = v36; state->m_decompStreamSize = v36;
if (inLen >= v38 && outLen >= v36) if (inLen >= v38 && outLen >= v36)
{ {
LABEL_25: LABEL_25:
v10 = state->qword70; v10 = state->qword70;
if (v9 >= v10) if (v9 >= v10)
{ {
v9 = ~state->m_nInvMaskIn & (v9 + 7); v9 = ~state->m_inputInvMask & (v9 + 7);
v10 += state->m_nInvMaskIn + 1; v10 += state->m_inputInvMask + 1;
state->qword70 = v10; state->qword70 = v10;
} }
if (state->m_nCompressedStreamSize < v10) if (state->m_compressedStreamSize < v10)
v10 = state->m_nCompressedStreamSize; v10 = state->m_compressedStreamSize;
goto LABEL_29; goto LABEL_29;
} }
v69 = state->qword70; v69 = state->qword70;
@ -594,11 +594,11 @@ uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, uint64_t i
} }
state->dword6C = v71; state->dword6C = v71;
result = 0; result = 0;
state->byte = v19; state->m_currentByte = v19;
state->m_nByteBitOffset = v7; state->m_currentByteBit = v7;
LABEL_69: LABEL_69:
state->m_nDecompPosition = v5; state->m_decompBytePosition = v5;
state->m_nInputBytePos = v9; state->m_fileBytePosition = v9;
return result; return result;
} }
@ -661,15 +661,15 @@ int32_t RTech::OpenFile(const CHAR* szFilePath, void* unused, LONGLONG* fileSize
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: gets information about loaded pak file via pak ID // Purpose: gets information about loaded pak file via pak ID
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
RPakLoadedInfo_t* RTech::GetPakLoadedInfo(RPakHandle_t nHandle) PakLoadedInfo_t* RTech::GetPakLoadedInfo(PakHandle_t nHandle)
{ {
for (int16_t i = 0; i < *g_pLoadedPakCount; ++i) for (int16_t i = 0; i < *g_pLoadedPakCount; ++i)
{ {
RPakLoadedInfo_t* info = &g_pLoadedPakInfo[i]; PakLoadedInfo_t* info = &g_pLoadedPakInfo[i];
if (!info) if (!info)
continue; continue;
if (info->m_nHandle != nHandle) if (info->m_handle != nHandle)
continue; continue;
return info; return info;
@ -682,18 +682,18 @@ RPakLoadedInfo_t* RTech::GetPakLoadedInfo(RPakHandle_t nHandle)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: gets information about loaded pak file via pak name // Purpose: gets information about loaded pak file via pak name
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
RPakLoadedInfo_t* RTech::GetPakLoadedInfo(const char* szPakName) PakLoadedInfo_t* RTech::GetPakLoadedInfo(const char* szPakName)
{ {
for (int16_t i = 0; i < *g_pLoadedPakCount; ++i) for (int16_t i = 0; i < *g_pLoadedPakCount; ++i)
{ {
RPakLoadedInfo_t* info = &g_pLoadedPakInfo[i]; PakLoadedInfo_t* info = &g_pLoadedPakInfo[i];
if (!info) if (!info)
continue; continue;
if (!info->m_pszFileName || !*info->m_pszFileName) if (!info->m_fileName || !*info->m_fileName)
continue; continue;
if (strcmp(szPakName, info->m_pszFileName) != 0) if (strcmp(szPakName, info->m_fileName) != 0)
continue; continue;
return info; return info;
@ -706,26 +706,26 @@ RPakLoadedInfo_t* RTech::GetPakLoadedInfo(const char* szPakName)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: returns pak status as string // Purpose: returns pak status as string
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const char* RTech::PakStatusToString(RPakStatus_t status) const char* RTech::PakStatusToString(EPakStatus status)
{ {
switch (status) switch (status)
{ {
case RPakStatus_t::PAK_STATUS_FREED: return "PAK_STATUS_FREED"; case EPakStatus::PAK_STATUS_FREED: return "PAK_STATUS_FREED";
case RPakStatus_t::PAK_STATUS_LOAD_PENDING: return "PAK_STATUS_LOAD_PENDING"; case EPakStatus::PAK_STATUS_LOAD_PENDING: return "PAK_STATUS_LOAD_PENDING";
case RPakStatus_t::PAK_STATUS_REPAK_RUNNING: return "PAK_STATUS_REPAK_RUNNING"; case EPakStatus::PAK_STATUS_REPAK_RUNNING: return "PAK_STATUS_REPAK_RUNNING";
case RPakStatus_t::PAK_STATUS_REPAK_DONE: return "PAK_STATUS_REPAK_DONE"; case EPakStatus::PAK_STATUS_REPAK_DONE: return "PAK_STATUS_REPAK_DONE";
case RPakStatus_t::PAK_STATUS_LOAD_STARTING: return "PAK_STATUS_LOAD_STARTING"; case EPakStatus::PAK_STATUS_LOAD_STARTING: return "PAK_STATUS_LOAD_STARTING";
case RPakStatus_t::PAK_STATUS_LOAD_PAKHDR: return "PAK_STATUS_LOAD_PAKHDR"; case EPakStatus::PAK_STATUS_LOAD_PAKHDR: return "PAK_STATUS_LOAD_PAKHDR";
case RPakStatus_t::PAK_STATUS_LOAD_PATCH_INIT: return "PAK_STATUS_LOAD_PATCH_INIT"; case EPakStatus::PAK_STATUS_LOAD_PATCH_INIT: return "PAK_STATUS_LOAD_PATCH_INIT";
case RPakStatus_t::PAK_STATUS_LOAD_PATCH_EDIT_STREAM: return "PAK_STATUS_LOAD_PATCH_EDIT_STREAM"; case EPakStatus::PAK_STATUS_LOAD_PATCH_EDIT_STREAM: return "PAK_STATUS_LOAD_PATCH_EDIT_STREAM";
case RPakStatus_t::PAK_STATUS_LOAD_ASSETS: return "PAK_STATUS_LOAD_ASSETS"; case EPakStatus::PAK_STATUS_LOAD_ASSETS: return "PAK_STATUS_LOAD_ASSETS";
case RPakStatus_t::PAK_STATUS_LOADED: return "PAK_STATUS_LOADED"; case EPakStatus::PAK_STATUS_LOADED: return "PAK_STATUS_LOADED";
case RPakStatus_t::PAK_STATUS_UNLOAD_PENDING: return "PAK_STATUS_UNLOAD_PENDING"; case EPakStatus::PAK_STATUS_UNLOAD_PENDING: return "PAK_STATUS_UNLOAD_PENDING";
case RPakStatus_t::PAK_STATUS_FREE_PENDING: return "PAK_STATUS_FREE_PENDING"; case EPakStatus::PAK_STATUS_FREE_PENDING: return "PAK_STATUS_FREE_PENDING";
case RPakStatus_t::PAK_STATUS_CANCELING: return "PAK_STATUS_CANCELING"; case EPakStatus::PAK_STATUS_CANCELING: return "PAK_STATUS_CANCELING";
case RPakStatus_t::PAK_STATUS_ERROR: return "PAK_STATUS_ERROR"; case EPakStatus::PAK_STATUS_ERROR: return "PAK_STATUS_ERROR";
case RPakStatus_t::PAK_STATUS_INVALID_PAKHANDLE: return "PAK_STATUS_INVALID_PAKHANDLE"; case EPakStatus::PAK_STATUS_INVALID_PAKHANDLE: return "PAK_STATUS_INVALID_PAKHANDLE";
case RPakStatus_t::PAK_STATUS_BUSY: return "PAK_STATUS_BUSY"; case EPakStatus::PAK_STATUS_BUSY: return "PAK_STATUS_BUSY";
default: return "PAK_STATUS_UNKNOWN"; default: return "PAK_STATUS_UNKNOWN";
} }
} }
@ -733,7 +733,7 @@ const char* RTech::PakStatusToString(RPakStatus_t status)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: process guid relations for asset // Purpose: process guid relations for asset
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void RTech::PakProcessGuidRelationsForAsset(PakFile_t* pPak, RPakAssetEntry_t* pAsset) void RTech::PakProcessGuidRelationsForAsset(PakFile_t* pPak, PakAsset_t* pAsset)
{ {
#if defined (GAMEDLL_S0) && defined (GAMEDLL_S1) && defined (GAMEDLL_S2) #if defined (GAMEDLL_S0) && defined (GAMEDLL_S1) && defined (GAMEDLL_S2)
static const int GLOBAL_MUL = 0x1D; static const int GLOBAL_MUL = 0x1D;
@ -741,27 +741,27 @@ void RTech::PakProcessGuidRelationsForAsset(PakFile_t* pPak, RPakAssetEntry_t* p
static const int GLOBAL_MUL = 0x17; static const int GLOBAL_MUL = 0x17;
#endif #endif
RPakDescriptor_t* pGuidDescriptors = &pPak->m_pGuidDescriptors[pAsset->m_nUsesStartIdx]; PakPage_t* pGuidDescriptors = &pPak->m_memoryData.m_guidDescriptors[pAsset->m_usesStartIdx];
volatile uint32_t* v5 = reinterpret_cast<volatile uint32_t*>(*(reinterpret_cast<uint64_t*>(g_pPakGlobals) + GLOBAL_MUL * (pPak->qword578 & 0x1FF) + 0x160212)); volatile uint32_t* v5 = reinterpret_cast<volatile uint32_t*>(*(reinterpret_cast<uint64_t*>(g_pPakGlobals) + GLOBAL_MUL * (pPak->m_memoryData.qword2D8 & 0x1FF) + 0x160212));
const bool bDebug = rtech_debug->GetBool(); const bool bDebug = rtech_debug->GetBool();
if (bDebug) if (bDebug)
Msg(eDLL_T::RTECH, "Processing GUID relations for asset '0x%-16llX' in pak '%-32s'. Uses: %-4i\n", pAsset->m_Guid, pPak->m_pszFileName, pAsset->m_nUsesCount); Msg(eDLL_T::RTECH, "Processing GUID relations for asset '0x%-16llX' in pak '%-32s'. Uses: %-4i\n", pAsset->m_guid, pPak->m_memoryData.m_fileName, pAsset->m_usesCount);
for (uint32_t i = 0; i < pAsset->m_nUsesCount; i++) for (uint32_t i = 0; i < pAsset->m_usesCount; i++)
{ {
void** pCurrentGuid = reinterpret_cast<void**>(pPak->m_ppPagePointers[pGuidDescriptors[i].m_Index] + pGuidDescriptors[i].m_Offset); void** pCurrentGuid = reinterpret_cast<void**>(pPak->m_memoryData.m_pagePointers[pGuidDescriptors[i].m_index] + pGuidDescriptors[i].offset);
// Get current guid. // Get current guid.
const uint64_t currentGuid = reinterpret_cast<uint64_t>(*pCurrentGuid); const uint64_t currentGuid = reinterpret_cast<uint64_t>(*pCurrentGuid);
// Get asset index. // Get asset index.
int assetIdx = currentGuid & 0x3FFFF; int assetIdx = currentGuid & 0x3FFFF;
uint64_t assetIdxEntryGuid = g_pPakGlobals->m_Assets[assetIdx].m_Guid; uint64_t assetIdxEntryGuid = g_pPakGlobals->m_assets[assetIdx].m_guid;
const int64_t v9 = 2i64 * InterlockedExchangeAdd(v5, 1u); const int64_t v9 = 2i64 * InterlockedExchangeAdd(v5, 1u);
*reinterpret_cast<uint64_t*>(const_cast<uint32_t*>(&v5[2 * v9 + 2])) = currentGuid; *reinterpret_cast<uint64_t*>(const_cast<uint32_t*>(&v5[2 * v9 + 2])) = currentGuid;
*reinterpret_cast<uint64_t*>(const_cast<uint32_t*>(&v5[2 * v9 + 4])) = pAsset->m_Guid; *reinterpret_cast<uint64_t*>(const_cast<uint32_t*>(&v5[2 * v9 + 4])) = pAsset->m_guid;
std::function<bool(bool)> fnCheckAsset = [&](bool shouldCheckTwo) std::function<bool(bool)> fnCheckAsset = [&](bool shouldCheckTwo)
{ {
@ -769,7 +769,7 @@ void RTech::PakProcessGuidRelationsForAsset(PakFile_t* pPak, RPakAssetEntry_t* p
{ {
if (shouldCheckTwo && assetIdxEntryGuid == 2) if (shouldCheckTwo && assetIdxEntryGuid == 2)
{ {
if (pPak->m_PakHdr.m_nAssetEntryCount) if (pPak->m_memoryData.m_pakHeader.m_assetEntryCount)
return false; return false;
} }
@ -778,13 +778,13 @@ void RTech::PakProcessGuidRelationsForAsset(PakFile_t* pPak, RPakAssetEntry_t* p
// Check if we have a deadlock and report it if we have rtech_debug enabled. // Check if we have a deadlock and report it if we have rtech_debug enabled.
if (bDebug && assetIdx >= 0x40000) if (bDebug && assetIdx >= 0x40000)
{ {
Warning(eDLL_T::RTECH, "Possible deadlock detected while processing asset '0x%-16llX' in pak '%-32s'. Uses: %-4i | assetIdxEntryGuid: '0x%-16llX' | currentGuid: '0x%-16llX'\n", pAsset->m_Guid, pPak->m_pszFileName, pAsset->m_nUsesCount, assetIdxEntryGuid, currentGuid); Warning(eDLL_T::RTECH, "Possible deadlock detected while processing asset '0x%-16llX' in pak '%-32s'. Uses: %-4i | assetIdxEntryGuid: '0x%-16llX' | currentGuid: '0x%-16llX'\n", pAsset->m_guid, pPak->m_memoryData.m_fileName, pAsset->m_usesCount, assetIdxEntryGuid, currentGuid);
if (IsDebuggerPresent()) if (IsDebuggerPresent())
DebugBreak(); DebugBreak();
} }
assetIdx &= 0x3FFFF; assetIdx &= 0x3FFFF;
assetIdxEntryGuid = g_pPakGlobals->m_Assets[assetIdx].m_Guid; assetIdxEntryGuid = g_pPakGlobals->m_assets[assetIdx].m_guid;
if (assetIdxEntryGuid == currentGuid) if (assetIdxEntryGuid == currentGuid)
return true; return true;
@ -796,24 +796,24 @@ void RTech::PakProcessGuidRelationsForAsset(PakFile_t* pPak, RPakAssetEntry_t* p
// Are we some special asset with the guid 2? // Are we some special asset with the guid 2?
if (!fnCheckAsset(true)) if (!fnCheckAsset(true))
{ {
RPakAssetEntry_t* assetEntries = pPak->m_pAssetEntries; PakAsset_t* assetEntries = pPak->m_memoryData.m_assetEntries;
uint64_t a = 0; uint64_t a = 0;
for (; assetEntries->m_Guid != currentGuid; a++, assetEntries++) for (; assetEntries->m_guid != currentGuid; a++, assetEntries++)
{ {
if (a >= pPak->m_PakHdr.m_nAssetEntryCount) if (a >= pPak->m_memoryData.m_pakHeader.m_assetEntryCount)
{ {
fnCheckAsset(false); fnCheckAsset(false);
break; break;
} }
} }
assetIdx = pPak->qword580[a]; assetIdx = pPak->m_memoryData.qword2E0[a];
} }
} }
// Finally write the pointer to the guid entry. // Finally write the pointer to the guid entry.
*pCurrentGuid = g_pPakGlobals->m_Assets[assetIdx].m_pHead; *pCurrentGuid = g_pPakGlobals->m_assets[assetIdx].m_head;
} }
} }
#endif // GAMEDLL_S3 #endif // GAMEDLL_S3

View File

@ -18,17 +18,17 @@ inline void(*RTech_RegisterAsset)(int, int, const char*, void*, void*, void*, vo
#ifdef GAMEDLL_S3 #ifdef GAMEDLL_S3
inline CMemory p_Pak_ProcessGuidRelationsForAsset; inline CMemory p_Pak_ProcessGuidRelationsForAsset;
inline void(*RTech_Pak_ProcessGuidRelationsForAsset)(PakFile_t*, RPakAssetEntry_t*); inline void(*RTech_Pak_ProcessGuidRelationsForAsset)(PakFile_t*, PakAsset_t*);
#endif #endif
inline CMemory p_StreamDB_Init; inline CMemory p_StreamDB_Init;
inline void(*v_StreamDB_Init)(const char* pszLevelName); inline void(*v_StreamDB_Init)(const char* pszLevelName);
inline RPakLoadedInfo_t* g_pLoadedPakInfo; inline PakLoadedInfo_t* g_pLoadedPakInfo;
inline int16_t* g_pRequestedPakCount; inline int16_t* g_pRequestedPakCount;
inline int16_t* g_pLoadedPakCount; inline int16_t* g_pLoadedPakCount;
inline JobID_t* g_pPakLoadJobID; inline JobID_t* g_pPakLoadJobID;
inline RPakGlobals_t* g_pPakGlobals; inline PakGlobals_t* g_pPakGlobals;
inline int32_t* s_pFileArray; inline int32_t* s_pFileArray;
inline PSRWLOCK* s_pFileArrayMutex; inline PSRWLOCK* s_pFileArrayMutex;
@ -42,15 +42,15 @@ class RTech
{ {
public: public:
uint64_t __fastcall StringToGuid(const char* pData); uint64_t __fastcall StringToGuid(const char* pData);
uint8_t __fastcall DecompressPakFile(RPakDecompState_t* state, uint64_t inLen, uint64_t outLen); uint8_t __fastcall DecompressPakFile(PakDecompState_t* state, uint64_t inLen, uint64_t outLen);
uint64_t __fastcall DecompressPakFileInit(RPakDecompState_t* state, uint8_t* fileBuffer, uint64_t fileSize, uint64_t offNoHeader, uint64_t headerSize); uint64_t __fastcall DecompressPakFileInit(PakDecompState_t* state, uint8_t* fileBuffer, uint64_t fileSize, uint64_t offNoHeader, uint64_t headerSize);
RPakLoadedInfo_t* GetPakLoadedInfo(RPakHandle_t nPakId); PakLoadedInfo_t* GetPakLoadedInfo(PakHandle_t nPakId);
RPakLoadedInfo_t* GetPakLoadedInfo(const char* szPakName); PakLoadedInfo_t* GetPakLoadedInfo(const char* szPakName);
const char* PakStatusToString(RPakStatus_t status); const char* PakStatusToString(EPakStatus status);
static int32_t OpenFile(const CHAR* szFilePath, void* unused, LONGLONG* fileSizeOut); static int32_t OpenFile(const CHAR* szFilePath, void* unused, LONGLONG* fileSizeOut);
#ifdef GAMEDLL_S3 #ifdef GAMEDLL_S3
static void PakProcessGuidRelationsForAsset(PakFile_t* pak, RPakAssetEntry_t* asset); static void PakProcessGuidRelationsForAsset(PakFile_t* pak, PakAsset_t* asset);
#endif // GAMEDLL_S3 #endif // GAMEDLL_S3
void** LoadShaderSet(void** VTablePtr); void** LoadShaderSet(void** VTablePtr);
@ -99,7 +99,7 @@ class V_RTechUtils : public IDetour
#ifdef GAMEDLL_S3 #ifdef GAMEDLL_S3
p_Pak_ProcessGuidRelationsForAsset = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 48 8B 86 ?? ?? ?? ?? 42 8B 0C B0").FollowNearCallSelf(); p_Pak_ProcessGuidRelationsForAsset = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 48 8B 86 ?? ?? ?? ?? 42 8B 0C B0").FollowNearCallSelf();
RTech_Pak_ProcessGuidRelationsForAsset = p_Pak_ProcessGuidRelationsForAsset.RCast<void(*)(PakFile_t*, RPakAssetEntry_t*)>(); /*E8 ? ? ? ? 48 8B 86 ? ? ? ? 42 8B 0C B0*/ RTech_Pak_ProcessGuidRelationsForAsset = p_Pak_ProcessGuidRelationsForAsset.RCast<void(*)(PakFile_t*, PakAsset_t*)>(); /*E8 ? ? ? ? 48 8B 86 ? ? ? ? 42 8B 0C B0*/
#endif #endif
} }
virtual void GetVar(void) const virtual void GetVar(void) const
@ -108,11 +108,11 @@ class V_RTechUtils : public IDetour
s_pFileHandles = p_StreamDB_Init.Offset(0x70).FindPatternSelf("4C 8D", CMemory::Direction::DOWN, 512, 1).ResolveRelativeAddress(0x3, 0x7).RCast<pFileHandleTracker_t*>(); s_pFileHandles = p_StreamDB_Init.Offset(0x70).FindPatternSelf("4C 8D", CMemory::Direction::DOWN, 512, 1).ResolveRelativeAddress(0x3, 0x7).RCast<pFileHandleTracker_t*>();
s_pFileArrayMutex = p_StreamDB_Init.Offset(0x70).FindPatternSelf("48 8D 0D", CMemory::Direction::DOWN, 512, 1).ResolveRelativeAddress(0x3, 0x7).RCast<PSRWLOCK*>(); s_pFileArrayMutex = p_StreamDB_Init.Offset(0x70).FindPatternSelf("48 8D 0D", CMemory::Direction::DOWN, 512, 1).ResolveRelativeAddress(0x3, 0x7).RCast<PSRWLOCK*>();
g_pLoadedPakInfo = p_Pak_UnloadPak.FindPattern("48 8D 05", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast<RPakLoadedInfo_t*>(); g_pLoadedPakInfo = p_Pak_UnloadPak.FindPattern("48 8D 05", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast<PakLoadedInfo_t*>();
g_pRequestedPakCount = p_Pak_UnloadPak.FindPattern("66 89", CMemory::Direction::DOWN, 450).ResolveRelativeAddressSelf(0x3, 0x7).RCast<int16_t*>(); g_pRequestedPakCount = p_Pak_UnloadPak.FindPattern("66 89", CMemory::Direction::DOWN, 450).ResolveRelativeAddressSelf(0x3, 0x7).RCast<int16_t*>();
g_pLoadedPakCount = &*g_pRequestedPakCount - 1; // '-1' shifts it back with sizeof(int16_t). g_pLoadedPakCount = &*g_pRequestedPakCount - 1; // '-1' shifts it back with sizeof(int16_t).
g_pPakGlobals = g_GameDll.FindPatternSIMD("48 8D 1D ?? ?? ?? ?? 45 8D 5A 0E").ResolveRelativeAddressSelf(0x3, 0x7).RCast<RPakGlobals_t*>(); /*48 8D 1D ? ? ? ? 45 8D 5A 0E*/ g_pPakGlobals = g_GameDll.FindPatternSIMD("48 8D 1D ?? ?? ?? ?? 45 8D 5A 0E").ResolveRelativeAddressSelf(0x3, 0x7).RCast<PakGlobals_t*>(); /*48 8D 1D ? ? ? ? 45 8D 5A 0E*/
g_pPakLoadJobID = reinterpret_cast<JobID_t*>(&*g_pLoadedPakCount - 2); g_pPakLoadJobID = reinterpret_cast<JobID_t*>(&*g_pLoadedPakCount - 2);
g_pPakFifoLock = p_JT_HelpWithAnything.Offset(0x155).FindPatternSelf("48 8D 0D").ResolveRelativeAddressSelf(0x3, 0x7).RCast<JobFifoLock_s*>(); g_pPakFifoLock = p_JT_HelpWithAnything.Offset(0x155).FindPatternSelf("48 8D 0D").ResolveRelativeAddressSelf(0x3, 0x7).RCast<JobFifoLock_s*>();