Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 26 additions & 8 deletions Server/mods/deathmatch/logic/CElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,22 +709,24 @@ bool CElement::GetCustomDataBool(const CStringName& name, bool& bOut, bool bInhe
return false;
}

void CElement::SetCustomData(const CStringName& name, const CLuaArgument& Variable, ESyncType syncType, CPlayer* pClient, bool bTriggerEvent)
bool CElement::SetCustomData(const CStringName& name, const CLuaArgument& Variable, ESyncType syncType, CPlayer* pClient, bool bTriggerEvent)
{
assert(name);
if (name->length() > MAX_CUSTOMDATA_NAME_LENGTH)
{
// Don't allow it to be set if the name is too long
CLogger::ErrorPrintf("Custom data name too long (%s)\n", *SStringX(name.ToCString()).Left(MAX_CUSTOMDATA_NAME_LENGTH + 1));
return;
return false;
}

// Grab the old variable
// Grab the old variable and sync type
CLuaArgument oldVariable;
ESyncType oldSyncType = ESyncType::LOCAL;
const SCustomData* pData = m_CustomData.Get(name);
if (pData)
{
oldVariable = pData->Variable;
oldSyncType = pData->syncType;
}

// Set the new data
Expand All @@ -737,18 +739,27 @@ void CElement::SetCustomData(const CStringName& name, const CLuaArgument& Variab
Arguments.PushString(name);
Arguments.PushArgument(oldVariable);
Arguments.PushArgument(Variable);
CallEvent("onElementDataChange", Arguments, pClient);
if (!CallEvent("onElementDataChange", Arguments, pClient))
{
// Event was cancelled, restore previous value
if (pData)
m_CustomData.Set(name, oldVariable, oldSyncType);
else
m_CustomData.Delete(name);
return false;
}
}
return true;
}

void CElement::DeleteCustomData(const CStringName& name)
bool CElement::DeleteCustomData(const CStringName& name)
{
// Grab the old variable
SCustomData* pData = m_CustomData.Get(name);
if (pData)
{
CLuaArgument oldVariable;
oldVariable = pData->Variable;
CLuaArgument oldVariable = pData->Variable;
ESyncType oldSyncType = pData->syncType;

// Delete the custom data
m_CustomData.Delete(name);
Expand All @@ -758,8 +769,15 @@ void CElement::DeleteCustomData(const CStringName& name)
Arguments.PushString(name);
Arguments.PushArgument(oldVariable);
Arguments.PushArgument(CLuaArgument()); // Use nil as the new value to indicate the data has been removed
CallEvent("onElementDataChange", Arguments);
if (!CallEvent("onElementDataChange", Arguments))
{
// Event was cancelled, restore previous value
m_CustomData.Set(name, oldVariable, oldSyncType);
return false;
}
return true;
}
return false;
}

// Used to send the root element data when a player joins
Expand Down
4 changes: 2 additions & 2 deletions Server/mods/deathmatch/logic/CElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ class CElement
bool GetCustomDataInt(const CStringName& name, int& iOut, bool bInheritData);
bool GetCustomDataFloat(const CStringName& name, float& fOut, bool bInheritData);
bool GetCustomDataBool(const CStringName& name, bool& bOut, bool bInheritData);
void SetCustomData(const CStringName& name, const CLuaArgument& Variable, ESyncType syncType = ESyncType::BROADCAST, CPlayer* pClient = NULL,
bool SetCustomData(const CStringName& name, const CLuaArgument& Variable, ESyncType syncType = ESyncType::BROADCAST, CPlayer* pClient = NULL,
bool bTriggerEvent = true);
void DeleteCustomData(const CStringName& name);
bool DeleteCustomData(const CStringName& name);
void SendAllCustomData(CPlayer* pPlayer);

CXMLNode* OutputToXML(CXMLNode* pNode);
Expand Down
44 changes: 32 additions & 12 deletions Server/mods/deathmatch/logic/CGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2738,25 +2738,45 @@ void CGame::Packet_CustomData(CCustomDataPacket& Packet)
return;
}

