From 60d0316b7bbfbf7074bae77e560ca1c196cb99dd Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sun, 20 Jan 2019 23:26:10 +0100 Subject: [PATCH] Fix scheduling and even notification --- src/game/game.cpp | 56 +++++++++++++++++++++++++++++++++++++--- src/game/game.hpp | 7 ++--- src/module/scripting.cpp | 15 +++++++++-- 3 files changed, 69 insertions(+), 9 deletions(-) diff --git a/src/game/game.cpp b/src/game/game.cpp index 7490658..ec154f8 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -13,14 +13,14 @@ namespace game DB_LoadXAssets_t DB_LoadXAssets; + G_RunFrame_t G_RunFrame; + MSG_ReadData_t MSG_ReadData; MT_AllocIndex_t MT_AllocIndex; RemoveRefToValue_t RemoveRefToValue; - Scr_NotifyId_t Scr_NotifyId; - SL_GetStringOfSize_t SL_GetStringOfSize; Sys_ShowConsole_t Sys_ShowConsole; @@ -179,6 +179,54 @@ namespace game } } + __declspec(naked) void scr_notify_id_multiplayer(unsigned int id, unsigned int stringValue, + unsigned int paramcount) + { + static DWORD func = 0x56B5E0; + + __asm + { + mov eax, paramcount + push stringValue + push id + call func + add esp, 8h + retn + } + } + + __declspec(naked) void scr_notify_id_singleplayer(unsigned int id, unsigned int stringValue, + unsigned int paramcount) + { + static DWORD func = 0x610980; + + __asm + { + mov eax, paramcount + push stringValue + push id + call func + add esp, 8h + retn + } + } + + void Scr_NotifyId(unsigned int id, unsigned int stringValue, unsigned int paramcount) + { + if (is_mp()) + { + return scr_notify_id_multiplayer(id, stringValue, paramcount); + } + else if (is_sp()) + { + return scr_notify_id_singleplayer(id, stringValue, paramcount); + } + else + { + return reinterpret_cast(0x4EFAA0)(id, stringValue, paramcount); + } + } + __declspec(naked) int scr_set_object_field_dedicated(unsigned int classnum, int entnum, int _offset) { static DWORD func = 0x4B15C0; @@ -250,14 +298,14 @@ namespace game native::DB_LoadXAssets = native::DB_LoadXAssets_t(SELECT_VALUE(0x48A8E0, 0x4CD020, 0x44F770)); + native::G_RunFrame = native::G_RunFrame_t(SELECT_VALUE(0x52EAA0, 0x50CB70, 0x48AD60)); + native::MSG_ReadData = native::MSG_ReadData_t(SELECT_VALUE(0, 0x5592A0, 0)); native::MT_AllocIndex = native::MT_AllocIndex_t(SELECT_VALUE(0x4B9610, 0x562080, 0x4E6C30)); native::RemoveRefToValue = native::RemoveRefToValue_t(SELECT_VALUE(0x477EA0, 0x565730, 0x4E8A40)); - native::Scr_NotifyId = native::Scr_NotifyId_t(SELECT_VALUE(0x610980, 0x56B5E0, 0x4EFAA0)); - native::SL_GetStringOfSize = native::SL_GetStringOfSize_t(SELECT_VALUE(0x4E13F0, 0x564650, 0x4E7490)); native::Sys_ShowConsole = native::Sys_ShowConsole_t(SELECT_VALUE(0x470AF0, 0x5CF590, 0)); diff --git a/src/game/game.hpp b/src/game/game.hpp index d10333e..59e5940 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -21,6 +21,9 @@ namespace game typedef void (*DB_LoadXAssets_t)(XZoneInfo* zoneInfo, unsigned int zoneCount, int sync); extern DB_LoadXAssets_t DB_LoadXAssets; + typedef int (*G_RunFrame_t)(int, int); + extern G_RunFrame_t G_RunFrame; + typedef void (*MSG_ReadData_t)(msg_t* msg, void* data, int len); extern MSG_ReadData_t MSG_ReadData; @@ -30,9 +33,6 @@ namespace game typedef void (*RemoveRefToValue_t)(scriptType_e type, VariableUnion u); extern RemoveRefToValue_t RemoveRefToValue; - typedef void (*Scr_NotifyId_t)(unsigned int id, unsigned int stringValue, unsigned int paramcount); - extern Scr_NotifyId_t Scr_NotifyId; - typedef unsigned int (*SL_GetStringOfSize_t)(const char* str, unsigned int user, unsigned int len, int type); extern SL_GetStringOfSize_t SL_GetStringOfSize; @@ -76,6 +76,7 @@ namespace game void Scr_ClearOutParams(); scr_entref_t Scr_GetEntityIdRef(unsigned int id); scr_call_t Scr_GetFunc(unsigned int index); + void Scr_NotifyId(unsigned int id, unsigned int stringValue, unsigned int paramcount); int Scr_SetObjectField(unsigned int classnum, int entnum, int offset); const char* SL_ConvertToString(unsigned int stringValue); diff --git a/src/module/scripting.cpp b/src/module/scripting.cpp index 442f189..cc039da 100644 --- a/src/module/scripting.cpp +++ b/src/module/scripting.cpp @@ -18,15 +18,20 @@ public: ->install() // ->quick(); + utils::hook(SELECT_VALUE(0x4F9706, 0x5772A0, 0x4FAB88), &frame_stub, HOOK_CALL).install()->quick(); + utils::hook(SELECT_VALUE(0x4FFA48, 0x5774AB, 0x4FEFD7), &frame_stub, HOOK_CALL).install()->quick(); // Only relevant one? + utils::hook(SELECT_VALUE(0x6109F3, 0x56B637, 0x4EDFF7), &vm_notify_stub, HOOK_CALL).install()->quick(); utils::hook(SELECT_VALUE(0x6128BE, 0x56D541, 0x4EFAF9), &vm_notify_stub, HOOK_CALL).install()->quick(); if (game::is_sp()) { + utils::hook(0x50C57E, &frame_stub, HOOK_CALL).install()->quick(); + utils::hook(0x6523A3, &frame_stub, HOOK_CALL).install()->quick(); + utils::hook(0x5145D2, &frame_stub, HOOK_CALL).install()->quick(); + utils::hook(0x610970, &vm_notify_stub, HOOK_JUMP).install()->quick(); } - - scheduler::on_frame(std::bind(&scripting::run_frame, this)); } void pre_destroy() override @@ -143,6 +148,12 @@ private: game::native::VM_Notify(notify_id, type, stack); } + + static int frame_stub(int a1, int a2) + { + module_loader::get()->run_frame(); + return game::native::G_RunFrame(a1, a2); + } }; utils::hook scripting::start_hook_;