diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 93d108e723..d452cef7fb 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -45,7 +45,7 @@ jobs: - name: Create build artifacts run: utils\premake5 compose_files - - uses: actions/upload-artifact@master + - uses: actions/upload-artifact@v3 with: name: InstallFiles path: InstallFiles/ diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index b8468395c0..c2c8485562 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -2443,6 +2443,10 @@ void CGame::Packet_Bulletsync(CBulletsyncPacket& Packet) CPlayer* pPlayer = Packet.GetSourcePlayer(); if (pPlayer && pPlayer->IsJoined()) { + // Early return when the player attempts to fire a weapon they do not have + if (!pPlayer->HasWeaponType(Packet.m_WeaponType)) + return; + // Relay to other players RelayNearbyPacket(Packet); diff --git a/Server/mods/deathmatch/logic/CPed.cpp b/Server/mods/deathmatch/logic/CPed.cpp index 0b2ba04d0d..e3b7e0128c 100644 --- a/Server/mods/deathmatch/logic/CPed.cpp +++ b/Server/mods/deathmatch/logic/CPed.cpp @@ -356,6 +356,17 @@ void CPed::SetWeaponTotalAmmo(unsigned short usTotalAmmo, unsigned char ucSlot) } } +bool CPed::HasWeaponType(unsigned char ucWeaponType) +{ + for (unsigned char slot = 0; slot < WEAPON_SLOTS; slot++) + { + if (GetWeaponType(slot) == ucWeaponType) + return true; + } + + return false; +} + float CPed::GetMaxHealth() { // TODO: Verify this formula diff --git a/Server/mods/deathmatch/logic/CPed.h b/Server/mods/deathmatch/logic/CPed.h index 00eee811ae..47e70e7189 100644 --- a/Server/mods/deathmatch/logic/CPed.h +++ b/Server/mods/deathmatch/logic/CPed.h @@ -168,6 +168,7 @@ class CPed : public CElement void SetWeaponAmmoInClip(unsigned short uscAmmoInClip, unsigned char ucSlot = 0xFF); unsigned short GetWeaponTotalAmmo(unsigned char ucSlot = 0xFF); void SetWeaponTotalAmmo(unsigned short usTotalAmmo, unsigned char ucSlot = 0xFF); + bool HasWeaponType(unsigned char ucWeaponType); float GetMaxHealth(); float GetHealth() { return m_fHealth; } diff --git a/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp index 3765f22980..54c63e49ff 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp @@ -175,6 +175,12 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) // Set weapon slot if (bWeaponCorrect) pSourcePlayer->SetWeaponSlot(uiSlot); + else + { + // remove invalid weapon data to prevent this from being relayed to other players + ucClientWeaponType = 0; + slot.data.uiSlot = 0; + } if (CWeaponNames::DoesSlotHaveAmmo(uiSlot)) {