Skip to content

Commit bca549b

Browse files
committed
Add removeElementData client side without a new RPC
1 parent 237d9a5 commit bca549b

13 files changed

Lines changed: 140 additions & 154 deletions

File tree

Client/mods/deathmatch/logic/CClientEntity.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -498,14 +498,14 @@ void CClientEntity::SetCustomData(const CStringName& name, const CLuaArgument& V
498498
CallEvent("onClientElementDataChange", Arguments, true);
499499
}
500500

501-
void CClientEntity::DeleteCustomData(const CStringName& name)
501+
bool CClientEntity::DeleteCustomData(const CStringName& name)
502502
{
503503
// Grab the old variable
504-
SCustomData* pData = m_pCustomData->Get(name);
505-
if (pData)
504+
auto* data = m_pCustomData->Get(name);
505+
if (data)
506506
{
507507
CLuaArgument oldVariable;
508-
oldVariable = pData->Variable;
508+
oldVariable = data->Variable;
509509

510510
// Delete the custom data
511511
m_pCustomData->Delete(name);
@@ -516,7 +516,10 @@ void CClientEntity::DeleteCustomData(const CStringName& name)
516516
Arguments.PushArgument(oldVariable);
517517
Arguments.PushArgument(CLuaArgument()); // Use nil as the new value to indicate the data has been removed
518518
CallEvent("onClientElementDataChange", Arguments, true);
519+
return true;
519520
}
521+
522+
return false;
520523
}
521524

522525
bool CClientEntity::GetMatrix(CMatrix& matrix) const

Client/mods/deathmatch/logic/CClientEntity.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ class CClientEntity : public CClientEntityBase
209209
bool GetCustomDataInt(const CStringName& name, int& iOut, bool bInheritData);
210210
bool GetCustomDataBool(const CStringName& name, bool& bOut, bool bInheritData);
211211
void SetCustomData(const CStringName& name, const CLuaArgument& Variable, bool bSynchronized = true);
212-
void DeleteCustomData(const CStringName& name);
212+
bool DeleteCustomData(const CStringName& name);
213213

214214
virtual bool GetMatrix(CMatrix& matrix) const;
215215
virtual bool SetMatrix(const CMatrix& matrix);

Client/mods/deathmatch/logic/CNetAPI.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ enum eServerRPCFunctions
3434
KEY_BIND,
3535
CURSOR_EVENT,
3636
REQUEST_STEALTH_KILL,
37-
REMOVE_ELEMENT_DATA_RPC,
3837
};
3938

4039
class CNetAPI

Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,25 +1059,28 @@ bool CStaticFunctionDefinitions::RemoveElementData(CClientEntity& Entity, CStrin
10591059
assert(name);
10601060
assert(name->length() <= MAX_CUSTOMDATA_NAME_LENGTH);
10611061

1062-
bool isSynced;
1063-
CLuaArgument* currentVariable = Entity.GetCustomData(name, false, &isSynced);
1062+
if (Entity.IsLocalEntity())
1063+
return Entity.DeleteCustomData(name);
1064+
1065+
bool isSynced = false;
1066+
auto* currentVariable = Entity.GetCustomData(name, false, &isSynced);
10641067
if (!currentVariable)
10651068
return false;
10661069

1067-
if (isSynced && !Entity.IsLocalEntity())
1070+
if (isSynced)
10681071
{
1069-
NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream();
1070-
// Write element ID and name for server-side removal handling
1071-
pBitStream->Write(Entity.GetID());
1072-
pBitStream->WriteString(name.ToString());
1072+
auto bitStream = g_pNet->AllocateNetBitStream();
1073+
// Omitting the value reuses the custom data packet for removals without adding another client-to-server RPC.
1074+
bitStream->Write(Entity.GetID());
1075+
std::uint16_t nameLength = static_cast<std::uint16_t>(name->length());
1076+
bitStream->WriteCompressed(nameLength);
1077+
bitStream->Write(name.ToCString(), nameLength);
10731078

1074-
// Send RPC and deallocate
1075-
g_pClientGame->GetNetAPI()->RPC(REMOVE_ELEMENT_DATA_RPC, pBitStream);
1076-
g_pNet->DeallocateNetBitStream(pBitStream);
1079+
g_pNet->SendPacket(PACKET_ID_CUSTOM_DATA, bitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED);
1080+
g_pNet->DeallocateNetBitStream(bitStream);
10771081
}
10781082

1079-
Entity.DeleteCustomData(name);
1080-
return true;
1083+
return Entity.DeleteCustomData(name);
10811084
}
10821085

10831086
bool CStaticFunctionDefinitions::SetElementMatrix(CClientEntity& Entity, const CMatrix& matrix)

