diff --git a/Robust.Server/GameStates/PvsSystem.Session.cs b/Robust.Server/GameStates/PvsSystem.Session.cs index 264cd7341cf..cf0bd472df4 100644 --- a/Robust.Server/GameStates/PvsSystem.Session.cs +++ b/Robust.Server/GameStates/PvsSystem.Session.cs @@ -90,7 +90,7 @@ internal void ComputeSessionState(PvsSession session) else GetAllEntityStates(session); - _playerManager.GetPlayerStates(session.FromTick, session.PlayerStates); + _playerManager.GetPlayerStates(session.Session, session.FromTick, session.PlayerStates); // lastAck varies with each client based on lag and such, we can't just make 1 global state and send it to everyone diff --git a/Robust.Server/Player/PlayerManager.cs b/Robust.Server/Player/PlayerManager.cs index f1673941bd8..8d70df59836 100644 --- a/Robust.Server/Player/PlayerManager.cs +++ b/Robust.Server/Player/PlayerManager.cs @@ -130,15 +130,19 @@ private void HandlePlayerListReq(MsgPlayerListReq message) session.ConnectedTime = DateTime.UtcNow; SetStatus(session, SessionStatus.Connected); - var list = new List(); + var list = new List(players.Length); + var ev = new GetSessionStateAttempt(session); + _entityManager.EventBus.RaiseEvent(EventSource.Local, ref ev); + foreach (var client in players) { var info = new SessionState { UserId = client.UserId, - Name = client.Name, + Name = ev.Cancelled ? string.Empty : client.Name, Status = client.Status, - Ping = client.Channel!.Ping + Ping = client.Channel.Ping, + ControlledEntity = EntManager.GetNetEntity(client.AttachedEntity), }; list.Add(info); } diff --git a/Robust.Shared/GameStates/SessionState.cs b/Robust.Shared/GameStates/SessionState.cs index 78a193800ef..48289a557c7 100644 --- a/Robust.Shared/GameStates/SessionState.cs +++ b/Robust.Shared/GameStates/SessionState.cs @@ -3,6 +3,7 @@ using Robust.Shared.Enums; using Robust.Shared.GameObjects; using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.ViewVariables; #nullable disable @@ -39,4 +40,14 @@ public SessionState Clone() }; } } + + /// + /// Event raised to determine whether the session can see all session state data. + /// + [ByRefEvent] + public record struct GetSessionStateAttempt(ICommonSession Session) + { + public ICommonSession Session = Session; + public bool Cancelled; + } } diff --git a/Robust.Shared/Player/ISharedPlayerManager.cs b/Robust.Shared/Player/ISharedPlayerManager.cs index 159bb581fd2..7f039d6d443 100644 --- a/Robust.Shared/Player/ISharedPlayerManager.cs +++ b/Robust.Shared/Player/ISharedPlayerManager.cs @@ -114,7 +114,7 @@ public interface ISharedPlayerManager bool HasPlayerData(NetUserId userId); IEnumerable GetAllPlayerData(); - void GetPlayerStates(GameTick fromTick, List states); + void GetPlayerStates(ICommonSession? session, GameTick fromTick, List states); void UpdateState(ICommonSession commonSession); void RemoveSession(ICommonSession session, bool removeData = false); diff --git a/Robust.Shared/Player/SharedPlayerManager.State.cs b/Robust.Shared/Player/SharedPlayerManager.State.cs index 19956162541..a9089b543fe 100644 --- a/Robust.Shared/Player/SharedPlayerManager.State.cs +++ b/Robust.Shared/Player/SharedPlayerManager.State.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Robust.Shared.GameObjects; using Robust.Shared.GameStates; using Robust.Shared.Timing; @@ -12,16 +13,36 @@ public void Dirty() LastStateUpdate = Timing.CurTick; } - public void GetPlayerStates(GameTick fromTick, List states) + public void GetPlayerStates(ICommonSession? session, GameTick fromTick, List states) { states.Clear(); if (LastStateUpdate < fromTick) return; states.EnsureCapacity(InternalSessions.Count); + var ev = new GetSessionStateAttempt(session); + + if (session == null) + { + ev.Cancelled = true; + } + else + { + EntManager.EventBus.RaiseEvent(EventSource.Local, ref ev); + } + foreach (var player in InternalSessions.Values) { - states.Add(player.State); + if (ev.Cancelled) + { + var copy = player.State.Clone(); + copy.Name = string.Empty; + states.Add(copy); + } + else + { + states.Add(player.State); + } } }