Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
18 changes: 17 additions & 1 deletion Server/mods/deathmatch/logic/CCustomData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ void CCustomData::Copy(CCustomData* pCustomData)
}
}

SCustomData* CCustomData::Get(const char* szName)
SCustomData* CCustomData::Get(const char* szName) const
{
assert(szName);

Expand Down Expand Up @@ -100,6 +100,7 @@ void CCustomData::Set(const char* szName, const CLuaArgument& Variable, ESyncTyp
SCustomData newData;
newData.Variable = Variable;
newData.syncType = syncType;
newData.clientChangesMode = ECustomDataClientTrust::UNSET;
m_Data[szName] = newData;
UpdateSynced(szName, Variable, syncType);
}
Expand All @@ -120,6 +121,21 @@ bool CCustomData::Delete(const char* szName)
return false;
}

bool CCustomData::IsClientChangesAllowed(const char* szName) const
{
SCustomData* pData = Get(szName);
if (!pData || pData->clientChangesMode == ECustomDataClientTrust::UNSET)
return IsClientChangesAllowed();

return pData->clientChangesMode == ECustomDataClientTrust::ALLOW;
}

void CCustomData::SetClientChangesMode(const char* szName, ECustomDataClientTrust mode)
{
SCustomData& pData = m_Data[szName];
pData.clientChangesMode = mode;
}

CXMLNode* CCustomData::OutputToXML(CXMLNode* pNode)
{
std::map<std::string, SCustomData>::const_iterator iter = m_Data.begin();
Expand Down
21 changes: 18 additions & 3 deletions Server/mods/deathmatch/logic/CCustomData.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,37 @@ enum class ESyncType
SUBSCRIBE,
};

enum class ECustomDataClientTrust : std::uint8_t
{
UNSET,
ALLOW,
DENY,
};

struct SCustomData
{
CLuaArgument Variable;
ESyncType syncType;
CLuaArgument Variable;
ESyncType syncType;
ECustomDataClientTrust clientChangesMode;
};

class CCustomData
{
public:
void Copy(CCustomData* pCustomData);

SCustomData* Get(const char* szName);
SCustomData* Get(const char* szName) const;
SCustomData* GetSynced(const char* szName);
void Set(const char* szName, const CLuaArgument& Variable, ESyncType syncType = ESyncType::BROADCAST);

bool Delete(const char* szName);

bool IsClientChangesAllowed(const char* szName) const;
void SetClientChangesMode(const char* szName, ECustomDataClientTrust mode);

bool IsClientChangesAllowed() const noexcept { return m_clientChangesAllowed; };
void SetClientChangesAllowed(bool enabled) noexcept { m_clientChangesAllowed = enabled; };

unsigned short CountOnlySynchronized();

CXMLNode* OutputToXML(CXMLNode* pNode);
Expand All @@ -58,4 +72,5 @@ class CCustomData

std::map<std::string, SCustomData> m_Data;
std::map<std::string, SCustomData> m_SyncedData;
bool m_clientChangesAllowed{true};
};
8 changes: 6 additions & 2 deletions Server/mods/deathmatch/logic/CElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ void CElement::ReadCustomData(CEvents* pEvents, CXMLNode& Node)
}
}

