Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync name and colors for vehicles, rocket and cyclops #2090

Merged
merged 3 commits into from
Dec 18, 2023
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
7 changes: 7 additions & 0 deletions Nitrox.Test/Server/Serialization/WorldPersistenceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,13 @@ private static void EntityTest(Entity entity, Entity entityAfter)
case SeamothMetadata metadata when entityAfter.Metadata is SeamothMetadata metadataAfter:
Assert.AreEqual(metadata.LightsOn, metadataAfter.LightsOn);
Assert.AreEqual(metadata.Health, metadataAfter.Health);
Assert.AreEqual(metadata.Name, metadataAfter.Name);
Assert.IsTrue(metadata.Colors.SequenceEqual(metadataAfter.Colors));
break;
case ExosuitMetadata metadata when entityAfter.Metadata is ExosuitMetadata metadataAfter:
Assert.AreEqual(metadata.Health, metadataAfter.Health);
Assert.AreEqual(metadata.Name, metadataAfter.Name);
Assert.IsTrue(metadata.Colors.SequenceEqual(metadataAfter.Colors));
break;
case SubNameInputMetadata metadata when entityAfter.Metadata is SubNameInputMetadata metadataAfter:
Assert.AreEqual(metadata.Name, metadataAfter.Name);
Expand Down
20 changes: 12 additions & 8 deletions NitroxClient/ClientAutoFacRegistrar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
using NitroxClient.GameLogic.PlayerLogic.PlayerPreferences;
using NitroxClient.GameLogic.Settings;
using NitroxClient.GameLogic.Spawning.Metadata;
using NitroxClient.GameLogic.Spawning.Metadata.Extractor;
using NitroxClient.GameLogic.Spawning.Metadata.Extractor.Abstract;
using NitroxClient.GameLogic.Spawning.Metadata.Processor.Abstract;
using NitroxClient.Map;
using NitroxModel.Core;
using NitroxModel.Helper;
Expand Down Expand Up @@ -54,7 +55,7 @@ public void RegisterDependencies(ContainerBuilder containerBuilder)
RegisterInitialSyncProcessors(containerBuilder);
}

