From 37ab1cfad523988c19e79ba3a0dd527f9550fc12 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Tue, 19 Sep 2023 20:43:01 +0200 Subject: [PATCH] Add new RPak types and rename existing Rename to enforce consistency. --- r5dev/common/callback.cpp | 100 +++---- r5dev/engine/cmodel_bsp.cpp | 18 +- r5dev/materialsystem/cmaterialsystem.cpp | 2 +- r5dev/public/rtech/ipakfile.h | 364 ++++++++++++++--------- r5dev/rtech/rtech_game.cpp | 16 +- r5dev/rtech/rtech_game.h | 22 +- r5dev/rtech/rtech_utils.cpp | 210 ++++++------- r5dev/rtech/rtech_utils.h | 24 +- 8 files changed, 413 insertions(+), 343 deletions(-) diff --git a/r5dev/common/callback.cpp b/r5dev/common/callback.cpp index a94e8ef0..ea9f7ad7 100644 --- a/r5dev/common/callback.cpp +++ b/r5dev/common/callback.cpp @@ -291,15 +291,15 @@ void Pak_ListPaks_f(const CCommand& args) 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; - 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 - 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++; } 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) { - 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; - 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++; } Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-------------|-------------|\n"); @@ -350,27 +350,27 @@ void Pak_RequestUnload_f(const CCommand& args) { if (args.HasOnlyDigits(1)) { - const RPakHandle_t pakHandle = atoi(args.Arg(1)); - const RPakLoadedInfo_t* pakInfo = g_pRTech->GetPakLoadedInfo(pakHandle); + const PakHandle_t pakHandle = atoi(args.Arg(1)); + const PakLoadedInfo_t* pakInfo = g_pRTech->GetPakLoadedInfo(pakHandle); if (!pakInfo) { 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); g_pakLoadApi->UnloadPak(pakHandle); } else { - const RPakLoadedInfo_t* pakInfo = g_pRTech->GetPakLoadedInfo(args.Arg(1)); + const PakLoadedInfo_t* pakInfo = g_pRTech->GetPakLoadedInfo(args.Arg(1)); if (!pakInfo) { throw std::exception("Found no pak entry for specified name."); } 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) @@ -401,8 +401,8 @@ void Pak_Swap_f(const CCommand& args) try { string pakName; - RPakHandle_t pakHandle = 0; - RPakLoadedInfo_t* pakInfo = nullptr; + PakHandle_t pakHandle = 0; + PakLoadedInfo_t* pakInfo = nullptr; 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."); } - pakName = pakInfo->m_pszFileName; + pakName = pakInfo->m_fileName; } else { @@ -424,14 +424,14 @@ void Pak_Swap_f(const CCommand& args) 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); 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)); 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()->Close(hPakFile); - RPakHeader_t* pHeader = reinterpret_cast(pPakBuf); - uint16_t flags = (pHeader->m_nFlags[0] << 8) | pHeader->m_nFlags[1]; + PakFileHeader_t* pHeader = reinterpret_cast(pPakBuf); + uint16_t flags = (pHeader->m_flags[0] << 8) | pHeader->m_flags[1]; SYSTEMTIME systemTime; - FileTimeToSystemTime(&pHeader->m_nFileTime, &systemTime); + FileTimeToSystemTime(&pHeader->m_fileTime, &systemTime); Msg(eDLL_T::RTECH, " | |-+ Header ------------------------------------------------\n"); - Msg(eDLL_T::RTECH, " | |-- Magic : '0x%08X'\n", pHeader->m_nMagic); - Msg(eDLL_T::RTECH, " | |-- Version : '%hu'\n", pHeader->m_nVersion); + Msg(eDLL_T::RTECH, " | |-- Magic : '0x%08X'\n", pHeader->m_magic); + Msg(eDLL_T::RTECH, " | |-- Version : '%hu'\n", pHeader->m_version); Msg(eDLL_T::RTECH, " | |-- Flags : '0x%04hX'\n", flags); Msg(eDLL_T::RTECH, " | |-- Time : '%hu-%hu-%hu/%hu %hu:%hu:%hu.%hu'\n", systemTime.wYear,systemTime.wMonth,systemTime.wDay, systemTime.wDayOfWeek, systemTime.wHour, systemTime.wMinute, systemTime.wSecond, systemTime.wMilliseconds); - Msg(eDLL_T::RTECH, " | |-- Hash : '0x%08llX'\n", pHeader->m_nHash); - Msg(eDLL_T::RTECH, " | |-- Entries : '%u'\n", pHeader->m_nAssetEntryCount); + Msg(eDLL_T::RTECH, " | |-- Hash : '0x%08llX'\n", pHeader->m_checksum); + Msg(eDLL_T::RTECH, " | |-- Entries : '%u'\n", pHeader->m_assetEntryCount); Msg(eDLL_T::RTECH, " | |-+ Compression -----------------------------------------\n"); - Msg(eDLL_T::RTECH, " | |-- Size comp: '%zu'\n", pHeader->m_nSizeDisk); - Msg(eDLL_T::RTECH, " | |-- Size decp: '%zu'\n", pHeader->m_nSizeMemory); + Msg(eDLL_T::RTECH, " | |-- Size comp: '%zu'\n", pHeader->m_compressedSize); + 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", __FUNCTION__, inPakFile.String()); 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", __FUNCTION__, inPakFile.String()); @@ -547,21 +547,21 @@ void RTech_Decompress_f(const CCommand& args) const size_t unsignedPakLen = static_cast(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", - __FUNCTION__, inPakFile.String(), unsignedPakLen, pHeader->m_nSizeMemory); + __FUNCTION__, inPakFile.String(), unsignedPakLen, pHeader->m_decompressedSize); return; } - RPakDecompState_t decompState; - const uint64_t nDecompSize = g_pRTech->DecompressPakFileInit(&decompState, pPakBuf, unsignedPakLen, NULL, sizeof(RPakHeader_t)); + PakDecompState_t decompState; + 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", - __FUNCTION__, nDecompSize, pHeader->m_nSizeMemory); + __FUNCTION__, nDecompSize, pHeader->m_decompressedSize); 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, " | |-- 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 pDecompBufContainer(new uint8_t[nPakLen]); uint8_t* const pDecompBuf = pDecompBufContainer.get(); - decompState.m_nOutMask = UINT64_MAX; - decompState.m_nOut = uint64_t(pDecompBuf); + decompState.m_outputMask = UINT64_MAX; + 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) { Error(eDLL_T::RTECH, NO_ERROR, "%s - decompression failed for '%s' return value: '%hu'!\n", __FUNCTION__, inPakFile.String(), nDecompResult); } - pHeader->m_nFlags[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_flags[1] = 0x0; // Set compressed flag to false for the decompressed pak file. + pHeader->m_compressedSize = pHeader->m_decompressedSize; // Equal compressed size with decompressed. FileSystem()->CreateDirHierarchy(PLATFORM_PAK_OVERRIDE_PATH, "GAME"); FileHandle_t hDecompFile = FileSystem()->Open(outPakFile.String(), "wb", "GAME"); @@ -600,25 +600,25 @@ void RTech_Decompress_f(const CCommand& args) 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. - for (uint32_t i = 1, nPatchOffset = (sizeof(RPakHeader_t) + sizeof(uint64_t)); - i <= pHeader->m_nPatchIndex; i++, nPatchOffset += sizeof(RPakPatchCompressedHeader_t)) + for (uint32_t i = 1, nPatchOffset = (sizeof(PakFileHeader_t) + sizeof(uint64_t)); + i <= pHeader->m_patchIndex; i++, nPatchOffset += sizeof(PakPatchFileHeader_t)) { - RPakPatchCompressedHeader_t* pPatchHeader = reinterpret_cast(pDecompBuf + nPatchOffset); + PakPatchFileHeader_t* pPatchHeader = reinterpret_cast(pDecompBuf + nPatchOffset); 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 decp: '%llu'\n", i < pHeader->m_nPatchIndex ? "|" : " ", pPatchHeader->m_nSizeMemory); + 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_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. - FileSystem()->Write(pDecompBuf, decompState.m_nDecompSize, hDecompFile); + 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_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, "--------------------------------------------------------------\n"); diff --git a/r5dev/engine/cmodel_bsp.cpp b/r5dev/engine/cmodel_bsp.cpp index 462c8303..daded7e8 100644 --- a/r5dev/engine/cmodel_bsp.cpp +++ b/r5dev/engine/cmodel_bsp.cpp @@ -240,28 +240,28 @@ void Mod_ProcessPakQueue() { // SDK pak files must be unloaded before the 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) { - const char* pszLoadedPakName = pLoadedPakInfo->m_pszFileName; + const char* pszLoadedPakName = pLoadedPakInfo->m_fileName; if (strcmp(pszLoadedPakName, "common_mp.rpak") == 0 || strcmp(pszLoadedPakName, "common_sp.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. - g_pakLoadApi->UnloadPak(pLoadedSdkPak->m_nHandle); + g_pakLoadApi->UnloadPak(pLoadedSdkPak->m_handle); } #ifndef DEDICATED 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. - g_pakLoadApi->UnloadPak(pLoadedSdkPak->m_nHandle); + g_pakLoadApi->UnloadPak(pLoadedSdkPak->m_handle); } #endif // !DEDICATED } @@ -278,7 +278,7 @@ void Mod_ProcessPakQueue() if (old_gather_props->GetBool()) old_gather_props->SetValue(false); - g_pakLoadApi->UnloadPak(*(RPakHandle_t*)v10); + g_pakLoadApi->UnloadPak(*(PakHandle_t*)v10); Mod_UnloadPakFile(); // Unload mod pak files. if (s_pLevelSetKV) @@ -455,7 +455,7 @@ void Mod_PreloadLevelPaks(const char* pszLevelName) continue; 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) 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) { - for (const RPakHandle_t& it : g_vLoadedPakHandle) + for (const PakHandle_t& it : g_vLoadedPakHandle) { if (it >= 0) { diff --git a/r5dev/materialsystem/cmaterialsystem.cpp b/r5dev/materialsystem/cmaterialsystem.cpp index 4591a29f..60ab77f7 100644 --- a/r5dev/materialsystem/cmaterialsystem.cpp +++ b/r5dev/materialsystem/cmaterialsystem.cpp @@ -22,7 +22,7 @@ InitReturnVal_t CMaterialSystem::Init(CMaterialSystem* thisptr) #ifdef MATERIALSYSTEM_NODX // Only load the 'startup.rpak' file, as 'common_early.rpak' has assets // 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); // Trick: return INIT_FAILED to disable the loading of hardware diff --git a/r5dev/public/rtech/ipakfile.h b/r5dev/public/rtech/ipakfile.h index f3ea8073..5041bcce 100644 --- a/r5dev/public/rtech/ipakfile.h +++ b/r5dev/public/rtech/ipakfile.h @@ -9,9 +9,14 @@ #define PAK_MAX_TYPES 64 #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_LOAD_PENDING = 1, @@ -31,134 +36,147 @@ enum class RPakStatus_t : int32_t PAK_STATUS_BUSY = 15 }; -struct RPakAssetBinding_t +struct PakAssetBinding_t { - uint32_t m_nExtension; // For example '0x6C74616D' for the material asset. - int m_iVersion; - const char* m_szDescription; // Description/Name of asset. - void* m_pLoadAssetFunction; - void* m_pUnloadAssetFunction; - void* m_pReplaceAssetFunction; - void* m_pAllocAssetFunctions; - int m_iSubHeaderSize; - int m_iNativeClassSize; // Native class size, for 'material' it would be CMaterialGlue full size. - uint32_t m_HeaderAlignment; + uint32_t m_extension; // For example '0x6C74616D' for the material asset. + int m_version; + const char* m_description; // Description/Name of asset. + void* m_loadAssetFunction; + void* m_unloadAssetFunction; + void* m_replaceAssetFunction; + void* m_allocAssetFunctions; + int m_subHeaderSize; + int m_nativeClassSize; // Native class size, for 'material' it would be CMaterialGlue full size. + uint32_t m_headerAlignment; int unk3; // [ PIXIE ]: Should be the full size across Season 0-3. }; -struct RPakAssetEntry_t +struct PakAsset_t { - uint64_t m_Guid; - uint64_t m_Padding; - uint32_t m_nHeadPageIdx; - uint32_t m_nHeadPageOffset; - uint32_t m_nCpuPageIdx; - uint32_t m_nCpuPageOffset; - uint64_t m_nStarpakOffset; - uint64_t m_nStarpakOptOffset; - uint16_t m_nPageEnd; + uint64_t m_guid; + uint64_t m_padding; + uint32_t m_headPageIdx; + uint32_t m_headPageOffset; + uint32_t m_cpuPageIdx; + uint32_t m_cpuPageOffset; + uint64_t m_starpakOffset; + uint64_t m_starpakOptOffset; + uint16_t m_pageEnd; uint16_t unk1; - uint32_t m_nRelationsStartIdx; - uint32_t m_nUsesStartIdx; - uint32_t m_nRelationsCount; - uint32_t m_nUsesCount; - uint32_t m_nAssetHeaderSize; - uint32_t m_nVersion; - uint32_t m_nMagic; + uint32_t m_relationsStartIdx; + uint32_t m_usesStartIdx; + uint32_t m_relationsCount; + uint32_t m_usesCount; + uint32_t m_assetHeaderSize; + uint32_t m_version; + uint32_t m_magic; }; -struct RPakAssetEntryShort +struct PakAssetShort_t { - uint64_t m_Guid; - uint64_t m_Padding; - void* m_pHead; - void* m_pCpu; + uint64_t m_guid; + uint64_t m_padding; + void* m_head; + 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. - RPakAssetEntryShort m_Assets[0x40000]; + PakAssetBinding_t m_assetBindings[64]; // [ PIXIE ]: Max possible registered assets on Season 3, 0-2 I did not check yet. + PakAssetShort_t m_assets[0x40000]; // End size unknown. }; -struct RPakHeader_t +struct PakFileHeader_t { - uint32_t m_nMagic; // 'RPak' - uint16_t m_nVersion; // R2 = '7' R5 = '8' - uint8_t m_nFlags[0x2]; // - FILETIME m_nFileTime; // - uint64_t m_nHash; // - uint64_t m_nSizeDisk; // Compressed size - uint64_t m_nEmbeddedStarpakOffset; // - uint8_t unk0[0x8]; // - uint64_t m_nSizeMemory; // Decompressed size - uint64_t m_nEmbeddedStarpakSize; // - uint8_t unk1[0x8]; // + uint32_t m_magic; // 'RPak' + uint16_t m_version; // R2 = '7' R5 = '8' + uint8_t m_flags[0x2]; // + FILETIME m_fileTime; // + uint64_t m_checksum; // + uint64_t m_compressedSize; // Compressed size + uint64_t m_embeddedStarpakOffset; // + uint8_t unk0[0x8]; // + uint64_t m_decompressedSize; // Decompressed size + uint64_t m_embeddedStarpakSize; // + uint8_t unk1[0x8]; // - uint16_t m_nStarpakReferenceSize; // - uint16_t m_nStarpakOptReferenceSize; // - uint16_t m_nVirtualSegmentCount; // * 0x10 - uint16_t m_nMemPageCount; // * 0xC + uint16_t m_starpakReferenceSize; // + uint16_t m_starpakOptReferenceSize; // + uint16_t m_virtualSegmentCount; // * 0x10 + uint16_t m_memPageCount; // * 0xC - uint32_t m_nPatchIndex; // + uint32_t m_patchIndex; // - uint32_t m_nDescriptorCount; // - uint32_t m_nAssetEntryCount; // File entry count - uint32_t m_nGuidDescriptorCount; // - uint32_t m_nRelationsCounts; // + uint32_t m_descriptorCount; // + uint32_t m_assetEntryCount; // File entry count + uint32_t m_guidDescriptorCount; // + uint32_t m_relationsCounts; // - 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' - uint8_t unk3[0x8]; // + uint8_t unk2[0x10]; // + 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]; // }; -struct RPakPatchCompressedHeader_t +struct PakPatchFileHeader_t { - uint64_t m_nSizeDisk; - uint64_t m_nSizeMemory; + size_t m_sizeDisk; + size_t m_sizeMemory; }; -struct RPakDecompState_t +struct PakPatchDataHeader_t { - uint64_t m_nInputBuf; - uint64_t m_nOut; - uint64_t m_nMask; - uint64_t m_nOutMask; - uint64_t m_nTotalFileLen; - uint64_t m_nDecompSize; - uint64_t m_nInvMaskIn; - uint64_t m_nInvMaskOut; - uint32_t m_nHeaderOffset; + int m_editStreamSize; + int m_pageCount; +}; + +struct PakSegmentHeader_t +{ + int m_flags; + int m_align; + 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; - uint64_t m_nInputBytePos; - uint64_t m_nDecompPosition; - uint64_t m_nLengthNeeded; - uint64_t byte; - uint32_t m_nByteBitOffset; + uint64_t m_fileBytePosition; + uint64_t m_decompBytePosition; + uint64_t m_bufferSizeNeeded; + uint64_t m_currentByte; + uint32_t m_currentByteBit; uint32_t dword6C; uint64_t qword70; - uint64_t m_nCompressedStreamSize; - uint64_t m_nDecompStreamSize; + uint64_t m_compressedStreamSize; + uint64_t m_decompStreamSize; }; -class RPakLoadedInfo_t +class PakLoadedInfo_t { public: - RPakHandle_t m_nHandle; //0x0000 - RPakStatus_t m_nStatus; //0x0004 + PakHandle_t m_handle; //0x0000 + EPakStatus m_status; //0x0004 uint64_t m_nUnk1; //0x0008 uint32_t m_nUnk2; //0x0010 - uint32_t m_nAssetCount; //0x0014 - char* m_pszFileName; //0x0018 - void* m_pMalloc; //0x0020 - uint64_t* m_pAssetGuids; //0x0028 size of the array is m_nAssetCount + uint32_t m_assetCount; //0x0014 + char* m_fileName; //0x0018 + void* m_allocator; //0x0020 + uint64_t* m_assetGuids; //0x0028 size of the array is m_nAssetCount #if defined (GAMEDLL_S3) - void* m_pVSegBuffers[4]; //0x0030 + void* m_virtualSegmentBuffers[4]; //0x0030 char pad_0050[16]; //0x0050 - void* m_pPakInfo; //0x0060 - RPakLoadedInfo_t* m_pUnknownLoadedPakInfo; //0x0068 + void* m_pakInfo; //0x0060 + PakLoadedInfo_t* m_pUnknownLoadedPakInfo; //0x0068 char pad_0070[4]; //0x0070 int8_t m_nUnk3; //0x0074 char pad_0075[51]; //0x0075 @@ -172,76 +190,128 @@ public: uint64_t m_nUnkEnd; //0x00B0/0x00E8 }; //Size: 0x00B8/0x00E8 -struct RPakDescriptor_t +struct PakPage_t { - uint32_t m_Index; - uint32_t m_Offset; + uint32_t m_index; + uint32_t m_offset; }; -struct RPakMemPageInfo_t +struct PakPageHeader_t { - uint32_t m_nVirtualSegmentIndex; - uint32_t m_nPageAlignment; - uint32_t m_nDataSize; + uint32_t m_virtualSegmentIndex; + uint32_t m_pageAlignment; + uint32_t m_dataSize; }; -struct RPakVirtualSegment_t +struct PakFileStream_t { - uint32_t m_nFlags; - uint32_t m_nAlignment; - uint64_t m_nDataSize; + _QWORD qword0; + _QWORD qword8; + _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; - int m_nProcessedAssetCount; - int m_nPageEnd; - int m_nPageStart; - uint32_t m_nPatchIndex_maybe; + uint64_t m_dataBuf; + int m_bitsRemaining; +}; +#pragma pack(pop) + +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; - char gap18[184]; + + PakFileStream_t* m_fileStream; + size_t m_compressSize; + int m_fileHandle; + + _BYTE gap2c[164]; uint32_t unsigned_intD0; char gapD4[284]; - uint64_t m_nInputBytePos; + uint64_t m_inputBytePos; uint8_t byte1F8; char gap1F9[4]; uint8_t byte1FD; - uint8_t byte1FE; - uint8_t byte200; - RPakDecompState_t m_PakDecompState; - uint64_t qword288; - uint64_t qword290; + short flags_1FE; + PakDecompState_t m_pakDecompState; + void* m_decompBuffer; + size_t m_maxCopySize; uint64_t qword298; - uint64_t qword2A0; - char* m_PatchData; - 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; + + PakMemoryData_t m_memoryData; }; #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 #endif // !GAMEDLL_S0 && !GAMEDLL_S1 -static_assert(sizeof(RPakDecompState_t) == 136); -static_assert(sizeof(RPakPatchCompressedHeader_t) == 16); +static_assert(sizeof(PakDecompState_t) == 136); +static_assert(sizeof(PakPatchFileHeader_t) == 16); #endif // RTECH_IPACKFILE_H diff --git a/r5dev/rtech/rtech_game.cpp b/r5dev/rtech/rtech_game.cpp index 7e37916e..c9b51053 100644 --- a/r5dev/rtech/rtech_game.cpp +++ b/r5dev/rtech/rtech_game.cpp @@ -14,7 +14,7 @@ // from within the level settings KV (located in // scripts/levels/settings/*.kv). On level unload, // each pak listed in this vector gets unloaded. -CUtlVector g_vLoadedPakHandle; +CUtlVector g_vLoadedPakHandle; //----------------------------------------------------------------------------- // Purpose: load user-requested pak files on-demand @@ -24,9 +24,9 @@ CUtlVector g_vLoadedPakHandle; // bUnk - // 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 pakOverridePath; @@ -56,15 +56,15 @@ RPakHandle_t Pak_LoadAsync(const char* szPakFileName, CAlignedMemAlloc* pMalloc, // Purpose: unloads loaded pak files // 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; } diff --git a/r5dev/rtech/rtech_game.h b/r5dev/rtech/rtech_game.h index c6c95adb..b7572306 100644 --- a/r5dev/rtech/rtech_game.h +++ b/r5dev/rtech/rtech_game.h @@ -5,34 +5,34 @@ /* ==== RTECH_GAME ====================================================================================================================================================== */ 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 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 unsigned int (*v_Pak_LoadPak)(void* thisptr, void* a2, uint64_t a3); 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 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 { void* LoadPatches; void* RegisterAsset; 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 (*UnloadPak)(RPakHandle_t handle); + void (*UnloadPak)(PakHandle_t handle); void* Func6; char unknown2[16]; void* Func7; void* Func8; - RPakStatus_t(*WaitAsync)(RPakHandle_t handle, void* pFinishCallback); + EPakStatus(*WaitAsync)(PakHandle_t handle, void* pFinishCallback); void* Func10; void* Func11; void* FindByGUID; @@ -62,7 +62,7 @@ typedef struct PakLoadFuncs_s } PakLoadFuncs_t; extern PakLoadFuncs_t* g_pakLoadApi; -extern CUtlVector g_vLoadedPakHandle; +extern CUtlVector g_vLoadedPakHandle; /////////////////////////////////////////////////////////////////////////////// class V_RTechGame : public IDetour @@ -79,16 +79,16 @@ class V_RTechGame : public IDetour virtual void GetFun(void) const { p_Pak_LoadAsync = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 89 03 8B 0B").FollowNearCallSelf(); - v_Pak_LoadAsync = p_Pak_LoadAsync.RCast(); + v_Pak_LoadAsync = p_Pak_LoadAsync.RCast(); p_Pak_WaitAsync = g_GameDll.FindPatternSIMD("40 53 55 48 83 EC 38 48 89 74 24 ??"); - v_Pak_WaitAsync = p_Pak_WaitAsync.RCast(); + v_Pak_WaitAsync = p_Pak_WaitAsync.RCast(); p_Pak_LoadPak = g_GameDll.FindPatternSIMD("48 89 4C 24 ?? 56 41 55 48 81 EC ?? ?? ?? ?? 4C"); v_Pak_LoadPak = p_Pak_LoadPak.RCast(); p_Pak_UnloadPak = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 85 FF 74 0C").FollowNearCallSelf(); - v_Pak_UnloadPak = p_Pak_UnloadPak.RCast(); + v_Pak_UnloadPak = p_Pak_UnloadPak.RCast(); } virtual void GetVar(void) const { diff --git a/r5dev/rtech/rtech_utils.cpp b/r5dev/rtech/rtech_utils.cpp index 2b052774..1743b223 100644 --- a/r5dev/rtech/rtech_utils.cpp +++ b/r5dev/rtech/rtech_utils.cpp @@ -68,7 +68,7 @@ uint64_t __fastcall RTech::StringToGuid(const char* pData) //----------------------------------------------------------------------------- // 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 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 file_buf = uintptr_t(fileBuffer); - state->m_nInputBuf = file_buf; - state->m_nOut = 0i64; - state->m_nOutMask = 0i64; + state->m_inputBuf = file_buf; + state->m_outputBuf = 0i64; + state->m_outputMask = 0i64; state->dword44 = 0; - state->m_nTotalFileLen = fileSize + offNoHeader; - state->m_nMask = mask; + state->m_fileSize = fileSize + offNoHeader; + state->m_inputMask = mask; input_byte_pos_init = offNoHeader + headerSize + 8; byte_init = *(uint64_t*)((mask & (offNoHeader + headerSize)) + file_buf); - state->m_nDecompPosition = headerSize; + state->m_decompBytePosition = headerSize; decompressed_size_bits = byte_init & 0x3F; byte_init >>= 6; - state->m_nInputBytePos = input_byte_pos_init; - state->m_nDecompSize = (byte_init & ((1i64 << decompressed_size_bits) - 1)) | (1i64 << decompressed_size_bits); + state->m_fileBytePosition = input_byte_pos_init; + 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 - ((uint8_t)decompressed_size_bits + 6)); 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; 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; inv_mask_in = 0xFFFFFFFFFFFFFFFFui64 >> (64 - (uint8_t)brih_bits); - state->m_nInvMaskIn = inv_mask_in; - state->m_nInvMaskOut = 0xFFFFFFFFFFFFFFFFui64 >> (63 - (((byte_1 >> 6) - 1) & 0x3F)); + state->m_inputInvMask = inv_mask_in; + 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 - (uint8_t)bit_pos_final)); bit_pos_final_1 = bit_pos_final; byte_bit_offset_final = bit_pos_final & 7; input_byte_pos_final = (bit_pos_final_1 >> 3) + input_byte_pos_1; 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) { - state->m_nHeaderOffset = 0; + state->m_headerOffset = 0; stream_len_needed = fileSize; } else { 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); - 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); } - result = state->m_nDecompSize; - inv_mask_out = state->m_nInvMaskOut; - qw70 = offNoHeader + state->m_nInvMaskIn - 6i64; - state->m_nLengthNeeded = stream_len_needed + offNoHeader; + result = state->m_decompSize; + inv_mask_out = state->m_outputInvMask; + qw70 = offNoHeader + state->m_inputInvMask - 6i64; + state->m_bufferSizeNeeded = stream_len_needed + offNoHeader; state->qword70 = qw70; - state->byte = byte_final; - state->m_nByteBitOffset = byte_bit_offset_final; + state->m_currentByte = byte_final; + state->m_currentByteBit = byte_bit_offset_final; state->dword6C = 0; - state->m_nCompressedStreamSize = stream_len_needed + offNoHeader; - state->m_nDecompStreamSize = result; + state->m_compressedStreamSize = stream_len_needed + offNoHeader; + state->m_decompStreamSize = result; if (result - 1 > inv_mask_out) { - stream_compressed_size_new = stream_len_needed + offNoHeader - state->m_nHeaderOffset; - state->m_nDecompStreamSize = inv_mask_out + 1; - state->m_nCompressedStreamSize = stream_compressed_size_new; + stream_compressed_size_new = stream_len_needed + offNoHeader - state->m_headerOffset; + state->m_decompStreamSize = inv_mask_out + 1; + state->m_compressedStreamSize = stream_compressed_size_new; } return result; @@ -280,7 +280,7 @@ static const unsigned char /*unk_141313180*/ s_PakFileCompressionLUT[0x720] = //----------------------------------------------------------------------------- // 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 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] uint64_t v74; // [rsp+78h] [rbp+20h] - if (inLen < state->m_nLengthNeeded) + if (inLen < state->m_bufferSizeNeeded) return 0; - v5 = state->m_nDecompPosition; - if (outLen < state->m_nInvMaskOut + (v5 & ~state->m_nInvMaskOut) + 1 && outLen < state->m_nDecompSize) + v5 = state->m_decompBytePosition; + if (outLen < state->m_outputInvMask + (v5 & ~state->m_outputInvMask) + 1 && outLen < state->m_decompSize) return 0; - v6 = state->m_nOut; - v7 = state->m_nByteBitOffset; - v8 = state->byte; - v9 = state->m_nInputBytePos; + v6 = state->m_outputBuf; + v7 = state->m_currentByteBit; + v8 = state->m_currentByte; + v9 = state->m_fileBytePosition; v10 = state->qword70; - v11 = state->m_nInputBuf; - if (state->m_nCompressedStreamSize < v10) - v10 = state->m_nCompressedStreamSize; + v11 = state->m_inputBuf; + if (state->m_compressedStreamSize < v10) + v10 = state->m_compressedStreamSize; v12 = state->dword6C; v74 = v11; v70 = v6; v71 = v12; if (!v7) 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) { v7 &= 7u; @@ -389,12 +389,12 @@ uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, uint64_t i if (*((char*)&s_PakFileCompressionLUT + v18) < 0) { v56 = -(int)v20; - v57 = (__int64*)(v11 + (v9 & state->m_nMask)); + v57 = (__int64*)(v11 + (v9 & state->m_inputMask)); 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 ((~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; v59 = char(v19); 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; 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)); - 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))))); 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; @@ -480,7 +480,7 @@ uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, uint64_t i v45 = *((_BYTE*)&s_PakFileCompressionLUT + v46 + 1216); 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); v7 -= 8; } @@ -536,18 +536,18 @@ uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, uint64_t i break; LABEL_29: 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; - v30 = state->m_nDecompSize; + v30 = state->m_decompSize; if (v5 == v30) { result = 1; goto LABEL_69; } - v31 = state->m_nInvMaskIn; - v32 = state->m_nHeaderOffset; + v31 = state->m_inputInvMask; + v32 = state->m_headerOffset; v33 = v31 & -(__int64)v9; v19 >>= 1; ++v7; @@ -558,32 +558,32 @@ uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, uint64_t i if (v9 > v34) state->qword70 = v31 + v34 + 1; } - v35 = v9 & state->m_nMask; + v35 = v9 & state->m_inputMask; v9 += v32; - v36 = v5 + state->m_nInvMaskOut + 1; + v36 = v5 + state->m_outputInvMask + 1; v37 = *(_QWORD*)(v35 + v11) & ((1i64 << (8 * (unsigned __int8)v32)) - 1); - v38 = v37 + state->m_nLengthNeeded; - v39 = v37 + state->m_nCompressedStreamSize; - state->m_nLengthNeeded = v38; - state->m_nCompressedStreamSize = v39; + v38 = v37 + state->m_bufferSizeNeeded; + v39 = v37 + state->m_compressedStreamSize; + state->m_bufferSizeNeeded = v38; + state->m_compressedStreamSize = v39; if (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) { LABEL_25: v10 = state->qword70; if (v9 >= v10) { - v9 = ~state->m_nInvMaskIn & (v9 + 7); - v10 += state->m_nInvMaskIn + 1; + v9 = ~state->m_inputInvMask & (v9 + 7); + v10 += state->m_inputInvMask + 1; state->qword70 = v10; } - if (state->m_nCompressedStreamSize < v10) - v10 = state->m_nCompressedStreamSize; + if (state->m_compressedStreamSize < v10) + v10 = state->m_compressedStreamSize; goto LABEL_29; } v69 = state->qword70; @@ -594,11 +594,11 @@ uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, uint64_t i } state->dword6C = v71; result = 0; - state->byte = v19; - state->m_nByteBitOffset = v7; + state->m_currentByte = v19; + state->m_currentByteBit = v7; LABEL_69: - state->m_nDecompPosition = v5; - state->m_nInputBytePos = v9; + state->m_decompBytePosition = v5; + state->m_fileBytePosition = v9; 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 //----------------------------------------------------------------------------- -RPakLoadedInfo_t* RTech::GetPakLoadedInfo(RPakHandle_t nHandle) +PakLoadedInfo_t* RTech::GetPakLoadedInfo(PakHandle_t nHandle) { for (int16_t i = 0; i < *g_pLoadedPakCount; ++i) { - RPakLoadedInfo_t* info = &g_pLoadedPakInfo[i]; + PakLoadedInfo_t* info = &g_pLoadedPakInfo[i]; if (!info) continue; - if (info->m_nHandle != nHandle) + if (info->m_handle != nHandle) continue; return info; @@ -682,18 +682,18 @@ RPakLoadedInfo_t* RTech::GetPakLoadedInfo(RPakHandle_t nHandle) //----------------------------------------------------------------------------- // 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) { - RPakLoadedInfo_t* info = &g_pLoadedPakInfo[i]; + PakLoadedInfo_t* info = &g_pLoadedPakInfo[i]; if (!info) continue; - if (!info->m_pszFileName || !*info->m_pszFileName) + if (!info->m_fileName || !*info->m_fileName) continue; - if (strcmp(szPakName, info->m_pszFileName) != 0) + if (strcmp(szPakName, info->m_fileName) != 0) continue; return info; @@ -706,26 +706,26 @@ RPakLoadedInfo_t* RTech::GetPakLoadedInfo(const char* szPakName) //----------------------------------------------------------------------------- // Purpose: returns pak status as string //----------------------------------------------------------------------------- -const char* RTech::PakStatusToString(RPakStatus_t status) +const char* RTech::PakStatusToString(EPakStatus status) { switch (status) { - case RPakStatus_t::PAK_STATUS_FREED: return "PAK_STATUS_FREED"; - case RPakStatus_t::PAK_STATUS_LOAD_PENDING: return "PAK_STATUS_LOAD_PENDING"; - case RPakStatus_t::PAK_STATUS_REPAK_RUNNING: return "PAK_STATUS_REPAK_RUNNING"; - case RPakStatus_t::PAK_STATUS_REPAK_DONE: return "PAK_STATUS_REPAK_DONE"; - case RPakStatus_t::PAK_STATUS_LOAD_STARTING: return "PAK_STATUS_LOAD_STARTING"; - case RPakStatus_t::PAK_STATUS_LOAD_PAKHDR: return "PAK_STATUS_LOAD_PAKHDR"; - case RPakStatus_t::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 RPakStatus_t::PAK_STATUS_LOAD_ASSETS: return "PAK_STATUS_LOAD_ASSETS"; - case RPakStatus_t::PAK_STATUS_LOADED: return "PAK_STATUS_LOADED"; - case RPakStatus_t::PAK_STATUS_UNLOAD_PENDING: return "PAK_STATUS_UNLOAD_PENDING"; - case RPakStatus_t::PAK_STATUS_FREE_PENDING: return "PAK_STATUS_FREE_PENDING"; - case RPakStatus_t::PAK_STATUS_CANCELING: return "PAK_STATUS_CANCELING"; - case RPakStatus_t::PAK_STATUS_ERROR: return "PAK_STATUS_ERROR"; - case RPakStatus_t::PAK_STATUS_INVALID_PAKHANDLE: return "PAK_STATUS_INVALID_PAKHANDLE"; - case RPakStatus_t::PAK_STATUS_BUSY: return "PAK_STATUS_BUSY"; + case EPakStatus::PAK_STATUS_FREED: return "PAK_STATUS_FREED"; + case EPakStatus::PAK_STATUS_LOAD_PENDING: return "PAK_STATUS_LOAD_PENDING"; + case EPakStatus::PAK_STATUS_REPAK_RUNNING: return "PAK_STATUS_REPAK_RUNNING"; + case EPakStatus::PAK_STATUS_REPAK_DONE: return "PAK_STATUS_REPAK_DONE"; + case EPakStatus::PAK_STATUS_LOAD_STARTING: return "PAK_STATUS_LOAD_STARTING"; + case EPakStatus::PAK_STATUS_LOAD_PAKHDR: return "PAK_STATUS_LOAD_PAKHDR"; + case EPakStatus::PAK_STATUS_LOAD_PATCH_INIT: return "PAK_STATUS_LOAD_PATCH_INIT"; + case EPakStatus::PAK_STATUS_LOAD_PATCH_EDIT_STREAM: return "PAK_STATUS_LOAD_PATCH_EDIT_STREAM"; + case EPakStatus::PAK_STATUS_LOAD_ASSETS: return "PAK_STATUS_LOAD_ASSETS"; + case EPakStatus::PAK_STATUS_LOADED: return "PAK_STATUS_LOADED"; + case EPakStatus::PAK_STATUS_UNLOAD_PENDING: return "PAK_STATUS_UNLOAD_PENDING"; + case EPakStatus::PAK_STATUS_FREE_PENDING: return "PAK_STATUS_FREE_PENDING"; + case EPakStatus::PAK_STATUS_CANCELING: return "PAK_STATUS_CANCELING"; + case EPakStatus::PAK_STATUS_ERROR: return "PAK_STATUS_ERROR"; + case EPakStatus::PAK_STATUS_INVALID_PAKHANDLE: return "PAK_STATUS_INVALID_PAKHANDLE"; + case EPakStatus::PAK_STATUS_BUSY: return "PAK_STATUS_BUSY"; default: return "PAK_STATUS_UNKNOWN"; } } @@ -733,7 +733,7 @@ const char* RTech::PakStatusToString(RPakStatus_t status) //----------------------------------------------------------------------------- // 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) 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; #endif - RPakDescriptor_t* pGuidDescriptors = &pPak->m_pGuidDescriptors[pAsset->m_nUsesStartIdx]; - volatile uint32_t* v5 = reinterpret_cast(*(reinterpret_cast(g_pPakGlobals) + GLOBAL_MUL * (pPak->qword578 & 0x1FF) + 0x160212)); + PakPage_t* pGuidDescriptors = &pPak->m_memoryData.m_guidDescriptors[pAsset->m_usesStartIdx]; + volatile uint32_t* v5 = reinterpret_cast(*(reinterpret_cast(g_pPakGlobals) + GLOBAL_MUL * (pPak->m_memoryData.qword2D8 & 0x1FF) + 0x160212)); const bool bDebug = rtech_debug->GetBool(); 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(pPak->m_ppPagePointers[pGuidDescriptors[i].m_Index] + pGuidDescriptors[i].m_Offset); + void** pCurrentGuid = reinterpret_cast(pPak->m_memoryData.m_pagePointers[pGuidDescriptors[i].m_index] + pGuidDescriptors[i].offset); // Get current guid. const uint64_t currentGuid = reinterpret_cast(*pCurrentGuid); // Get asset index. 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); *reinterpret_cast(const_cast(&v5[2 * v9 + 2])) = currentGuid; - *reinterpret_cast(const_cast(&v5[2 * v9 + 4])) = pAsset->m_Guid; + *reinterpret_cast(const_cast(&v5[2 * v9 + 4])) = pAsset->m_guid; std::function fnCheckAsset = [&](bool shouldCheckTwo) { @@ -769,7 +769,7 @@ void RTech::PakProcessGuidRelationsForAsset(PakFile_t* pPak, RPakAssetEntry_t* p { if (shouldCheckTwo && assetIdxEntryGuid == 2) { - if (pPak->m_PakHdr.m_nAssetEntryCount) + if (pPak->m_memoryData.m_pakHeader.m_assetEntryCount) 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. 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()) DebugBreak(); } assetIdx &= 0x3FFFF; - assetIdxEntryGuid = g_pPakGlobals->m_Assets[assetIdx].m_Guid; + assetIdxEntryGuid = g_pPakGlobals->m_assets[assetIdx].m_guid; if (assetIdxEntryGuid == currentGuid) return true; @@ -796,24 +796,24 @@ void RTech::PakProcessGuidRelationsForAsset(PakFile_t* pPak, RPakAssetEntry_t* p // Are we some special asset with the guid 2? if (!fnCheckAsset(true)) { - RPakAssetEntry_t* assetEntries = pPak->m_pAssetEntries; + PakAsset_t* assetEntries = pPak->m_memoryData.m_assetEntries; 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); break; } } - assetIdx = pPak->qword580[a]; + assetIdx = pPak->m_memoryData.qword2E0[a]; } } // 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 diff --git a/r5dev/rtech/rtech_utils.h b/r5dev/rtech/rtech_utils.h index 2d55d8a6..a8c6e18b 100644 --- a/r5dev/rtech/rtech_utils.h +++ b/r5dev/rtech/rtech_utils.h @@ -18,17 +18,17 @@ inline void(*RTech_RegisterAsset)(int, int, const char*, void*, void*, void*, vo #ifdef GAMEDLL_S3 inline CMemory p_Pak_ProcessGuidRelationsForAsset; -inline void(*RTech_Pak_ProcessGuidRelationsForAsset)(PakFile_t*, RPakAssetEntry_t*); +inline void(*RTech_Pak_ProcessGuidRelationsForAsset)(PakFile_t*, PakAsset_t*); #endif inline CMemory p_StreamDB_Init; 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_pLoadedPakCount; inline JobID_t* g_pPakLoadJobID; -inline RPakGlobals_t* g_pPakGlobals; +inline PakGlobals_t* g_pPakGlobals; inline int32_t* s_pFileArray; inline PSRWLOCK* s_pFileArrayMutex; @@ -42,15 +42,15 @@ class RTech { public: uint64_t __fastcall StringToGuid(const char* pData); - uint8_t __fastcall DecompressPakFile(RPakDecompState_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); - RPakLoadedInfo_t* GetPakLoadedInfo(RPakHandle_t nPakId); - RPakLoadedInfo_t* GetPakLoadedInfo(const char* szPakName); - const char* PakStatusToString(RPakStatus_t status); + uint8_t __fastcall DecompressPakFile(PakDecompState_t* state, uint64_t inLen, uint64_t outLen); + uint64_t __fastcall DecompressPakFileInit(PakDecompState_t* state, uint8_t* fileBuffer, uint64_t fileSize, uint64_t offNoHeader, uint64_t headerSize); + PakLoadedInfo_t* GetPakLoadedInfo(PakHandle_t nPakId); + PakLoadedInfo_t* GetPakLoadedInfo(const char* szPakName); + const char* PakStatusToString(EPakStatus status); static int32_t OpenFile(const CHAR* szFilePath, void* unused, LONGLONG* fileSizeOut); #ifdef GAMEDLL_S3 - static void PakProcessGuidRelationsForAsset(PakFile_t* pak, RPakAssetEntry_t* asset); + static void PakProcessGuidRelationsForAsset(PakFile_t* pak, PakAsset_t* asset); #endif // GAMEDLL_S3 void** LoadShaderSet(void** VTablePtr); @@ -99,7 +99,7 @@ class V_RTechUtils : public IDetour #ifdef GAMEDLL_S3 p_Pak_ProcessGuidRelationsForAsset = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 48 8B 86 ?? ?? ?? ?? 42 8B 0C B0").FollowNearCallSelf(); - RTech_Pak_ProcessGuidRelationsForAsset = p_Pak_ProcessGuidRelationsForAsset.RCast(); /*E8 ? ? ? ? 48 8B 86 ? ? ? ? 42 8B 0C B0*/ + RTech_Pak_ProcessGuidRelationsForAsset = p_Pak_ProcessGuidRelationsForAsset.RCast(); /*E8 ? ? ? ? 48 8B 86 ? ? ? ? 42 8B 0C B0*/ #endif } 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(); s_pFileArrayMutex = p_StreamDB_Init.Offset(0x70).FindPatternSelf("48 8D 0D", CMemory::Direction::DOWN, 512, 1).ResolveRelativeAddress(0x3, 0x7).RCast(); - g_pLoadedPakInfo = p_Pak_UnloadPak.FindPattern("48 8D 05", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + g_pLoadedPakInfo = p_Pak_UnloadPak.FindPattern("48 8D 05", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); g_pRequestedPakCount = p_Pak_UnloadPak.FindPattern("66 89", CMemory::Direction::DOWN, 450).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); 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(); /*48 8D 1D ? ? ? ? 45 8D 5A 0E*/ + g_pPakGlobals = g_GameDll.FindPatternSIMD("48 8D 1D ?? ?? ?? ?? 45 8D 5A 0E").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); /*48 8D 1D ? ? ? ? 45 8D 5A 0E*/ g_pPakLoadJobID = reinterpret_cast(&*g_pLoadedPakCount - 2); g_pPakFifoLock = p_JT_HelpWithAnything.Offset(0x155).FindPatternSelf("48 8D 0D").ResolveRelativeAddressSelf(0x3, 0x7).RCast();