fix crash in SND func (#407)

This commit is contained in:
Edo 2022-08-03 18:27:07 +02:00 committed by GitHub
parent 358b503009
commit 50eaba2ca9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 27 deletions

View File

@ -47,7 +47,7 @@ namespace Components
} }
} }
__declspec(naked) void QuickPatch::JavelinResetHookStub() __declspec(naked) void QuickPatch::JavelinResetHook_Stub()
{ {
__asm __asm
{ {
@ -62,7 +62,7 @@ namespace Components
} }
Game::dvar_t* QuickPatch::g_antilag; Game::dvar_t* QuickPatch::g_antilag;
__declspec(naked) void QuickPatch::ClientEventsFireWeaponStub() __declspec(naked) void QuickPatch::ClientEventsFireWeapon_Stub()
{ {
__asm __asm
{ {
@ -90,7 +90,7 @@ namespace Components
} }
} }
__declspec(naked) void QuickPatch::ClientEventsFireWeaponMeleeStub() __declspec(naked) void QuickPatch::ClientEventsFireWeaponMelee_Stub()
{ {
__asm __asm
{ {
@ -144,7 +144,7 @@ namespace Components
Utils::Hook::Set<float>(0x66E1C78, r_customAspectRatio.get<float>()); Utils::Hook::Set<float>(0x66E1C78, r_customAspectRatio.get<float>());
} }
__declspec(naked) void QuickPatch::SetAspectRatioStub() __declspec(naked) void QuickPatch::SetAspectRatio_Stub()
{ {
__asm __asm
{ {
@ -175,7 +175,7 @@ namespace Components
} }
} }
BOOL QuickPatch::IsDynClassnameStub(const char* classname) BOOL QuickPatch::IsDynClassname_Stub(const char* classname)
{ {
const auto version = Zones::Version(); const auto version = Zones::Version();
@ -248,10 +248,46 @@ namespace Components
} }
auto workingDir = std::filesystem::current_path().string(); auto workingDir = std::filesystem::current_path().string();
auto dir = FileSystem::GetAppdataPath() / "data" / "iw4x" / *Game::sys_exitCmdLine; auto binary = FileSystem::GetAppdataPath() / "data" / "iw4x" / *Game::sys_exitCmdLine;
SetEnvironmentVariableA("XLABS_MW2_INSTALL", workingDir.data()); SetEnvironmentVariableA("XLABS_MW2_INSTALL", workingDir.data());
Utils::Library::LaunchProcess(dir.string(), "-singleplayer", workingDir); Utils::Library::LaunchProcess(binary.string(), "-singleplayer", workingDir);
}
__declspec(naked) void QuickPatch::SND_GetAliasOffset_Stub()
{
using namespace Game;
static const char* msg = "SND_GetAliasOffset: Could not find sound alias '%s'";
static const DWORD func = 0x4B22D0; // Com_Error
__asm
{
// Check if snd_alias_t* is null immediately after call to Com_FindSoundAlias_FastFile
test eax, eax
jz error
// Game code hook skipped
mov ecx, eax
mov edx, dword ptr [ecx + 0x4]
// Resume function
push 0x437CB2
ret
error:
add esp, 0x4 // Com_FindSoundAlias_FastFile takes one argument
push [esi] // alias->aliasName
push msg
push ERR_DROP
call func // Going to longjmp back to safety
add esp, 0xC
xor eax, eax
pop esi
ret
}
} }
Game::dvar_t* QuickPatch::Dvar_RegisterConMinicon(const char* dvarName, [[maybe_unused]] bool value, unsigned __int16 flags, const char* description) Game::dvar_t* QuickPatch::Dvar_RegisterConMinicon(const char* dvarName, [[maybe_unused]] bool value, unsigned __int16 flags, const char* description)
@ -267,7 +303,7 @@ namespace Components
QuickPatch::QuickPatch() QuickPatch::QuickPatch()
{ {
// Filtering any mapents that is intended for Spec:Ops gamemode (CODO) and prevent them from spawning // Filtering any mapents that is intended for Spec:Ops gamemode (CODO) and prevent them from spawning
Utils::Hook(0x5FBD6E, QuickPatch::IsDynClassnameStub, HOOK_CALL).install()->quick(); Utils::Hook(0x5FBD6E, QuickPatch::IsDynClassname_Stub, HOOK_CALL).install()->quick();
// Hook escape handling on open console to change behaviour to close the console instead of only canceling autocomplete // Hook escape handling on open console to change behaviour to close the console instead of only canceling autocomplete
Utils::Hook(0x4F66A3, CL_KeyEvent_ConsoleEscape_Stub, HOOK_JUMP).install()->quick(); Utils::Hook(0x4F66A3, CL_KeyEvent_ConsoleEscape_Stub, HOOK_JUMP).install()->quick();
@ -276,15 +312,15 @@ namespace Components
Game::Dvar_RegisterFloat("scr_intermissionTime", 10, 0, 120, Game::DVAR_NONE, "Time in seconds before match server loads the next map"); Game::Dvar_RegisterFloat("scr_intermissionTime", 10, 0, 120, Game::DVAR_NONE, "Time in seconds before match server loads the next map");
g_antilag = Game::Dvar_RegisterBool("g_antilag", true, Game::DVAR_CODINFO, "Perform antilag"); g_antilag = Game::Dvar_RegisterBool("g_antilag", true, Game::DVAR_CODINFO, "Perform antilag");
Utils::Hook(0x5D6D56, QuickPatch::ClientEventsFireWeaponStub, HOOK_JUMP).install()->quick(); Utils::Hook(0x5D6D56, QuickPatch::ClientEventsFireWeapon_Stub, HOOK_JUMP).install()->quick();
Utils::Hook(0x5D6D6A, QuickPatch::ClientEventsFireWeaponMeleeStub, HOOK_JUMP).install()->quick(); Utils::Hook(0x5D6D6A, QuickPatch::ClientEventsFireWeaponMelee_Stub, HOOK_JUMP).install()->quick();
// Javelin fix // Javelin fix
Utils::Hook(0x578F52, QuickPatch::JavelinResetHookStub, HOOK_JUMP).install()->quick(); Utils::Hook(0x578F52, QuickPatch::JavelinResetHook_Stub, HOOK_JUMP).install()->quick();
// Add ultrawide support // Add ultrawide support
Utils::Hook(0x51B13B, QuickPatch::Dvar_RegisterAspectRatioDvar, HOOK_CALL).install()->quick(); Utils::Hook(0x51B13B, QuickPatch::Dvar_RegisterAspectRatioDvar, HOOK_CALL).install()->quick();
Utils::Hook(0x5063F3, QuickPatch::SetAspectRatioStub, HOOK_JUMP).install()->quick(); Utils::Hook(0x5063F3, QuickPatch::SetAspectRatio_Stub, HOOK_JUMP).install()->quick();
Utils::Hook(0x4FA448, QuickPatch::Dvar_RegisterConMinicon, HOOK_CALL).install()->quick(); Utils::Hook(0x4FA448, QuickPatch::Dvar_RegisterConMinicon, HOOK_CALL).install()->quick();
@ -293,6 +329,9 @@ namespace Components
Utils::Hook::Set<const char*>(0x41DB8C, "iw4x-sp.exe"); Utils::Hook::Set<const char*>(0x41DB8C, "iw4x-sp.exe");
Utils::Hook(0x4D6989, QuickPatch::Sys_SpawnQuitProcess_Hk, HOOK_CALL).install()->quick(); Utils::Hook(0x4D6989, QuickPatch::Sys_SpawnQuitProcess_Hk, HOOK_CALL).install()->quick();
// Fix crash as nullptr goes unchecked
Utils::Hook(0x437CAD, QuickPatch::SND_GetAliasOffset_Stub, HOOK_JUMP).install()->quick();
// protocol version (workaround for hacks) // protocol version (workaround for hacks)
Utils::Hook::Set<int>(0x4FB501, PROTOCOL); Utils::Hook::Set<int>(0x4FB501, PROTOCOL);

View File

@ -12,18 +12,18 @@ namespace Components
static void UnlockStats(); static void UnlockStats();
private: private:
static void JavelinResetHookStub(); static void JavelinResetHook_Stub();
static Dvar::Var r_customAspectRatio; static Dvar::Var r_customAspectRatio;
static Game::dvar_t* Dvar_RegisterAspectRatioDvar(const char* dvarName, const char** valueList, int defaultIndex, unsigned __int16 flags, const char* description); static Game::dvar_t* Dvar_RegisterAspectRatioDvar(const char* dvarName, const char** valueList, int defaultIndex, unsigned __int16 flags, const char* description);
static void SetAspectRatioStub(); static void SetAspectRatio_Stub();
static void SetAspectRatio(); static void SetAspectRatio();
static Game::dvar_t* g_antilag; static Game::dvar_t* g_antilag;
static void ClientEventsFireWeaponStub(); static void ClientEventsFireWeapon_Stub();
static void ClientEventsFireWeaponMeleeStub(); static void ClientEventsFireWeaponMelee_Stub();
static BOOL IsDynClassnameStub(const char* classname); static BOOL IsDynClassname_Stub(const char* classname);
static void CL_KeyEvent_OnEscape(); static void CL_KeyEvent_OnEscape();
static void CL_KeyEvent_ConsoleEscape_Stub(); static void CL_KeyEvent_ConsoleEscape_Stub();
@ -32,6 +32,8 @@ namespace Components
static void Sys_SpawnQuitProcess_Hk(); static void Sys_SpawnQuitProcess_Hk();
static void SND_GetAliasOffset_Stub();
static Game::dvar_t* Dvar_RegisterConMinicon(const char* dvarName, bool value, unsigned __int16 flags, const char* description); static Game::dvar_t* Dvar_RegisterConMinicon(const char* dvarName, bool value, unsigned __int16 flags, const char* description);
}; };
} }

View File

@ -107,15 +107,6 @@ using namespace std::literals;
static_assert(offsetof(x, y) == (offset), \ static_assert(offsetof(x, y) == (offset), \
#x "::" #y " is not at the right offset. Must be at " #offset) #x "::" #y " is not at the right offset. Must be at " #offset)
// Helps the optimizer know code such as default label in a switch statement is unreachable.
// It may generate less assembly (speed increase) if used properly
#define ASSUME(e) ( (assert(0)), __assume(e) )
#ifdef NDEBUG
#define AssertUnreachable __assume(0)
#else
#define AssertUnreachable ASSUME(0)
#endif
// Protobuf // Protobuf
#include "proto/session.pb.h" #include "proto/session.pb.h"
#include "proto/party.pb.h" #include "proto/party.pb.h"

View File

@ -27,7 +27,7 @@ namespace Utils::Json
case nlohmann::json::value_t::discarded: case nlohmann::json::value_t::discarded:
return "discarded"; return "discarded";
default: default:
AssertUnreachable; return "null";
} }
} }
} }