using NUnit.Framework; using Robust.Server.Containers; using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.GameStates; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Timing; using Robust.Shared.Utility; using Robust.UnitTesting.Server; namespace Robust.Server.IntegrationTests.GameObjects.Components { [TestFixture, Parallelizable] internal sealed partial class ContainerTest { private static EntityCoordinates _coords; private static ISimulation SimulationFactory() { var sim = RobustServerSimulation .NewSimulation() .InitializeInstance(); var map = sim.CreateMap(); _coords = new EntityCoordinates(map.Uid, default); return sim; } [Test] public void TestCreation() { var sim = SimulationFactory(); var entMan = sim.Resolve(); var containerSys = entMan.System(); var entity = entMan.SpawnAttachedTo(null, _coords); var container = containerSys.MakeContainer(entity, "dummy"); Assert.That(container.ID, Is.EqualTo("dummy")); Assert.That(container.Owner, Is.EqualTo(entity)); var manager = entMan.GetComponent(entity); Assert.That(container.Manager, Is.EqualTo(manager)); Assert.That(() => containerSys.MakeContainer(entity, "dummy"), Throws.ArgumentException); Assert.That(containerSys.HasContainer(entity, "dummy2", manager), Is.False); var container2 = containerSys.MakeContainer(entity, "dummy2"); Assert.That(container2.Manager, Is.EqualTo(manager)); Assert.That(container2.Owner, Is.EqualTo(entity)); Assert.That(container2.ID, Is.EqualTo("dummy2")); Assert.That(containerSys.HasContainer(entity, "dummy", manager), Is.True); Assert.That(containerSys.HasContainer(entity, "dummy2",manager), Is.True); Assert.That(containerSys.HasContainer(entity, "dummy3", manager), Is.False); Assert.That(containerSys.GetContainer(entity, "dummy", manager), Is.EqualTo(container)); Assert.That(containerSys.GetContainer(entity, "dummy2", manager), Is.EqualTo(container2)); Assert.That(() => containerSys.GetContainer(entity, "dummy3", manager), Throws.TypeOf()); entMan.DeleteEntity(entity); } [Test] public void TestInsertion() { var sim = SimulationFactory(); var entMan = sim.Resolve(); var containerSys = entMan.System(); var owner = entMan.SpawnAttachedTo(null, _coords); var inserted = entMan.SpawnAttachedTo(null, _coords); var transform = entMan.GetComponent(inserted); var container = containerSys.MakeContainer(owner, "dummy"); Assert.That(containerSys.Insert(inserted, container), Is.True); Assert.That(transform.ParentUid, Is.EqualTo(owner)); var container2 = containerSys.MakeContainer(inserted, "dummy"); Assert.That(containerSys.Insert(owner, container2), Is.False); var success = containerSys.Remove(inserted, container); Assert.That(success, Is.True); success = containerSys.Remove(inserted, container); Assert.That(success, Is.False); containerSys.Insert(inserted, container); entMan.DeleteEntity(owner); // Make sure inserted was detached. Assert.That(transform.Deleted, Is.True); } [Test] public void TestNestedRemoval() { var sim = SimulationFactory(); var entMan = sim.Resolve(); var containerSys = entMan.System(); var owner = entMan.SpawnAttachedTo(null, _coords); var inserted = entMan.SpawnAttachedTo(null, _coords); var transform = entMan.GetComponent(inserted); var entity = entMan.SpawnAttachedTo(null, _coords); var container = containerSys.MakeContainer(owner, "dummy"); Assert.That(containerSys.Insert(inserted, container), Is.True); Assert.That(transform.ParentUid, Is.EqualTo(owner)); var container2 = containerSys.MakeContainer(inserted, "dummy"); Assert.That(containerSys.Insert(entity, container2), Is.True); Assert.That(entMan.GetComponent(entity).ParentUid, Is.EqualTo(inserted)); Assert.That(containerSys.Remove(entity, container2), Is.True); Assert.That(container.Contains(entity), Is.True); Assert.That(entMan.GetComponent(entity).ParentUid, Is.EqualTo(owner)); entMan.DeleteEntity(owner); Assert.That(transform.Deleted, Is.True); } [Test] public void TestNestedRemovalWithDenial() { var sim = SimulationFactory(); var entMan = sim.Resolve(); var containerSys = entMan.System(); var coordinates =_coords; var entityOne = entMan.SpawnAttachedTo(null, coordinates); var entityTwo = entMan.SpawnAttachedTo(null, coordinates); var entityThree = entMan.SpawnAttachedTo(null, coordinates); var entityItem = entMan.SpawnAttachedTo(null, coordinates); var container = containerSys.MakeContainer(entityOne, "dummy"); var container2 = containerSys.MakeContainer(entityTwo, "dummy"); var container3 = containerSys.MakeContainer(entityThree, "dummy"); Assert.That(containerSys.Insert(entityTwo, container), Is.True); Assert.That(entMan.GetComponent(entityTwo).ParentUid, Is.EqualTo(entityOne)); Assert.That(containerSys.Insert(entityThree, container2), Is.True); Assert.That(entMan.GetComponent(entityThree).ParentUid, Is.EqualTo(entityTwo)); Assert.That(containerSys.Insert(entityItem, container3), Is.True); Assert.That(entMan.GetComponent(entityItem).ParentUid, Is.EqualTo(entityThree)); Assert.That(containerSys.Remove(entityItem, container3), Is.True); Assert.That(container.Contains(entityItem), Is.True); Assert.That(entMan.GetComponent(entityItem).ParentUid, Is.EqualTo(entityOne)); entMan.DeleteEntity(entityOne); Assert.That(entMan.Deleted(entityOne), Is.True); } [Test] public void BaseContainer_SelfInsert_False() { var sim = SimulationFactory(); var entMan = sim.Resolve(); var containerSys = entMan.System(); var entity = entMan.SpawnAttachedTo(null,_coords); var container = containerSys.MakeContainer(entity, "dummy"); Assert.That(containerSys.Insert(entity, container), Is.False); Assert.That(containerSys.CanInsert(entity, container), Is.False); } [Test] public void BaseContainer_InsertMap_False() { var sim = SimulationFactory(); var entMan = sim.Resolve(); var containerSys = entMan.System(); var mapEnt = new EntityUid(1); var entity = entMan.SpawnAttachedTo(null,_coords); var container = containerSys.MakeContainer(entity, "dummy"); Assert.That(containerSys.Insert(mapEnt, container), Is.False); Assert.That(containerSys.CanInsert(mapEnt, container), Is.False); } [Test] public void BaseContainer_InsertGrid_False() { var sim = SimulationFactory(); var entMan = sim.Resolve(); var mapSys = entMan.System(); var containerSys = entMan.System(); var grid = mapSys.CreateGridEntity(new MapId(1)).Owner; var entity = entMan.SpawnAttachedTo(null,_coords); var container = containerSys.MakeContainer(entity, "dummy"); Assert.That(containerSys.Insert(grid, container), Is.False); Assert.That(containerSys.CanInsert(grid, container), Is.False); } [Test] public void BaseContainer_Insert_True() { var sim = SimulationFactory(); var entMan = sim.Resolve(); var containerSys = entMan.System(); var containerEntity = entMan.SpawnAttachedTo(null,_coords); var container = containerSys.MakeContainer(containerEntity, "dummy"); var insertEntity = entMan.SpawnAttachedTo(null,_coords); var result = containerSys.Insert(insertEntity, container); Assert.That(result, Is.True); Assert.That(container.ContainedEntities.Count, Is.EqualTo(1)); Assert.That(entMan.GetComponent(containerEntity).ChildCount, Is.EqualTo(1)); Assert.That(entMan.GetComponent(containerEntity)._children.First(), Is.EqualTo(insertEntity)); result = containerSys.TryGetContainingContainer(insertEntity, out var resultContainerMan); Assert.That(result, Is.True); Assert.That(resultContainerMan?.Manager, Is.EqualTo(container.Manager)); } [Test] public void BaseContainer_RemoveNotAdded_False() { var sim = SimulationFactory(); var entMan = sim.Resolve(); var containerSys = entMan.System(); var containerEntity = entMan.SpawnAttachedTo(null,_coords); var container = containerSys.MakeContainer(containerEntity, "dummy"); var insertEntity = entMan.SpawnAttachedTo(null,_coords); var result = containerSys.Remove(insertEntity, container); Assert.That(result, Is.False); } [Test] public void BaseContainer_Transfer_True() { var sim = SimulationFactory(); var entMan = sim.Resolve(); var containerSys = entMan.System(); var entity1 = entMan.SpawnAttachedTo(null,_coords); var container1 = containerSys.MakeContainer(entity1, "dummy"); var entity2 = entMan.SpawnAttachedTo(null,_coords); var container2 = containerSys.MakeContainer(entity2, "dummy"); var transferEntity = entMan.SpawnAttachedTo(null,_coords); containerSys.Insert(transferEntity, container1); var result = containerSys.Insert(transferEntity, container2); Assert.That(result, Is.True); Assert.That(container1.ContainedEntities, Is.Empty); Assert.That(container2.ContainedEntities, Has.Count.EqualTo(1)); } [Test] public void Container_Serialize() { var sim = SimulationFactory(); var entMan = sim.Resolve(); var containerSys = entMan.System(); var entity = entMan.SpawnAttachedTo(null,_coords); var container = containerSys.MakeContainer(entity, "dummy"); var childEnt = entMan.SpawnAttachedTo(null,_coords); container.OccludesLight = true; container.ShowContents = true; containerSys.Insert(childEnt, container); var containerMan = entMan.GetComponent(entity); var getState = new ComponentGetState(); entMan.EventBus.RaiseComponentEvent(entity, containerMan, ref getState); var state = (ContainerManagerComponent.ContainerManagerComponentState)getState.State!; Assert.That(state.Containers, Has.Count.EqualTo(1)); var cont = state.Containers.Values.First(); Assert.That(state.Containers.Keys.First(), Is.EqualTo("dummy")); Assert.That(cont.OccludesLight, Is.True); Assert.That(cont.ShowContents, Is.True); Assert.That(cont.ContainedEntities, Has.Length.EqualTo(1)); Assert.That(cont.ContainedEntities[0], Is.EqualTo(entMan.GetNetEntity(childEnt))); } private sealed partial class ContainerOnlyContainer : BaseContainer { /// /// The generic container class uses a list of entities /// private readonly List _containerList = new(); public override int Count => _containerList.Count; /// public override IReadOnlyList ContainedEntities => _containerList; /// protected internal override void InternalInsert(EntityUid toInsert, IEntityManager entMan) { _containerList.Add(toInsert); } /// protected internal override void InternalRemove(EntityUid toRemove, IEntityManager entMan) { _containerList.Remove(toRemove); } /// public override bool Contains(EntityUid contained) { if (!_containerList.Contains(contained)) return false; if (IoCManager.Resolve().ApplyingState) return true; var flags = IoCManager.Resolve().GetComponent(contained).Flags; DebugTools.Assert((flags & MetaDataFlags.InContainer) != 0); return true; } /// protected internal override void InternalShutdown(IEntityManager entMan, SharedContainerSystem system, bool isClient) { foreach (var entity in _containerList.ToArray()) { if (!isClient) entMan.DeleteEntity(entity); else if (entMan.EntityExists(entity)) system.Remove(entity, this, reparent: false, force: true); } } protected internal override bool CanInsert(EntityUid toinsert, bool assumeEmpty, IEntityManager entMan) { return entMan.HasComponent(toinsert); } } } }