Skip to content
5 changes: 5 additions & 0 deletions Server/mods/deathmatch/logic/CGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Member

@qaisjp qaisjp Jan 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same q as above


// Reset his vehicle action, but only if not jacking
// If jacking we wait for him to reply with VEHICLE_NOTIFY_JACK_ABORT
Expand Down Expand Up @@ -3363,6 +3364,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);

Comment on lines +3367 to +3370
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same q as above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I’m working on it. I think I’ll find time for it over the weekend.

// Update our engine State
if (g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLE_ENGINE_AUTOSTART))
pVehicle->SetEngineOn(true);
Expand Down
4 changes: 4 additions & 0 deletions Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4320,6 +4320,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);

Comment on lines +4323 to +4326
Copy link
Member

@qaisjp qaisjp Jan 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this change? Is this because we need to account for all the scenarios where the client automatically unsets the jetpack state?

// If he's the driver, switch on the engine
if (uiSeat == 0 && g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLE_ENGINE_AUTOSTART))
pVehicle->SetEngineOn(true);
Expand Down
1 change: 1 addition & 0 deletions Server/mods/deathmatch/logic/net/CSimPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class CSimPlayer
ushort m_usLatency;
uchar m_ucSyncTimeContext;
uchar m_ucWeaponType;
bool m_hasJetPack;

// Used in CSimVehiclePuresyncPacket
ushort m_usVehicleModel;
Expand Down
4 changes: 3 additions & 1 deletion Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_hasJetPack = pPlayer->HasJetPack();

if (pVehicle)
{
pSim->m_uiVehicleDamageInfoSendPhase = pVehicle->m_uiDamageInfoSendPhase;
Expand Down Expand Up @@ -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_hasJetPack);
if (pPacket->Read(*BitStream))
{
// Relay it to nearbyers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 hasJetPack)

: m_PlayerID(PlayerID),
m_PlayerLatency(PlayerLatency),
m_PlayerSyncTimeContext(PlayerSyncTimeContext),
m_PlayerGotWeaponType(PlayerGotWeaponType),
m_WeaponRange(WeaponRange),
m_sharedControllerState(sharedControllerState)
m_sharedControllerState(sharedControllerState),
m_hasJetPack(hasJetPack)
{
}

Expand Down Expand Up @@ -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_hasJetPack;

// Success
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 hasJetPack);

ePacketID GetPacketID() const { return PACKET_ID_PLAYER_PURESYNC; };
unsigned long GetFlags() const { return PACKET_MEDIUM_PRIORITY | PACKET_SEQUENCED; };
Expand All @@ -56,6 +56,7 @@ class CSimPlayerPuresyncPacket : public CSimPacket
const uchar m_PlayerGotWeaponType;
const float m_WeaponRange;
CControllerState& m_sharedControllerState;
const bool m_hasJetPack;

// Set in Read ()
struct
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream)

pSourcePlayer->SetInWater(flags.data.bIsInWater);
pSourcePlayer->SetOnGround(flags.data.bIsOnGround);
pSourcePlayer->SetHasJetPack(flags.data.bHasJetPack);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the specific important change for ignoring the client's opinion on the jetpack state?

pSourcePlayer->SetDucked(flags.data.bIsDucked);
pSourcePlayer->SetWearingGoggles(flags.data.bWearsGoogles);
pSourcePlayer->SetChoking(flags.data.bIsChoking);
Expand Down