From 8e4c10298489096ad106c8314a54c3f94db0bdac Mon Sep 17 00:00:00 2001 From: Louvenarde Date: Sat, 14 Aug 2021 00:27:19 +0200 Subject: [PATCH] Sound mutex workaround --- src/Components/Loader.cpp | 1 + src/Components/Loader.hpp | 1 + src/Components/Modules/SoundMutexFix.cpp | 43 ++++++++++++++++++++++++ src/Components/Modules/SoundMutexFix.hpp | 14 ++++++++ 4 files changed, 59 insertions(+) create mode 100644 src/Components/Modules/SoundMutexFix.cpp create mode 100644 src/Components/Modules/SoundMutexFix.hpp diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index 30819a9f..c6b86290 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -101,6 +101,7 @@ namespace Components Loader::Register(new StructuredData()); Loader::Register(new ConnectProtocol()); Loader::Register(new StartupMessages()); + Loader::Register(new SoundMutexFix()); Loader::Register(new Client()); diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index 589f256a..998e71e8 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -130,5 +130,6 @@ namespace Components #include "Modules/ConnectProtocol.hpp" #include "Modules/StartupMessages.hpp" #include "Modules/Stats.hpp" +#include "Modules/SoundMutexFix.hpp" #include "Modules/Client.hpp" \ No newline at end of file diff --git a/src/Components/Modules/SoundMutexFix.cpp b/src/Components/Modules/SoundMutexFix.cpp new file mode 100644 index 00000000..b80f936c --- /dev/null +++ b/src/Components/Modules/SoundMutexFix.cpp @@ -0,0 +1,43 @@ +#include "STDInclude.hpp" + +namespace Components +{ + /// This component is a workaround for issue https://github.com/XLabsProject/iw4x-client/issues/80 + /// In case the link goes down, this is a "game hangs randomly" issue: + /// + /// Investigations on the issue pointed out it comes from a situation on Intel processors where + /// WaitForSingleObjectA is ignored by a thread, for some (?) reason. + /// + /// This locks up the game randomly, mostly at the end of rounds or when too many things happen at + /// once, due to trying to stop sounds (AIL_Stop_sounds) and playing streams at the same time, + /// rushing for the same resource via AIL_lock_mutex. + /// + /// This bug has been reproduced on mp_terminal, mp_overgrown, mp_rust, with and without bots, + /// and so far this has been the only way to circumvent it afaik. This component wraps + /// miles' mutex into another mutex, created below, and for some reason (?) that mutex is + /// respected when miles' is not. + /// + /// As soon as a real fix is found, please discard this fix. In the meantime, it should not + /// have side effects too bad - worst case it might cause a slight performance drop during + /// team switch and intermission. + /// + + std::mutex SoundMutexFix::snd_mutex; + + static void __stdcall LockSoundMutex(int unk) + { + std::lock_guard lock(SoundMutexFix::snd_mutex); + + DWORD funcPtr = *reinterpret_cast(0x6D7554); // AIL_close_stream + ((void(__stdcall*)(int unk))(funcPtr))(unk); + } + + SoundMutexFix::SoundMutexFix() + { + Utils::Hook(0x689EFE, &LockSoundMutex, HOOK_JUMP).install()->quick(); + } + + SoundMutexFix::~SoundMutexFix() + { + } +} \ No newline at end of file diff --git a/src/Components/Modules/SoundMutexFix.hpp b/src/Components/Modules/SoundMutexFix.hpp new file mode 100644 index 00000000..3e6e2b20 --- /dev/null +++ b/src/Components/Modules/SoundMutexFix.hpp @@ -0,0 +1,14 @@ +#pragma once + +namespace Components +{ + class SoundMutexFix : public Component + { + public: + SoundMutexFix(); + ~SoundMutexFix(); + + static void SND_StopStreamChannelHook(int channel); + static std::mutex snd_mutex; + }; +}