Fix ghost respawn bug (#17511)
This commit is contained in:
@@ -18,6 +18,38 @@ namespace Content.IntegrationTests.Tests.Minds;
|
||||
[TestFixture]
|
||||
public sealed partial class MindTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a server-client pair and ensures that the client is attached to a simple mind test entity.
|
||||
/// </summary>
|
||||
public async Task<PairTracker> SetupPair()
|
||||
{
|
||||
var pairTracker = await PoolManager.GetServerClient(new PoolSettings{ ExtraPrototypes = Prototypes });
|
||||
var pair = pairTracker.Pair;
|
||||
|
||||
var entMan = pair.Server.ResolveDependency<IServerEntityManager>();
|
||||
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
|
||||
var mindSys = entMan.System<MindSystem>();
|
||||
|
||||
var player = playerMan.ServerSessions.Single();
|
||||
|
||||
EntityUid entity = default;
|
||||
await pair.Server.WaitPost(() =>
|
||||
{
|
||||
entity = entMan.SpawnEntity("MindTestEntity", MapCoordinates.Nullspace);
|
||||
mindSys.TransferTo(mindSys.CreateMind(player.UserId), entity);
|
||||
});
|
||||
|
||||
await PoolManager.RunTicksSync(pair, 5);
|
||||
|
||||
var mind = player.ContentData()?.Mind;
|
||||
Assert.NotNull(mind);
|
||||
Assert.That(player.AttachedEntity, Is.EqualTo(entity));
|
||||
Assert.That(player.AttachedEntity, Is.EqualTo(mind.CurrentEntity), "Player is not attached to the mind's current entity.");
|
||||
Assert.That(entMan.EntityExists(mind.OwnedEntity), "The mind's current entity does not exist");
|
||||
Assert.That(mind.VisitingEntity == null || entMan.EntityExists(mind.VisitingEntity), "The minds visited entity does not exist.");
|
||||
return pairTracker;
|
||||
}
|
||||
|
||||
public async Task<EntityUid> BecomeGhost(Pair pair, bool visit = false)
|
||||
{
|
||||
var entMan = pair.Server.ResolveDependency<IServerEntityManager>();
|
||||
@@ -74,9 +106,9 @@ public sealed partial class MindTests
|
||||
|
||||
var mind = player.ContentData()!.Mind;
|
||||
Assert.NotNull(mind);
|
||||
Assert.That(player.AttachedEntity, Is.EqualTo(mind.CurrentEntity));
|
||||
Assert.That(entMan.EntityExists(mind.OwnedEntity));
|
||||
Assert.That(entMan.EntityExists(mind.CurrentEntity));
|
||||
Assert.That(player.AttachedEntity, Is.EqualTo(mind.CurrentEntity), "Player is not attached to the mind's current entity.");
|
||||
Assert.That(entMan.EntityExists(mind.OwnedEntity), "The mind's current entity does not exist");
|
||||
Assert.That(mind.VisitingEntity == null || entMan.EntityExists(mind.VisitingEntity), "The minds visited entity does not exist.");
|
||||
|
||||
return mind;
|
||||
}
|
||||
|
||||
@@ -20,21 +20,19 @@ public sealed partial class MindTests
|
||||
[Test]
|
||||
public async Task TestGhostsCanReconnect()
|
||||
{
|
||||
await using var pairTracker = await PoolManager.GetServerClient();
|
||||
await using var pairTracker = await SetupPair();
|
||||
var pair = pairTracker.Pair;
|
||||
|
||||
var entMan = pair.Server.ResolveDependency<IEntityManager>();
|
||||
await PoolManager.RunTicksSync(pair, 5);
|
||||
var mind = GetMind(pair);
|
||||
|
||||
var ghost = await BecomeGhost(pair);
|
||||
await DisconnectReconnect(pair);
|
||||
|
||||
// Player in control of a NEW entity
|
||||
var newMind = GetMind(pair);
|
||||
Assert.That(newMind != mind);
|
||||
// Player in control of a new ghost, but with the same mind
|
||||
Assert.That(GetMind(pair) == mind);
|
||||
Assert.That(entMan.Deleted(ghost));
|
||||
Assert.Null(newMind.VisitingEntity);
|
||||
Assert.That(entMan.HasComponent<GhostComponent>(mind.OwnedEntity));
|
||||
Assert.Null(mind.VisitingEntity);
|
||||
|
||||
await pairTracker.CleanReturnAsync();
|
||||
}
|
||||
@@ -47,11 +45,9 @@ public sealed partial class MindTests
|
||||
[Test]
|
||||
public async Task TestDeletedCanReconnect()
|
||||
{
|
||||
await using var pairTracker = await PoolManager.GetServerClient();
|
||||
await using var pairTracker = await SetupPair();
|
||||
var pair = pairTracker.Pair;
|
||||
|
||||
var entMan = pair.Server.ResolveDependency<IEntityManager>();
|
||||
await PoolManager.RunTicksSync(pair, 5);
|
||||
var mind = GetMind(pair);
|
||||
|
||||
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
|
||||
@@ -76,15 +72,12 @@ public sealed partial class MindTests
|
||||
// Reconnect
|
||||
await Connect(pair, name);
|
||||
player = playerMan.ServerSessions.Single();
|
||||
Assert.That(user == player.UserId);
|
||||
Assert.That(user, Is.EqualTo(player.UserId));
|
||||
|
||||
// Player is now a new entity
|
||||
var newMind = GetMind(pair);
|
||||
Assert.That(newMind != mind);
|
||||
Assert.Null(mind.UserId);
|
||||
Assert.Null(mind.CurrentEntity);
|
||||
Assert.NotNull(newMind.OwnedEntity);
|
||||
Assert.That(entMan.EntityExists(newMind.OwnedEntity));
|
||||
// Player is now a new ghost entity
|
||||
Assert.That(GetMind(pair), Is.EqualTo(mind));
|
||||
Assert.That(mind.OwnedEntity, Is.Not.EqualTo(entity));
|
||||
Assert.That(entMan.HasComponent<GhostComponent>(mind.OwnedEntity));
|
||||
|
||||
await pairTracker.CleanReturnAsync();
|
||||
}
|
||||
@@ -97,11 +90,10 @@ public sealed partial class MindTests
|
||||
[Test]
|
||||
public async Task TestVisitingGhostReconnect()
|
||||
{
|
||||
await using var pairTracker = await PoolManager.GetServerClient();
|
||||
await using var pairTracker = await SetupPair();
|
||||
var pair = pairTracker.Pair;
|
||||
|
||||
var entMan = pair.Server.ResolveDependency<IEntityManager>();
|
||||
await PoolManager.RunTicksSync(pair, 5);
|
||||
var mind = GetMind(pair);
|
||||
|
||||
var original = mind.CurrentEntity;
|
||||
@@ -109,8 +101,8 @@ public sealed partial class MindTests
|
||||
await DisconnectReconnect(pair);
|
||||
|
||||
// Player now controls their original mob, mind was preserved
|
||||
Assert.That(mind == GetMind(pair));
|
||||
Assert.That(mind.CurrentEntity == original);
|
||||
Assert.That(mind, Is.EqualTo(GetMind(pair)));
|
||||
Assert.That(mind.CurrentEntity, Is.EqualTo(original));
|
||||
Assert.That(!entMan.Deleted(original));
|
||||
Assert.That(entMan.Deleted(ghost));
|
||||
|
||||
@@ -125,7 +117,7 @@ public sealed partial class MindTests
|
||||
[Test]
|
||||
public async Task TestVisitingReconnect()
|
||||
{
|
||||
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{ ExtraPrototypes = Prototypes });
|
||||
await using var pairTracker = await SetupPair();
|
||||
var pair = pairTracker.Pair;
|
||||
|
||||
var entMan = pair.Server.ResolveDependency<IEntityManager>();
|
||||
|
||||
@@ -61,26 +61,6 @@ public sealed partial class MindTests
|
||||
- !type:GibBehavior { }
|
||||
";
|
||||
|
||||
/// <summary>
|
||||
/// Exception handling for PlayerData and NetUserId invalid due to testing.
|
||||
/// Can be removed when Players can be mocked.
|
||||
/// </summary>
|
||||
/// <param name="func"></param>
|
||||
private void CatchPlayerDataException(Action func)
|
||||
{
|
||||
try
|
||||
{
|
||||
func();
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
// Prevent exiting due to PlayerData not being initialized.
|
||||
if (e.Message == "New owner must have previously logged into the server. (Parameter 'newOwner')")
|
||||
return;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestCreateAndTransferMindToNewEntity()
|
||||
{
|
||||
@@ -382,11 +362,11 @@ public sealed partial class MindTests
|
||||
await pairTracker.CleanReturnAsync();
|
||||
}
|
||||
|
||||
[Test]
|
||||
// TODO Implement
|
||||
/*[Test]
|
||||
public async Task TestPlayerCanReturnFromGhostWhenDead()
|
||||
{
|
||||
// TODO Implement
|
||||
}
|
||||
}*/
|
||||
|
||||
[Test]
|
||||
public async Task TestGhostDoesNotInfiniteLoop()
|
||||
|
||||
Reference in New Issue
Block a user