+++ /dev/null
-using System.Linq;
-using System.Numerics;
-using Content.Client.Administration.UI.CustomControls;
-using Content.Shared.Administration.BanList;
-using Robust.Client.AutoGenerated;
-using Robust.Client.UserInterface;
-using Robust.Client.UserInterface.XAML;
-
-namespace Content.Client.Administration.UI.BanList;
-
-[GenerateTypedNameReferences]
-public sealed partial class BanListControl : Control
-{
- private BanListIdsPopup? _popup;
-
- public BanListControl()
- {
- RobustXamlLoader.Load(this);
- }
-
- public void SetBans(List<SharedServerBan> bans)
- {
- foreach (var control in Bans.Children.ToArray()[1..])
- {
- control.Orphan();
- }
-
- foreach (var ban in bans)
- {
- Bans.AddChild(new HSeparator());
-
- var line = new BanListLine(ban);
- line.OnIdsClicked += LineIdsClicked;
-
- Bans.AddChild(line);
- }
- }
-
- private void ClosePopup()
- {
- _popup?.Close();
- _popup = null;
- }
-
- private bool LineIdsClicked(BanListLine line)
- {
- ClosePopup();
-
- var ban = line.Ban;
- var id = ban.Id == null ? string.Empty : Loc.GetString("ban-list-id", ("id", ban.Id.Value));
- var ip = ban.Address == null
- ? string.Empty
- : Loc.GetString("ban-list-ip", ("ip", ban.Address.Value.address));
- var hwid = ban.HWId == null ? string.Empty : Loc.GetString("ban-list-hwid", ("hwid", ban.HWId));
- var guid = ban.UserId == null
- ? string.Empty
- : Loc.GetString("ban-list-guid", ("guid", ban.UserId.Value.ToString()));
-
- _popup = new BanListIdsPopup(id, ip, hwid, guid);
-
- var box = UIBox2.FromDimensions(UserInterfaceManager.MousePositionScaled.Position, new Vector2(1, 1));
- _popup.Open(box);
-
- return true;
- }
-
- protected override void Dispose(bool disposing)
- {
- base.Dispose(disposing);
-
- if (_popup != null)
- {
- UserInterfaceManager.PopupRoot.RemoveChild(_popup);
- }
- }
-}
-using Content.Client.Eui;
+using System.Numerics;
+using Content.Client.Administration.UI.BanList.Bans;
+using Content.Client.Administration.UI.BanList.RoleBans;
+using Content.Client.Eui;
using Content.Shared.Administration.BanList;
using Content.Shared.Eui;
-using Content.Shared.Ghost.Roles;
+using JetBrains.Annotations;
+using Robust.Client.UserInterface;
namespace Content.Client.Administration.UI.BanList;
+[UsedImplicitly]
public sealed class BanListEui : BaseEui
{
+ [Dependency] private readonly IUserInterfaceManager _ui = default!;
+
+ private BanListIdsPopup? _popup;
+
public BanListEui()
{
BanWindow = new BanListWindow();
BanWindow.OnClose += OnClosed;
+
BanControl = BanWindow.BanList;
+ BanControl.LineIdsClicked += OnLineIdsClicked;
+
+ RoleBanControl = BanWindow.RoleBanList;
+ RoleBanControl.LineIdsClicked += OnLineIdsClicked;
}
+ private BanListWindow BanWindow { get; }
+
+ private BanListControl BanControl { get; }
+ private RoleBanListControl RoleBanControl { get; }
+
private void OnClosed()
{
+ if (_popup != null)
+ {
+ _popup.Close();
+ _popup.Dispose();
+ _popup = null;
+ }
+
SendMessage(new CloseEuiMessage());
}
BanWindow.Close();
}
- private BanListWindow BanWindow { get; }
-
- private BanListControl BanControl { get; }
-
public override void HandleState(EuiStateBase state)
{
if (state is not BanListEuiState s)
s.Bans.Sort((a, b) => a.BanTime.CompareTo(b.BanTime));
BanControl.SetBans(s.Bans);
+ RoleBanControl.SetRoleBans(s.RoleBans);
}
public override void Opened()
{
BanWindow.OpenCentered();
}
+
+ private static string FormatDate(DateTimeOffset date)
+ {
+ return date.ToString("MM/dd/yyyy h:mm tt");
+ }
+
+ public static void SetData<T>(IBanListLine<T> line, SharedServerBan ban) where T : SharedServerBan
+ {
+ line.Reason.Text = ban.Reason;
+ line.BanTime.Text = FormatDate(ban.BanTime);
+ line.Expires.Text = ban.ExpirationTime == null
+ ? Loc.GetString("ban-list-permanent")
+ : FormatDate(ban.ExpirationTime.Value);
+
+ if (ban.Unban is { } unban)
+ {
+ var unbanned = Loc.GetString("ban-list-unbanned", ("date", FormatDate(unban.UnbanTime)));
+ var unbannedBy = unban.UnbanningAdmin == null
+ ? string.Empty
+ : $"\n{Loc.GetString("ban-list-unbanned-by", ("unbanner", unban.UnbanningAdmin))}";
+
+ line.Expires.Text += $"\n{unbanned}{unbannedBy}";
+ }
+
+ line.BanningAdmin.Text = ban.BanningAdminName;
+ }
+
+ private void OnLineIdsClicked<T>(IBanListLine<T> line) where T : SharedServerBan
+ {
+ _popup?.Close();
+ _popup = null;
+
+ var ban = line.Ban;
+ var id = ban.Id == null ? string.Empty : Loc.GetString("ban-list-id", ("id", ban.Id.Value));
+ var ip = ban.Address == null
+ ? string.Empty
+ : Loc.GetString("ban-list-ip", ("ip", ban.Address.Value.address));
+ var hwid = ban.HWId == null ? string.Empty : Loc.GetString("ban-list-hwid", ("hwid", ban.HWId));
+ var guid = ban.UserId == null
+ ? string.Empty
+ : Loc.GetString("ban-list-guid", ("guid", ban.UserId.Value.ToString()));
+
+ _popup = new BanListIdsPopup(id, ip, hwid, guid);
+
+ var box = UIBox2.FromDimensions(_ui.MousePositionScaled.Position, new Vector2(1, 1));
+ _popup.Open(box);
+ }
}
+++ /dev/null
-using Content.Shared.Administration.BanList;
-using Robust.Client.AutoGenerated;
-using Robust.Client.UserInterface.Controls;
-using Robust.Client.UserInterface.XAML;
-
-namespace Content.Client.Administration.UI.BanList;
-
-[GenerateTypedNameReferences]
-public sealed partial class BanListLine : BoxContainer
-{
- public readonly SharedServerBan Ban;
-
- public event Func<BanListLine, bool>? OnIdsClicked;
-
- public BanListLine(SharedServerBan ban)
- {
- RobustXamlLoader.Load(this);
-
- Ban = ban;
-
- IdsHidden.OnPressed += IdsPressed;
-
- Reason.Text = ban.Reason;
- BanTime.Text = FormatDate(ban.BanTime);
- Expires.Text = ban.ExpirationTime == null
- ? Loc.GetString("ban-list-permanent")
- : FormatDate(ban.ExpirationTime.Value);
-
- if (ban.Unban is { } unban)
- {
- var unbanned = Loc.GetString("ban-list-unbanned", ("date", FormatDate(unban.UnbanTime)));
- var unbannedBy = unban.UnbanningAdmin == null
- ? string.Empty
- : $"\n{Loc.GetString("ban-list-unbanned-by", ("unbanner", unban.UnbanningAdmin))}";
-
- Expires.Text += $"\n{unbanned}{unbannedBy}";
- }
-
- BanningAdmin.Text = ban.BanningAdminName;
- }
-
- private static string FormatDate(DateTimeOffset date)
- {
- return date.ToString("MM/dd/yyyy h:mm tt");
- }
-
- private void IdsPressed(BaseButton.ButtonEventArgs buttonEventArgs)
- {
- OnIdsClicked?.Invoke(this);
- }
-
- protected override void Dispose(bool disposing)
- {
- base.Dispose(disposing);
-
- IdsHidden.OnPressed -= IdsPressed;
- OnIdsClicked = null;
- }
-}
<controls:BanListWindow
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.Administration.UI.BanList"
+ xmlns:bans="clr-namespace:Content.Client.Administration.UI.BanList.Bans"
+ xmlns:roleBans="clr-namespace:Content.Client.Administration.UI.BanList.RoleBans"
SetSize="1400 400">
- <controls:BanListControl Name="BanList" Access="Public"/>
+ <TabContainer Name="TabContainer">
+ <bans:BanListControl Name="BanList" Access="Public"/>
+ <roleBans:RoleBanListControl Name="RoleBanList" Access="Public"/>
+ </TabContainer>
</controls:BanListWindow>
public BanListWindow()
{
RobustXamlLoader.Load(this);
+
+ TabContainer.SetTabTitle(0, Loc.GetString("ban-list-bans"));
+ TabContainer.SetTabTitle(1, Loc.GetString("ban-list-role-bans"));
}
public void SetTitlePlayer(string playerName)
-<controls:BanListControl
+<bans:BanListControl
xmlns="https://spacestation14.io"
- xmlns:controls="clr-namespace:Content.Client.Administration.UI.BanList">
+ xmlns:bans="clr-namespace:Content.Client.Administration.UI.BanList.Bans">
<PanelContainer StyleClasses="BackgroundDark">
<ScrollContainer>
<BoxContainer Name="Bans" Access="Public" Orientation="Vertical">
- <controls:BanListHeader Name="BansHeader"/>
+ <bans:BanListHeader Name="BansHeader"/>
</BoxContainer>
</ScrollContainer>
</PanelContainer>
-</controls:BanListControl>
+</bans:BanListControl>
--- /dev/null
+using Content.Client.Administration.UI.CustomControls;
+using Content.Shared.Administration.BanList;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client.Administration.UI.BanList.Bans;
+
+[GenerateTypedNameReferences]
+public sealed partial class BanListControl : Control
+{
+ public event Action<BanListLine>? LineIdsClicked;
+
+ public BanListControl()
+ {
+ RobustXamlLoader.Load(this);
+ }
+
+ public void SetBans(List<SharedServerBan> bans)
+ {
+ for (var i = Bans.ChildCount - 1; i >= 1; i--)
+ {
+ Bans.GetChild(i).Dispose();
+ }
+
+ foreach (var ban in bans)
+ {
+ Bans.AddChild(new HSeparator());
+
+ var line = new BanListLine(ban);
+ line.IdsClicked += LineIdsClicked;
+
+ Bans.AddChild(line);
+ }
+ }
+}
<Label Text="{Loc ban-list-header-banning-admin}"
SizeFlagsStretchRatio="2"
HorizontalExpand="True"/>
- <cc:VSeparator/>
</BoxContainer>
</PanelContainer>
</ContainerButton>
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
-namespace Content.Client.Administration.UI.BanList;
+namespace Content.Client.Administration.UI.BanList.Bans;
[GenerateTypedNameReferences]
public sealed partial class BanListHeader : ContainerButton
</BoxContainer>
<cc:VSeparator/>
<Label Name="Reason"
+ Access="Public"
SizeFlagsStretchRatio="6"
HorizontalExpand="True"
VerticalExpand="True"/>
<cc:VSeparator/>
<Label Name="BanTime"
+ Access="Public"
SizeFlagsStretchRatio="2"
HorizontalExpand="True"
ClipText="True"/>
<cc:VSeparator/>
<Label Name="Expires"
+ Access="Public"
SizeFlagsStretchRatio="4"
HorizontalExpand="True"
ClipText="True"/>
<cc:VSeparator/>
<Label Name="BanningAdmin"
+ Access="Public"
SizeFlagsStretchRatio="2"
HorizontalExpand="True"
ClipText="True"/>
- <cc:VSeparator/>
</BoxContainer>
--- /dev/null
+using Content.Shared.Administration.BanList;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+using static Robust.Client.UserInterface.Controls.BaseButton;
+
+namespace Content.Client.Administration.UI.BanList.Bans;
+
+[GenerateTypedNameReferences]
+public sealed partial class BanListLine : BoxContainer, IBanListLine<SharedServerBan>
+{
+ public SharedServerBan Ban { get; }
+
+ public event Action<BanListLine>? IdsClicked;
+
+ public BanListLine(SharedServerBan ban)
+ {
+ RobustXamlLoader.Load(this);
+
+ Ban = ban;
+ IdsHidden.OnPressed += IdsPressed;
+
+ BanListEui.SetData(this, ban);
+ }
+
+ private void IdsPressed(ButtonEventArgs buttonEventArgs)
+ {
+ IdsClicked?.Invoke(this);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+
+ IdsHidden.OnPressed -= IdsPressed;
+ IdsClicked = null;
+ }
+}
--- /dev/null
+using Content.Shared.Administration.BanList;
+using Robust.Client.UserInterface.Controls;
+
+namespace Content.Client.Administration.UI.BanList;
+
+public interface IBanListLine<T> where T : SharedServerBan
+{
+ T Ban { get; }
+ Label Reason { get; }
+ Label BanTime { get; }
+ Label Expires { get; }
+ Label BanningAdmin { get; }
+}
--- /dev/null
+<roleBans:RoleBanListControl
+ xmlns="https://spacestation14.io"
+ xmlns:roleBans="clr-namespace:Content.Client.Administration.UI.BanList.RoleBans">
+ <PanelContainer StyleClasses="BackgroundDark">
+ <ScrollContainer>
+ <BoxContainer Name="RoleBans" Access="Public" Orientation="Vertical">
+ <roleBans:RoleBanListHeader Name="BansHeader"/>
+ </BoxContainer>
+ </ScrollContainer>
+ </PanelContainer>
+</roleBans:RoleBanListControl>
--- /dev/null
+using Content.Client.Administration.UI.CustomControls;
+using Content.Shared.Administration.BanList;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client.Administration.UI.BanList.RoleBans;
+
+[GenerateTypedNameReferences]
+public sealed partial class RoleBanListControl : Control
+{
+ public event Action<RoleBanListLine>? LineIdsClicked;
+
+ public RoleBanListControl()
+ {
+ RobustXamlLoader.Load(this);
+ }
+
+ public void SetRoleBans(List<SharedServerRoleBan> bans)
+ {
+ for (var i = RoleBans.ChildCount - 1; i >= 1; i--)
+ {
+ RoleBans.GetChild(i).Dispose();
+ }
+
+ foreach (var ban in bans)
+ {
+ RoleBans.AddChild(new HSeparator());
+
+ var line = new RoleBanListLine(ban);
+ line.IdsClicked += LineIdsClicked;
+
+ RoleBans.AddChild(line);
+ }
+ }
+}
--- /dev/null
+<ContainerButton
+ xmlns="https://spacestation14.io"
+ xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls">
+ <PanelContainer Name="BackgroundPanel" Access="Public">
+ <BoxContainer
+ Orientation="Horizontal"
+ HorizontalExpand="True"
+ SeparationOverride="4">
+ <Label Text="{Loc ban-list-header-ids}"
+ SizeFlagsStretchRatio="1"
+ HorizontalExpand="True"/>
+ <cc:VSeparator/>
+ <Label Text="{Loc ban-list-header-reason}"
+ SizeFlagsStretchRatio="4.5"
+ HorizontalExpand="True"/>
+ <cc:VSeparator Name="ReasonSeparator" Access="Public"/>
+ <Label Text="{Loc ban-list-header-role}"
+ SizeFlagsStretchRatio="1.5"
+ HorizontalExpand="True"/>
+ <cc:VSeparator/>
+ <Label Text="{Loc ban-list-header-time}"
+ SizeFlagsStretchRatio="2"
+ HorizontalExpand="True"/>
+ <cc:VSeparator/>
+ <Label Text="{Loc ban-list-header-expires}"
+ SizeFlagsStretchRatio="4"
+ HorizontalExpand="True"/>
+ <cc:VSeparator/>
+ <Label Text="{Loc ban-list-header-banning-admin}"
+ SizeFlagsStretchRatio="2"
+ HorizontalExpand="True"/>
+ </BoxContainer>
+ </PanelContainer>
+</ContainerButton>
--- /dev/null
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client.Administration.UI.BanList.RoleBans;
+
+[GenerateTypedNameReferences]
+public sealed partial class RoleBanListHeader : ContainerButton
+{
+ public RoleBanListHeader()
+ {
+ RobustXamlLoader.Load(this);
+ }
+}
--- /dev/null
+<BoxContainer
+ xmlns="https://spacestation14.io"
+ xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
+ Orientation="Horizontal"
+ HorizontalExpand="True"
+ SeparationOverride="4">
+ <BoxContainer Orientation="Vertical"
+ SizeFlagsStretchRatio="1"
+ HorizontalExpand="True"
+ RectClipContent="True">
+ <Button Name="IdsHidden"
+ Text="{Loc 'ban-list-view'}"
+ HorizontalExpand="True"
+ VerticalExpand="True"
+ MouseFilter="Pass"/>
+ </BoxContainer>
+ <cc:VSeparator/>
+ <Label Name="Reason"
+ Access="Public"
+ SizeFlagsStretchRatio="4.5"
+ HorizontalExpand="True"
+ VerticalExpand="True"/>
+ <cc:VSeparator/>
+ <Label Name="Role"
+ SizeFlagsStretchRatio="1.5"
+ HorizontalExpand="True"
+ VerticalExpand="True"/>
+ <cc:VSeparator/>
+ <Label Name="BanTime"
+ Access="Public"
+ SizeFlagsStretchRatio="2"
+ HorizontalExpand="True"
+ ClipText="True"/>
+ <cc:VSeparator/>
+ <Label Name="Expires"
+ Access="Public"
+ SizeFlagsStretchRatio="4"
+ HorizontalExpand="True"
+ ClipText="True"/>
+ <cc:VSeparator/>
+ <Label Name="BanningAdmin"
+ Access="Public"
+ SizeFlagsStretchRatio="2"
+ HorizontalExpand="True"
+ ClipText="True"/>
+</BoxContainer>
--- /dev/null
+using Content.Shared.Administration.BanList;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+using static Robust.Client.UserInterface.Controls.BaseButton;
+
+namespace Content.Client.Administration.UI.BanList.RoleBans;
+
+[GenerateTypedNameReferences]
+public sealed partial class RoleBanListLine : BoxContainer, IBanListLine<SharedServerRoleBan>
+{
+ public SharedServerRoleBan Ban { get; }
+
+ public event Action<RoleBanListLine>? IdsClicked;
+
+ public RoleBanListLine(SharedServerRoleBan ban)
+ {
+ RobustXamlLoader.Load(this);
+
+ Ban = ban;
+ IdsHidden.OnPressed += IdsPressed;
+
+ BanListEui.SetData(this, ban);
+ Role.Text = ban.Role;
+ }
+
+ private void IdsPressed(ButtonEventArgs buttonEventArgs)
+ {
+ IdsClicked?.Invoke(this);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+
+ IdsHidden.OnPressed -= IdsPressed;
+ IdsClicked = null;
+ }
+}
+
private Guid BanListPlayer { get; set; }
private string BanListPlayerName { get; set; } = string.Empty;
- private List<SharedServerBan> Bans { get; set; } = new();
+ private List<SharedServerBan> Bans { get; } = new();
+ private List<SharedServerRoleBan> RoleBans { get; } = new();
public override void Opened()
{
public override EuiStateBase GetNewState()
{
- return new BanListEuiState(BanListPlayerName, Bans);
+ return new BanListEuiState(BanListPlayerName, Bans, RoleBans);
}
private void OnPermsChanged(AdminPermsChangedEventArgs args)
}
}
- private async Task LoadFromDb()
+ private async Task LoadBans(NetUserId userId)
{
- Bans.Clear();
-
- var userId = new NetUserId(BanListPlayer);
- BanListPlayerName = (await _playerLocator.LookupIdAsync(userId))?.Username ??
- string.Empty;
-
foreach (var ban in await _db.GetServerBansAsync(null, userId, null))
{
SharedServerUnban? unban = null;
unban
));
}
+ }
+
+ private async Task LoadRoleBans(NetUserId userId)
+ {
+ foreach (var ban in await _db.GetServerRoleBansAsync(null, userId, null))
+ {
+ SharedServerUnban? unban = null;
+ if (ban.Unban is { } unbanDef)
+ {
+ var unbanningAdmin = unbanDef.UnbanningAdmin == null
+ ? null
+ : (await _playerLocator.LookupIdAsync(unbanDef.UnbanningAdmin.Value))?.Username;
+ unban = new SharedServerUnban(unbanningAdmin, ban.Unban.UnbanTime.UtcDateTime);
+ }
+
+ RoleBans.Add(new SharedServerRoleBan(
+ ban.Id,
+ ban.UserId,
+ ban.Address is { } address
+ ? (address.address.ToString(), address.cidrMask)
+ : null,
+ ban.HWId == null ? null : Convert.ToBase64String(ban.HWId.Value.AsSpan()),
+ ban.BanTime.UtcDateTime,
+ ban.ExpirationTime?.UtcDateTime,
+ ban.Reason,
+ ban.BanningAdmin == null
+ ? null
+ : (await _playerLocator.LookupIdAsync(ban.BanningAdmin.Value))?.Username,
+ unban,
+ ban.Role
+ ));
+ }
+ }
+
+ private async Task LoadFromDb()
+ {
+ Bans.Clear();
+ RoleBans.Clear();
+
+ var userId = new NetUserId(BanListPlayer);
+ BanListPlayerName = (await _playerLocator.LookupIdAsync(userId))?.Username ??
+ string.Empty;
+
+ await LoadBans(userId);
+ await LoadRoleBans(userId);
StateDirty();
}
[Serializable, NetSerializable]
public sealed class BanListEuiState : EuiStateBase
{
- public BanListEuiState(string banListPlayerName, List<SharedServerBan> bans)
+ public BanListEuiState(string banListPlayerName, List<SharedServerBan> bans, List<SharedServerRoleBan> roleBans)
{
BanListPlayerName = banListPlayerName;
Bans = bans;
+ RoleBans = roleBans;
}
public string BanListPlayerName { get; }
public List<SharedServerBan> Bans { get; }
+ public List<SharedServerRoleBan> RoleBans { get; }
}
namespace Content.Shared.Administration.BanList;
[Serializable, NetSerializable]
-public sealed record SharedServerBan(
+public record SharedServerBan(
int? Id,
NetUserId? UserId,
(string address, int cidrMask)? Address,
--- /dev/null
+using Robust.Shared.Network;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Administration.BanList;
+
+[Serializable, NetSerializable]
+public sealed record SharedServerRoleBan(
+ int? Id,
+ NetUserId? UserId,
+ (string address, int cidrMask)? Address,
+ string? HWId,
+ DateTime BanTime,
+ DateTime? ExpirationTime,
+ string Reason,
+ string? BanningAdminName,
+ SharedServerUnban? Unban,
+ string Role
+) : SharedServerBan(Id, UserId, Address, HWId, BanTime, ExpirationTime, Reason, BanningAdminName, Unban);
# UI
+ban-list-bans = Bans
+ban-list-role-bans = Role Bans
+
ban-list-header-ids = Ids
ban-list-header-reason = Reason
+ban-list-header-role = Role
ban-list-header-time = Ban time
ban-list-header-expires = Expires
ban-list-header-banning-admin = Banning admin