diff --git a/Content.Client/UserInterface/AdminMenu/AdminMenuManager.cs b/Content.Client/UserInterface/AdminMenu/AdminMenuManager.cs index 4d13992720..1d6363baa4 100644 --- a/Content.Client/UserInterface/AdminMenu/AdminMenuManager.cs +++ b/Content.Client/UserInterface/AdminMenu/AdminMenuManager.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Content.Client.Administration; +using Content.Shared.Administration.AdminMenu; using Content.Shared.Input; using Robust.Client.Console; using Robust.Client.Input; @@ -18,11 +19,14 @@ namespace Content.Client.UserInterface.AdminMenu [Dependency] private readonly IClientAdminManager _clientAdminManager = default!; [Dependency] private readonly IClientConGroupController _clientConGroupController = default!; - private SS14Window _window; + private AdminMenuWindow _window; private List _commandWindows; public void Initialize() { + _netManager.RegisterNetMessage(AdminMenuPlayerListRequest.NAME); + _netManager.RegisterNetMessage(AdminMenuPlayerListMessage.NAME, HandlePlayerListMessage); + _commandWindows = new List(); // Reset the AdminMenu Window on disconnect _netManager.Disconnect += (sender, channel) => ResetWindow(); @@ -55,6 +59,18 @@ namespace Content.Client.UserInterface.AdminMenu _gameHud.AdminButtonDown = false; } + private void RequestPlayerList() + { + var message = _netManager.CreateNetMessage(); + + _netManager.ClientSendMessage(message); + } + + private void HandlePlayerListMessage(AdminMenuPlayerListMessage msg) + { + _window.RefreshPlayerList(msg.NamesToPlayers); + } + public void ResetWindow() { _window?.Close(); @@ -73,8 +89,8 @@ namespace Content.Client.UserInterface.AdminMenu public void Open() { - if (_window == null) - _window = new AdminMenuWindow(); + _window ??= new AdminMenuWindow(); + _window.OnPlayerListRefresh += RequestPlayerList; _window.OpenCentered(); } diff --git a/Content.Client/UserInterface/AdminMenu/AdminMenuWindow.cs b/Content.Client/UserInterface/AdminMenu/AdminMenuWindow.cs index bff971a090..18b78ee142 100644 --- a/Content.Client/UserInterface/AdminMenu/AdminMenuWindow.cs +++ b/Content.Client/UserInterface/AdminMenu/AdminMenuWindow.cs @@ -33,6 +33,10 @@ namespace Content.Client.UserInterface.AdminMenu protected override Vector2? CustomSize => (500, 250); + public delegate void PlayerListRefresh(); + + public event PlayerListRefresh? OnPlayerListRefresh; + private readonly List _adminButtons = new() { new KickCommandButton(), @@ -94,15 +98,14 @@ namespace Content.Client.UserInterface.AdminMenu } } - private void RefreshPlayerList(ButtonEventArgs args) + public void RefreshPlayerList(Dictionary namesToPlayers) { PlayerList.RemoveAllChildren(); var playerManager = IoCManager.Resolve(); - var sessions = playerManager.Sessions; PlayerCount.Text = $"Players: {playerManager.PlayerCount}"; - Color altColor = Color.FromHex("#292B38"); - Color defaultColor = Color.FromHex("#2F2F3B"); + var altColor = Color.FromHex("#292B38"); + var defaultColor = Color.FromHex("#2F2F3B"); var header = new HBoxContainer { @@ -117,15 +120,6 @@ namespace Content.Client.UserInterface.AdminMenu new Label { Text = "Player", SizeFlagsStretchRatio = 2f, SizeFlagsHorizontal = SizeFlags.FillExpand }, - new VSeperator(), - new Label { Text = "Status", - SizeFlagsStretchRatio = 1f, - SizeFlagsHorizontal = SizeFlags.FillExpand }, - new VSeperator(), - new Label { Text = "Ping", - SizeFlagsStretchRatio = 1f, - SizeFlagsHorizontal = SizeFlags.FillExpand, - Align = Label.AlignMode.Right }, } }; PlayerList.AddChild(new PanelContainer @@ -142,36 +136,25 @@ namespace Content.Client.UserInterface.AdminMenu PlayerList.AddChild(new HSeparator()); var useAltColor = false; - foreach (var player in sessions) + foreach (var (name, player) in namesToPlayers) { - var hbox = new HBoxContainer + var hBox = new HBoxContainer { SizeFlagsHorizontal = SizeFlags.FillExpand, SeparationOverride = 4, Children = { new Label { - Text = player.Name, + Text = name, SizeFlagsStretchRatio = 2f, SizeFlagsHorizontal = SizeFlags.FillExpand, ClipText = true }, new VSeperator(), new Label { - Text = player.AttachedEntity?.Name, + Text = player, SizeFlagsStretchRatio = 2f, SizeFlagsHorizontal = SizeFlags.FillExpand, ClipText = true }, - new VSeperator(), - new Label { - Text = player.Status.ToString(), - SizeFlagsStretchRatio = 1f, - SizeFlagsHorizontal = SizeFlags.FillExpand }, - new VSeperator(), - new Label { - Text = player.Ping.ToString(), - SizeFlagsStretchRatio = 1f, - SizeFlagsHorizontal = SizeFlags.FillExpand, - Align = Label.AlignMode.Right }, } }; PlayerList.AddChild(new PanelContainer @@ -182,7 +165,7 @@ namespace Content.Client.UserInterface.AdminMenu }, Children = { - hbox + hBox } }); useAltColor ^= true; @@ -234,7 +217,7 @@ namespace Content.Client.UserInterface.AdminMenu SizeFlagsStretchRatio = 0.3f, Text = "Refresh", }; - refreshButton.OnPressed += RefreshPlayerList; + refreshButton.OnPressed += (_) => OnPlayerListRefresh?.Invoke(); PlayerList = new VBoxContainer(); @@ -265,7 +248,7 @@ namespace Content.Client.UserInterface.AdminMenu } }; playerTabContainer.AddChild(playerVBox); - RefreshPlayerList(null!); + OnPlayerListRefresh?.Invoke(); #endregion PlayerList #region Admin Tab diff --git a/Content.Server/Administration/AdminManager.cs b/Content.Server/Administration/AdminManager.cs index 3b8b6f9bfb..f1d9540017 100644 --- a/Content.Server/Administration/AdminManager.cs +++ b/Content.Server/Administration/AdminManager.cs @@ -10,6 +10,7 @@ using Content.Server.Interfaces.Chat; using Content.Server.Players; using Content.Shared; using Content.Shared.Administration; +using Content.Shared.Administration.AdminMenu; using Content.Shared.Network.NetMessages; using Robust.Server.Console; using Robust.Server.Player; @@ -167,6 +168,8 @@ namespace Content.Server.Administration public void Initialize() { _netMgr.RegisterNetMessage(MsgUpdateAdminStatus.NAME); + _netMgr.RegisterNetMessage(AdminMenuPlayerListRequest.NAME, HandlePlayerListRequest); + _netMgr.RegisterNetMessage(AdminMenuPlayerListMessage.NAME); // Cache permissions for loaded console commands with the requisite attributes. foreach (var (cmdName, cmd) in _consoleHost.RegisteredCommands) @@ -227,6 +230,31 @@ namespace Content.Server.Administration } } + private void HandlePlayerListRequest(AdminMenuPlayerListRequest message) + { + var senderSession = _playerManager.GetSessionByChannel(message.MsgChannel); + + if (!_admins.ContainsKey(senderSession)) + { + return; + } + + var netMsg = _netMgr.CreateNetMessage(); + var namesToPlayers = new Dictionary(); + + foreach (var session in _playerManager.GetAllPlayers()) + { + var name = session.Name; + var player = session.AttachedEntity?.Name ?? ""; + + namesToPlayers.Add(name, player); + } + + netMsg.NamesToPlayers = namesToPlayers; + + _netMgr.ServerSendMessage(netMsg, senderSession.ConnectedClient); + } + public void PromoteHost(IPlayerSession player) { _promotedPlayers.Add(player.UserId); diff --git a/Content.Shared/Administration/AdminMenu/AdminMenuPlayerListMessage.cs b/Content.Shared/Administration/AdminMenu/AdminMenuPlayerListMessage.cs new file mode 100644 index 0000000000..62128c67cc --- /dev/null +++ b/Content.Shared/Administration/AdminMenu/AdminMenuPlayerListMessage.cs @@ -0,0 +1,44 @@ +#nullable enable +using System.Collections.Generic; +using Lidgren.Network; +using Robust.Shared.Network; + +namespace Content.Shared.Administration.AdminMenu +{ + public class AdminMenuPlayerListMessage : NetMessage + { + #region REQUIRED + public static readonly MsgGroups GROUP = MsgGroups.Command; + public static readonly string NAME = nameof(AdminMenuPlayerListMessage); + public AdminMenuPlayerListMessage(INetChannel channel) : base(NAME, GROUP) { } + #endregion + + public Dictionary NamesToPlayers = default!; + + public override void ReadFromBuffer(NetIncomingMessage buffer) + { + var pairs = buffer.ReadInt32(); + + NamesToPlayers = new Dictionary(); + + for (var i = 0; i < pairs; i++) + { + var name = buffer.ReadString(); + var player = buffer.ReadString(); + + NamesToPlayers.Add(name, player); + } + } + + public override void WriteToBuffer(NetOutgoingMessage buffer) + { + buffer.Write(NamesToPlayers.Count); + + foreach (var (name, player) in NamesToPlayers) + { + buffer.Write(name); + buffer.Write(player); + } + } + } +} diff --git a/Content.Shared/Administration/AdminMenu/AdminMenuPlayerListRequest.cs b/Content.Shared/Administration/AdminMenu/AdminMenuPlayerListRequest.cs new file mode 100644 index 0000000000..f99eb62d91 --- /dev/null +++ b/Content.Shared/Administration/AdminMenu/AdminMenuPlayerListRequest.cs @@ -0,0 +1,22 @@ +using Lidgren.Network; +using Robust.Shared.Network; + +namespace Content.Shared.Administration.AdminMenu +{ + public class AdminMenuPlayerListRequest : NetMessage + { + #region REQUIRED + public static readonly MsgGroups GROUP = MsgGroups.Command; + public static readonly string NAME = nameof(AdminMenuPlayerListRequest); + public AdminMenuPlayerListRequest(INetChannel channel) : base(NAME, GROUP) { } + #endregion + + public override void ReadFromBuffer(NetIncomingMessage buffer) + { + } + + public override void WriteToBuffer(NetOutgoingMessage buffer) + { + } + } +}