if (lastSyncType != ESyncType::LOCAL)
if (pElement->SetCustomData(szName, Value, lastSyncType, pSourcePlayer))
{
// Tell our clients to update their data. Send to everyone but the one we got this packet from.
if (lastSyncType != ESyncType::LOCAL)
{
// Tell our clients to update their data. Send to everyone but the one we got this packet from.
unsigned short usNameLength = static_cast<unsigned short>(strlen(szName));
CBitStream BitStream;
BitStream.pBitStream->WriteCompressed(usNameLength);
BitStream.pBitStream->Write(szName, usNameLength);
Value.WriteToBitStream(*BitStream.pBitStream);
if (lastSyncType == ESyncType::BROADCAST)
m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pElement, SET_ELEMENT_DATA, *BitStream.pBitStream), pSourcePlayer);
else
m_pPlayerManager->BroadcastOnlySubscribed(CElementRPCPacket(pElement, SET_ELEMENT_DATA, *BitStream.pBitStream), pElement, szName,
pSourcePlayer);

CPerfStatEventPacketUsage::GetSingleton()->UpdateElementDataUsageRelayed(szName, m_pPlayerManager->Count(),
BitStream.pBitStream->GetNumberOfBytesUsed());
}
}
else
{
// Event was cancelled; sync the authoritative value back to the source player
unsigned short usNameLength = static_cast<unsigned short>(strlen(szName));
CBitStream BitStream;
BitStream.pBitStream->WriteCompressed(usNameLength);
BitStream.pBitStream->Write(szName, usNameLength);
Value.WriteToBitStream(*BitStream.pBitStream);
if (lastSyncType == ESyncType::BROADCAST)
m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pElement, SET_ELEMENT_DATA, *BitStream.pBitStream), pSourcePlayer);
else
m_pPlayerManager->BroadcastOnlySubscribed(CElementRPCPacket(pElement, SET_ELEMENT_DATA, *BitStream.pBitStream), pElement, szName,
pSourcePlayer);

CPerfStatEventPacketUsage::GetSingleton()->UpdateElementDataUsageRelayed(szName, m_pPlayerManager->Count(),
BitStream.pBitStream->GetNumberOfBytesUsed());
if (CLuaArgument* pServerValue = pElement->GetCustomData(szName, false))
{
pServerValue->WriteToBitStream(*BitStream.pBitStream);
pSourcePlayer->Send(CElementRPCPacket(pElement, SET_ELEMENT_DATA, *BitStream.pBitStream));
}
else
{
BitStream.pBitStream->WriteBit(false);
pSourcePlayer->Send(CElementRPCPacket(pElement, REMOVE_ELEMENT_DATA, *BitStream.pBitStream));
}
}

pElement->SetCustomData(szName, Value, lastSyncType, pSourcePlayer);
}
}
}
Expand Down
10 changes: 6 additions & 4 deletions Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,9 @@ bool CStaticFunctionDefinitions::SetElementData(CElement* pElement, CStringName

if (!pCurrentVariable || *pCurrentVariable != Variable || lastSyncType != syncType)
{
if (!pElement->SetCustomData(name, Variable, syncType))
return false; // The server cancelled the change in onElementDataChange

if (syncType != ESyncType::LOCAL)
{
// Tell our clients to update their data
Expand All @@ -1037,8 +1040,6 @@ bool CStaticFunctionDefinitions::SetElementData(CElement* pElement, CStringName
if (lastSyncType == ESyncType::SUBSCRIBE && syncType != ESyncType::SUBSCRIBE)
m_pPlayerManager->ClearElementData(pElement, name);

// Set its custom data
pElement->SetCustomData(name, Variable, syncType);
return true;
}
return false;
Expand All @@ -1053,6 +1054,9 @@ bool CStaticFunctionDefinitions::RemoveElementData(CElement* pElement, CStringNa
// Check it exists
if (pElement->GetCustomData(name, false))
{
if (!pElement->DeleteCustomData(name))
return false; // The server cancelled the change in onElementDataChange

// Tell our clients to update their data
unsigned short usNameLength = static_cast<unsigned short>(name->length());
CBitStream BitStream;
Expand All @@ -1064,8 +1068,6 @@ bool CStaticFunctionDefinitions::RemoveElementData(CElement* pElement, CStringNa
// Clean up after the data removal
m_pPlayerManager->ClearElementData(pElement, name);

// Delete here
pElement->DeleteCustomData(name);
return true;
}

Expand Down
Loading