Revert "Admin Log Browser Improvements (#39130)"
This reverts commit f67cebf7a4.
Per request of @Kowlin and @southbridge-fur
Check out https://github.com/space-wizards/space-station-14/issues/39960 for further information
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
|
||||
namespace Content.Client.Administration.UI.CustomControls;
|
||||
|
||||
public sealed class AdminLogLabel : RichTextLabel
|
||||
{
|
||||
public AdminLogLabel(ref SharedAdminLog log, HSeparator separator)
|
||||
{
|
||||
Log = log;
|
||||
Separator = separator;
|
||||
|
||||
SetMessage($"{log.Date:HH:mm:ss}: {log.Message}");
|
||||
OnVisibilityChanged += VisibilityChanged;
|
||||
}
|
||||
|
||||
public SharedAdminLog Log { get; }
|
||||
|
||||
public HSeparator Separator { get; }
|
||||
|
||||
private void VisibilityChanged(Control control)
|
||||
{
|
||||
Separator.Visible = Visible;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
OnVisibilityChanged -= VisibilityChanged;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Content.Client.Administration.Systems;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Client.Verbs.UI;
|
||||
using Content.Shared.Administration;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Administration.UI.CustomControls;
|
||||
|
||||
@@ -95,26 +96,13 @@ public sealed partial class PlayerListControl : BoxContainer
|
||||
private void FilterList()
|
||||
{
|
||||
_sortedPlayerList.Clear();
|
||||
|
||||
Regex filterRegex;
|
||||
// There is no neat way to handle invalid regex being submitted other than
|
||||
// catching and ignoring the exception which gets thrown when it's invalid.
|
||||
try
|
||||
{
|
||||
filterRegex = new Regex(FilterLineEdit.Text, RegexOptions.IgnoreCase);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var info in _playerList)
|
||||
{
|
||||
var displayName = $"{info.CharacterName} ({info.Username})";
|
||||
if (info.IdentityName != info.CharacterName)
|
||||
displayName += $" [{info.IdentityName}]";
|
||||
if (!string.IsNullOrEmpty(FilterLineEdit.Text)
|
||||
&& !filterRegex.IsMatch(displayName))
|
||||
&& !displayName.ToLowerInvariant().Contains(FilterLineEdit.Text.Trim().ToLowerInvariant()))
|
||||
continue;
|
||||
_sortedPlayerList.Add(info);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Shared.Administration;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Administration.UI.CustomControls;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<Control xmlns="https://spacestation14.io"
|
||||
xmlns:aui="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
xmlns:ui="clr-namespace:Content.Client.Options.UI">
|
||||
xmlns:aui="clr-namespace:Content.Client.Administration.UI.CustomControls">
|
||||
<PanelContainer StyleClasses="BackgroundDark">
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
@@ -53,13 +52,6 @@
|
||||
<Button Name="ExportLogs" Access="Public" Text="{Loc admin-logs-export}"/>
|
||||
<Button Name="PopOutButton" Access="Public" Text="{Loc admin-logs-pop-out}"/>
|
||||
</BoxContainer>
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<Button Name="RenderRichTextButton" Access="Public" Text="{Loc admin-logs-render-rich-text}"
|
||||
StyleClasses="OpenRight" ToggleMode="True"/>
|
||||
<Button Name="RemoveMarkupButton" Access="Public" Text="{Loc admin-logs-remove-markup}"
|
||||
StyleClasses="OpenLeft" ToggleMode="True"/>
|
||||
<Control HorizontalExpand="True"/>
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<LineEdit Name="LogSearch" Access="Public" StyleClasses="actionSearchBox"
|
||||
HorizontalExpand="true" PlaceHolder="{Loc admin-logs-search-logs-placeholder}"/>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
using Content.Client.Administration.UI.CustomControls;
|
||||
using Content.Client.Administration.UI.Logs.Entries;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Database;
|
||||
using Robust.Client.AutoGenerated;
|
||||
@@ -40,9 +38,6 @@ public sealed partial class AdminLogsControl : Control
|
||||
SelectAllPlayersButton.OnPressed += SelectAllPlayers;
|
||||
SelectNoPlayersButton.OnPressed += SelectNoPlayers;
|
||||
|
||||
RenderRichTextButton.OnPressed += RenderRichTextChanged;
|
||||
RemoveMarkupButton.OnPressed += RemoveMarkupChanged;
|
||||
|
||||
RoundSpinBox.IsValid = i => i > 0 && i <= CurrentRound;
|
||||
RoundSpinBox.ValueChanged += RoundSpinBoxChanged;
|
||||
RoundSpinBox.InitDefaultButtons();
|
||||
@@ -55,16 +50,13 @@ public sealed partial class AdminLogsControl : Control
|
||||
|
||||
private int CurrentRound { get; set; }
|
||||
|
||||
private Regex LogSearchRegex { get; set; } = new("");
|
||||
|
||||
public int SelectedRoundId => RoundSpinBox.Value;
|
||||
public string Search => LogSearch.Text;
|
||||
private int ShownLogs { get; set; }
|
||||
private int TotalLogs { get; set; }
|
||||
private int RoundLogs { get; set; }
|
||||
public bool IncludeNonPlayerLogs { get; set; }
|
||||
private bool RenderRichText { get; set; }
|
||||
private bool RemoveMarkup { get; set; }
|
||||
|
||||
public HashSet<LogType> SelectedTypes { get; } = new();
|
||||
|
||||
public HashSet<Guid> SelectedPlayers { get; } = new();
|
||||
@@ -111,19 +103,6 @@ public sealed partial class AdminLogsControl : Control
|
||||
|
||||
private void LogSearchChanged(LineEditEventArgs args)
|
||||
{
|
||||
// This exception is thrown if the regex is invalid, which happens often, so we ignore it.
|
||||
try
|
||||
{
|
||||
LogSearchRegex = new Regex(
|
||||
"(" + LogSearch.Text + ")",
|
||||
RegexOptions.IgnoreCase,
|
||||
TimeSpan.FromSeconds(1));
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateLogs();
|
||||
}
|
||||
|
||||
@@ -205,26 +184,6 @@ public sealed partial class AdminLogsControl : Control
|
||||
UpdateLogs();
|
||||
}
|
||||
|
||||
private void RenderRichTextChanged(ButtonEventArgs args)
|
||||
{
|
||||
RenderRichText = args.Button.Pressed;
|
||||
|
||||
RemoveMarkup = RemoveMarkup && !RenderRichText;
|
||||
RemoveMarkupButton.Pressed = RemoveMarkup;
|
||||
|
||||
UpdateLogs();
|
||||
}
|
||||
|
||||
private void RemoveMarkupChanged(ButtonEventArgs args)
|
||||
{
|
||||
RemoveMarkup = args.Button.Pressed;
|
||||
|
||||
RenderRichText = !RemoveMarkup && RenderRichText;
|
||||
RenderRichTextButton.Pressed = RenderRichText;
|
||||
|
||||
UpdateLogs();
|
||||
}
|
||||
|
||||
public void SetTypesSelection(HashSet<LogType> selectedTypes, bool invert = false)
|
||||
{
|
||||
SelectedTypes.Clear();
|
||||
@@ -283,15 +242,16 @@ public sealed partial class AdminLogsControl : Control
|
||||
|
||||
foreach (var child in LogsContainer.Children)
|
||||
{
|
||||
if (child is not AdminLogEntry log)
|
||||
if (child is not AdminLogLabel log)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
child.Visible = ShouldShowLog(log);
|
||||
if (!child.Visible)
|
||||
continue;
|
||||
|
||||
log.RenderResults(LogSearchRegex, RenderRichText, RemoveMarkup);
|
||||
ShownLogs++;
|
||||
if (child.Visible)
|
||||
{
|
||||
ShownLogs++;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateCount();
|
||||
@@ -309,30 +269,30 @@ public sealed partial class AdminLogsControl : Control
|
||||
button.Text.Contains(PlayerSearch.Text, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private bool LogMatchesPlayerFilter(AdminLogEntry entry)
|
||||
private bool LogMatchesPlayerFilter(AdminLogLabel label)
|
||||
{
|
||||
if (entry.Log.Players.Length == 0)
|
||||
if (label.Log.Players.Length == 0)
|
||||
return SelectedPlayers.Count == 0 || IncludeNonPlayerLogs;
|
||||
|
||||
return SelectedPlayers.Overlaps(entry.Log.Players);
|
||||
return SelectedPlayers.Overlaps(label.Log.Players);
|
||||
}
|
||||
|
||||
private bool ShouldShowLog(AdminLogEntry entry)
|
||||
private bool ShouldShowLog(AdminLogLabel label)
|
||||
{
|
||||
// Check log type
|
||||
if (!SelectedTypes.Contains(entry.Log.Type))
|
||||
if (!SelectedTypes.Contains(label.Log.Type))
|
||||
return false;
|
||||
|
||||
// Check players
|
||||
if (!LogMatchesPlayerFilter(entry))
|
||||
if (!LogMatchesPlayerFilter(label))
|
||||
return false;
|
||||
|
||||
// Check impact
|
||||
if (!SelectedImpacts.Contains(entry.Log.Impact))
|
||||
if (!SelectedImpacts.Contains(label.Log.Impact))
|
||||
return false;
|
||||
|
||||
// Check search
|
||||
if (!LogSearchRegex.IsMatch(entry.Log.Message))
|
||||
if (!label.Log.Message.Contains(LogSearch.Text, StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -508,11 +468,21 @@ public sealed partial class AdminLogsControl : Control
|
||||
for (var i = 0; i < span.Length; i++)
|
||||
{
|
||||
ref var log = ref span[i];
|
||||
var entry = new AdminLogEntry(ref log);
|
||||
var separator = new HSeparator();
|
||||
var label = new AdminLogLabel(ref log, separator);
|
||||
label.Visible = ShouldShowLog(label);
|
||||
|
||||
TotalLogs++;
|
||||
LogsContainer.AddChild(entry);
|
||||
if (label.Visible)
|
||||
{
|
||||
ShownLogs++;
|
||||
}
|
||||
|
||||
LogsContainer.AddChild(label);
|
||||
LogsContainer.AddChild(separator);
|
||||
}
|
||||
UpdateLogs();
|
||||
|
||||
UpdateCount();
|
||||
}
|
||||
|
||||
public void SetLogs(List<SharedAdminLog> logs)
|
||||
@@ -556,7 +526,6 @@ public sealed partial class AdminLogsControl : Control
|
||||
SelectAllTypesButton.OnPressed -= SelectAllTypes;
|
||||
SelectNoTypesButton.OnPressed -= SelectNoTypes;
|
||||
|
||||
IncludeNonPlayersButton.OnPressed -= IncludeNonPlayers;
|
||||
IncludeNonPlayersButton.OnPressed -= IncludeNonPlayers;
|
||||
SelectAllPlayersButton.OnPressed -= SelectAllPlayers;
|
||||
SelectNoPlayersButton.OnPressed -= SelectNoPlayers;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Content.Client.Administration.UI.Logs.Entries;
|
||||
using Content.Client.Administration.UI.CustomControls;
|
||||
using Content.Client.Eui;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Eui;
|
||||
@@ -22,7 +22,7 @@ public sealed class AdminLogsEui : BaseEui
|
||||
|
||||
private const char CsvSeparator = ',';
|
||||
private const string CsvQuote = "\"";
|
||||
private const string CsvHeader = "Date,ID,PlayerID,Severity,Type,Message,CurTime";
|
||||
private const string CsvHeader = "Date,ID,PlayerID,Severity,Type,Message";
|
||||
|
||||
private ISawmill _sawmill;
|
||||
|
||||
@@ -109,10 +109,10 @@ public sealed class AdminLogsEui : BaseEui
|
||||
await writer.WriteLineAsync(CsvHeader);
|
||||
foreach (var child in LogsControl.LogsContainer.Children)
|
||||
{
|
||||
if (child is not AdminLogEntry entry || !child.Visible)
|
||||
if (child is not AdminLogLabel logLabel || !child.Visible)
|
||||
continue;
|
||||
|
||||
var log = entry.Log;
|
||||
var log = logLabel.Log;
|
||||
|
||||
// Date
|
||||
// I swear to god if someone adds ,s or "s to the other fields...
|
||||
@@ -138,9 +138,6 @@ public sealed class AdminLogsEui : BaseEui
|
||||
await writer.WriteAsync(CsvQuote);
|
||||
await writer.WriteAsync(log.Message.Replace(CsvQuote, CsvQuote + CsvQuote));
|
||||
await writer.WriteAsync(CsvQuote);
|
||||
await writer.WriteAsync(CsvSeparator);
|
||||
// CurTime
|
||||
await writer.WriteAsync(log.CurTime.ToString());
|
||||
|
||||
await writer.WriteLineAsync();
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
<BoxContainer xmlns="https://spacestation14.io"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
Orientation="Vertical">
|
||||
<BoxContainer Margin="2">
|
||||
<Collapsible>
|
||||
<CollapsibleHeading Name="DetailsHeading" Access="Public">
|
||||
<RichTextLabel Margin="20 0 0 0" Name="Message" MinSize="50 10" VerticalExpand="True" Access="Public" />
|
||||
</CollapsibleHeading>
|
||||
<CollapsibleBody Name="DetailsBody" Access="Public" />
|
||||
</Collapsible>
|
||||
</BoxContainer>
|
||||
<cc:HSeparator/>
|
||||
</BoxContainer>
|
||||
@@ -1,79 +0,0 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using Content.Client.Message;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.CCVar;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Administration.UI.Logs.Entries;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class AdminLogEntry : BoxContainer
|
||||
{
|
||||
private readonly IConfigurationManager _cfgManager;
|
||||
|
||||
public SharedAdminLog Log { get; }
|
||||
|
||||
private readonly string _rawMessage;
|
||||
|
||||
public AdminLogEntry(ref SharedAdminLog log)
|
||||
{
|
||||
_cfgManager = IoCManager.Resolve<IConfigurationManager>();
|
||||
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
Log = log;
|
||||
|
||||
_rawMessage = $"{log.Date:HH:mm:ss}: {log.Message}";
|
||||
Message.SetMessage(_rawMessage);
|
||||
|
||||
DetailsHeading.OnToggled += DetailsToggled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets text to be highlighted from a search result, and renders rich text, or removes all rich text markup.
|
||||
/// </summary>
|
||||
public void RenderResults(Regex highlightRegex, bool renderRichText, bool removeMarkup)
|
||||
{
|
||||
var color = _cfgManager.GetCVar(CCVars.AdminLogsHighlightColor);
|
||||
var formattedMessage = renderRichText
|
||||
? _rawMessage
|
||||
: removeMarkup
|
||||
? FormattedMessage.RemoveMarkupPermissive(_rawMessage)
|
||||
: FormattedMessage.EscapeText(_rawMessage);
|
||||
|
||||
// Want to avoid highlighting smaller strings
|
||||
if (highlightRegex.ToString().Length > 4)
|
||||
{
|
||||
try
|
||||
{
|
||||
formattedMessage = highlightRegex.Replace(formattedMessage, $"[color={color}]$1[/color]", 3);
|
||||
}
|
||||
catch (RegexMatchTimeoutException)
|
||||
{
|
||||
// if we time out then don't bother highlighting results
|
||||
}
|
||||
}
|
||||
|
||||
if (!FormattedMessage.TryFromMarkup(formattedMessage, out var outputMessage))
|
||||
return;
|
||||
|
||||
Message.SetMessage(outputMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We perform some extra calculations in the dropdown, so we want to render that only when
|
||||
/// the dropdown is actually opened.
|
||||
/// This also removes itself from the event listener so it doesn't trigger again.
|
||||
/// </summary>
|
||||
private void DetailsToggled(BaseButton.ButtonToggledEventArgs args)
|
||||
{
|
||||
if (!args.Pressed || DetailsBody.ChildCount > 0)
|
||||
return;
|
||||
DetailsBody.AddChild(new AdminLogEntryDetails(Log));
|
||||
DetailsHeading.OnToggled -= DetailsToggled;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
<BoxContainer xmlns="https://spacestation14.io"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
StyleClasses="BackgroundDark">
|
||||
<BoxContainer Orientation="Vertical" Margin="4">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<Label Text="{Loc admin-logs-field-type}" Margin="0 0 4 0"/>
|
||||
<Label Name="Type" Text="None" StyleClasses="LabelSecondaryColor" Access="Public"/>
|
||||
</BoxContainer>
|
||||
<cc:HSeparator/>
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<Label Text="{Loc admin-logs-field-impact}" Margin="0 0 4 0"/>
|
||||
<Label Name="Impact" Text="None" StyleClasses="LabelSecondaryColor" Access="Public"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
<cc:VSeparator/>
|
||||
<BoxContainer Orientation="Vertical" Margin="4">
|
||||
<Label Text="{Loc admin-logs-field-time-header}"/>
|
||||
<cc:HSeparator/>
|
||||
<BoxContainer>
|
||||
<Label Text="{Loc admin-logs-field-time-local}" Margin="0 0 4 0" HorizontalExpand="True"/>
|
||||
<Label Name="LocalTime" Text="None" StyleClasses="LabelSecondaryColor" Access="Public" HorizontalExpand="True"/>
|
||||
</BoxContainer>
|
||||
<cc:HSeparator/>
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<Label Text="{Loc admin-logs-field-time-utc}" Margin="0 0 4 0" HorizontalExpand="True"/>
|
||||
<Label Name="UTCTime" Text="None" StyleClasses="LabelSecondaryColor" Access="Public" HorizontalExpand="True"/>
|
||||
</BoxContainer>
|
||||
<cc:HSeparator/>
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<Label Text="{Loc admin-logs-field-time-round}" Margin="0 0 4 0" HorizontalExpand="True"/>
|
||||
<Label Name="CurTime" Text="None" StyleClasses="LabelSecondaryColor" Access="Public" HorizontalExpand="True"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
<cc:VSeparator/>
|
||||
<BoxContainer Orientation="Vertical" Margin="4" HorizontalExpand="True">
|
||||
<Label Text="{Loc admin-logs-field-players-header}"/>
|
||||
<cc:HSeparator/>
|
||||
<BoxContainer Orientation="Horizontal" Margin="4" VerticalExpand="True">
|
||||
<controls:ListContainer Name="PlayerListContainer" Access="Public" HorizontalExpand="True"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
@@ -1,98 +0,0 @@
|
||||
using System.Linq;
|
||||
using Content.Client.Administration.Systems;
|
||||
using Content.Client.Administration.UI.CustomControls;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Client.Verbs.UI;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Network;
|
||||
|
||||
namespace Content.Client.Administration.UI.Logs.Entries;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class AdminLogEntryDetails : BoxContainer
|
||||
{
|
||||
private readonly AdminSystem _adminSystem;
|
||||
private readonly IUserInterfaceManager _uiManager;
|
||||
private readonly IEntityManager _entManager;
|
||||
|
||||
public AdminLogEntryDetails(SharedAdminLog log)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
_entManager = IoCManager.Resolve<IEntityManager>();
|
||||
_uiManager = IoCManager.Resolve<IUserInterfaceManager>();
|
||||
_adminSystem = _entManager.System<AdminSystem>();
|
||||
|
||||
Type.Text = log.Type.ToString();
|
||||
Impact.Text = log.Impact.ToString();
|
||||
|
||||
LocalTime.Text = $"{log.Date.ToLocalTime():HH:mm:ss}";
|
||||
UTCTime.Text = $"{log.Date:HH:mm:ss}";
|
||||
// TimeSpan and DateTime use different formatting string conventions for some completely logical reason
|
||||
// that mere mortals such as myself will never be able to understand.
|
||||
CurTime.Text = new TimeSpan(log.CurTime).ToString(@"hh\:mm\:ss");
|
||||
|
||||
PlayerListContainer.ItemKeyBindDown += PlayerListItemKeyBindDown;
|
||||
PlayerListContainer.GenerateItem += GenerateButton;
|
||||
PopulateList(log.Players);
|
||||
}
|
||||
|
||||
private void PopulateList(Guid[] players)
|
||||
{
|
||||
if (players.Length == 0)
|
||||
return;
|
||||
|
||||
if (_adminSystem.PlayerList is not { } allPlayers || allPlayers.Count == 0)
|
||||
return;
|
||||
|
||||
var listData = new List<PlayerListData>();
|
||||
foreach (var playerGuid in players)
|
||||
{
|
||||
var netUserId = new NetUserId(playerGuid);
|
||||
|
||||
// Linq here is fine since this runs in response to admin input in the UI and
|
||||
// this loop only tends to go through 1-4 iterations.
|
||||
if (allPlayers.FirstOrDefault(player => player.SessionId == netUserId) is not { } playerInfo)
|
||||
continue;
|
||||
|
||||
listData.Add(new PlayerListData(playerInfo));
|
||||
}
|
||||
|
||||
if (listData.Count == 0)
|
||||
return;
|
||||
|
||||
PlayerListContainer.PopulateList(listData);
|
||||
}
|
||||
|
||||
private void PlayerListItemKeyBindDown(GUIBoundKeyEventArgs? args, ListData? data)
|
||||
{
|
||||
if (args == null || data is not PlayerListData { Info: var selectedPlayer })
|
||||
return;
|
||||
|
||||
if (!(args.Function == EngineKeyFunctions.UIRightClick
|
||||
|| args.Function == EngineKeyFunctions.UIClick)
|
||||
|| selectedPlayer.NetEntity == null)
|
||||
return;
|
||||
|
||||
_uiManager.GetUIController<VerbMenuUIController>().OpenVerbMenu(selectedPlayer.NetEntity.Value, true);
|
||||
args.Handle();
|
||||
}
|
||||
|
||||
private void GenerateButton(ListData data, ListContainerButton button)
|
||||
{
|
||||
if (data is not PlayerListData { Info: var info })
|
||||
return;
|
||||
|
||||
var entryLabel = new Label();
|
||||
entryLabel.Text = $"{info.CharacterName} ({info.Username})";
|
||||
var entry = new BoxContainer();
|
||||
entry.AddChild(entryLabel);
|
||||
|
||||
button.AddChild(entry);
|
||||
button.AddStyleClass(ListContainer.StyleClassListContainerButton);
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,7 @@ public sealed partial class PlayerTab : Control
|
||||
_config.OnValueChanged(CCVars.AdminPlayerTabColorSetting, ColorSettingChanged, true);
|
||||
_config.OnValueChanged(CCVars.AdminPlayerTabSymbolSetting, SymbolSettingChanged, true);
|
||||
|
||||
|
||||
OverlayButton.OnPressed += OverlayButtonPressed;
|
||||
ShowDisconnectedButton.OnPressed += ShowDisconnectedPressed;
|
||||
|
||||
@@ -64,6 +65,7 @@ public sealed partial class PlayerTab : Control
|
||||
SearchList.ItemKeyBindDown += (args, data) => OnEntryKeyBindDown?.Invoke(args, data);
|
||||
|
||||
RefreshPlayerList(_adminSystem.PlayerList);
|
||||
|
||||
}
|
||||
|
||||
#region Antag Overlay
|
||||
|
||||
@@ -9,9 +9,6 @@
|
||||
<ui:OptionDropDown Name="DropDownPlayerTabSymbolSetting" Title="{Loc 'ui-options-admin-player-tab-symbol-setting'}" />
|
||||
<ui:OptionDropDown Name="DropDownPlayerTabRoleSetting" Title="{Loc 'ui-options-admin-player-tab-role-setting'}" />
|
||||
<ui:OptionDropDown Name="DropDownPlayerTabColorSetting" Title="{Loc 'ui-options-admin-player-tab-color-setting'}" />
|
||||
<Label Text="{Loc 'ui-options-admin-logs-title'}"
|
||||
StyleClasses="LabelKeyText"/>
|
||||
<ui:OptionColorSlider Name="ColorSliderLogsHighlight" Title="{Loc 'ui-options-admin-logs-highlight-color'}" />
|
||||
<Label Text="{Loc 'ui-options-admin-overlay-title'}"
|
||||
StyleClasses="LabelKeyText"/>
|
||||
<ui:OptionDropDown Name="DropDownOverlayAntagFormat" Title="{Loc 'ui-options-admin-overlay-antag-format'}" />
|
||||
|
||||
@@ -51,8 +51,6 @@ public sealed partial class AdminOptionsTab : Control
|
||||
playerTabSymbolSettings.Add(new OptionDropDownCVar<string>.ValueOption(setting.ToString()!, Loc.GetString($"ui-options-admin-player-tab-symbol-setting-{setting.ToString()!.ToLower()}")));
|
||||
}
|
||||
|
||||
Control.AddOptionColorSlider(CCVars.AdminLogsHighlightColor, ColorSliderLogsHighlight);
|
||||
|
||||
Control.AddOptionDropDown(CCVars.AdminPlayerTabSymbolSetting, DropDownPlayerTabSymbolSetting, playerTabSymbolSettings);
|
||||
Control.AddOptionDropDown(CCVars.AdminPlayerTabRoleSetting, DropDownPlayerTabRoleSetting, playerTabRoleSettings);
|
||||
Control.AddOptionDropDown(CCVars.AdminPlayerTabColorSetting, DropDownPlayerTabColorSetting, playerTabColorSettings);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,29 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Content.Server.Database.Migrations.Postgres
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AdminLogsCurtime : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<long>(
|
||||
name: "cur_time",
|
||||
table: "admin_log",
|
||||
type: "bigint",
|
||||
nullable: false,
|
||||
defaultValue: 0L);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "cur_time",
|
||||
table: "admin_log");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
using Content.Server.Database;
|
||||
@@ -102,10 +101,6 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("admin_log_id");
|
||||
|
||||
b.Property<long>("CurTime")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("cur_time");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("date");
|
||||
@@ -800,7 +795,7 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("admin_ooc_color");
|
||||
|
||||
b.PrimitiveCollection<List<string>>("ConstructionFavorites")
|
||||
b.PrimitiveCollection<string[]>("ConstructionFavorites")
|
||||
.IsRequired()
|
||||
.HasColumnType("text[]")
|
||||
.HasColumnName("construction_favorites");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,29 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Content.Server.Database.Migrations.Sqlite
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AdminLogsCurtime : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<long>(
|
||||
name: "cur_time",
|
||||
table: "admin_log",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0L);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "cur_time",
|
||||
table: "admin_log");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,10 +91,6 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("admin_log_id");
|
||||
|
||||
b.Property<long>("CurTime")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("cur_time");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("date");
|
||||
|
||||
@@ -705,11 +705,6 @@ namespace Content.Server.Database
|
||||
|
||||
[Required] public DateTime Date { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current time in the round in ticks since the start of the round.
|
||||
/// </summary>
|
||||
public long CurTime { get; set; }
|
||||
|
||||
[Required] public string Message { get; set; } = default!;
|
||||
|
||||
[Required, Column(TypeName = "jsonb")] public JsonDocument Json { get; set; } = default!;
|
||||
|
||||
@@ -51,7 +51,7 @@ public sealed partial class AdminLogManager
|
||||
private void CacheLog(AdminLog log)
|
||||
{
|
||||
var players = log.Players.Select(player => player.PlayerUserId).ToArray();
|
||||
var record = new SharedAdminLog(log.Id, log.Type, log.Impact, log.Date, log.CurTime, log.Message, players);
|
||||
var record = new SharedAdminLog(log.Id, log.Type, log.Impact, log.Date, log.Message, players);
|
||||
|
||||
CacheLog(record);
|
||||
}
|
||||
|
||||
@@ -87,7 +87,6 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
||||
// Per round
|
||||
private int _currentRoundId;
|
||||
private int _currentLogId;
|
||||
private TimeSpan _currentRoundStartTime;
|
||||
private int NextLogId => Interlocked.Increment(ref _currentLogId);
|
||||
private GameRunLevel _runLevel = GameRunLevel.PreRoundLobby;
|
||||
|
||||
@@ -261,7 +260,6 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
||||
|
||||
public void RoundStarting(int id)
|
||||
{
|
||||
_currentRoundStartTime = _timing.CurTime;
|
||||
_currentRoundId = id;
|
||||
CacheNewRound();
|
||||
}
|
||||
@@ -318,7 +316,6 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
||||
Type = type,
|
||||
Impact = impact,
|
||||
Date = DateTime.UtcNow,
|
||||
CurTime = (_timing.CurTime - _currentRoundStartTime).Ticks,
|
||||
Message = message,
|
||||
Json = json,
|
||||
Players = new List<AdminLogPlayer>(players.Count)
|
||||
|
||||
@@ -1075,7 +1075,7 @@ INSERT INTO player_round (players_id, rounds_id) VALUES ({players[player]}, {id}
|
||||
players[i] = log.Players[i].PlayerUserId;
|
||||
}
|
||||
|
||||
yield return new SharedAdminLog(log.Id, log.Type, log.Impact, log.Date, log.CurTime, log.Message, players);
|
||||
yield return new SharedAdminLog(log.Id, log.Type, log.Impact, log.Date, log.Message, players);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,5 @@ public readonly record struct SharedAdminLog(
|
||||
LogType Type,
|
||||
LogImpact Impact,
|
||||
DateTime Date,
|
||||
long CurTime,
|
||||
string Message,
|
||||
Guid[] Players);
|
||||
|
||||
@@ -37,12 +37,6 @@ public sealed partial class CCVars
|
||||
public static readonly CVarDef<bool> OutlineEnabled =
|
||||
CVarDef.Create("outline.enabled", true, CVar.CLIENTONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Determines the color to use when highlighting search results in the admin log browser.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> AdminLogsHighlightColor =
|
||||
CVarDef.Create("ui.admin_logs_highlight_color", Color.Red.ToHex(), CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// Determines how antagonist status/roletype is displayed. Based on AdminOverlayAntagFormats enum
|
||||
/// Binary: Roletypes of interest get an "ANTAG" label
|
||||
|
||||
@@ -21,18 +21,3 @@ admin-logs-include-non-player = Include Non-players
|
||||
admin-logs-search-logs-placeholder = Search Logs
|
||||
admin-logs-refresh = Refresh
|
||||
admin-logs-next = Next
|
||||
admin-logs-render-rich-text = Render Rich Text
|
||||
admin-logs-remove-markup = Remove Markup
|
||||
|
||||
# Log Data Fields
|
||||
admin-logs-field-type = Type
|
||||
admin-logs-field-impact = Impact
|
||||
admin-logs-field-time-header = Time
|
||||
admin-logs-field-time-local = Local
|
||||
admin-logs-field-time-utc = UTC
|
||||
admin-logs-field-time-round = Round
|
||||
admin-logs-field-players-header = Players
|
||||
|
||||
# Log Player Fields
|
||||
admin-logs-player-field-no-players = No Players
|
||||
admin-logs-player-field-not-in-round = Not in round.
|
||||
|
||||
@@ -385,9 +385,6 @@ ui-options-admin-player-tab-color-setting-character = Colorize antag character n
|
||||
ui-options-admin-player-tab-color-setting-roletype = Colorize all role types
|
||||
ui-options-admin-player-tab-color-setting-both = Colorize both
|
||||
|
||||
ui-options-admin-logs-title = Admin Logs
|
||||
ui-options-admin-logs-highlight-color = Highlight Color
|
||||
|
||||
ui-options-admin-overlay-title = Admin Overlay
|
||||
|
||||
ui-options-admin-overlay-antag-format = Antag label style
|
||||
@@ -405,4 +402,3 @@ ui-options-admin-enable-overlay-starting-job = Show starting job
|
||||
ui-options-admin-overlay-merge-distance = Stack merge distance
|
||||
ui-options-admin-overlay-ghost-fade-distance = Ghost overlay fade range from mouse
|
||||
ui-options-admin-overlay-ghost-hide-distance = Ghost overlay hide range from mouse
|
||||
|
||||
|
||||
Reference in New Issue
Block a user