From 626261652632dfc39a20220c55f1cfaa483435d0 Mon Sep 17 00:00:00 2001 From: qaisjp Date: Mon, 19 Jan 2026 12:41:18 -0500 Subject: [PATCH 1/7] Remove brace-init in favour of copy-init --- .../logic/packets/CBulletsyncPacket.cpp | 1 - .../logic/packets/CBulletsyncPacket.h | 17 ++++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp index a185a2d892..964ceb03df 100644 --- a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp @@ -18,7 +18,6 @@ #include "CWeaponNames.h" CBulletsyncPacket::CBulletsyncPacket(CPlayer* player) - : m_weapon(WEAPONTYPE_UNARMED), m_start(), m_end(), m_order(0), m_damage(0.0f), m_zone(0), m_damaged(INVALID_ELEMENT_ID) { m_pSourceElement = player; } diff --git a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.h b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.h index 0f46f8e964..6e2834c48f 100644 --- a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.h +++ b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.h @@ -1,6 +1,6 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: mods/deathmatch/logic/packets/CBulletsyncPacket.h * PURPOSE: Bullet synchronization packet class @@ -9,9 +9,6 @@ * *****************************************************************************/ -#ifndef __CBULLETSYNCPACKET_H -#define __CBULLETSYNCPACKET_H - #pragma once #include "CPacket.h" @@ -48,13 +45,11 @@ class CBulletsyncPacket final : public CPacket static bool IsValidWeaponId(unsigned char weaponId) noexcept; public: - eWeaponType m_weapon{}; + eWeaponType m_weapon = WEAPONTYPE_UNARMED; CVector m_start{}; CVector m_end{}; - std::uint8_t m_order{}; - float m_damage{}; - std::uint8_t m_zone{}; - ElementID m_damaged{INVALID_ELEMENT_ID}; + std::uint8_t m_order = 0; + float m_damage = 0.0f; + std::uint8_t m_zone = 0; + ElementID m_damaged = INVALID_ELEMENT_ID; }; - -#endif // __CBULLETSYNCPACKET_H From da0f34be8b49a3edb9e68bab5bb8a98200074cba Mon Sep 17 00:00:00 2001 From: qaisjp Date: Mon, 19 Jan 2026 12:41:49 -0500 Subject: [PATCH 2/7] Dry up ResetDamageData --- .../logic/packets/CBulletsyncPacket.cpp | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp index 964ceb03df..83134c0046 100644 --- a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp @@ -100,41 +100,28 @@ bool CBulletsyncPacket::ReadWeaponAndPositions(NetBitStreamInterface& stream) return true; } +// Returns false when there's a validation error. +// Make sure to reset damage data to defaults when that happens. bool CBulletsyncPacket::ReadOptionalDamage(NetBitStreamInterface& stream) { if (!stream.ReadBit()) - { - ResetDamageData(); return true; - } stream.Read(m_damage); stream.Read(m_zone); stream.Read(m_damaged); if (IsNaN(m_damage)) - { - ResetDamageData(); return false; - } if (m_damage < 0.0f || m_damage > MAX_DAMAGE) - { - ResetDamageData(); return false; - } if (m_zone > MAX_BODY_ZONE) - { - ResetDamageData(); return false; - } if (m_damaged == 0) - { - ResetDamageData(); return false; - } // Check that target element exists (if specified) // Note: m_damaged can be INVALID_ELEMENT_ID when shooting at ground/world @@ -142,10 +129,7 @@ bool CBulletsyncPacket::ReadOptionalDamage(NetBitStreamInterface& stream) { CElement* pElement = CElementIDs::GetElement(m_damaged); if (!pElement) - { - ResetDamageData(); return false; - } // Element exists } @@ -204,7 +188,10 @@ bool CBulletsyncPacket::Read(NetBitStreamInterface& stream) return false; if (!ReadOptionalDamage(stream)) + { + ResetDamageData(); return false; + } return true; } From 32fba2ca3b5e684400a8f7c5e5545139d95fb729 Mon Sep 17 00:00:00 2001 From: qaisjp Date: Mon, 19 Jan 2026 13:08:28 -0500 Subject: [PATCH 3/7] ask question about ResetDamageData --- Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp index 83134c0046..5d2b042ca9 100644 --- a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp @@ -189,6 +189,9 @@ bool CBulletsyncPacket::Read(NetBitStreamInterface& stream) if (!ReadOptionalDamage(stream)) { + // todo: do we really need to reset damage data when we're returning + // false? returning false deletes the packet, and other packets don't + // reset internal data based on validation failures. ResetDamageData(); return false; } From 1663f0df8f770221dec2d1ec8f13d6964453d534 Mon Sep 17 00:00:00 2001 From: qaisjp Date: Mon, 19 Jan 2026 13:13:17 -0500 Subject: [PATCH 4/7] remove dead code --- Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp index 5d2b042ca9..87e327af82 100644 --- a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp @@ -147,12 +147,6 @@ bool CBulletsyncPacket::Read(NetBitStreamInterface& stream) // Check if player is spawned and alive if (!pPlayer->IsSpawned() || pPlayer->IsDead()) return false; - - // Check player position is reasonable relative to bullet start - const CVector& playerPos = pPlayer->GetPosition(); - const float maxShootDistance = 50.0f; // Max distance from player to bullet start - - // This check will be done after we read positions } if (!ReadWeaponAndPositions(stream)) From 2f1f7ad388db859e3521160687a17af625b531aa Mon Sep 17 00:00:00 2001 From: qaisjp Date: Mon, 19 Jan 2026 13:13:53 -0500 Subject: [PATCH 5/7] ask some more questions --- Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp index 87e327af82..3040584d1f 100644 --- a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp @@ -141,6 +141,7 @@ bool CBulletsyncPacket::Read(NetBitStreamInterface& stream) if (!m_pSourceElement) return false; + // todo: is this condition always true? CPlayer* pPlayer = static_cast(m_pSourceElement); if (pPlayer) { @@ -207,6 +208,7 @@ bool CBulletsyncPacket::Write(NetBitStreamInterface& stream) const if (id == INVALID_ELEMENT_ID) return false; + // why? if (id == 0) return false; From 1915561c559f6e628af5e2ed573b4bbb4a7792a1 Mon Sep 17 00:00:00 2001 From: qaisjp Date: Mon, 19 Jan 2026 14:17:18 -0500 Subject: [PATCH 6/7] Document CPacket more --- Server/mods/deathmatch/logic/packets/CPacket.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Server/mods/deathmatch/logic/packets/CPacket.h b/Server/mods/deathmatch/logic/packets/CPacket.h index 455e9a1c41..d9c3537bbc 100644 --- a/Server/mods/deathmatch/logic/packets/CPacket.h +++ b/Server/mods/deathmatch/logic/packets/CPacket.h @@ -43,7 +43,22 @@ class CPacket virtual ePacketOrdering GetPacketOrdering() const { return PACKET_ORDERING_DEFAULT; } virtual unsigned long GetFlags() const = 0; + // Overridden when it's an incoming packet. + // + // Incoming packets always have CPlayer* as the source element. + // + // - Examples of incoming-only packets: CPlayerDiagnosticPacket, CCommandPacket + // - Examples of dual packets: CBulletsyncPacket, CVoiceDataPacket virtual bool Read(NetBitStreamInterface& BitStream) { return false; }; + + // Overridden when it's an outgoing packet. + // + // Outgoing packets may have any element type as the source element. As of + // 2026-01, CStaticFunctionDefinitions::SetPedStat is the caller of + // SetSourceElement with a non-player source. + // + // - Examples of outgoing-only packets: CPlayerStatsPacket, CDebugEchoPacket + // - Examples of dual packets: CBulletsyncPacket, CVoiceDataPacket virtual bool Write(NetBitStreamInterface& BitStream) const { return false; }; void SetSourceElement(CElement* pSource) { m_pSourceElement = pSource; }; From 93fdb488e975051c2f0a26eb6b1ad4792c456803 Mon Sep 17 00:00:00 2001 From: qaisjp Date: Mon, 19 Jan 2026 14:18:48 -0500 Subject: [PATCH 7/7] Remove unnecessary check --- .../deathmatch/logic/packets/CBulletsyncPacket.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp index 3040584d1f..2d7b364e73 100644 --- a/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CBulletsyncPacket.cpp @@ -141,14 +141,10 @@ bool CBulletsyncPacket::Read(NetBitStreamInterface& stream) if (!m_pSourceElement) return false; - // todo: is this condition always true? - CPlayer* pPlayer = static_cast(m_pSourceElement); - if (pPlayer) - { - // Check if player is spawned and alive - if (!pPlayer->IsSpawned() || pPlayer->IsDead()) - return false; - } + // Check if player is spawned and alive + CPlayer* pPlayer = GetSourcePlayer(); + if (!pPlayer->IsSpawned() || pPlayer->IsDead()) + return false; if (!ReadWeaponAndPositions(stream)) return false;