CLuaArgument* CElement::GetCustomData(const char* szName, bool bInheritData, ESyncType* pSyncType)
CLuaArgument* CElement::GetCustomData(const char* szName, bool bInheritData, ESyncType* pSyncType, ECustomDataClientTrust* clientChangesMode)
{
assert(szName);

Expand All @@ -518,13 +518,17 @@ CLuaArgument* CElement::GetCustomData(const char* szName, bool bInheritData, ESy
{
if (pSyncType)
*pSyncType = pData->syncType;

if (clientChangesMode)
*clientChangesMode = pData->clientChangesMode;

return &pData->Variable;
}

// If none, try returning parent's custom data
if (bInheritData && m_pParent)
{
return m_pParent->GetCustomData(szName, true, pSyncType);
return m_pParent->GetCustomData(szName, true, pSyncType, clientChangesMode);
}

// None available
Expand Down
2 changes: 1 addition & 1 deletion Server/mods/deathmatch/logic/CElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class CElement

void ReadCustomData(CEvents* pEvents, CXMLNode& Node);
CCustomData& GetCustomDataManager() { return m_CustomData; }
CLuaArgument* GetCustomData(const char* szName, bool bInheritData, ESyncType* pSyncType = NULL);
CLuaArgument* GetCustomData(const char* szName, bool bInheritData, ESyncType* pSyncType = nullptr, ECustomDataClientTrust* clientChangesMode = nullptr);
CLuaArguments* GetAllCustomData(CLuaArguments* table);
bool GetCustomDataString(const char* szName, char* pOut, size_t sizeBuffer, bool bInheritData);
bool GetCustomDataInt(const char* szName, int& iOut, bool bInheritData);
Expand Down
20 changes: 19 additions & 1 deletion Server/mods/deathmatch/logic/CGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1607,6 +1607,7 @@ void CGame::AddBuiltInEvents()
m_Events.AddEvent("onPlayerTriggerEventThreshold", "", nullptr, false);
m_Events.AddEvent("onPlayerTeamChange", "oldTeam, newTeam", nullptr, false);
m_Events.AddEvent("onPlayerTriggerInvalidEvent", "eventName, isAdded, isRemote", nullptr, false);
m_Events.AddEvent("onPlayerChangesProtectedData", "element, key, value", nullptr, false);

// Ped events
m_Events.AddEvent("onPedVehicleEnter", "vehicle, seat, jacked", NULL, false);
Expand Down Expand Up @@ -2652,7 +2653,24 @@ void CGame::Packet_CustomData(CCustomDataPacket& Packet)
}

ESyncType lastSyncType = ESyncType::BROADCAST;
pElement->GetCustomData(szName, false, &lastSyncType);
ECustomDataClientTrust clientChangesMode{};

pElement->GetCustomData(szName, false, &lastSyncType, &clientChangesMode);

const bool changesAllowed = clientChangesMode == ECustomDataClientTrust::UNSET ? pElement->GetCustomDataManager().IsClientChangesAllowed()
: clientChangesMode == ECustomDataClientTrust::ALLOW;
if (!changesAllowed)
{
CLogger::ErrorPrintf("Client trying to change protected element data %s (%s)", Packet.GetSourcePlayer()->GetNick(),
szName);

CLuaArguments arguments;
arguments.PushElement(pElement);
arguments.PushString(szName);
arguments.PushArgument(Value);
pSourcePlayer->CallEvent("onPlayerChangesProtectedData", arguments);
return;
}

if (lastSyncType != ESyncType::LOCAL)
{
Expand Down
30 changes: 30 additions & 0 deletions Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ void CLuaElementDefs::LoadFunctions()
{"addElementDataSubscriber", addElementDataSubscriber},
{"removeElementDataSubscriber", removeElementDataSubscriber},
{"hasElementDataSubscriber", hasElementDataSubscriber},
{"setElementDataClientTrust", ArgumentParser<SetElementDataClientTrust>},
{"isElementDataClientTrusted", ArgumentParser<IsElementDataClientTrusted>},
{"resetElementDataClientTrust", ArgumentParser<ResetElementDataClientTrust>},

// Set
{"setElementID", setElementID},
Expand Down Expand Up @@ -129,6 +132,7 @@ void CLuaElementDefs::AddClass(lua_State* luaVM)
lua_classfunction(luaVM, "addDataSubscriber", "addElementDataSubscriber");
lua_classfunction(luaVM, "removeDataSubscriber", "removeElementDataSubscriber");
lua_classfunction(luaVM, "hasDataSubscriber", "hasElementDataSubscriber");
lua_classfunction(luaVM, "resetDataClientTrust", "resetElementDataClientTrust");

lua_classfunction(luaVM, "setParent", "setElementParent");
lua_classfunction(luaVM, "setFrozen", "setElementFrozen");
Expand All @@ -151,6 +155,7 @@ void CLuaElementDefs::AddClass(lua_State* luaVM)
lua_classfunction(luaVM, "setLowLOD", "setLowLODElement");
lua_classfunction(luaVM, "setAttachedOffsets", "setElementAttachedOffsets");
lua_classfunction(luaVM, "setCallPropagationEnabled", "setElementCallPropagationEnabled");
lua_classfunction(luaVM, "setDataClientTrust", "setElementDataClientTrust");

lua_classfunction(luaVM, "getAttachedOffsets", "getElementAttachedOffsets");
lua_classfunction(luaVM, "getChild", "getElementChild");
Expand Down Expand Up @@ -189,6 +194,7 @@ void CLuaElementDefs::AddClass(lua_State* luaVM)
lua_classfunction(luaVM, "isVisibleTo", "isElementVisibleTo");
lua_classfunction(luaVM, "isLowLOD", "isElementLowLOD");
lua_classfunction(luaVM, "isAttached", "isElementAttached");
lua_classfunction(luaVM, "isDataClientTrusted", "isElementDataClientTrusted");

lua_classvariable(luaVM, "id", "setElementID", "getElementID");
lua_classvariable(luaVM, "callPropagationEnabled", "setElementCallPropagationEnabled", "isElementCallPropagationEnabled");
Expand Down Expand Up @@ -2437,3 +2443,27 @@ int CLuaElementDefs::isElementCallPropagationEnabled(lua_State* luaVM)
lua_pushboolean(luaVM, false);
return 1;
}

void CLuaElementDefs::SetElementDataClientTrust(CElement* pElement, bool enabled, std::optional<std::string_view> key)
{
if (key.has_value())
pElement->GetCustomDataManager().SetClientChangesMode(key.value().data(), enabled ? ECustomDataClientTrust::ALLOW : ECustomDataClientTrust::DENY);
else
pElement->GetCustomDataManager().SetClientChangesAllowed(enabled);
}

bool CLuaElementDefs::IsElementDataClientTrusted(CElement* pElement, std::optional<std::string_view> key)
{
if (key.has_value())
return pElement->GetCustomDataManager().IsClientChangesAllowed(key.value().data());
else
return pElement->GetCustomDataManager().IsClientChangesAllowed();
}

void CLuaElementDefs::ResetElementDataClientTrust(CElement* pElement, std::optional<std::string_view> key)
{
if (key.has_value())
pElement->GetCustomDataManager().SetClientChangesMode(key.value().data(), ECustomDataClientTrust::UNSET);
else
pElement->GetCustomDataManager().SetClientChangesAllowed(true);
}
3 changes: 3 additions & 0 deletions Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ class CLuaElementDefs : public CLuaDefs
LUA_DECLARE(addElementDataSubscriber);
LUA_DECLARE(removeElementDataSubscriber);
LUA_DECLARE(hasElementDataSubscriber);
static void SetElementDataClientTrust(CElement* pElement, bool enabled, std::optional<std::string_view> key);
static void ResetElementDataClientTrust(CElement* pElement, std::optional<std::string_view> key);
static bool IsElementDataClientTrusted(CElement* pElement, std::optional<std::string_view> key);

// Attachement
LUA_DECLARE(attachElements);
Expand Down
Loading