From 15365dd481494e00d94899969600e622cd52821c Mon Sep 17 00:00:00 2001 From: Ehbw Date: Tue, 5 Nov 2024 16:11:54 +0000 Subject: [PATCH] fix(net/five): correct train track node on ownership change --- .../gta-net-five/include/netBlender.h | 2 +- .../gta-net-five/src/CloneObjectManager.cpp | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/code/components/gta-net-five/include/netBlender.h b/code/components/gta-net-five/include/netBlender.h index 8fde4a2603..9ec1e2b495 100644 --- a/code/components/gta-net-five/include/netBlender.h +++ b/code/components/gta-net-five/include/netBlender.h @@ -17,7 +17,7 @@ class netBlender virtual void m_28() = 0; - virtual void m_30() = 0; + virtual void Update() = 0; virtual void m_38() = 0; diff --git a/code/components/gta-net-five/src/CloneObjectManager.cpp b/code/components/gta-net-five/src/CloneObjectManager.cpp index 919374793c..de15d2ebe9 100644 --- a/code/components/gta-net-five/src/CloneObjectManager.cpp +++ b/code/components/gta-net-five/src/CloneObjectManager.cpp @@ -12,6 +12,11 @@ #include #include +#include +#include +#include +#include + static ICoreGameInit* icgi; extern void CD_AllocateSyncData(uint16_t objectId); @@ -81,6 +86,20 @@ static void netObjectMgrBase__DestroyNetworkObject(rage::netObjectMgr* manager, } } +#ifdef GTA_FIVE +static int g_trainTrackNodeIndexOffset; + +static hook::cdecl_stub CTrain__SetTrainCoord([]() +{ + return hook::pattern("44 8B C2 48 83 C4 ? 5B").count(1).get(0).get(8); +}); + +static hook::cdecl_stub CTrain__IsCarriageEngine([]() +{ + return hook::get_call(hook::get_pattern("E8 ? ? ? ? 80 A3 ? ? ? ? ? 24 ? 02 C0 08 83 ? ? ? ? F6 83 ? ? ? ? ? 74 ? 8A 05")); +}); +#endif + static void(*g_orig_netObjectMgrBase__ChangeOwner)(rage::netObjectMgr*, rage::netObject*, CNetGamePlayer*, int); static void netObjectMgrBase__ChangeOwner(rage::netObjectMgr* manager, rage::netObject* object, CNetGamePlayer* targetPlayer, int migrationType) @@ -96,6 +115,25 @@ static void netObjectMgrBase__ChangeOwner(rage::netObjectMgr* manager, rage::net object->PostMigrate(migrationType); CloneObjectMgr->ChangeOwner(object, oldOwnerId, targetPlayer, migrationType); + // Handle scenarios where a train was previously owned by the server +#ifdef GTA_FIVE + // Make sure that this is a train and that we are now the new owner of it + if (object->objectType == (uint16_t)NetObjEntityType::Train && targetPlayer->physicalPlayerIndex() == rage::GetLocalPlayer()->physicalPlayerIndex()) + { + // Ensure that the vehicle isn't a nullptr + if (CVehicle* train = (CVehicle*)object->GetGameObject()) + { + // Ensure this is the engine and the client has no knowledge of the trains current track node. + if (CTrain__IsCarriageEngine(train) && *(int*)((uintptr_t)train + TrainTrackNodeIndexOffset) == 0) + { + //Find the trains track node based on its current location + CTrain__SetTrainCoord(train, -1, -1); + // Force blend to apply location + object->GetBlender()->Update(); + } + } + } +#endif } static rage::netObject* (*g_orig_netObjectMgrBase__GetNetworkObject)(rage::netObjectMgr* manager, uint16_t id, bool evenIfDeleting); @@ -148,6 +186,9 @@ static HookFunction hookFunction([]() MH_Initialize(); #if GTA_FIVE + //Taken from extra-natives-five/VehicleExtraNatives.cpp + g_trainTrackNodeIndexOffset = *hook::get_pattern("E8 ? ? ? ? 40 8A F8 84 C0 75 ? 48 8B CB E8", -4); + MH_CreateHook(hook::get_pattern("48 8B F2 0F B7 52 0A 41 B0 01", -0x19), netObjectMgrBase__RegisterNetworkObject, (void**)&g_orig_netObjectMgrBase__RegisterNetworkObject); // MH_CreateHook(hook::get_pattern("8A 42 4C 45 33 FF 48 8B DA C0 E8 02", -0x21), netObjectMgrBase__DestroyNetworkObject, (void**)&g_orig_netObjectMgrBase__DestroyNetworkObject); // if (xbr::IsGameBuildOrGreater<3258>())