diff --git a/Content.Server/Research/Systems/ResearchSystem.Client.cs b/Content.Server/Research/Systems/ResearchSystem.Client.cs index f8fdba55b7..3f75982425 100644 --- a/Content.Server/Research/Systems/ResearchSystem.Client.cs +++ b/Content.Server/Research/Systems/ResearchSystem.Client.cs @@ -1,4 +1,5 @@ using System.Diagnostics.CodeAnalysis; +using System.Linq; using Content.Server.Power.EntitySystems; using Content.Shared.Research.Components; @@ -12,6 +13,7 @@ public sealed partial class ResearchSystem SubscribeLocalEvent(OnClientShutdown); SubscribeLocalEvent(OnClientUIOpen); SubscribeLocalEvent(OnConsoleSelect); + SubscribeLocalEvent(OnClientAnchorStateChanged); SubscribeLocalEvent(OnClientSyncMessage); SubscribeLocalEvent(OnClientSelected); @@ -23,7 +25,11 @@ public sealed partial class ResearchSystem private void OnClientSelected(EntityUid uid, ResearchClientComponent component, ResearchClientServerSelectedMessage args) { - if (!TryGetServerById(args.ServerId, out var serveruid, out var serverComponent)) + if (!TryGetServerById(uid, args.ServerId, out var serveruid, out var serverComponent)) + return; + + // Validate that we can access this server. + if (!GetServers(uid).Contains((serveruid.Value, serverComponent))) return; UnregisterClient(uid, component); @@ -56,12 +62,7 @@ public sealed partial class ResearchSystem private void OnClientMapInit(EntityUid uid, ResearchClientComponent component, MapInitEvent args) { - var allServers = new List>(); - var query = AllEntityQuery(); - while (query.MoveNext(out var serverUid, out var serverComp)) - { - allServers.Add((serverUid, serverComp)); - } + var allServers = GetServers(uid).ToList(); if (allServers.Count > 0) RegisterClient(uid, allServers[0], component, allServers[0]); @@ -77,6 +78,24 @@ public sealed partial class ResearchSystem UpdateClientInterface(uid, component); } + private void OnClientAnchorStateChanged(Entity ent, ref AnchorStateChangedEvent args) + { + if (args.Anchored) + { + if (ent.Comp.Server is not null) + return; + + var allServers = GetServers(ent).ToList(); + + if (allServers.Count > 0) + RegisterClient(ent, allServers[0], ent, allServers[0]); + } + else + { + UnregisterClient(ent, ent.Comp); + } + } + private void UpdateClientInterface(EntityUid uid, ResearchClientComponent? component = null) { if (!Resolve(uid, ref component, false)) @@ -84,9 +103,12 @@ public sealed partial class ResearchSystem TryGetClientServer(uid, out _, out var serverComponent, component); - var names = GetServerNames(); - var state = new ResearchClientBoundInterfaceState(names.Length, names, - GetServerIds(), serverComponent?.Id ?? -1); + var names = GetServerNames(uid); + var state = new ResearchClientBoundInterfaceState( + names.Length, + names, + GetServerIds(uid), + serverComponent?.Id ?? -1); _uiSystem.SetUiState(uid, ResearchClientUiKey.Key, state); } diff --git a/Content.Server/Research/Systems/ResearchSystem.cs b/Content.Server/Research/Systems/ResearchSystem.cs index f8c4d6902a..5cad4d51ba 100644 --- a/Content.Server/Research/Systems/ResearchSystem.cs +++ b/Content.Server/Research/Systems/ResearchSystem.cs @@ -18,10 +18,13 @@ namespace Content.Server.Research.Systems [Dependency] private readonly IAdminLogManager _adminLog = default!; [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly AccessReaderSystem _accessReader = default!; + [Dependency] private readonly EntityLookupSystem _lookup = default!; [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly RadioSystem _radio = default!; + private static readonly HashSet> ClientLookup = new(); + public override void Initialize() { base.Initialize(); @@ -34,19 +37,20 @@ namespace Content.Server.Research.Systems } /// - /// Gets a server based on it's unique numeric id. + /// Gets a server based on its unique numeric id. /// + /// /// /// /// /// - public bool TryGetServerById(int id, [NotNullWhen(true)] out EntityUid? serverUid, [NotNullWhen(true)] out ResearchServerComponent? serverComponent) + public bool TryGetServerById(EntityUid client, int id, [NotNullWhen(true)] out EntityUid? serverUid, [NotNullWhen(true)] out ResearchServerComponent? serverComponent) { serverUid = null; serverComponent = null; - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var server)) + var query = GetServers(client).ToList(); + foreach (var (uid, server) in query) { if (server.Id != id) continue; @@ -61,14 +65,14 @@ namespace Content.Server.Research.Systems /// Gets the names of all the servers. /// /// - public string[] GetServerNames() + public string[] GetServerNames(EntityUid client) { - var allServers = EntityQuery(true).ToArray(); + var allServers = GetServers(client).ToArray(); var list = new string[allServers.Length]; for (var i = 0; i < allServers.Length; i++) { - list[i] = allServers[i].ServerName; + list[i] = allServers[i].Comp.ServerName; } return list; @@ -78,19 +82,31 @@ namespace Content.Server.Research.Systems /// Gets the ids of all the servers /// /// - public int[] GetServerIds() + public int[] GetServerIds(EntityUid client) { - var allServers = EntityQuery(true).ToArray(); + var allServers = GetServers(client).ToArray(); var list = new int[allServers.Length]; for (var i = 0; i < allServers.Length; i++) { - list[i] = allServers[i].Id; + list[i] = allServers[i].Comp.Id; } return list; } + public HashSet> GetServers(EntityUid client) + { + ClientLookup.Clear(); + + var clientXform = Transform(client); + if (clientXform.GridUid is not { } grid) + return ClientLookup; + + _lookup.GetGridEntities(grid, ClientLookup); + return ClientLookup; + } + public override void Update(float frameTime) { var query = EntityQueryEnumerator();