From 2fc8b7b90f567229cc92a62f9aacb0220bbbacf5 Mon Sep 17 00:00:00 2001 From: FileEX Date: Thu, 2 May 2024 01:34:19 +0200 Subject: [PATCH] Add server-side object events --- Client/mods/deathmatch/logic/CClientGame.cpp | 57 +++++++++++++++++- Client/mods/deathmatch/logic/CClientGame.h | 3 + Server/mods/deathmatch/logic/CGame.cpp | 60 +++++++++++++++++++ Server/mods/deathmatch/logic/CGame.h | 4 ++ .../deathmatch/logic/CPacketTranslator.cpp | 10 ++++ .../logic/packets/CObjectBreakPacket.cpp | 45 ++++++++++++++ .../logic/packets/CObjectBreakPacket.h | 32 ++++++++++ .../logic/packets/CObjectDamagePacket.cpp | 48 +++++++++++++++ .../logic/packets/CObjectDamagePacket.h | 33 ++++++++++ Shared/sdk/net/Packets.h | 3 + 10 files changed, 293 insertions(+), 2 deletions(-) create mode 100644 Server/mods/deathmatch/logic/packets/CObjectBreakPacket.cpp create mode 100644 Server/mods/deathmatch/logic/packets/CObjectBreakPacket.h create mode 100644 Server/mods/deathmatch/logic/packets/CObjectDamagePacket.cpp create mode 100644 Server/mods/deathmatch/logic/packets/CObjectDamagePacket.h diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 63bd6174be..0fdb4225dd 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -4774,12 +4774,22 @@ bool CClientGame::ObjectDamageHandler(CObjectSAInterface* pObjectInterface, floa Arguments.PushNumber(fLoss); CClientEntity* pClientAttacker = pPools->GetClientEntity((DWORD*)pAttackerInterface); + ElementID attackerID; + if (pClientAttacker) + { + attackerID = pClientAttacker->GetID(); Arguments.PushElement(pClientAttacker); + } else Arguments.PushNil(); - return pClientObject->CallEvent("onClientObjectDamage", Arguments, true); + bool bResult = pClientObject->CallEvent("onClientObjectDamage", Arguments, true); + + if (bResult && !pClientObject->IsLocalEntity()) + SendObjectDamagePacket(pClientObject, fLoss, attackerID); + + return bResult; } } return true; @@ -4808,12 +4818,22 @@ bool CClientGame::ObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEnti CLuaArguments Arguments; CClientEntity* pClientAttacker = pPools->GetClientEntity((DWORD*)pAttackerInterface); + ElementID attackerID = INVALID_ELEMENT_ID; + if (pClientAttacker) + { + attackerID = pClientAttacker->GetID(); Arguments.PushElement(pClientAttacker); + } else Arguments.PushNil(); - return pClientObject->CallEvent("onClientObjectBreak", Arguments, true); + bool bResult = pClientObject->CallEvent("onClientObjectBreak", Arguments, true); + + if (bResult && !pClientObject->IsLocalEntity()) + SendObjectBreakPacket(pClientObject, attackerID); + + return bResult; } } return true; @@ -5582,6 +5602,39 @@ void CClientGame::ResetMapInfo() ReinitMarkers(); } +void CClientGame::SendObjectBreakPacket(CClientObject* Object, ElementID attackerID) +{ + if (Object && Object->GetHealth() == 0.0f) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + pBitStream->Write(Object->GetID()); + pBitStream->Write(attackerID); + + g_pNet->SendPacket(PACKET_ID_OBJECT_BREAK, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } +} + +void CClientGame::SendObjectDamagePacket(CClientObject* Object, float fLoss, ElementID attackerID) +{ + if (Object) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + pBitStream->Write(Object->GetID()); + pBitStream->Write(fLoss); + pBitStream->Write(attackerID); + + g_pNet->SendPacket(PACKET_ID_OBJECT_DAMAGE, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } +} + void CClientGame::SendPedWastedPacket(CClientPed* Ped, ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, AnimationId animID) { diff --git a/Client/mods/deathmatch/logic/CClientGame.h b/Client/mods/deathmatch/logic/CClientGame.h index 96d82c37a7..613c6b91d4 100644 --- a/Client/mods/deathmatch/logic/CClientGame.h +++ b/Client/mods/deathmatch/logic/CClientGame.h @@ -390,6 +390,9 @@ class CClientGame void SendPedWastedPacket(CClientPed* Ped, ElementID damagerID = INVALID_ELEMENT_ID, unsigned char ucWeapon = 0xFF, unsigned char ucBodyPiece = 0xFF, AssocGroupId animGroup = 0, AnimationId animID = 15); + void SendObjectBreakPacket(CClientObject* Object, ElementID attackerID); + void SendObjectDamagePacket(CClientObject* Object, float fHealthLoss, ElementID attackerID); + CClientGUIElement* GetClickedGUIElement() { return m_pClickedGUIElement; } void SetClickedGUIElement(CClientGUIElement* pElement) { m_pClickedGUIElement = NULL; } diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index c2c8485562..784b6737b0 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -1152,6 +1152,18 @@ bool CGame::ProcessPacket(CPacket& Packet) return true; } + case PACKET_ID_OBJECT_BREAK: + { + Packet_ObjectBreak(static_cast(Packet)); + return true; + } + + case PACKET_ID_OBJECT_DAMAGE: + { + Packet_ObjectDamage(static_cast(Packet)); + return true; + } + case PACKET_ID_WEAPON_BULLETSYNC: { Packet_WeaponBulletsync(static_cast(Packet)); @@ -1546,6 +1558,8 @@ void CGame::AddBuiltInEvents() m_Events.AddEvent("onPlayerVoiceStop", "", NULL, false); // Object events + m_Events.AddEvent("onObjectBreak", "attacker", NULL, false); + m_Events.AddEvent("onObjectDamage", "loss, atacker", NULL, false); // Pickup events m_Events.AddEvent("onPickupHit", "player", NULL, false); @@ -2325,6 +2339,52 @@ void CGame::Packet_Command(CCommandPacket& Packet) } } +void CGame::Packet_ObjectBreak(CObjectBreakPacket& Packet) +{ + CPlayer* pPlayer = Packet.GetSourcePlayer(); + if (!pPlayer || !pPlayer->IsJoined()) + return; + + CObject* pObject = static_cast(CElementIDs::GetElement(Packet.m_ObjectID)); + + if (pObject != nullptr) + { + CElement* pAttacker = (Packet.m_Attacker != INVALID_ELEMENT_ID) ? CElementIDs::GetElement(Packet.m_Attacker) : NULL; + + CLuaArguments Arguments; + if (pAttacker) + Arguments.PushElement(pAttacker); + else + Arguments.PushNil(); + + pObject->CallEvent("onObjectBreak", Arguments); + } +} + +void CGame::Packet_ObjectDamage(CObjectDamagePacket& Packet) +{ + CPlayer* pPlayer = Packet.GetSourcePlayer(); + if (!pPlayer || !pPlayer->IsJoined()) + return; + + CObject* pObject = static_cast(CElementIDs::GetElement(Packet.m_ObjectID)); + + if (pObject != nullptr) + { + CElement* pAttacker = (Packet.m_Attacker != INVALID_ELEMENT_ID) ? CElementIDs::GetElement(Packet.m_Attacker) : NULL; + + CLuaArguments Arguments; + Arguments.PushNumber(Packet.m_fLoss); + + if (pAttacker) + Arguments.PushElement(pAttacker); + else + Arguments.PushNil(); + + pObject->CallEvent("onObjectDamage", Arguments); + } +} + void CGame::Packet_VehicleDamageSync(CVehicleDamageSyncPacket& Packet) { // Grab the source player diff --git a/Server/mods/deathmatch/logic/CGame.h b/Server/mods/deathmatch/logic/CGame.h index 22e38aadf4..2d0c327d5a 100644 --- a/Server/mods/deathmatch/logic/CGame.h +++ b/Server/mods/deathmatch/logic/CGame.h @@ -51,6 +51,8 @@ class CGame; #include "packets/CPlayerModInfoPacket.h" #include "packets/CPlayerACInfoPacket.h" #include "packets/CPlayerScreenShotPacket.h" +#include "packets/CObjectBreakPacket.h" +#include "packets/CObjectDamagePacket.h" #include "CRPCFunctions.h" @@ -485,6 +487,8 @@ class CGame void Packet_ExplosionSync(class CExplosionSyncPacket& Packet); void Packet_ProjectileSync(class CProjectileSyncPacket& Packet); void Packet_Command(class CCommandPacket& Packet); + void Packet_ObjectBreak(class CObjectBreakPacket& Packet); + void Packet_ObjectDamage(class CObjectDamagePacket& Packet); void Packet_VehicleDamageSync(class CVehicleDamageSyncPacket& Packet); void Packet_VehiclePuresync(class CVehiclePuresyncPacket& Packet); void Packet_Keysync(class CKeysyncPacket& Packet); diff --git a/Server/mods/deathmatch/logic/CPacketTranslator.cpp b/Server/mods/deathmatch/logic/CPacketTranslator.cpp index 3b6d92c3db..0ce17514a1 100644 --- a/Server/mods/deathmatch/logic/CPacketTranslator.cpp +++ b/Server/mods/deathmatch/logic/CPacketTranslator.cpp @@ -38,6 +38,8 @@ #include "packets/CLuaEventPacket.h" #include "packets/CCustomDataPacket.h" #include "packets/CCameraSyncPacket.h" +#include "packets/CObjectBreakPacket.h" +#include "packets/CObjectDamagePacket.h" #include "packets/CObjectSyncPacket.h" #include "packets/CPlayerTransgressionPacket.h" #include "packets/CPlayerDiagnosticPacket.h" @@ -176,6 +178,14 @@ CPacket* CPacketTranslator::Translate(const NetServerPlayerID& Socket, ePacketID pTemp = new CObjectSyncPacket; break; + case PACKET_ID_OBJECT_BREAK: + pTemp = new CObjectBreakPacket; + break; + + case PACKET_ID_OBJECT_DAMAGE: + pTemp = new CObjectDamagePacket; + break; + case PACKET_ID_PLAYER_TRANSGRESSION: pTemp = new CPlayerTransgressionPacket; break; diff --git a/Server/mods/deathmatch/logic/packets/CObjectBreakPacket.cpp b/Server/mods/deathmatch/logic/packets/CObjectBreakPacket.cpp new file mode 100644 index 0000000000..4ea2db51bb --- /dev/null +++ b/Server/mods/deathmatch/logic/packets/CObjectBreakPacket.cpp @@ -0,0 +1,45 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/packets/CObjectBreakPacket.cpp + * PURPOSE: Header for object break packet class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include "CObjectBreakPacket.h" +#include +#include + +CObjectBreakPacket::CObjectBreakPacket() +{ + m_ObjectID = INVALID_ELEMENT_ID; + m_Attacker = INVALID_ELEMENT_ID; +} + +CObjectBreakPacket::CObjectBreakPacket(CObject* pObject, CElement* pAttacker) +{ + m_ObjectID = pObject->GetID(); + m_Attacker = (pAttacker) ? pAttacker->GetID() : INVALID_ELEMENT_ID; +} + +bool CObjectBreakPacket::Read(NetBitStreamInterface& BitStream) +{ + if (BitStream.Read(m_ObjectID) && BitStream.Read(m_Attacker)) + { + return true; + } + + return false; +} + +bool CObjectBreakPacket::Write(NetBitStreamInterface& BitStream) const +{ + BitStream.Write(m_ObjectID); + BitStream.Write(m_Attacker); + + return true; +} diff --git a/Server/mods/deathmatch/logic/packets/CObjectBreakPacket.h b/Server/mods/deathmatch/logic/packets/CObjectBreakPacket.h new file mode 100644 index 0000000000..0cd29ebcad --- /dev/null +++ b/Server/mods/deathmatch/logic/packets/CObjectBreakPacket.h @@ -0,0 +1,32 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/packets/CObjectBreakPacket.h + * PURPOSE: Object break state class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include "CPacket.h" + +class CObject; + +class CObjectBreakPacket final : public CPacket +{ +public: + CObjectBreakPacket(); + CObjectBreakPacket(CObject* pObject, CElement* pAttacker); + + ePacketID GetPacketID() const { return PACKET_ID_OBJECT_BREAK; }; + unsigned long GetFlags() const { return PACKET_MEDIUM_PRIORITY | PACKET_RELIABLE; }; + + bool Read(NetBitStreamInterface& BitStream); + bool Write(NetBitStreamInterface& BitStream) const; + + ElementID m_ObjectID; + ElementID m_Attacker; +}; diff --git a/Server/mods/deathmatch/logic/packets/CObjectDamagePacket.cpp b/Server/mods/deathmatch/logic/packets/CObjectDamagePacket.cpp new file mode 100644 index 0000000000..9b72c3af19 --- /dev/null +++ b/Server/mods/deathmatch/logic/packets/CObjectDamagePacket.cpp @@ -0,0 +1,48 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/packets/CObjectDamagePacket.cpp + * PURPOSE: Header for object damage packet class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include "CObjectDamagePacket.h" +#include +#include + +CObjectDamagePacket::CObjectDamagePacket() +{ + m_ObjectID = INVALID_ELEMENT_ID; + m_Attacker = INVALID_ELEMENT_ID; + m_fLoss = 0; +} + +CObjectDamagePacket::CObjectDamagePacket(CObject* pObject, float fLoss, CElement* pAttacker) +{ + m_ObjectID = pObject->GetID(); + m_Attacker = (pAttacker) ? pAttacker->GetID() : INVALID_ELEMENT_ID; + m_fLoss = fLoss; +} + +bool CObjectDamagePacket::Read(NetBitStreamInterface& BitStream) +{ + if (BitStream.Read(m_ObjectID) && BitStream.Read(m_fLoss) && BitStream.Read(m_Attacker)) + { + return true; + } + + return false; +} + +bool CObjectDamagePacket::Write(NetBitStreamInterface& BitStream) const +{ + BitStream.Write(m_ObjectID); + BitStream.Write(m_fLoss); + BitStream.Write(m_Attacker); + + return true; +} diff --git a/Server/mods/deathmatch/logic/packets/CObjectDamagePacket.h b/Server/mods/deathmatch/logic/packets/CObjectDamagePacket.h new file mode 100644 index 0000000000..d0d5cc3771 --- /dev/null +++ b/Server/mods/deathmatch/logic/packets/CObjectDamagePacket.h @@ -0,0 +1,33 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/packets/CObjectDamagePacket.h + * PURPOSE: Object damage state class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include "CPacket.h" + +class CObject; + +class CObjectDamagePacket final : public CPacket +{ +public: + CObjectDamagePacket(); + CObjectDamagePacket(CObject* pObject, float fLoss, CElement* pAttacker); + + ePacketID GetPacketID() const { return PACKET_ID_OBJECT_DAMAGE; }; + unsigned long GetFlags() const { return PACKET_MEDIUM_PRIORITY | PACKET_RELIABLE; }; + + bool Read(NetBitStreamInterface& BitStream); + bool Write(NetBitStreamInterface& BitStream) const; + + ElementID m_ObjectID; + float m_fLoss; + ElementID m_Attacker; +}; diff --git a/Shared/sdk/net/Packets.h b/Shared/sdk/net/Packets.h index 0941ca49dd..fa0f4c6ede 100644 --- a/Shared/sdk/net/Packets.h +++ b/Shared/sdk/net/Packets.h @@ -125,6 +125,9 @@ enum ePacketID PACKET_ID_OBJECT_STOPSYNC, PACKET_ID_OBJECT_SYNC, + PACKET_ID_OBJECT_BREAK, + PACKET_ID_OBJECT_DAMAGE, + PACKET_ID_UPDATE_INFO, PACKET_ID_DISCONNECT_MESSAGE, PACKET_ID_PLAYER_TRANSGRESSION,