Skip to content
Open
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
111 changes: 69 additions & 42 deletions code/components/citizen-server-impl/include/state/SyncTrees_Five.h
Original file line number Diff line number Diff line change
Expand Up @@ -508,78 +508,105 @@ struct CVehicleScriptGameStateDataNode
}
};

struct CEntityScriptInfoDataNode
struct CEntityScriptInfoDataNode : GenericSerializeDataNode<CEntityScriptInfoDataNode>
{
uint32_t m_scriptHash;
uint32_t m_timestamp;
uint32_t m_positionHash;
uint32_t m_instanceId;
uint32_t m_scriptObjectId;
uint32_t m_hostToken;

bool Parse(SyncParseState& state)
template<typename Serializer>
bool Serialize(Serializer& s)
{
auto hasScript = state.buffer.ReadBit();
bool hasScript = m_scriptHash != 0;
s.Serialize(hasScript);

if (hasScript) // Has script info
if (hasScript)
{
// deserialize CGameScriptObjInfo
// -> CGameScriptObjInfo

// -> CGameScriptId
{
// -> CGameScriptId

// ---> rage::scriptId
m_scriptHash = state.buffer.Read<uint32_t>(32);
// ---> end
{
// -> rage::scriptId
s.Serialize(32, m_scriptHash);
}

m_timestamp = state.buffer.Read<uint32_t>(32);
s.Serialize(32, m_timestamp);

if (state.buffer.ReadBit())
{
auto positionHash = state.buffer.Read<uint32_t>(32);
}
bool hasPositionHash = m_positionHash != 0;
s.Serialize(hasPositionHash);

if (state.buffer.ReadBit())
{
auto instanceId = state.buffer.Read<uint32_t>(7);
}
if (hasPositionHash)
{
s.Serialize(32, m_positionHash);
}
else if constexpr (Serializer::isReader)
{
m_positionHash = 0;
}

bool hasInstanceId = m_instanceId != 0;
s.Serialize(hasInstanceId);

// -> end
if (hasInstanceId)
{
s.Serialize(8, m_instanceId);
}
else if constexpr (Serializer::isReader)
{
m_instanceId = 0;
}
}

auto scriptObjectId = state.buffer.Read<uint32_t>(32);
s.Serialize(32, m_scriptObjectId);

auto hostTokenLength = state.buffer.ReadBit() ? 16 : 3;
auto hostToken = state.buffer.Read<uint32_t>(hostTokenLength);
bool longHostToken = m_hostToken >= (1 << 3);
s.Serialize(longHostToken);

// end
auto hostTokenLength = longHostToken ? 16 : 3;
s.Serialize(hostTokenLength, m_hostToken);
}
else
else if constexpr (Serializer::isReader)
{
m_scriptHash = 0;
}

return true;
}
};

bool Unparse(sync::SyncUnparseState& state)
{
rl::MessageBuffer& buffer = state.buffer;

if (m_scriptHash)
{
buffer.WriteBit(true);

buffer.Write<uint32_t>(32, m_scriptHash);
buffer.Write<uint32_t>(32, m_timestamp);
template<>
struct NodeProcessor<CEntityScriptInfoDataNode>
{
uint32_t lastScriptId = 0;

buffer.WriteBit(false);
buffer.WriteBit(false);
bool PreParse(CEntityScriptInfoDataNode& node, SyncParseState& state)
{
lastScriptId = node.m_scriptHash;

buffer.Write<uint32_t>(32, 12);
return false;
}

buffer.WriteBit(false);
buffer.Write<uint32_t>(3, 0);
}
else
bool PostParse(CEntityScriptInfoDataNode& node, SyncParseState& state)
{
if (lastScriptId && !node.m_scriptHash)
{
buffer.WriteBit(false);
if (state.entity && state.entity->IsOwnedByServerScript())
{
node.m_scriptHash = lastScriptId;
return true;
}
}

return false;
}

constexpr bool IsHandled()
{
return true;
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,28 @@

namespace fx::sync
{
template<typename TNode>
inline constexpr bool AffectsBlender();

template<typename TNode>
struct NodeProcessor
{
bool PreParse(TNode& node, SyncParseState& state)
{
return false;
}

bool PostParse(TNode& node, SyncParseState& state)
{
return false;
}

constexpr bool IsHandled()
{
return false;
}
};

template<int Id1, int Id2, int Id3, bool CanSendOnFirst = true>
struct NodeIds
{
Expand Down Expand Up @@ -393,10 +415,39 @@ struct NodeWrapper : public NodeBase
// parse manual data
if constexpr (ShouldParseNode<TNode>(0))
{
state.buffer.SetCurrentBit(endBit);
node.Parse(state);
NodeProcessor<TNode> nodeProc;

auto doParse = [this, &state, endBit, length]()
{
state.buffer.SetCurrentBit(endBit);
node.Parse(state);

state.buffer.SetCurrentBit(endBit + length);
};

if constexpr (nodeProc.IsHandled())
{
bool needReparse = nodeProc.PreParse(node, state);

doParse();

needReparse |= nodeProc.PostParse(node, state);

if (needReparse)
{
rl::MessageBuffer mb(data.size());
sync::SyncUnparseState unparseState{ mb };
node.Unparse(unparseState);

memcpy(data.data(), mb.GetBuffer().data(), mb.GetBuffer().size());

state.buffer.SetCurrentBit(endBit + length);
this->length = mb.GetCurrentBit();
}
}
else
{
doParse();
}
}

frameIndex = state.frameIndex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ std::shared_ptr<sync::SyncTreeBase> MakeAutomobile(uint32_t model, float posX, f
{
cdn.m_scriptHash = resourceHash;
cdn.m_timestamp = msec().count();
cdn.m_instanceId = 12;
cdn.m_scriptObjectId = 12;
});

return tree;
Expand Down Expand Up @@ -151,6 +153,8 @@ std::shared_ptr<sync::SyncTreeBase> MakeVehicle(uint32_t model, float posX, floa
{
cdn.m_scriptHash = resourceHash;
cdn.m_timestamp = msec().count();
cdn.m_instanceId = 12;
cdn.m_scriptObjectId = 12;
});

return tree;
Expand Down Expand Up @@ -195,6 +199,8 @@ std::shared_ptr<sync::SyncTreeBase> MakePed(uint32_t model, float posX, float po
{
cdn.m_scriptHash = resourceHash;
cdn.m_timestamp = msec().count();
cdn.m_instanceId = 12;
cdn.m_scriptObjectId = 12;
});

return tree;
Expand Down Expand Up @@ -235,6 +241,8 @@ std::shared_ptr<sync::SyncTreeBase> MakeObject(uint32_t model, float posX, float
{
cdn.m_scriptHash = resourceHash;
cdn.m_timestamp = msec().count();
cdn.m_instanceId = 12;
cdn.m_scriptObjectId = 12;
});

return tree;
Expand Down
Loading