diff --git a/Content.Client/UserInterface/GhostGui.cs b/Content.Client/UserInterface/GhostGui.cs index 7cd2fcb60d..99db855839 100644 --- a/Content.Client/UserInterface/GhostGui.cs +++ b/Content.Client/UserInterface/GhostGui.cs @@ -1,3 +1,4 @@ +#nullable enable using Content.Client.GameObjects.Components.Observer; using Robust.Client.Console; using Robust.Client.UserInterface; @@ -16,17 +17,19 @@ namespace Content.Client.UserInterface private readonly Button _ghostRoles = new() {Text = Loc.GetString("Ghost Roles")}; private readonly GhostComponent _owner; + public GhostTargetWindow? TargetWindow { get; private set; } + public GhostGui(GhostComponent owner) { IoCManager.InjectDependencies(this); _owner = owner; - var targetMenu = new GhostTargetWindow(owner); + TargetWindow = new GhostTargetWindow(owner); MouseFilter = MouseFilterMode.Ignore; - _ghostWarp.OnPressed += args => targetMenu.Populate(); + _ghostWarp.OnPressed += args => TargetWindow.Populate(); _returnToBody.OnPressed += args => owner.SendReturnToBodyMessage(); _ghostRoles.OnPressed += _ => IoCManager.Resolve().RemoteExecuteCommand(null, "ghostroles"); @@ -49,7 +52,7 @@ namespace Content.Client.UserInterface } } - internal class GhostTargetWindow : SS14Window + public class GhostTargetWindow : SS14Window { protected override Vector2? CustomSize => (300, 450); private readonly GhostComponent _owner; diff --git a/Content.Server/GameObjects/Components/Observer/GhostComponent.cs b/Content.Server/GameObjects/Components/Observer/GhostComponent.cs index 41ee838a36..9f1f72df37 100644 --- a/Content.Server/GameObjects/Components/Observer/GhostComponent.cs +++ b/Content.Server/GameObjects/Components/Observer/GhostComponent.cs @@ -71,7 +71,8 @@ namespace Content.Server.GameObjects.Components.Observer switch (message) { - case ReturnToBodyComponentMessage _: + case ReturnToBodyComponentMessage: + { if (!Owner.TryGetComponent(out IActorComponent? actor) || !CanReturnToBody) { @@ -85,6 +86,7 @@ namespace Content.Server.GameObjects.Components.Observer Owner.Delete(); } break; + } case ReturnToCloneComponentMessage _: if (Owner.TryGetComponent(out VisitingMindComponent? mind)) @@ -93,16 +95,31 @@ namespace Content.Server.GameObjects.Components.Observer } break; case GhostWarpRequestMessage warp: + { + if (session?.AttachedEntity != Owner) + { + break; + } + if (warp.PlayerTarget != default) { - foreach (var player in _playerManager.GetAllPlayers()) + if (!Owner.EntityManager.TryGetEntity(warp.PlayerTarget, out var entity)) { - if (player.AttachedEntity != null && warp.PlayerTarget == player.AttachedEntity.Uid) - { - session!.AttachedEntity!.Transform.Coordinates = - player.AttachedEntity.Transform.Coordinates; - } + break; } + + if (!entity.TryGetComponent(out IActorComponent? actor)) + { + break; + } + + if (!_playerManager.TryGetSessionByChannel(actor.playerSession.ConnectedClient, out var player) || + player.AttachedEntity != entity) + { + break; + } + + Owner.Transform.Coordinates = entity.Transform.Coordinates; } else { @@ -110,11 +127,12 @@ namespace Content.Server.GameObjects.Components.Observer { if (warp.WarpName == warpPoint.Location) { - session!.AttachedEntity!.Transform.Coordinates = warpPoint.Owner.Transform.Coordinates ; + Owner.Transform.Coordinates = warpPoint.Owner.Transform.Coordinates; } } } break; + } case GhostRequestPlayerNameData _: var playerNames = new Dictionary(); foreach (var names in _playerManager.GetAllPlayers())