From 26751e67ba9ac824c90923dab705030bc248298f Mon Sep 17 00:00:00 2001 From: samr46 Date: Thu, 5 Jun 2025 14:18:42 +0300 Subject: [PATCH 1/2] Add new glich (vehicle_rapid_stop) --- Client/mods/deathmatch/logic/CClientGame.cpp | 4 ++ Client/mods/deathmatch/logic/CClientGame.h | 1 + .../mods/deathmatch/logic/CPacketHandler.cpp | 1 + Client/multiplayer_sa/CMultiplayerSA.h | 5 ++ .../CMultiplayerSA_FrameRateFixes.cpp | 71 +++++++++++++++++++ Client/sdk/multiplayer/CMultiplayer.h | 3 + Server/mods/deathmatch/logic/CGame.cpp | 2 + Server/mods/deathmatch/logic/CGame.h | 1 + .../logic/packets/CMapInfoPacket.cpp | 1 + Shared/sdk/net/SyncStructures.h | 16 +++++ Shared/sdk/net/bitstream.h | 4 ++ 11 files changed, 109 insertions(+) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 25f440fab5..56ba8b26cd 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -137,6 +137,8 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo()) m_Glitches[GLITCH_BADDRIVEBYHITBOX] = false; m_Glitches[GLITCH_QUICKSTAND] = false; m_Glitches[GLITCH_KICKOUTOFVEHICLE_ONMODELREPLACE] = false; + m_Glitches[GLITCH_VEHICLE_RAPID_STOP] = false; + g_pMultiplayer->SetRapidVehicleStopFixEnabled(true); g_pMultiplayer->DisableBadDrivebyHitboxes(true); @@ -5992,6 +5994,8 @@ bool CClientGame::SetGlitchEnabled(unsigned char ucGlitch, bool bEnabled) g_pMultiplayer->DisableQuickReload(!bEnabled); if (ucGlitch == GLITCH_CLOSEDAMAGE) g_pMultiplayer->DisableCloseRangeDamage(!bEnabled); + if (ucGlitch == GLITCH_VEHICLE_RAPID_STOP) + g_pMultiplayer->SetRapidVehicleStopFixEnabled(!bEnabled); return true; } return false; diff --git a/Client/mods/deathmatch/logic/CClientGame.h b/Client/mods/deathmatch/logic/CClientGame.h index d21de68f06..60d185f641 100644 --- a/Client/mods/deathmatch/logic/CClientGame.h +++ b/Client/mods/deathmatch/logic/CClientGame.h @@ -204,6 +204,7 @@ class CClientGame GLITCH_BADDRIVEBYHITBOX, GLITCH_QUICKSTAND, GLITCH_KICKOUTOFVEHICLE_ONMODELREPLACE, + GLITCH_VEHICLE_RAPID_STOP, NUM_GLITCHES }; diff --git a/Client/mods/deathmatch/logic/CPacketHandler.cpp b/Client/mods/deathmatch/logic/CPacketHandler.cpp index 1f50f7ac67..f62e9955b4 100644 --- a/Client/mods/deathmatch/logic/CPacketHandler.cpp +++ b/Client/mods/deathmatch/logic/CPacketHandler.cpp @@ -2378,6 +2378,7 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream) g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_FASTSPRINT, funBugs.data3.bFastSprint); g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_BADDRIVEBYHITBOX, funBugs.data4.bBadDrivebyHitboxes); g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_QUICKSTAND, funBugs.data5.bQuickStand); + g_pClientGame->SetGlitchEnabled(CClientGame::GLITCH_VEHICLE_RAPID_STOP, funBugs.data6.vehicleRapidStop); SWorldSpecialPropertiesStateSync wsProps; if (bitStream.Can(eBitStreamVersion::WorldSpecialProperties)) diff --git a/Client/multiplayer_sa/CMultiplayerSA.h b/Client/multiplayer_sa/CMultiplayerSA.h index f4c79ce9b6..5068545338 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -336,6 +336,9 @@ class CMultiplayerSA : public CMultiplayer bool IsVehicleEngineAutoStartEnabled() const noexcept override; void SetVehicleEngineAutoStartEnabled(bool enabled) override; + bool IsRapidVehicleStopFixEnabled() const noexcept override { return isRapidVehicleStopFixEnabled; }; + void SetRapidVehicleStopFixEnabled(bool enabled) override; + void SetPedTargetingMarkerEnabled(bool bEnable); bool IsPedTargetingMarkerEnabled(); bool IsConnected(); @@ -385,6 +388,8 @@ class CMultiplayerSA : public CMultiplayer DWORD m_dwLastAnimArrayAddress; float m_fShadowsOffset; + bool isRapidVehicleStopFixEnabled{false}; + /* VOID SetPlayerShotVectors(CPlayerPed* player, Vector3D * vecTarget, Vector3D * vecStart); VOID SetPlayerCameraVectors(CPlayerPed* player, Vector3D * vecSource, Vector3D * vecFront); Vector3D * GetLocalShotOriginVector();*/ diff --git a/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp b/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp index 550789c246..019f83553a 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp @@ -619,6 +619,77 @@ static void __declspec(naked) HOOK_CWeapon_Update() } } +#define HOOKPOS_CPhysical__ApplyAirResistance 0x544D29 +#define HOOKSIZE_CPhysical__ApplyAirResistance 5 +static const unsigned int RETURN_CPhysical__ApplyAirResistance = 0x544D4D; +static void _declspec(naked) HOOK_CPhysical__ApplyAirResistance() +{ + _asm { + fld ds:[0x862CD0] // 0.99000001f + fld ds:[0xB7CB5C] // CTimer::ms_fTimeStep + fdiv kOriginalTimeStep // 1.666f + mov eax, 0x822130 // powf + call eax + + fld st(0) + fmul [esi+0x50] + fstp [esi+0x50] + + fld st(0) + fmul [esi+0x54] + fstp [esi+0x54] + + fmul [esi+0x58] + fstp [esi+0x58] + jmp RETURN_CPhysical__ApplyAirResistance + } +} + +template +static void _declspec(naked) HOOK_VehicleRapidStopFix() +{ + static unsigned int RETURN_VehicleRapidStopFix = returnAddress; + _asm { + fld ds:[0xC2B9CC] // mod_HandlingManager.m_fWheelFriction + fmul ds:[0xB7CB5C] // CTimer::ms_fTimeStep + fdiv kOriginalTimeStep // 1.666f + jmp RETURN_VehicleRapidStopFix + } +} + +void CMultiplayerSA::SetRapidVehicleStopFixEnabled(bool enabled) +{ + if (isRapidVehicleStopFixEnabled == enabled) + return; + + if (enabled) + { + EZHookInstall(CPhysical__ApplyAirResistance); + + // CVehicle::ProcessWheel + HookInstall(0x6D6E69, (DWORD)HOOK_VehicleRapidStopFix<0x6D6E6F>, 6); + HookInstall(0x6D6EA8, (DWORD)HOOK_VehicleRapidStopFix<0x6D6EAE>, 6); + + // CVehicle::ProcessBikeWheel + HookInstall(0x6D767F, (DWORD)HOOK_VehicleRapidStopFix<0x6D7685>, 6); + HookInstall(0x6D76AB, (DWORD)HOOK_VehicleRapidStopFix<0x6D76B1>, 6); + HookInstall(0x6D76CD, (DWORD)HOOK_VehicleRapidStopFix<0x6D76D3>, 6); + } + else + { + MemCpy((void*)HOOKPOS_CPhysical__ApplyAirResistance, "\xD9\x46\x50\xD8\x0D", 5); + + MemCpy((void*)0x6D6E69, "\xD9\x05\xCC\xB9\xC2\x00", 6); + MemCpy((void*)0x6D6EA8, "\xD9\x05\xCC\xB9\xC2\x00", 6); + + MemCpy((void*)0x6D767F, "\xD9\x05\xCC\xB9\xC2\x00", 6); + MemCpy((void*)0x6D76AB, "\xD9\x05\xCC\xB9\xC2\x00", 6); + MemCpy((void*)0x6D76CD, "\xD9\x05\xCC\xB9\xC2\x00", 6); + } + + isRapidVehicleStopFixEnabled = enabled; +} + void CMultiplayerSA::InitHooks_FrameRateFixes() { EZHookInstall(CTaskSimpleUseGun__SetMoveAnim); diff --git a/Client/sdk/multiplayer/CMultiplayer.h b/Client/sdk/multiplayer/CMultiplayer.h index 555de9e526..af3ae03f20 100644 --- a/Client/sdk/multiplayer/CMultiplayer.h +++ b/Client/sdk/multiplayer/CMultiplayer.h @@ -447,6 +447,9 @@ class CMultiplayer virtual bool IsVehicleEngineAutoStartEnabled() const noexcept = 0; virtual void SetVehicleEngineAutoStartEnabled(bool enabled) = 0; + virtual bool IsRapidVehicleStopFixEnabled() const noexcept = 0; + virtual void SetRapidVehicleStopFixEnabled(bool enabled) = 0; + virtual void SetPedTargetingMarkerEnabled(bool bEnabled) = 0; virtual bool IsPedTargetingMarkerEnabled() = 0; diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index 16e7b7312b..e327383645 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -240,6 +240,7 @@ CGame::CGame() : m_FloodProtect(4, 30000, 30000) // Max of 4 connecti m_Glitches[GLITCH_BADDRIVEBYHITBOX] = false; m_Glitches[GLITCH_QUICKSTAND] = false; m_Glitches[GLITCH_KICKOUTOFVEHICLE_ONMODELREPLACE] = false; + m_Glitches[GLITCH_VEHICLE_RAPID_STOP] = false; for (int i = 0; i < WEAPONTYPE_LAST_WEAPONTYPE; i++) m_JetpackWeapons[i] = false; @@ -279,6 +280,7 @@ CGame::CGame() : m_FloodProtect(4, 30000, 30000) // Max of 4 connecti m_GlitchNames["baddrivebyhitbox"] = GLITCH_BADDRIVEBYHITBOX; m_GlitchNames["quickstand"] = GLITCH_QUICKSTAND; m_GlitchNames["kickoutofvehicle_onmodelreplace"] = GLITCH_KICKOUTOFVEHICLE_ONMODELREPLACE; + m_GlitchNames["vehicle_rapid_stop"] = GLITCH_VEHICLE_RAPID_STOP; m_bCloudsEnabled = true; diff --git a/Server/mods/deathmatch/logic/CGame.h b/Server/mods/deathmatch/logic/CGame.h index bffd2970e3..338ce119cc 100644 --- a/Server/mods/deathmatch/logic/CGame.h +++ b/Server/mods/deathmatch/logic/CGame.h @@ -196,6 +196,7 @@ class CGame GLITCH_BADDRIVEBYHITBOX, GLITCH_QUICKSTAND, GLITCH_KICKOUTOFVEHICLE_ONMODELREPLACE, + GLITCH_VEHICLE_RAPID_STOP, NUM_GLITCHES }; diff --git a/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp b/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp index 0fd78c8bd3..614ff8c9ab 100644 --- a/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp @@ -170,6 +170,7 @@ bool CMapInfoPacket::Write(NetBitStreamInterface& BitStream) const funBugs.data3.bFastSprint = g_pGame->IsGlitchEnabled(CGame::GLITCH_FASTSPRINT); funBugs.data4.bBadDrivebyHitboxes = g_pGame->IsGlitchEnabled(CGame::GLITCH_BADDRIVEBYHITBOX); funBugs.data5.bQuickStand = g_pGame->IsGlitchEnabled(CGame::GLITCH_QUICKSTAND); + funBugs.data6.vehicleRapidStop = g_pGame->IsGlitchEnabled(CGame::GLITCH_VEHICLE_RAPID_STOP); BitStream.Write(&funBugs); // Write world special properties states diff --git a/Shared/sdk/net/SyncStructures.h b/Shared/sdk/net/SyncStructures.h index c9d4a98075..87109e3202 100644 --- a/Shared/sdk/net/SyncStructures.h +++ b/Shared/sdk/net/SyncStructures.h @@ -1964,6 +1964,10 @@ struct SFunBugsStateSync : public ISyncStructure { BITCOUNT5 = 1 }; + enum + { + BITCOUNT6 = 1 + }; bool Read(NetBitStreamInterface& bitStream) { @@ -1984,6 +1988,10 @@ struct SFunBugsStateSync : public ISyncStructure bOk &= bitStream.ReadBits(reinterpret_cast(&data5), BITCOUNT5); else data5.bQuickStand = 0; + if (bitStream.Can(eBitStreamVersion::Glitch_VehicleRapidStop)) + bOk &= bitStream.ReadBits(reinterpret_cast(&data6), BITCOUNT6); + else + data6.vehicleRapidStop = 0; //// Example for adding item: // if ( bitStream.Version() >= 0x999 ) @@ -2004,6 +2012,8 @@ struct SFunBugsStateSync : public ISyncStructure bitStream.WriteBits(reinterpret_cast(&data4), BITCOUNT4); if (bitStream.Can(eBitStreamVersion::QuickStandGlitch)) bitStream.WriteBits(reinterpret_cast(&data5), BITCOUNT5); + if (bitStream.Can(eBitStreamVersion::Glitch_VehicleRapidStop)) + bitStream.WriteBits(reinterpret_cast(&data6), BITCOUNT6); //// Example for adding item: // if (bitStream.Can(eBitStreamVersion::YourGlitch)) @@ -2042,6 +2052,12 @@ struct SFunBugsStateSync : public ISyncStructure { bool bQuickStand : 1; } data5; + + // Add new ones in separate structs + struct + { + bool vehicleRapidStop : 1; + } data6; }; ////////////////////////////////////////// diff --git a/Shared/sdk/net/bitstream.h b/Shared/sdk/net/bitstream.h index 160077ec35..3c45f47ad6 100644 --- a/Shared/sdk/net/bitstream.h +++ b/Shared/sdk/net/bitstream.h @@ -624,6 +624,10 @@ enum class eBitStreamVersion : unsigned short // 2025-06-02 WorldSpecialProperty_VehicleEngineAutoStart, + // Add "vehicle_rapid_stop" to setGlitchEnabled + // 2025-06-05 + Glitch_VehicleRapidStop, + // This allows us to automatically increment the BitStreamVersion when things are added to this enum. // Make sure you only add things above this comment. Next, From e007b3a147263f971ceaeda3129e1f5fa06f2beb Mon Sep 17 00:00:00 2001 From: samr46 Date: Thu, 5 Jun 2025 14:40:42 +0300 Subject: [PATCH 2/2] Rename variable --- Client/multiplayer_sa/CMultiplayerSA.h | 4 ++-- Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Client/multiplayer_sa/CMultiplayerSA.h b/Client/multiplayer_sa/CMultiplayerSA.h index 5068545338..75206d8211 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -336,7 +336,7 @@ class CMultiplayerSA : public CMultiplayer bool IsVehicleEngineAutoStartEnabled() const noexcept override; void SetVehicleEngineAutoStartEnabled(bool enabled) override; - bool IsRapidVehicleStopFixEnabled() const noexcept override { return isRapidVehicleStopFixEnabled; }; + bool IsRapidVehicleStopFixEnabled() const noexcept override { return m_isRapidVehicleStopFixEnabled; }; void SetRapidVehicleStopFixEnabled(bool enabled) override; void SetPedTargetingMarkerEnabled(bool bEnable); @@ -388,7 +388,7 @@ class CMultiplayerSA : public CMultiplayer DWORD m_dwLastAnimArrayAddress; float m_fShadowsOffset; - bool isRapidVehicleStopFixEnabled{false}; + bool m_isRapidVehicleStopFixEnabled{false}; /* VOID SetPlayerShotVectors(CPlayerPed* player, Vector3D * vecTarget, Vector3D * vecStart); VOID SetPlayerCameraVectors(CPlayerPed* player, Vector3D * vecSource, Vector3D * vecFront); diff --git a/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp b/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp index 019f83553a..620d9ba2ea 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp @@ -659,7 +659,7 @@ static void _declspec(naked) HOOK_VehicleRapidStopFix() void CMultiplayerSA::SetRapidVehicleStopFixEnabled(bool enabled) { - if (isRapidVehicleStopFixEnabled == enabled) + if (m_isRapidVehicleStopFixEnabled == enabled) return; if (enabled) @@ -687,7 +687,7 @@ void CMultiplayerSA::SetRapidVehicleStopFixEnabled(bool enabled) MemCpy((void*)0x6D76CD, "\xD9\x05\xCC\xB9\xC2\x00", 6); } - isRapidVehicleStopFixEnabled = enabled; + m_isRapidVehicleStopFixEnabled = enabled; } void CMultiplayerSA::InitHooks_FrameRateFixes()