Server/mods/deathmatch/logic/CElement.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -752,14 +752,14 @@ bool CElement::SetCustomData(const CStringName& name, const CLuaArgument& Variab
752752
return true;
753753
}
754754

755-
bool CElement::DeleteCustomData(const CStringName& name, CPlayer* pClient)
755+
bool CElement::DeleteCustomData(const CStringName& name, CPlayer* client)
756756
{
757757
// Grab the old variable
758-
SCustomData* pData = m_CustomData.Get(name);
759-
if (pData)
758+
auto* data = m_CustomData.Get(name);
759+
if (data)
760760
{
761-
CLuaArgument oldVariable = pData->Variable;
762-
ESyncType oldSyncType = pData->syncType;
761+
CLuaArgument oldVariable = data->Variable;
762+
ESyncType oldSyncType = data->syncType;
763763

764764
// Delete the custom data
765765
m_CustomData.Delete(name);
@@ -769,7 +769,7 @@ bool CElement::DeleteCustomData(const CStringName& name, CPlayer* pClient)
769769
Arguments.PushString(name);
770770
Arguments.PushArgument(oldVariable);
771771
Arguments.PushArgument(CLuaArgument()); // Use nil as the new value to indicate the data has been removed
772-
if (!CallEvent("onElementDataChange", Arguments, pClient))
772+
if (!CallEvent("onElementDataChange", Arguments, client))
773773
{
774774
// Event was cancelled, restore previous value
775775
m_CustomData.Set(name, oldVariable, oldSyncType);

Server/mods/deathmatch/logic/CElement.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class CElement
148148
bool GetCustomDataBool(const CStringName& name, bool& bOut, bool bInheritData);
149149
bool SetCustomData(const CStringName& name, const CLuaArgument& Variable, ESyncType syncType = ESyncType::BROADCAST, CPlayer* pClient = NULL,
150150
bool bTriggerEvent = true);
151-
bool DeleteCustomData(const CStringName& name, CPlayer* pClient = nullptr);
151+
bool DeleteCustomData(const CStringName& name, CPlayer* client = nullptr);
152152
void SendAllCustomData(CPlayer* pPlayer);
153153

154154
CXMLNode* OutputToXML(CXMLNode* pNode);

Server/mods/deathmatch/logic/CGame.cpp

Lines changed: 92 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2712,85 +2712,134 @@ void CGame::Packet_LuaEvent(CLuaEventPacket& Packet)
27122712
}
27132713
}
27142714

2715-
void CGame::Packet_CustomData(CCustomDataPacket& Packet)
2715+
void CGame::Packet_CustomData(CCustomDataPacket& packet)
27162716
{
27172717
// Got a valid source?
2718-
CPlayer* pSourcePlayer = Packet.GetSourcePlayer();
2719-
if (pSourcePlayer)
2718+
auto* sourcePlayer = packet.GetSourcePlayer();
2719+
if (sourcePlayer)
27202720
{
27212721
// Grab the element
2722-
ElementID ID = Packet.GetElementID();
2723-
CElement* pElement = CElementIDs::GetElement(ID);
2724-
if (pElement)
2722+
ElementID elementId = packet.GetElementID();
2723+
auto* element = CElementIDs::GetElement(elementId);
2724+
if (element)
27252725
{
27262726
// Change the data
2727-
const char* szName = Packet.GetName();
2728-
CLuaArgument& Value = Packet.GetValue();
2727+
const char* name = packet.GetName();
2728+
CLuaArgument& value = packet.GetValue();
2729+
const bool isDelete = packet.IsDelete();
27292730

27302731
// Ignore if the wrong length
2731-
if (strlen(szName) > MAX_CUSTOMDATA_NAME_LENGTH)
2732+
if (strlen(name) > MAX_CUSTOMDATA_NAME_LENGTH)
27322733
{
2733-
CLogger::ErrorPrintf("Received oversized custom data name from %s (%s)\n", Packet.GetSourcePlayer()->GetNick(),
2734-
*SStringX(szName).Left(MAX_CUSTOMDATA_NAME_LENGTH + 1));
2734+
CLogger::ErrorPrintf("Received oversized custom data name from %s (%s)\n", sourcePlayer->GetNick(),
2735+
*SStringX(name).Left(MAX_CUSTOMDATA_NAME_LENGTH + 1));
27352736
return;
27362737
}
27372738

27382739
ESyncType lastSyncType = ESyncType::BROADCAST;
27392740
eCustomDataClientTrust clientChangesMode{};
27402741

2741-
pElement->GetCustomData(szName, false, &lastSyncType, &clientChangesMode);
2742+
element->GetCustomData(name, false, &lastSyncType, &clientChangesMode);
27422743

27432744
const bool changesAllowed = clientChangesMode == eCustomDataClientTrust::UNSET ? !m_pMainConfig->IsElementDataWhitelisted()
27442745
: clientChangesMode == eCustomDataClientTrust::ALLOW;
27452746
if (!changesAllowed)
27462747
{
2747-
CLogger::ErrorPrintf("Client trying to change protected element data %s (%s)\n", Packet.GetSourcePlayer()->GetNick(), szName);
2748+
CLogger::ErrorPrintf("Client trying to change protected element data %s (%s)\n", sourcePlayer->GetNick(), name);
27482749

27492750
CLuaArguments arguments;
2750-
arguments.PushElement(pElement);
2751-
arguments.PushString(szName);
2752-
arguments.PushArgument(Value);
2753-
pSourcePlayer->CallEvent("onPlayerChangesProtectedData", arguments);
2751+
arguments.PushElement(element);
2752+
arguments.PushString(name);
2753+
arguments.PushArgument(value);
2754+
sourcePlayer->CallEvent("onPlayerChangesProtectedData", arguments);
27542755
return;
27552756
}
27562757

2757-
if (pElement->SetCustomData(szName, Value, lastSyncType, pSourcePlayer))
2758+
if (isDelete)
27582759
{
2759-
if (lastSyncType != ESyncType::LOCAL)
2760+
if (element->DeleteCustomData(name, sourcePlayer))
27602761
{
2761-
// Tell our clients to update their data. Send to everyone but the one we got this packet from.
2762-
unsigned short usNameLength = static_cast<unsigned short>(strlen(szName));
2763-
CBitStream BitStream;
2764-
BitStream.pBitStream->WriteCompressed(usNameLength);
2765-
BitStream.pBitStream->Write(szName, usNameLength);
2766-
Value.WriteToBitStream(*BitStream.pBitStream);
2767-
if (lastSyncType == ESyncType::BROADCAST)
2768-
m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pElement, SET_ELEMENT_DATA, *BitStream.pBitStream), pSourcePlayer);
2769-
else
2770-
m_pPlayerManager->BroadcastOnlySubscribed(CElementRPCPacket(pElement, SET_ELEMENT_DATA, *BitStream.pBitStream), pElement, szName,
2771-
pSourcePlayer);
2762+
if (lastSyncType != ESyncType::LOCAL)
2763+
{
2764+
// Tell our clients to remove their data. Send to everyone but the one we got this packet from.
2765+
std::uint16_t nameLength = static_cast<std::uint16_t>(strlen(name));
2766+
CBitStream bitStream;
2767+
bitStream.pBitStream->WriteCompressed(nameLength);
2768+
bitStream.pBitStream->Write(name, nameLength);
2769+
bitStream.pBitStream->WriteBit(false); // Unused (was recursive flag)
2770+
if (lastSyncType == ESyncType::BROADCAST)
2771+
m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(element, REMOVE_ELEMENT_DATA, *bitStream.pBitStream), sourcePlayer);
2772+
else
2773+
m_pPlayerManager->BroadcastOnlySubscribed(CElementRPCPacket(element, REMOVE_ELEMENT_DATA, *bitStream.pBitStream), element, name,
2774+
sourcePlayer);
27722775

2773-
CPerfStatEventPacketUsage::GetSingleton()->UpdateElementDataUsageRelayed(szName, m_pPlayerManager->Count(),
2774-
BitStream.pBitStream->GetNumberOfBytesUsed());
2776+
CPerfStatEventPacketUsage::GetSingleton()->UpdateElementDataUsageRelayed(name, m_pPlayerManager->Count(),
2777+
bitStream.pBitStream->GetNumberOfBytesUsed());
2778+
}
2779+
2780+
if (lastSyncType == ESyncType::SUBSCRIBE)
2781+
m_pPlayerManager->ClearElementData(element, name);
2782+
}
2783+
else
2784+
{
2785+
// Restore the element data on the client, because the server cancelled the change in onElementDataChange.
2786+
std::uint16_t nameLength = static_cast<std::uint16_t>(strlen(name));
2787+
CBitStream bitStream;
2788+
bitStream.pBitStream->WriteCompressed(nameLength);
2789+
bitStream.pBitStream->Write(name, nameLength);
2790+
2791+
if (auto* serverValue = element->GetCustomData(name, false))
2792+
{
2793+
serverValue->WriteToBitStream(*bitStream.pBitStream);
2794+
sourcePlayer->Send(CElementRPCPacket(element, SET_ELEMENT_DATA, *bitStream.pBitStream));
2795+
}
2796+
else
2797+
{
2798+
bitStream.pBitStream->WriteBit(false);
2799+
sourcePlayer->Send(CElementRPCPacket(element, REMOVE_ELEMENT_DATA, *bitStream.pBitStream));
2800+
}
27752801
}
27762802
}
27772803
else
27782804
{
2779-
// Event was cancelled; sync the authoritative value back to the source player
2780-
unsigned short usNameLength = static_cast<unsigned short>(strlen(szName));
2781-
CBitStream BitStream;
2782-
BitStream.pBitStream->WriteCompressed(usNameLength);
2783-
BitStream.pBitStream->Write(szName, usNameLength);
2784-
2785-
if (CLuaArgument* pServerValue = pElement->GetCustomData(szName, false))
2805+
if (element->SetCustomData(name, value, lastSyncType, sourcePlayer))
27862806
{
2787-
pServerValue->WriteToBitStream(*BitStream.pBitStream);
2788-
pSourcePlayer->Send(CElementRPCPacket(pElement, SET_ELEMENT_DATA, *BitStream.pBitStream));
2807+
if (lastSyncType != ESyncType::LOCAL)
2808+
{
2809+
// Tell our clients to update their data. Send to everyone but the one we got this packet from.
2810+
std::uint16_t nameLength = static_cast<std::uint16_t>(strlen(name));
2811+
CBitStream bitStream;
2812+
bitStream.pBitStream->WriteCompressed(nameLength);
2813+
bitStream.pBitStream->Write(name, nameLength);
2814+
value.WriteToBitStream(*bitStream.pBitStream);
2815+
if (lastSyncType == ESyncType::BROADCAST)
2816+
m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(element, SET_ELEMENT_DATA, *bitStream.pBitStream), sourcePlayer);
2817+
else
2818+
m_pPlayerManager->BroadcastOnlySubscribed(CElementRPCPacket(element, SET_ELEMENT_DATA, *bitStream.pBitStream), element, name,
2819+
sourcePlayer);
2820+
2821+
CPerfStatEventPacketUsage::GetSingleton()->UpdateElementDataUsageRelayed(name, m_pPlayerManager->Count(),
2822+
bitStream.pBitStream->GetNumberOfBytesUsed());
2823+
}
27892824
}
27902825
else
27912826
{
2792-
BitStream.pBitStream->WriteBit(false);
2793-
pSourcePlayer->Send(CElementRPCPacket(pElement, REMOVE_ELEMENT_DATA, *BitStream.pBitStream));
2827+
// Restore the element data on the client, because the server cancelled the change in onElementDataChange.
2828+
std::uint16_t nameLength = static_cast<std::uint16_t>(strlen(name));
2829+
CBitStream bitStream;
2830+
bitStream.pBitStream->WriteCompressed(nameLength);
2831+
bitStream.pBitStream->Write(name, nameLength);
2832+
2833+
if (auto* serverValue = element->GetCustomData(name, false))
2834+
{
2835+
serverValue->WriteToBitStream(*bitStream.pBitStream);
2836+
sourcePlayer->Send(CElementRPCPacket(element, SET_ELEMENT_DATA, *bitStream.pBitStream));
2837+
}
2838+
else
2839+
{
2840+
bitStream.pBitStream->WriteBit(false);
2841+
sourcePlayer->Send(CElementRPCPacket(element, REMOVE_ELEMENT_DATA, *bitStream.pBitStream));
2842+
}
27942843
}
27952844
}
27962845
}