private static void RegisterCoreDependencies(ContainerBuilder containerBuilder)
private void RegisterCoreDependencies(ContainerBuilder containerBuilder)
{
#if DEBUG
containerBuilder.RegisterAssemblyTypes(currentAssembly)
Expand Down Expand Up @@ -136,13 +137,16 @@ private static void RegisterCoreDependencies(ContainerBuilder containerBuilder)
private void RegisterMetadataDependencies(ContainerBuilder containerBuilder)
{
containerBuilder.RegisterAssemblyTypes(currentAssembly)
.AssignableTo<EntityMetadataExtractor>()
.As<EntityMetadataExtractor>()
.InstancePerLifetimeScope();
.AssignableTo<IEntityMetadataExtractor>()
.As<IEntityMetadataExtractor>()
.AsSelf()
.SingleInstance();
containerBuilder.RegisterAssemblyTypes(currentAssembly)
.AssignableTo<EntityMetadataProcessor>()
.As<EntityMetadataProcessor>()
.InstancePerLifetimeScope();
.AssignableTo<IEntityMetadataProcessor>()
.As<IEntityMetadataProcessor>()
.AsSelf()
.SingleInstance();
containerBuilder.RegisterType<EntityMetadataManager>().InstancePerLifetimeScope();
}

private void RegisterPacketProcessors(ContainerBuilder containerBuilder)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using NitroxClient.GameLogic;
using NitroxClient.GameLogic.Bases;
using NitroxClient.GameLogic.Spawning.Bases;
using NitroxClient.GameLogic.Spawning.Metadata;
using NitroxClient.MonoBehaviours;
using NitroxClient.Unity.Helper;
using NitroxModel.DataStructures;
Expand All @@ -22,10 +23,12 @@ namespace NitroxClient.Communication.Packets.Processors;
public class BuildingResyncProcessor : ClientPacketProcessor<BuildingResync>
{
private readonly Entities entities;
private readonly EntityMetadataManager entityMetadataManager;

public BuildingResyncProcessor(Entities entities)
public BuildingResyncProcessor(Entities entities, EntityMetadataManager entityMetadataManager)
{
this.entities = entities;
this.entityMetadataManager = entityMetadataManager;
}

public override void Process(BuildingResync packet)
Expand Down Expand Up @@ -132,6 +135,7 @@ public IEnumerator OverwriteModule(Constructable constructable, ModuleEntity mod
{
Log.Info($"[Module RESYNC] Overwriting module with id {moduleEntity.Id}");
ModuleEntitySpawner.ApplyModuleData(moduleEntity, constructable.gameObject);
entityMetadataManager.ApplyMetadata(constructable.gameObject, moduleEntity.Metadata);
yield break;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
using NitroxClient.Communication.Packets.Processors.Abstract;
using NitroxClient.Communication.Packets.Processors.Abstract;
using NitroxClient.GameLogic.Spawning.Metadata;
using NitroxClient.GameLogic.Spawning.Metadata.Processor.Abstract;
using NitroxClient.MonoBehaviours;
using NitroxModel.DataStructures.Util;
using NitroxModel.Helper;
using NitroxModel.Packets;
using UnityEngine;

namespace NitroxClient.Communication.Packets.Processors
namespace NitroxClient.Communication.Packets.Processors;

public class EntityMetadataUpdateProcessor : ClientPacketProcessor<EntityMetadataUpdate>
{
public class EntityMetadataUpdateProcessor : ClientPacketProcessor<EntityMetadataUpdate>
private readonly EntityMetadataManager entityMetadataManager;

public EntityMetadataUpdateProcessor(EntityMetadataManager entityMetadataManager)
{
this.entityMetadataManager = entityMetadataManager;
}

public override void Process(EntityMetadataUpdate update)
{
public override void Process(EntityMetadataUpdate update)
{
GameObject gameObject = NitroxEntity.RequireObjectFrom(update.Id);
GameObject gameObject = NitroxEntity.RequireObjectFrom(update.Id);

Optional<EntityMetadataProcessor> metadataProcessor = EntityMetadataProcessor.FromMetaData(update.NewValue);
Validate.IsTrue(metadataProcessor.HasValue, $"No processor found for EntityMetadata of type {update.NewValue.GetType()}");
Optional<IEntityMetadataProcessor> metadataProcessor = entityMetadataManager.FromMetaData(update.NewValue);
Validate.IsTrue(metadataProcessor.HasValue, $"No processor found for EntityMetadata of type {update.NewValue.GetType()}");

metadataProcessor.Value.ProcessMetadata(gameObject, update.NewValue);
}
metadataProcessor.Value.ProcessMetadata(gameObject, update.NewValue);
}
}
3 changes: 2 additions & 1 deletion NitroxClient/Debuggers/NetworkDebugger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public class NetworkDebugger : BaseDebugger, INetworkDebugger
private readonly List<string> filter = new()
{
nameof(PlayerMovement), nameof(EntityTransformUpdates), nameof(PlayerStats), nameof(SpawnEntities), nameof(VehicleMovement), nameof(PlayerCinematicControllerCall),
nameof(PlayFMODAsset), nameof(PlayFMODCustomEmitter), nameof(PlayFMODStudioEmitter), nameof(PlayFMODCustomLoopingEmitter), nameof(SimulationOwnershipChange)
nameof(PlayFMODAsset), nameof(PlayFMODCustomEmitter), nameof(PlayFMODStudioEmitter), nameof(PlayFMODCustomLoopingEmitter), nameof(SimulationOwnershipChange),
nameof(CellVisibilityChanged), nameof(BatchVisibilityChanged)
};
private readonly List<PacketDebugWrapper> packets = new List<PacketDebugWrapper>(PACKET_STORED_COUNT);

Expand Down
10 changes: 6 additions & 4 deletions NitroxClient/GameLogic/Bases/BuildUtils.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using NitroxClient.GameLogic.Spawning.Bases;
using NitroxClient.GameLogic.Spawning.Metadata;
using NitroxClient.MonoBehaviours;
using NitroxClient.Unity.Helper;
using NitroxModel.DataStructures;
Expand Down Expand Up @@ -236,14 +237,15 @@ public static MapRoomEntity CreateMapRoomEntityFrom(MapRoomFunctionality mapRoom
return new(id, parentId, mapRoomCell.ToDto());
}

public static List<GlobalRootEntity> GetGlobalRootChildren(Transform globalRoot)
// TODO: Use this for a latter singleplayer save converter
public static List<GlobalRootEntity> GetGlobalRootChildren(Transform globalRoot, EntityMetadataManager entityMetadataManager)
{
List<GlobalRootEntity> entities = new();
foreach (Transform child in globalRoot)
{
if (child.TryGetComponent(out Base @base))
{
entities.Add(BuildEntitySpawner.From(@base));
entities.Add(BuildEntitySpawner.From(@base, entityMetadataManager));
}
else if (child.TryGetComponent(out Constructable constructable))
{
Expand All @@ -258,7 +260,7 @@ public static List<GlobalRootEntity> GetGlobalRootChildren(Transform globalRoot)
return entities;
}

public static List<Entity> GetChildEntities(Base targetBase, NitroxId baseId)
public static List<Entity> GetChildEntities(Base targetBase, NitroxId baseId, EntityMetadataManager entityMetadataManager)
{
List<Entity> childEntities = new();
void AddChild(Entity childEntity)
Expand Down Expand Up @@ -286,7 +288,7 @@ void AddChild(Entity childEntity)
continue;
}
MonoBehaviour moduleMB = baseModule as MonoBehaviour;
AddChild(InteriorPieceEntitySpawner.From(baseModule));
AddChild(InteriorPieceEntitySpawner.From(baseModule, entityMetadataManager));
}
else if (transform.TryGetComponent(out Constructable constructable))
{
Expand Down
9 changes: 8 additions & 1 deletion NitroxClient/GameLogic/Bases/BuildingHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
using NitroxClient.Communication;
using NitroxClient.Communication.Abstract;
using NitroxClient.GameLogic.Spawning.Bases;
using NitroxClient.GameLogic.Spawning.Metadata;
using NitroxClient.MonoBehaviours;
using NitroxClient.Unity.Helper;
using NitroxModel.DataStructures;
using NitroxModel.DataStructures.GameLogic;
using NitroxModel.DataStructures.GameLogic.Bases;
using NitroxModel.DataStructures.GameLogic.Entities.Bases;
using NitroxModel.DataStructures.Util;
using NitroxModel.Packets;
using NitroxModel_Subnautica.DataStructures;
using UnityEngine;
Expand Down Expand Up @@ -126,7 +128,12 @@ public IEnumerator BuildModule(PlaceModule placeModule)
{
ModuleEntity moduleEntity = placeModule.ModuleEntity;
Transform parent = GetParentOrGlobalRoot(moduleEntity.ParentId);
yield return ModuleEntitySpawner.RestoreModule(parent, moduleEntity);
TaskResult<Optional<GameObject>> result = new();
yield return ModuleEntitySpawner.RestoreModule(parent, moduleEntity, result);
if (result.value.HasValue)
{
this.Resolve<EntityMetadataManager>().ApplyMetadata(result.value.Value.gameObject, moduleEntity.Metadata);
}
BasesCooldown[moduleEntity.ParentId ?? moduleEntity.Id] = DateTimeOffset.UtcNow;
}

Expand Down
29 changes: 18 additions & 11 deletions NitroxClient/GameLogic/Entities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using NitroxClient.Communication;
using NitroxClient.Communication.Abstract;
using NitroxClient.GameLogic.PlayerLogic.PlayerModel.Abstract;
using NitroxClient.GameLogic.Spawning;
using NitroxClient.GameLogic.Spawning.Abstract;
using NitroxClient.GameLogic.Spawning.Bases;
using NitroxClient.GameLogic.Spawning.Metadata;
using NitroxClient.GameLogic.Spawning.Metadata.Extractor;
using NitroxClient.GameLogic.Spawning.WorldEntities;
using NitroxClient.MonoBehaviours;
using NitroxClient.Unity.Helper;
Expand All @@ -29,6 +29,7 @@ public class Entities
{
private readonly IPacketSender packetSender;
private readonly ThrottledPacketSender throttledPacketSender;
private readonly EntityMetadataManager entityMetadataManager;

private readonly Dictionary<NitroxId, Type> spawnedAsType = new();
private readonly Dictionary<NitroxId, List<Entity>> pendingParentEntitiesByParentId = new Dictionary<NitroxId, List<Entity>>();
Expand All @@ -38,10 +39,11 @@ public class Entities
public List<Entity> EntitiesToSpawn { get; private init; }
private bool spawningEntities;

public Entities(IPacketSender packetSender, ThrottledPacketSender throttledPacketSender, PlayerManager playerManager, ILocalNitroxPlayer localPlayer)
public Entities(IPacketSender packetSender, ThrottledPacketSender throttledPacketSender, EntityMetadataManager entityMetadataManager, PlayerManager playerManager, ILocalNitroxPlayer localPlayer)
{
this.packetSender = packetSender;
this.throttledPacketSender = throttledPacketSender;
this.entityMetadataManager = entityMetadataManager;
EntitiesToSpawn = new();

entitySpawnersByType[typeof(PrefabChildEntity)] = new PrefabChildEntitySpawner();
Expand All @@ -50,7 +52,7 @@ public Entities(IPacketSender packetSender, ThrottledPacketSender throttledPacke
entitySpawnersByType[typeof(InstalledBatteryEntity)] = new InstalledBatteryEntitySpawner();
entitySpawnersByType[typeof(InventoryEntity)] = new InventoryEntitySpawner();
entitySpawnersByType[typeof(InventoryItemEntity)] = new InventoryItemEntitySpawner();
entitySpawnersByType[typeof(WorldEntity)] = new WorldEntitySpawner(playerManager, localPlayer, this);
entitySpawnersByType[typeof(WorldEntity)] = new WorldEntitySpawner(entityMetadataManager, playerManager, localPlayer, this);
entitySpawnersByType[typeof(PlaceholderGroupWorldEntity)] = entitySpawnersByType[typeof(WorldEntity)];
entitySpawnersByType[typeof(EscapePodWorldEntity)] = entitySpawnersByType[typeof(WorldEntity)];
entitySpawnersByType[typeof(PlayerWorldEntity)] = entitySpawnersByType[typeof(WorldEntity)];
Expand All @@ -59,28 +61,33 @@ public Entities(IPacketSender packetSender, ThrottledPacketSender throttledPacke
entitySpawnersByType[typeof(BuildEntity)] = new BuildEntitySpawner(this);
entitySpawnersByType[typeof(ModuleEntity)] = new ModuleEntitySpawner(this);
entitySpawnersByType[typeof(GhostEntity)] = new GhostEntitySpawner();
entitySpawnersByType[typeof(InteriorPieceEntity)] = new InteriorPieceEntitySpawner(this);
entitySpawnersByType[typeof(OxygenPipeEntity)] = new OxygenPipeEntitySpawner(this, (WorldEntitySpawner)entitySpawnersByType[typeof(WorldEntity)]);
entitySpawnersByType[typeof(PlacedWorldEntity)] = new PlacedWorldEntitySpawner((WorldEntitySpawner)entitySpawnersByType[typeof(WorldEntity)]);
entitySpawnersByType[typeof(InteriorPieceEntity)] = new InteriorPieceEntitySpawner(this, entityMetadataManager);
}

public void EntityMetadataChanged(object o, NitroxId id)
{
Optional<EntityMetadata> metadata = EntityMetadataExtractor.Extract(o);
Optional<EntityMetadata> metadata = entityMetadataManager.Extract(o);

if (metadata.HasValue)
{
BroadcastMetadataUpdate(id, metadata.Value);
}
}

public void EntityMetadataChangedThrottled(object o, NitroxId id)
public void EntityMetadataChangedThrottled(object o, NitroxId id, float throttleTime = 0.2f)
{
Optional<EntityMetadata> metadata = EntityMetadataExtractor.Extract(o);
// As throttled broadcasting is done after some time by a different function, this is where the packet sending should be interrupted
if (PacketSuppressor<EntityMetadataUpdate>.IsSuppressed)
{
return;
}
Optional<EntityMetadata> metadata = entityMetadataManager.Extract(o);

if (metadata.HasValue)
{
BroadcastMetadataUpdateThrottled(id, metadata.Value);
BroadcastMetadataUpdateThrottled(id, metadata.Value, throttleTime);
}
}

Expand All @@ -89,9 +96,9 @@ public void BroadcastMetadataUpdate(NitroxId id, EntityMetadata metadata)
packetSender.Send(new EntityMetadataUpdate(id, metadata));
}

public void BroadcastMetadataUpdateThrottled(NitroxId id, EntityMetadata metadata)
public void BroadcastMetadataUpdateThrottled(NitroxId id, EntityMetadata metadata, float throttleTime = 0.2f)
{
throttledPacketSender.SendThrottled(new EntityMetadataUpdate(id, metadata), (packet) => ((EntityMetadataUpdate)packet).Id);
throttledPacketSender.SendThrottled(new EntityMetadataUpdate(id, metadata), packet => packet.Id, throttleTime);
}

public void BroadcastEntitySpawnedByClient(WorldEntity entity)
Expand Down Expand Up @@ -178,7 +185,7 @@ public IEnumerator SpawnBatchAsync(List<Entity> batch, bool forceRespawn = false

MarkAsSpawned(entity);

EntityMetadataProcessor.ApplyMetadata(entityResult.Get().Value, entity.Metadata);
entityMetadataManager.ApplyMetadata(entityResult.Get().Value, entity.Metadata);

// Finding out about all children (can be hidden in the object's hierarchy or in a pending list)

Expand Down
12 changes: 7 additions & 5 deletions NitroxClient/GameLogic/ItemContainers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,28 @@
using NitroxClient.Communication.Abstract;
using NitroxClient.GameLogic.Helper;
using NitroxClient.GameLogic.PlayerLogic;
using NitroxClient.GameLogic.Spawning.Metadata.Extractor;
using NitroxClient.GameLogic.Spawning.Metadata;
using NitroxClient.MonoBehaviours;
using NitroxClient.Unity.Helper;
using NitroxModel.DataStructures;
using NitroxModel.DataStructures.GameLogic.Entities.Metadata;
using NitroxModel.DataStructures.GameLogic.Entities;
using NitroxModel.DataStructures.GameLogic.Entities.Metadata;
using NitroxModel.DataStructures.Util;
using NitroxModel.Packets;
using UnityEngine;
using NitroxModel_Subnautica.DataStructures;
using UnityEngine;

namespace NitroxClient.GameLogic
{
public class ItemContainers
{
private readonly IPacketSender packetSender;
private readonly EntityMetadataManager entityMetadataManager;

public ItemContainers(IPacketSender packetSender)
public ItemContainers(IPacketSender packetSender, EntityMetadataManager entityMetadataManager)
{
this.packetSender = packetSender;
this.entityMetadataManager = entityMetadataManager;
}

public void BroadcastItemAdd(Pickupable pickupable, Transform containerTransform)
Expand Down Expand Up @@ -85,7 +87,7 @@ public void BroadcastBatteryAdd(GameObject gameObject, GameObject parent, TechTy
return;
}

Optional<EntityMetadata> metadata = EntityMetadataExtractor.Extract(gameObject);
Optional<EntityMetadata> metadata = entityMetadataManager.Extract(gameObject);

InstalledBatteryEntity installedBattery = new(id, techType.ToDto(), metadata.OrNull(), parentId, new());

Expand Down
Loading