Files
Nitrox/NitroxServer/GameLogic/Entities/EntityData.cs
2025-07-06 00:23:46 +02:00

78 lines
2.7 KiB
C#

using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using NitroxModel.DataStructures;
using NitroxModel.DataStructures.GameLogic;
using NitroxModel.DataStructures.GameLogic.Entities;
using NitroxModel.DataStructures.Unity;
using ProtoBufNet;
namespace NitroxServer.GameLogic.Entities;
[DataContract]
public class EntityData
{
[DataMember(Order = 1)]
public List<Entity> Entities = [];
[ProtoAfterDeserialization]
private void ProtoAfterDeserialization()
{
// After deserialization, we want to assign all of the
// children to their respective parent entities.
Dictionary<NitroxId, Entity> entitiesById = Entities.ToDictionary(entity => entity.Id);
foreach (Entity entity in Entities)
{
if (entity is WorldEntity we)
{
NitroxVector3 pos = we.Transform.LocalPosition;
if (float.IsNaN(pos.X) || float.IsNaN(pos.Y) || float.IsNaN(pos.Z) ||
float.IsInfinity(pos.X) || float.IsInfinity(pos.Y) || float.IsInfinity(pos.Z))
{
Log.Error("Found WorldEntity with NaN or infinite position. Teleporting it to world origin.");
we.Transform.LocalPosition = NitroxVector3.Zero;
}
NitroxQuaternion rot = we.Transform.LocalRotation;
if (float.IsNaN(rot.X) || float.IsNaN(rot.Y) || float.IsNaN(rot.Z) || float.IsNaN(rot.W) ||
float.IsInfinity(rot.X) || float.IsInfinity(rot.Y) || float.IsInfinity(rot.Z) || float.IsInfinity(rot.W))
{
Log.Error("Found WorldEntity with NaN or infinite rotation. Resetting rotation.");
we.Transform.LocalRotation = NitroxQuaternion.Identity;
}
}
// We will re-build the child hierarchy below and want to avoid duplicates.
// TODO: Rework system to no longer persist children entities because they are duplicates.
entity.ChildEntities.Clear();
if (entity.ParentId == null)
{
continue;
}
if (entitiesById.TryGetValue(entity.ParentId, out Entity parent))
{
parent.ChildEntities.Add(entity);
if (entity is WorldEntity we2 && parent is WorldEntity weParent)
{
we2.Transform.SetParent(weParent.Transform, false);
}
}
}
}
[OnDeserialized]
private void JsonAfterDeserialization(StreamingContext context)
{
ProtoAfterDeserialization();
}
public static EntityData From(List<Entity> entities)
{
return new EntityData { Entities = entities };
}
}