From 7a33fe42e8a5cc3e456970e75bdfe6e0241b4923 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Tue, 18 Jan 2022 11:10:53 +0000 Subject: [PATCH] :rotating_light: Fix DB_EnumXAssetEntries :zap: --- .../Modules/AssetInterfaces/IMaterial.cpp | 35 ++++++++++--------- src/Game/Functions.cpp | 22 +++++++++--- src/Game/Functions.hpp | 11 ++++++ src/Game/Structs.hpp | 13 +++++++ 4 files changed, 60 insertions(+), 21 deletions(-) diff --git a/src/Components/Modules/AssetInterfaces/IMaterial.cpp b/src/Components/Modules/AssetInterfaces/IMaterial.cpp index 89abca3d..23f63ef2 100644 --- a/src/Components/Modules/AssetInterfaces/IMaterial.cpp +++ b/src/Components/Modules/AssetInterfaces/IMaterial.cpp @@ -250,28 +250,31 @@ namespace Assets if (iw4TechSet) { Game::DB_EnumXAssetEntries(Game::XAssetType::ASSET_TYPE_MATERIAL, [asset, iw4TechSet](Game::XAssetEntry* entry) + { + if (!replacementFound) { - if (!replacementFound) + Game::XAssetHeader header = entry->asset.header; + + if (header.material->techniqueSet == iw4TechSet->asset.header.techniqueSet) { - Game::XAssetHeader header = entry->asset.header; + Components::Logger::Print("Material %s with techset %s has been mapped to %s (last chance!), taking the sort key of material %s\n", + asset->info.name, asset->techniqueSet->name, + header.material->techniqueSet->name, header.material->info.name); - if (header.material->techniqueSet == iw4TechSet->asset.header.techniqueSet) - { - Components::Logger::Print("Material %s with techset %s has been mapped to %s (last chance!), taking the sort key of material %s\n", asset->info.name, asset->techniqueSet->name, header.material->techniqueSet->name, header.material->info.name); - asset->info.sortKey = header.material->info.sortKey; - asset->techniqueSet = iw4TechSet->asset.header.techniqueSet; + asset->info.sortKey = header.material->info.sortKey; + asset->techniqueSet = iw4TechSet->asset.header.techniqueSet; - // this is terrible! - asset->stateBitsCount = header.material->stateBitsCount; - asset->stateBitsTable = header.material->stateBitsTable; - std::memcpy(asset->stateBitsEntry, header.material->stateBitsEntry, 48); - asset->constantCount = header.material->constantCount; - asset->constantTable = header.material->constantTable; + // this is terrible! + asset->stateBitsCount = header.material->stateBitsCount; + asset->stateBitsTable = header.material->stateBitsTable; + std::memcpy(asset->stateBitsEntry, header.material->stateBitsEntry, 48); + asset->constantCount = header.material->constantCount; + asset->constantTable = header.material->constantTable; - replacementFound = true; - } + replacementFound = true; } - }, false, false); + } + }, false, false); if (!replacementFound) { diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 86d8b5c5..39c91002 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -336,6 +336,9 @@ namespace Game Sys_SuspendOtherThreads_t Sys_SuspendOtherThreads = Sys_SuspendOtherThreads_t(0x45A190); Sys_ListFiles_t Sys_ListFiles = Sys_ListFiles_t(0x45A660); Sys_Milliseconds_t Sys_Milliseconds = Sys_Milliseconds_t(0x42A660); + Sys_LockWrite_t Sys_LockWrite = Sys_LockWrite_t(0x435880); + Sys_TempPriorityAtLeastNormalBegin_t Sys_TempPriorityAtLeastNormalBegin = Sys_TempPriorityAtLeastNormalBegin_t(0x478680); + Sys_TempPriorityEnd_t Sys_TempPriorityEnd = Sys_TempPriorityEnd_t(0x4DCF00); TeleportPlayer_t TeleportPlayer = TeleportPlayer_t(0x496850); @@ -493,6 +496,16 @@ namespace Game GraphFloat* aaInputGraph = reinterpret_cast(0x7A2FC0); + FastCriticalSection* db_hashCritSect = reinterpret_cast(0x16B8A54); + + void Sys_UnlockWrite(FastCriticalSection* critSect) + { + assert(critSect->writeCount > 0); + + InterlockedDecrement(&critSect->writeCount); + Sys_TempPriorityEnd(&critSect->tempPriority); + } + XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize) { int elSize = DB_GetXAssetSizeHandlers[type](); @@ -609,10 +622,8 @@ namespace Game void DB_EnumXAssetEntries(XAssetType type, std::function callback, bool overrides, bool lock) { - volatile long* lockVar = reinterpret_cast(0x16B8A54); - if (lock) InterlockedIncrement(lockVar); - - while (lock && *reinterpret_cast(0x16B8A58)) std::this_thread::sleep_for(1ms); + if (lock) + Sys_LockWrite(db_hashCritSect); const auto pool = Components::Maps::GetAssetEntryPool(); for(auto hash = 0; hash < 37000; hash++) @@ -641,7 +652,8 @@ namespace Game } } - if(lock) InterlockedDecrement(lockVar); + if(lock) + Sys_UnlockWrite(db_hashCritSect); } // this cant be MessageBox because windows.h has a define that converts it to MessageBoxW. which is just stupid diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 7da47215..127e606d 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -804,6 +804,15 @@ namespace Game typedef int(__cdecl * Sys_Milliseconds_t)(); extern Sys_Milliseconds_t Sys_Milliseconds; + typedef void(__cdecl * Sys_LockWrite_t)(FastCriticalSection* critSect); + extern Sys_LockWrite_t Sys_LockWrite; + + typedef void(__cdecl * Sys_TempPriorityAtLeastNormalBegin_t)(TempPriority*); + extern Sys_TempPriorityAtLeastNormalBegin_t Sys_TempPriorityAtLeastNormalBegin; + + typedef void(__cdecl * Sys_TempPriorityEnd_t)(TempPriority*); + extern Sys_TempPriorityEnd_t Sys_TempPriorityEnd; + typedef void(__cdecl * TeleportPlayer_t)(gentity_t* entity, float* pos, float* orientation); extern TeleportPlayer_t TeleportPlayer; @@ -1013,6 +1022,8 @@ namespace Game constexpr auto AIM_ASSIST_GRAPH_COUNT = 4u; extern GraphFloat* aaInputGraph; + void Sys_UnlockWrite(FastCriticalSection*); + XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize); void Menu_FreeItemMemory(Game::itemDef_s* item); void Menu_SetNextCursorItem(Game::UiContext* ctx, Game::menuDef_t* currentMenu, int unk = 1); diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 8a74e54d..a0ea28a9 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -6961,6 +6961,19 @@ namespace Game PM_EFF_STANCE_COUNT = 4 }; + struct TempPriority + { + void* threadHandle; + int oldPriority; + }; + + struct FastCriticalSection + { + volatile long readCount; + volatile long writeCount; + TempPriority tempPriority; + }; + #pragma endregion #ifndef IDA