diff --git a/Content.Client/Administration/UI/PlayerPanel/PlayerPanel.xaml b/Content.Client/Administration/UI/PlayerPanel/PlayerPanel.xaml
index 8feec273b4..4791dcf6aa 100644
--- a/Content.Client/Administration/UI/PlayerPanel/PlayerPanel.xaml
+++ b/Content.Client/Administration/UI/PlayerPanel/PlayerPanel.xaml
@@ -19,12 +19,13 @@
-
+
+
diff --git a/Content.Client/Administration/UI/PlayerPanel/PlayerPanel.xaml.cs b/Content.Client/Administration/UI/PlayerPanel/PlayerPanel.xaml.cs
index 1674989c27..14311851b4 100644
--- a/Content.Client/Administration/UI/PlayerPanel/PlayerPanel.xaml.cs
+++ b/Content.Client/Administration/UI/PlayerPanel/PlayerPanel.xaml.cs
@@ -2,7 +2,6 @@ using Content.Client.Administration.Managers;
using Content.Client.UserInterface.Controls;
using Content.Shared.Administration;
using Robust.Client.AutoGenerated;
-using Robust.Client.UserInterface;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Network;
using Robust.Shared.Utility;
@@ -21,6 +20,7 @@ public sealed partial class PlayerPanel : FancyWindow
public event Action? OnKick;
public event Action? OnOpenBanPanel;
public event Action? OnWhitelistToggle;
+ public event Action? OnFollow;
public event Action? OnFreezeAndMuteToggle;
public event Action? OnFreeze;
public event Action? OnLogs;
@@ -47,6 +47,7 @@ public sealed partial class PlayerPanel : FancyWindow
OnWhitelistToggle?.Invoke(TargetPlayer, _isWhitelisted);
SetWhitelisted(!_isWhitelisted);
};
+ FollowButton.OnPressed += _ => OnFollow?.Invoke();
FreezeButton.OnPressed += _ => OnFreeze?.Invoke();
FreezeAndMuteToggleButton.OnPressed += _ => OnFreezeAndMuteToggle?.Invoke();
LogsButton.OnPressed += _ => OnLogs?.Invoke();
diff --git a/Content.Client/Administration/UI/PlayerPanel/PlayerPanelEui.cs b/Content.Client/Administration/UI/PlayerPanel/PlayerPanelEui.cs
index 87ce756046..2129fa5b0c 100644
--- a/Content.Client/Administration/UI/PlayerPanel/PlayerPanelEui.cs
+++ b/Content.Client/Administration/UI/PlayerPanel/PlayerPanelEui.cs
@@ -38,6 +38,7 @@ public sealed class PlayerPanelEui : BaseEui
PlayerPanel.OnLogs += () => SendMessage(new PlayerPanelLogsMessage());
PlayerPanel.OnRejuvenate += () => SendMessage(new PlayerPanelRejuvenationMessage());
PlayerPanel.OnDelete+= () => SendMessage(new PlayerPanelDeleteMessage());
+ PlayerPanel.OnFollow += () => SendMessage(new PlayerPanelFollowMessage());
PlayerPanel.OnClose += () => SendMessage(new CloseEuiMessage());
}
diff --git a/Content.Server/Administration/PlayerPanelEui.cs b/Content.Server/Administration/PlayerPanelEui.cs
index 6c30488886..31acd33bf1 100644
--- a/Content.Server/Administration/PlayerPanelEui.cs
+++ b/Content.Server/Administration/PlayerPanelEui.cs
@@ -8,6 +8,7 @@ using Content.Server.EUI;
using Content.Shared.Administration;
using Content.Shared.Database;
using Content.Shared.Eui;
+using Content.Shared.Follower;
using Robust.Server.Player;
using Robust.Shared.Player;
@@ -33,11 +34,13 @@ public sealed class PlayerPanelEui : BaseEui
private bool _frozen;
private bool _canFreeze;
private bool _canAhelp;
+ private FollowerSystem _follower;
public PlayerPanelEui(LocatedPlayerData player)
{
IoCManager.InjectDependencies(this);
_targetPlayer = player;
+ _follower = _entity.System();
}
public override void Opened()
@@ -141,6 +144,16 @@ public sealed class PlayerPanelEui : BaseEui
_entity.DeleteEntity(session.AttachedEntity);
}
break;
+ case PlayerPanelFollowMessage:
+ if (!_admins.HasAdminFlag(Player, AdminFlags.Admin) ||
+ !_player.TryGetSessionById(_targetPlayer.UserId, out session) ||
+ session.AttachedEntity == null ||
+ Player.AttachedEntity is null ||
+ session.AttachedEntity == Player.AttachedEntity)
+ return;
+
+ _follower.StartFollowingEntity(Player.AttachedEntity.Value, session.AttachedEntity.Value);
+ break;
}
}
diff --git a/Content.Shared/Administration/PlayerPanelEuiState.cs b/Content.Shared/Administration/PlayerPanelEuiState.cs
index 186b992e4e..8942cc8aab 100644
--- a/Content.Shared/Administration/PlayerPanelEuiState.cs
+++ b/Content.Shared/Administration/PlayerPanelEuiState.cs
@@ -1,12 +1,12 @@
using Content.Shared.Eui;
using Robust.Shared.Network;
using Robust.Shared.Serialization;
-using YamlDotNet.Serialization.Callbacks;
namespace Content.Shared.Administration;
[Serializable, NetSerializable]
-public sealed class PlayerPanelEuiState(NetUserId guid,
+public sealed class PlayerPanelEuiState(
+ NetUserId guid,
string username,
TimeSpan playtime,
int? totalNotes,
@@ -52,3 +52,6 @@ public sealed class PlayerPanelDeleteMessage : EuiMessageBase;
[Serializable, NetSerializable]
public sealed class PlayerPanelRejuvenationMessage: EuiMessageBase;
+
+[Serializable, NetSerializable]
+public sealed class PlayerPanelFollowMessage: EuiMessageBase;
diff --git a/Resources/Locale/en-US/administration/ui/player-panel.ftl b/Resources/Locale/en-US/administration/ui/player-panel.ftl
index cfb014948d..f2d89fe2c2 100644
--- a/Resources/Locale/en-US/administration/ui/player-panel.ftl
+++ b/Resources/Locale/en-US/administration/ui/player-panel.ftl
@@ -21,3 +21,4 @@ player-panel-delete = Delete
player-panel-rejuvenate = Rejuvenate
player-panel-false = False
player-panel-true = True
+player-panel-follow = Follow