Server/mods/deathmatch/logic/CGame.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ class CGame
510510
void Packet_Vehicle_InOut(class CVehicleInOutPacket& Packet);
511511
void Packet_VehicleTrailer(class CVehicleTrailerPacket& Packet);
512512
void Packet_LuaEvent(class CLuaEventPacket& Packet);
513-
void Packet_CustomData(class CCustomDataPacket& Packet);
513+
void Packet_CustomData(class CCustomDataPacket& packet);
514514
void Packet_Voice_Data(class CVoiceDataPacket& Packet);
515515
void Packet_Voice_End(class CVoiceEndPacket& Packet);
516516
void Packet_CameraSync(class CCameraSyncPacket& Packet);

Server/mods/deathmatch/logic/CPerfStat.RPCPacketUsage.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,6 @@ ADD_ENUM1(CRPCFunctions::PLAYER_WEAPON)
243243
ADD_ENUM1(CRPCFunctions::KEY_BIND)
244244
ADD_ENUM1(CRPCFunctions::CURSOR_EVENT)
245245
ADD_ENUM1(CRPCFunctions::REQUEST_STEALTH_KILL)
246-
ADD_ENUM1(CRPCFunctions::REMOVE_ELEMENT_DATA_RPC)
247246
IMPLEMENT_ENUM_END("eRPCFunctions")
248247

249248
struct SRPCPacketStat

0 commit comments

Comments
 (0)