Add UnknownEntityDeleteTest (#4380)

This commit is contained in:
Leon Friedrich
2023-09-13 14:57:50 +12:00
committed by GitHub
parent 6af0c88f27
commit d62efe7301

View File

@@ -153,6 +153,156 @@ public sealed partial class ComponentStateTests : RobustIntegrationTest
}
}
/// <summary>
/// This is a variant of <see cref="UnknownEntityTest"/> that deletes one of the entities before the other entity gets sent.
/// </summary>
[Test]
public async Task UnknownEntityDeleteTest()
{
// The first chunk of the test just follows UnknownEntityTest
var compReg = () => IoCManager.Resolve<IComponentFactory>().RegisterClass<UnknownEntityTestComponent>();
var sysReg = () => IoCManager.Resolve<IEntitySystemManager>().LoadExtraSystemType<UnknownEntityTestComponent.UnknownEntityTestComponent_AutoNetworkSystem>();
var serverOpts = new ServerIntegrationOptions
{
Pool = false,
BeforeRegisterComponents = compReg,
BeforeStart = sysReg,
};
var clientOpts = new ClientIntegrationOptions
{
Pool = false,
BeforeRegisterComponents = compReg,
BeforeStart = sysReg,
};
var server = StartServer(serverOpts);
var client = StartClient(clientOpts);
await Task.WhenAll(client.WaitIdleAsync(), server.WaitIdleAsync());
var netMan = client.ResolveDependency<IClientNetManager>();
var xforms = server.System<SharedTransformSystem>();
Assert.DoesNotThrow(() => client.SetConnectTarget(server));
client.Post(() => netMan.ClientConnect(null!, 0, null!));
server.Post(() => server.CfgMan.SetCVar(CVars.NetPVS, true));
// Set up map.
EntityUid map = default;
await server.WaitPost(() =>
{
var mapId = server.MapMan.CreateMap();
map = server.MapMan.GetMapEntityId(mapId);
});
await RunTicks();
// Spawn entities
var coordsA = new EntityCoordinates(map, default);
var coordsB = new EntityCoordinates(map, new Vector2(100, 100));
EntityUid player = default;
EntityUid cPlayer = default;
EntityUid serverEntA = default;
EntityUid serverEntB = default;
NetEntity serverNetA = default;
NetEntity serverNetB = default;
await server.WaitPost(() =>
{
// Attach player.
player = server.EntMan.Spawn();
var session = (IPlayerSession) server.PlayerMan.Sessions.First();
server.System<ActorSystem>().Attach(player, session);
session.JoinGame();
// Spawn test entities.
serverEntA = server.EntMan.SpawnAttachedTo(null, coordsA);
serverEntB = server.EntMan.SpawnAttachedTo(null, coordsB);
serverNetA = server.EntMan.GetNetEntity(serverEntA);
serverNetB = server.EntMan.GetNetEntity(serverEntB);
// Setup components
var cmp = server.EntMan.EnsureComponent<UnknownEntityTestComponent>(serverEntA);
cmp.Other = serverEntB;
server.EntMan.Dirty(serverEntA, cmp);
cmp = server.EntMan.EnsureComponent<UnknownEntityTestComponent>(serverEntB);
cmp.Other = serverEntA;
server.EntMan.Dirty(serverEntB, cmp);
});
await RunTicks();
// Check player got properly attached and only knows about the expected entities
await client.WaitPost(() =>
{
cPlayer = client.EntMan.GetEntity(server.EntMan.GetNetEntity(player));
Assert.That(client.AttachedEntity, Is.EqualTo(cPlayer));
Assert.That(client.EntMan.EntityExists(cPlayer));
Assert.That(client.EntMan.EntityExists(client.EntMan.GetEntity(serverNetA)), Is.False);
Assert.That(client.EntMan.EntityExists(client.EntMan.GetEntity(serverNetB)), Is.False);
});
// Move the player into PVS range of one of the entities.
await server.WaitPost(() => xforms.SetCoordinates(player, coordsB));
await RunTicks();
await client.WaitPost(() =>
{
var clientEntA = client.EntMan.GetEntity(serverNetA);
var clientEntB = client.EntMan.GetEntity(serverNetB);
Assert.That(client.EntMan.EntityExists(clientEntB), Is.True);
Assert.That(client.EntMan.EntityExists(client.EntMan.GetEntity(serverNetA)), Is.False);
Assert.That(client.EntMan.TryGetComponent(clientEntB, out UnknownEntityTestComponent? cmp));
Assert.That(cmp?.Other, Is.EqualTo(clientEntA));
});
// This is where the test difffers from UnknownEntityTest:
// We delete the entity that the player knows about before it receives the entity that it references.
await server.WaitPost(() =>
{
server.EntMan.DeleteEntity(serverEntB);
var comp = server.EntMan.GetComponent<UnknownEntityTestComponent>(serverEntA);
comp.Other = EntityUid.Invalid;
server.EntMan.Dirty(serverEntA, comp);
});
await RunTicks();
await client.WaitPost(() =>
{
var clientEntA = client.EntMan.GetEntity(serverNetA);
var clientEntB = client.EntMan.GetEntity(serverNetB);
Assert.That(clientEntA, Is.EqualTo(EntityUid.Invalid));
Assert.That(clientEntB, Is.EqualTo(EntityUid.Invalid));
});
// Move the player into PVS range of the other entity
await server.WaitPost(() => xforms.SetCoordinates(player, coordsA));
await RunTicks();
await client.WaitPost(() =>
{
var clientEntA = client.EntMan.GetEntity(serverNetA);
var clientEntB = client.EntMan.GetEntity(serverNetB);
Assert.That(clientEntB, Is.EqualTo(EntityUid.Invalid));
Assert.That(client.EntMan.EntityExists(clientEntA), Is.True);
Assert.That(client.EntMan.TryGetComponent(clientEntA, out UnknownEntityTestComponent? cmp));
Assert.That(cmp?.Other, Is.EqualTo(EntityUid.Invalid));
});
server.Post(() => server.CfgMan.SetCVar(CVars.NetPVS, false));
// wait for errors.
await RunTicks();
async Task RunTicks()
{
for (int i = 0; i < 10; i++)
{
await server!.WaitRunTicks(1);
await client!.WaitRunTicks(1);
}
}
}
}
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]