Use dummy sessions in NukeOpsTest (#28549)
* Add dummy sessions * Update NukeOpsTest * Fix PvsBenchmark
This commit is contained in:
@@ -1,19 +1,17 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using BenchmarkDotNet.Attributes;
|
using BenchmarkDotNet.Attributes;
|
||||||
using Content.IntegrationTests;
|
using Content.IntegrationTests;
|
||||||
using Content.IntegrationTests.Pair;
|
using Content.IntegrationTests.Pair;
|
||||||
|
using Content.Server.Mind;
|
||||||
using Content.Server.Warps;
|
using Content.Server.Warps;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared;
|
using Robust.Shared;
|
||||||
using Robust.Shared.Analyzers;
|
using Robust.Shared.Analyzers;
|
||||||
using Robust.Shared.Enums;
|
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.GameStates;
|
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Network;
|
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
@@ -58,15 +56,20 @@ public class PvsBenchmark
|
|||||||
_pair.Server.CfgMan.SetCVar(CVars.NetPvsAsync, false);
|
_pair.Server.CfgMan.SetCVar(CVars.NetPvsAsync, false);
|
||||||
_sys = _entMan.System<SharedTransformSystem>();
|
_sys = _entMan.System<SharedTransformSystem>();
|
||||||
|
|
||||||
|
SetupAsync().Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SetupAsync()
|
||||||
|
{
|
||||||
// Spawn the map
|
// Spawn the map
|
||||||
_pair.Server.ResolveDependency<IRobustRandom>().SetSeed(42);
|
_pair.Server.ResolveDependency<IRobustRandom>().SetSeed(42);
|
||||||
_pair.Server.WaitPost(() =>
|
await _pair.Server.WaitPost(() =>
|
||||||
{
|
{
|
||||||
var success = _entMan.System<MapLoaderSystem>().TryLoad(_mapId, Map, out _);
|
var success = _entMan.System<MapLoaderSystem>().TryLoad(_mapId, Map, out _);
|
||||||
if (!success)
|
if (!success)
|
||||||
throw new Exception("Map load failed");
|
throw new Exception("Map load failed");
|
||||||
_pair.Server.MapMan.DoMapInitialize(_mapId);
|
_pair.Server.MapMan.DoMapInitialize(_mapId);
|
||||||
}).Wait();
|
});
|
||||||
|
|
||||||
// Get list of ghost warp positions
|
// Get list of ghost warp positions
|
||||||
_spawns = _entMan.AllComponentsList<WarpPointComponent>()
|
_spawns = _entMan.AllComponentsList<WarpPointComponent>()
|
||||||
@@ -76,17 +79,19 @@ public class PvsBenchmark
|
|||||||
|
|
||||||
Array.Resize(ref _players, PlayerCount);
|
Array.Resize(ref _players, PlayerCount);
|
||||||
|
|
||||||
// Spawn "Players".
|
// Spawn "Players"
|
||||||
_pair.Server.WaitPost(() =>
|
_players = await _pair.Server.AddDummySessions(PlayerCount);
|
||||||
|
await _pair.Server.WaitPost(() =>
|
||||||
{
|
{
|
||||||
|
var mind = _pair.Server.System<MindSystem>();
|
||||||
for (var i = 0; i < PlayerCount; i++)
|
for (var i = 0; i < PlayerCount; i++)
|
||||||
{
|
{
|
||||||
var pos = _spawns[i % _spawns.Length];
|
var pos = _spawns[i % _spawns.Length];
|
||||||
var uid =_entMan.SpawnEntity("MobHuman", pos);
|
var uid =_entMan.SpawnEntity("MobHuman", pos);
|
||||||
_pair.Server.ConsoleHost.ExecuteCommand($"setoutfit {_entMan.GetNetEntity(uid)} CaptainGear");
|
_pair.Server.ConsoleHost.ExecuteCommand($"setoutfit {_entMan.GetNetEntity(uid)} CaptainGear");
|
||||||
_players[i] = new DummySession{AttachedEntity = uid};
|
mind.ControlMob(_players[i].UserId, uid);
|
||||||
}
|
}
|
||||||
}).Wait();
|
});
|
||||||
|
|
||||||
// Repeatedly move players around so that they "explore" the map and see lots of entities.
|
// Repeatedly move players around so that they "explore" the map and see lots of entities.
|
||||||
// This will populate their PVS data with out-of-view entities.
|
// This will populate their PVS data with out-of-view entities.
|
||||||
@@ -168,20 +173,4 @@ public class PvsBenchmark
|
|||||||
}).Wait();
|
}).Wait();
|
||||||
_pair.Server.PvsTick(_players);
|
_pair.Server.PvsTick(_players);
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class DummySession : ICommonSession
|
|
||||||
{
|
|
||||||
public SessionStatus Status => SessionStatus.InGame;
|
|
||||||
public EntityUid? AttachedEntity {get; set; }
|
|
||||||
public NetUserId UserId => default;
|
|
||||||
public string Name => string.Empty;
|
|
||||||
public short Ping => default;
|
|
||||||
public INetChannel Channel { get; set; } = default!;
|
|
||||||
public LoginType AuthType => default;
|
|
||||||
public HashSet<EntityUid> ViewSubscriptions { get; } = new();
|
|
||||||
public DateTime ConnectedTime { get; set; }
|
|
||||||
public SessionState State => default!;
|
|
||||||
public SessionData Data => default!;
|
|
||||||
public bool ClientSide { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ using Content.Shared.Preferences;
|
|||||||
using Content.Shared.Roles;
|
using Content.Shared.Roles;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Network;
|
||||||
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.UnitTesting;
|
using Robust.UnitTesting;
|
||||||
|
|
||||||
@@ -136,10 +138,15 @@ public sealed partial class TestPair
|
|||||||
/// Helper method for enabling or disabling a antag role
|
/// Helper method for enabling or disabling a antag role
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task SetAntagPref(ProtoId<AntagPrototype> id, bool value)
|
public async Task SetAntagPref(ProtoId<AntagPrototype> id, bool value)
|
||||||
|
{
|
||||||
|
await SetAntagPref(Client.User!.Value, id, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetAntagPref(NetUserId user, ProtoId<AntagPrototype> id, bool value)
|
||||||
{
|
{
|
||||||
var prefMan = Server.ResolveDependency<IServerPreferencesManager>();
|
var prefMan = Server.ResolveDependency<IServerPreferencesManager>();
|
||||||
|
|
||||||
var prefs = prefMan.GetPreferences(Client.User!.Value);
|
var prefs = prefMan.GetPreferences(user);
|
||||||
// what even is the point of ICharacterProfile if we always cast it to HumanoidCharacterProfile to make it usable?
|
// what even is the point of ICharacterProfile if we always cast it to HumanoidCharacterProfile to make it usable?
|
||||||
var profile = (HumanoidCharacterProfile) prefs.SelectedCharacter;
|
var profile = (HumanoidCharacterProfile) prefs.SelectedCharacter;
|
||||||
|
|
||||||
@@ -148,11 +155,11 @@ public sealed partial class TestPair
|
|||||||
|
|
||||||
await Server.WaitPost(() =>
|
await Server.WaitPost(() =>
|
||||||
{
|
{
|
||||||
prefMan.SetProfile(Client.User.Value, prefs.SelectedCharacterIndex, newProfile).Wait();
|
prefMan.SetProfile(user, prefs.SelectedCharacterIndex, newProfile).Wait();
|
||||||
});
|
});
|
||||||
|
|
||||||
// And why the fuck does it always create a new preference and profile object instead of just reusing them?
|
// And why the fuck does it always create a new preference and profile object instead of just reusing them?
|
||||||
var newPrefs = prefMan.GetPreferences(Client.User.Value);
|
var newPrefs = prefMan.GetPreferences(user);
|
||||||
var newProf = (HumanoidCharacterProfile) newPrefs.SelectedCharacter;
|
var newProf = (HumanoidCharacterProfile) newPrefs.SelectedCharacter;
|
||||||
Assert.That(newProf.AntagPreferences.Contains(id), Is.EqualTo(value));
|
Assert.That(newProf.AntagPreferences.Contains(id), Is.EqualTo(value));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ public sealed partial class TestPair : IAsyncDisposable
|
|||||||
|
|
||||||
private async Task OnCleanDispose()
|
private async Task OnCleanDispose()
|
||||||
{
|
{
|
||||||
|
await Server.RemoveAllDummySessions();
|
||||||
|
|
||||||
if (TestMap != null)
|
if (TestMap != null)
|
||||||
{
|
{
|
||||||
await Server.WaitPost(() => Server.EntMan.DeleteEntity(TestMap.MapUid));
|
await Server.WaitPost(() => Server.EntMan.DeleteEntity(TestMap.MapUid));
|
||||||
|
|||||||
@@ -37,7 +37,10 @@ public sealed partial class TestPair
|
|||||||
client = Client;
|
client = Client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICommonSession? Player => Server.PlayerMan.Sessions.FirstOrDefault();
|
public ICommonSession? Player => Client.User == null
|
||||||
|
? null
|
||||||
|
: Server.PlayerMan.SessionsDict.GetValueOrDefault(Client.User.Value);
|
||||||
|
|
||||||
public ContentPlayerData? PlayerData => Player?.Data.ContentData();
|
public ContentPlayerData? PlayerData => Player?.Data.ContentData();
|
||||||
|
|
||||||
public PoolTestLogHandler ServerLogHandler { get; private set; } = default!;
|
public PoolTestLogHandler ServerLogHandler { get; private set; } = default!;
|
||||||
|
|||||||
@@ -57,8 +57,17 @@ public sealed class NukeOpsTest
|
|||||||
Assert.That(client.AttachedEntity, Is.Null);
|
Assert.That(client.AttachedEntity, Is.Null);
|
||||||
Assert.That(ticker.PlayerGameStatuses[client.User!.Value], Is.EqualTo(PlayerGameStatus.NotReadyToPlay));
|
Assert.That(ticker.PlayerGameStatuses[client.User!.Value], Is.EqualTo(PlayerGameStatus.NotReadyToPlay));
|
||||||
|
|
||||||
|
// Add several dummy players
|
||||||
|
var dummies = await pair.Server.AddDummySessions(3);
|
||||||
|
await pair.RunTicksSync(5);
|
||||||
|
|
||||||
// Opt into the nukies role.
|
// Opt into the nukies role.
|
||||||
await pair.SetAntagPref("NukeopsCommander", true);
|
await pair.SetAntagPref("NukeopsCommander", true);
|
||||||
|
await pair.SetAntagPref(dummies[1].UserId, "NukeopsMedic", true);
|
||||||
|
|
||||||
|
// Initially, the players have no attached entities
|
||||||
|
Assert.That(pair.Player?.AttachedEntity, Is.Null);
|
||||||
|
Assert.That(dummies.All(x => x.AttachedEntity == null));
|
||||||
|
|
||||||
// There are no grids or maps
|
// There are no grids or maps
|
||||||
Assert.That(entMan.Count<MapComponent>(), Is.Zero);
|
Assert.That(entMan.Count<MapComponent>(), Is.Zero);
|
||||||
@@ -75,17 +84,20 @@ public sealed class NukeOpsTest
|
|||||||
Assert.That(entMan.Count<NukeOperativeSpawnerComponent>(), Is.Zero);
|
Assert.That(entMan.Count<NukeOperativeSpawnerComponent>(), Is.Zero);
|
||||||
|
|
||||||
// Ready up and start nukeops
|
// Ready up and start nukeops
|
||||||
await pair.WaitClientCommand("toggleready True");
|
ticker.ToggleReadyAll(true);
|
||||||
Assert.That(ticker.PlayerGameStatuses[client.User!.Value], Is.EqualTo(PlayerGameStatus.ReadyToPlay));
|
Assert.That(ticker.PlayerGameStatuses.Values.All(x => x == PlayerGameStatus.ReadyToPlay));
|
||||||
await pair.WaitCommand("forcepreset Nukeops");
|
await pair.WaitCommand("forcepreset Nukeops");
|
||||||
await pair.RunTicksSync(10);
|
await pair.RunTicksSync(10);
|
||||||
|
|
||||||
// Game should have started
|
// Game should have started
|
||||||
Assert.That(ticker.RunLevel, Is.EqualTo(GameRunLevel.InRound));
|
Assert.That(ticker.RunLevel, Is.EqualTo(GameRunLevel.InRound));
|
||||||
Assert.That(ticker.PlayerGameStatuses[client.User!.Value], Is.EqualTo(PlayerGameStatus.JoinedGame));
|
Assert.That(ticker.PlayerGameStatuses.Values.All(x => x == PlayerGameStatus.JoinedGame));
|
||||||
Assert.That(client.EntMan.EntityExists(client.AttachedEntity));
|
Assert.That(client.EntMan.EntityExists(client.AttachedEntity));
|
||||||
|
|
||||||
|
var dummyEnts = dummies.Select(x => x.AttachedEntity ?? default).ToArray();
|
||||||
var player = pair.Player!.AttachedEntity!.Value;
|
var player = pair.Player!.AttachedEntity!.Value;
|
||||||
Assert.That(entMan.EntityExists(player));
|
Assert.That(entMan.EntityExists(player));
|
||||||
|
Assert.That(dummyEnts.All(e => entMan.EntityExists(e)));
|
||||||
|
|
||||||
// Maps now exist
|
// Maps now exist
|
||||||
Assert.That(entMan.Count<MapComponent>(), Is.GreaterThan(0));
|
Assert.That(entMan.Count<MapComponent>(), Is.GreaterThan(0));
|
||||||
@@ -96,8 +108,8 @@ public sealed class NukeOpsTest
|
|||||||
|
|
||||||
// And we now have nukie related components
|
// And we now have nukie related components
|
||||||
Assert.That(entMan.Count<NukeopsRuleComponent>(), Is.EqualTo(1));
|
Assert.That(entMan.Count<NukeopsRuleComponent>(), Is.EqualTo(1));
|
||||||
Assert.That(entMan.Count<NukeopsRoleComponent>(), Is.EqualTo(1));
|
Assert.That(entMan.Count<NukeopsRoleComponent>(), Is.EqualTo(2));
|
||||||
Assert.That(entMan.Count<NukeOperativeComponent>(), Is.EqualTo(1));
|
Assert.That(entMan.Count<NukeOperativeComponent>(), Is.EqualTo(2));
|
||||||
Assert.That(entMan.Count<NukeOpsShuttleComponent>(), Is.EqualTo(1));
|
Assert.That(entMan.Count<NukeOpsShuttleComponent>(), Is.EqualTo(1));
|
||||||
|
|
||||||
// The player entity should be the nukie commander
|
// The player entity should be the nukie commander
|
||||||
@@ -107,11 +119,36 @@ public sealed class NukeOpsTest
|
|||||||
Assert.That(roleSys.MindHasRole<NukeopsRoleComponent>(mind));
|
Assert.That(roleSys.MindHasRole<NukeopsRoleComponent>(mind));
|
||||||
Assert.That(factionSys.IsMember(player, "Syndicate"), Is.True);
|
Assert.That(factionSys.IsMember(player, "Syndicate"), Is.True);
|
||||||
Assert.That(factionSys.IsMember(player, "NanoTrasen"), Is.False);
|
Assert.That(factionSys.IsMember(player, "NanoTrasen"), Is.False);
|
||||||
|
|
||||||
var roles = roleSys.MindGetAllRoles(mind);
|
var roles = roleSys.MindGetAllRoles(mind);
|
||||||
var cmdRoles = roles.Where(x => x.Prototype == "NukeopsCommander" && x.Component is NukeopsRoleComponent);
|
var cmdRoles = roles.Where(x => x.Prototype == "NukeopsCommander" && x.Component is NukeopsRoleComponent);
|
||||||
Assert.That(cmdRoles.Count(), Is.EqualTo(1));
|
Assert.That(cmdRoles.Count(), Is.EqualTo(1));
|
||||||
|
|
||||||
|
// The second dummy player should be a medic
|
||||||
|
var dummyMind = mindSys.GetMind(dummyEnts[1])!.Value;
|
||||||
|
Assert.That(entMan.HasComponent<NukeOperativeComponent>(dummyEnts[1]));
|
||||||
|
Assert.That(roleSys.MindIsAntagonist(dummyMind));
|
||||||
|
Assert.That(roleSys.MindHasRole<NukeopsRoleComponent>(dummyMind));
|
||||||
|
Assert.That(factionSys.IsMember(dummyEnts[1], "Syndicate"), Is.True);
|
||||||
|
Assert.That(factionSys.IsMember(dummyEnts[1], "NanoTrasen"), Is.False);
|
||||||
|
roles = roleSys.MindGetAllRoles(dummyMind);
|
||||||
|
cmdRoles = roles.Where(x => x.Prototype == "NukeopsMedic" && x.Component is NukeopsRoleComponent);
|
||||||
|
Assert.That(cmdRoles.Count(), Is.EqualTo(1));
|
||||||
|
|
||||||
|
// The other two players should have just spawned in as normal.
|
||||||
|
CheckDummy(0);
|
||||||
|
CheckDummy(2);
|
||||||
|
void CheckDummy(int i)
|
||||||
|
{
|
||||||
|
var ent = dummyEnts[i];
|
||||||
|
var mind = mindSys.GetMind(ent)!.Value;
|
||||||
|
Assert.That(entMan.HasComponent<NukeOperativeComponent>(ent), Is.False);
|
||||||
|
Assert.That(roleSys.MindIsAntagonist(mind), Is.False);
|
||||||
|
Assert.That(roleSys.MindHasRole<NukeopsRoleComponent>(mind), Is.False);
|
||||||
|
Assert.That(factionSys.IsMember(ent, "Syndicate"), Is.False);
|
||||||
|
Assert.That(factionSys.IsMember(ent, "NanoTrasen"), Is.True);
|
||||||
|
Assert.That(roleSys.MindGetAllRoles(mind).Any(x => x.Component is NukeopsRoleComponent), Is.False);
|
||||||
|
}
|
||||||
|
|
||||||
// The game rule exists, and all the stations/shuttles/maps are properly initialized
|
// The game rule exists, and all the stations/shuttles/maps are properly initialized
|
||||||
var rule = entMan.AllComponents<NukeopsRuleComponent>().Single().Component;
|
var rule = entMan.AllComponents<NukeopsRuleComponent>().Single().Component;
|
||||||
var gridsRule = entMan.AllComponents<RuleGridsComponent>().Single().Component;
|
var gridsRule = entMan.AllComponents<RuleGridsComponent>().Single().Component;
|
||||||
@@ -178,7 +215,7 @@ public sealed class NukeOpsTest
|
|||||||
// While we're at it, lets make sure they aren't naked. I don't know how many inventory slots all mobs will be
|
// While we're at it, lets make sure they aren't naked. I don't know how many inventory slots all mobs will be
|
||||||
// likely to have in the future. But nukies should probably have at least 3 slots with something in them.
|
// likely to have in the future. But nukies should probably have at least 3 slots with something in them.
|
||||||
var enumerator = invSys.GetSlotEnumerator(player);
|
var enumerator = invSys.GetSlotEnumerator(player);
|
||||||
int total = 0;
|
var total = 0;
|
||||||
while (enumerator.NextItem(out _))
|
while (enumerator.NextItem(out _))
|
||||||
{
|
{
|
||||||
total++;
|
total++;
|
||||||
@@ -200,6 +237,7 @@ public sealed class NukeOpsTest
|
|||||||
|
|
||||||
ticker.SetGamePreset((GamePresetPrototype?)null);
|
ticker.SetGamePreset((GamePresetPrototype?)null);
|
||||||
await pair.SetAntagPref("NukeopsCommander", false);
|
await pair.SetAntagPref("NukeopsCommander", false);
|
||||||
|
await pair.SetAntagPref(dummies[1].UserId, "NukeopsMedic", false);
|
||||||
await pair.CleanReturnAsync();
|
await pair.CleanReturnAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user