From c4f33b7ac11a3a7d8a0404e3131f4d7db4a45455 Mon Sep 17 00:00:00 2001 From: DmitriyColeman Date: Sat, 6 Dec 2025 13:05:42 +0300 Subject: [PATCH 1/9] Force server-side jetpack state --- Server/mods/deathmatch/logic/net/CSimPlayer.h | 1 + Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp | 4 +++- .../deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp | 8 ++++++-- .../mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h | 3 ++- .../deathmatch/logic/packets/CPlayerPuresyncPacket.cpp | 1 - 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Server/mods/deathmatch/logic/net/CSimPlayer.h b/Server/mods/deathmatch/logic/net/CSimPlayer.h index 7519c140706..4ead08973bf 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayer.h +++ b/Server/mods/deathmatch/logic/net/CSimPlayer.h @@ -50,6 +50,7 @@ class CSimPlayer ushort m_usLatency; uchar m_ucSyncTimeContext; uchar m_ucWeaponType; + bool m_bHasJetPack; // Used in CSimVehiclePuresyncPacket ushort m_usVehicleModel; diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp b/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp index 24afdac00e6..c346592f5f5 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp +++ b/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp @@ -141,6 +141,8 @@ void CSimPlayerManager::UpdateSimPlayer(CPlayer* pPlayer) pSim->m_bVehicleHasHydraulics = pVehicle ? pVehicle->GetUpgrades()->HasUpgrade(1087) : false; pSim->m_bVehicleIsPlaneOrHeli = pVehicle ? pVehicle->GetVehicleType() == VEHICLE_PLANE || pVehicle->GetVehicleType() == VEHICLE_HELI : false; pSim->m_sharedControllerState.Copy(pPlayer->GetPad()->GetCurrentControllerState()); + pSim->m_bHasJetPack = pPlayer->HasJetPack(); + if (pVehicle) { pSim->m_uiVehicleDamageInfoSendPhase = pVehicle->m_uiDamageInfoSendPhase; @@ -239,7 +241,7 @@ bool CSimPlayerManager::HandlePlayerPureSync(const NetServerPlayerID& Socket, Ne // Read the incoming packet data CSimPlayerPuresyncPacket* pPacket = new CSimPlayerPuresyncPacket(pSourceSimPlayer->m_PlayerID, pSourceSimPlayer->m_usLatency, pSourceSimPlayer->m_ucSyncTimeContext, - pSourceSimPlayer->m_ucWeaponType, pSourceSimPlayer->m_fWeaponRange, pSourceSimPlayer->m_sharedControllerState); + pSourceSimPlayer->m_ucWeaponType, pSourceSimPlayer->m_fWeaponRange, pSourceSimPlayer->m_sharedControllerState, pSourceSimPlayer->m_bHasJetPack); if (pPacket->Read(*BitStream)) { // Relay it to nearbyers diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp index 8542cb4793a..174ee732dec 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp @@ -13,14 +13,15 @@ #include "CWeaponNames.h" CSimPlayerPuresyncPacket::CSimPlayerPuresyncPacket(ElementID PlayerID, ushort PlayerLatency, uchar PlayerSyncTimeContext, uchar PlayerGotWeaponType, - float WeaponRange, CControllerState& sharedControllerState) + float WeaponRange, CControllerState& sharedControllerState, bool bHasJetPack) : m_PlayerID(PlayerID), m_PlayerLatency(PlayerLatency), m_PlayerSyncTimeContext(PlayerSyncTimeContext), m_PlayerGotWeaponType(PlayerGotWeaponType), m_WeaponRange(WeaponRange), - m_sharedControllerState(sharedControllerState) + m_sharedControllerState(sharedControllerState), + m_bHasJetPack(bHasJetPack) { } @@ -179,6 +180,9 @@ bool CSimPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) m_Cache.usTotalAmmo = 1; } + // Enforce we use server-side jetpack state + m_Cache.flags.data.bHasJetPack = m_bHasJetPack; + // Success return true; } diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h index a3132568f71..df40df015a9 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h +++ b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h @@ -34,7 +34,7 @@ class CSimPlayerPuresyncPacket : public CSimPacket ZERO_ON_NEW CSimPlayerPuresyncPacket(ElementID PlayerID, ushort PlayerLatency, uchar PlayerSyncTimeContext, uchar PlayerGotWeaponType, float WeaponRange, - CControllerState& sharedControllerState); + CControllerState& sharedControllerState, bool bHasJetPack); ePacketID GetPacketID() const { return PACKET_ID_PLAYER_PURESYNC; }; unsigned long GetFlags() const { return PACKET_MEDIUM_PRIORITY | PACKET_SEQUENCED; }; @@ -56,6 +56,7 @@ class CSimPlayerPuresyncPacket : public CSimPacket const uchar m_PlayerGotWeaponType; const float m_WeaponRange; CControllerState& m_sharedControllerState; + const bool m_bHasJetPack; // Set in Read () struct diff --git a/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp index 2297e985c16..34c1fa24408 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp @@ -54,7 +54,6 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) pSourcePlayer->SetInWater(flags.data.bIsInWater); pSourcePlayer->SetOnGround(flags.data.bIsOnGround); - pSourcePlayer->SetHasJetPack(flags.data.bHasJetPack); pSourcePlayer->SetDucked(flags.data.bIsDucked); pSourcePlayer->SetWearingGoggles(flags.data.bWearsGoogles); pSourcePlayer->SetChoking(flags.data.bIsChoking); From ea3f19a3a0ab388135949ee7f7cfae602f13b4e0 Mon Sep 17 00:00:00 2001 From: DmitriyColeman Date: Sat, 6 Dec 2025 19:04:42 +0300 Subject: [PATCH 2/9] Added a forced removal of the jetpack flag when a player dies --- Server/mods/deathmatch/logic/CGame.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index 5807a7f3edf..f2d625b17cb 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -2133,6 +2133,7 @@ void CGame::Packet_PlayerWasted(CPlayerWastedPacket& Packet) pPlayer->SetHealth(0.0f); pPlayer->SetArmor(0.0f); pPlayer->SetPosition(Packet.m_vecPosition); + pPlayer->SetHasJetPack(false); // Reset his vehicle action, but only if not jacking // If jacking we wait for him to reply with VEHICLE_NOTIFY_JACK_ABORT From 6d217d28e5e201e83b99401be986c3f4239a4438 Mon Sep 17 00:00:00 2001 From: DmitriyColeman <47474886+DmitriyColeman@users.noreply.github.com> Date: Fri, 16 Jan 2026 08:45:48 +0300 Subject: [PATCH 3/9] Fix naming (#1) Co-authored-by: Nico <122193236+Nico8345@users.noreply.github.com> --- Server/mods/deathmatch/logic/net/CSimPlayer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server/mods/deathmatch/logic/net/CSimPlayer.h b/Server/mods/deathmatch/logic/net/CSimPlayer.h index 4ead08973bf..10b8dfa545a 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayer.h +++ b/Server/mods/deathmatch/logic/net/CSimPlayer.h @@ -50,7 +50,7 @@ class CSimPlayer ushort m_usLatency; uchar m_ucSyncTimeContext; uchar m_ucWeaponType; - bool m_bHasJetPack; + bool m_hasJetPack; // Used in CSimVehiclePuresyncPacket ushort m_usVehicleModel; From 1118597497a2d9a03df50ac3d39ea07966dfa485 Mon Sep 17 00:00:00 2001 From: DmitriyColeman <47474886+DmitriyColeman@users.noreply.github.com> Date: Fri, 16 Jan 2026 08:46:24 +0300 Subject: [PATCH 4/9] Fix naming (#2) Co-authored-by: Nico <122193236+Nico8345@users.noreply.github.com> --- Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp b/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp index c346592f5f5..c2a5c846651 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp +++ b/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp @@ -141,7 +141,7 @@ void CSimPlayerManager::UpdateSimPlayer(CPlayer* pPlayer) pSim->m_bVehicleHasHydraulics = pVehicle ? pVehicle->GetUpgrades()->HasUpgrade(1087) : false; pSim->m_bVehicleIsPlaneOrHeli = pVehicle ? pVehicle->GetVehicleType() == VEHICLE_PLANE || pVehicle->GetVehicleType() == VEHICLE_HELI : false; pSim->m_sharedControllerState.Copy(pPlayer->GetPad()->GetCurrentControllerState()); - pSim->m_bHasJetPack = pPlayer->HasJetPack(); + pSim->m_hasJetPack = pPlayer->HasJetPack(); if (pVehicle) { From f86d311aa35bbb79a86c8414f666c43c0563995f Mon Sep 17 00:00:00 2001 From: DmitriyColeman <47474886+DmitriyColeman@users.noreply.github.com> Date: Fri, 16 Jan 2026 08:46:34 +0300 Subject: [PATCH 5/9] Fix naming (#3) Co-authored-by: Nico <122193236+Nico8345@users.noreply.github.com> --- Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp b/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp index c2a5c846651..cd256ac8d8c 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp +++ b/Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp @@ -241,7 +241,7 @@ bool CSimPlayerManager::HandlePlayerPureSync(const NetServerPlayerID& Socket, Ne // Read the incoming packet data CSimPlayerPuresyncPacket* pPacket = new CSimPlayerPuresyncPacket(pSourceSimPlayer->m_PlayerID, pSourceSimPlayer->m_usLatency, pSourceSimPlayer->m_ucSyncTimeContext, - pSourceSimPlayer->m_ucWeaponType, pSourceSimPlayer->m_fWeaponRange, pSourceSimPlayer->m_sharedControllerState, pSourceSimPlayer->m_bHasJetPack); + pSourceSimPlayer->m_ucWeaponType, pSourceSimPlayer->m_fWeaponRange, pSourceSimPlayer->m_sharedControllerState, pSourceSimPlayer->m_hasJetPack); if (pPacket->Read(*BitStream)) { // Relay it to nearbyers From a74b1e2b999298e8f7939c67ea3282d3876cd9df Mon Sep 17 00:00:00 2001 From: DmitriyColeman <47474886+DmitriyColeman@users.noreply.github.com> Date: Fri, 16 Jan 2026 08:46:43 +0300 Subject: [PATCH 6/9] Fix naming (#4) Co-authored-by: Nico <122193236+Nico8345@users.noreply.github.com> --- Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp index 174ee732dec..aecafe9ee56 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp @@ -13,7 +13,7 @@ #include "CWeaponNames.h" CSimPlayerPuresyncPacket::CSimPlayerPuresyncPacket(ElementID PlayerID, ushort PlayerLatency, uchar PlayerSyncTimeContext, uchar PlayerGotWeaponType, - float WeaponRange, CControllerState& sharedControllerState, bool bHasJetPack) + float WeaponRange, CControllerState& sharedControllerState, bool hasJetPack) : m_PlayerID(PlayerID), m_PlayerLatency(PlayerLatency), From cafdc5a072793315b43660c179d75dc4d04b8ae3 Mon Sep 17 00:00:00 2001 From: DmitriyColeman <47474886+DmitriyColeman@users.noreply.github.com> Date: Fri, 16 Jan 2026 08:47:00 +0300 Subject: [PATCH 7/9] Fix naming (#5) Co-authored-by: Nico <122193236+Nico8345@users.noreply.github.com> --- Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp index aecafe9ee56..75f0723aa7a 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp @@ -21,7 +21,7 @@ CSimPlayerPuresyncPacket::CSimPlayerPuresyncPacket(ElementID PlayerID, ushort Pl m_PlayerGotWeaponType(PlayerGotWeaponType), m_WeaponRange(WeaponRange), m_sharedControllerState(sharedControllerState), - m_bHasJetPack(bHasJetPack) + m_hasJetPack(hasJetPack) { } From d1a6d8adb8df69cf253093d04043d6583efbf82f Mon Sep 17 00:00:00 2001 From: DmitriyColeman <47474886+DmitriyColeman@users.noreply.github.com> Date: Fri, 16 Jan 2026 08:47:48 +0300 Subject: [PATCH 8/9] Fix naming (#6) Co-authored-by: Nico <122193236+Nico8345@users.noreply.github.com> --- Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp | 2 +- Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp index 75f0723aa7a..0480131f620 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.cpp @@ -181,7 +181,7 @@ bool CSimPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) } // Enforce we use server-side jetpack state - m_Cache.flags.data.bHasJetPack = m_bHasJetPack; + m_Cache.flags.data.bHasJetPack = m_hasJetPack; // Success return true; diff --git a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h index df40df015a9..be14001c7db 100644 --- a/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h +++ b/Server/mods/deathmatch/logic/net/CSimPlayerPuresyncPacket.h @@ -34,7 +34,7 @@ class CSimPlayerPuresyncPacket : public CSimPacket ZERO_ON_NEW CSimPlayerPuresyncPacket(ElementID PlayerID, ushort PlayerLatency, uchar PlayerSyncTimeContext, uchar PlayerGotWeaponType, float WeaponRange, - CControllerState& sharedControllerState, bool bHasJetPack); + CControllerState& sharedControllerState, bool hasJetPack); ePacketID GetPacketID() const { return PACKET_ID_PLAYER_PURESYNC; }; unsigned long GetFlags() const { return PACKET_MEDIUM_PRIORITY | PACKET_SEQUENCED; }; @@ -56,7 +56,7 @@ class CSimPlayerPuresyncPacket : public CSimPacket const uchar m_PlayerGotWeaponType; const float m_WeaponRange; CControllerState& m_sharedControllerState; - const bool m_bHasJetPack; + const bool m_hasJetPack; // Set in Read () struct From 417e174ad1c1a7e96e539d0d3c3fbc2d2ed634a6 Mon Sep 17 00:00:00 2001 From: DmitriyColeman Date: Sat, 17 Jan 2026 10:41:34 +0300 Subject: [PATCH 9/9] Remove jetpack if player has entered vehicle --- Server/mods/deathmatch/logic/CGame.cpp | 4 ++++ Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index f2d625b17cb..f0ebd6c10f3 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -3367,6 +3367,10 @@ void CGame::Packet_Vehicle_InOut(CVehicleInOutPacket& Packet) // Mark him as successfully entered pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE); + // Remove jetpack from him + if (pPed->IsPlayer() && pPed->HasJetPack()) + pPed->SetHasJetPack(false); + // Update our engine State if (g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLE_ENGINE_AUTOSTART)) pVehicle->SetEngineOn(true); diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 810820a820e..33d9c629eac 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -4319,6 +4319,10 @@ bool CStaticFunctionDefinitions::WarpPedIntoVehicle(CPed* pPed, CVehicle* pVehic pPed->SetOccupiedVehicle(pVehicle, uiSeat); pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE); + // Remove jetpack if he has one + if (pPed->IsPlayer() && pPed->HasJetPack()) + pPed->SetHasJetPack(false); + // If he's the driver, switch on the engine if (uiSeat == 0 && g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLE_ENGINE_AUTOSTART)) pVehicle->SetEngineOn(true);