Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to copy admin logs #74

Merged
merged 4 commits into from
Jul 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Content.Client/Administration/UI/Logs/AdminLogsControl.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@
<Button Name="RefreshButton" Access="Public" Text="{Loc admin-logs-refresh}" StyleClasses="ButtonSquare"/>
<Button Name="NextButton" Access="Public" Text="{Loc admin-logs-next}" StyleClasses="OpenLeft"/>
</BoxContainer>
<ScrollContainer VerticalExpand="True" HorizontalExpand="True" HScrollEnabled="False">
<BoxContainer Name="LogsContainer" Access="Public" Orientation="Vertical" VerticalExpand="True"/>
<ScrollContainer Name="AdminLogsScrollContainer" Access="Public" VerticalExpand="True" HorizontalExpand="True" HScrollEnabled="False">
<TextEdit Name="AdminLogsTextEdit" Access="Public" VerticalExpand="True"/>
</ScrollContainer>
</BoxContainer>
</BoxContainer>
Expand Down
110 changes: 66 additions & 44 deletions Content.Client/Administration/UI/Logs/AdminLogsControl.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using Content.Client.Administration.UI.CustomControls;
using Content.Shared.Administration.Logs;
using Content.Shared.Database;
Expand All @@ -15,13 +15,20 @@ namespace Content.Client.Administration.UI.Logs;
[GenerateTypedNameReferences]
public sealed partial class AdminLogsControl : Control
{
/// <summary>
/// <para>List of used tags can be found here: Robust.Client/UserInterface/RichText/MarkupTagManager.cs</para>
/// <para>Pattern test online: https://regex101.com/r/3krK2I/2</para>
/// </summary>
private const string BBCodeRegexPattern = "((\\[|\\[/)(color|cmdlink|font|bold|italic)=?\\w*\\])";
private readonly Comparer<AdminLogTypeButton> _adminLogTypeButtonComparer =
Comparer<AdminLogTypeButton>.Create((a, b) =>
string.Compare(a.Type.ToString(), b.Type.ToString(), StringComparison.Ordinal));
Comparer<AdminLogTypeButton>.Create(
(a, b) => string.Compare(a.Type.ToString(), b.Type.ToString(), StringComparison.Ordinal)
);

private readonly Comparer<AdminLogPlayerButton> _adminLogPlayerButtonComparer =
Comparer<AdminLogPlayerButton>.Create((a, b) =>
string.Compare(a.Text, b.Text, StringComparison.Ordinal));
Comparer<AdminLogPlayerButton>.Create(
(a, b) => string.Compare(a.Text, b.Text, StringComparison.Ordinal)
);

public AdminLogsControl()
{
Expand All @@ -44,6 +51,8 @@ public AdminLogsControl()

ResetRoundButton.OnPressed += ResetRoundPressed;

RecievedLogs = new List<SharedAdminLog>();

SetImpacts(Enum.GetValues<LogImpact>().OrderBy(impact => impact).ToArray());
SetTypes(Enum.GetValues<LogType>());
}
Expand All @@ -55,6 +64,12 @@ public AdminLogsControl()
private int ShownLogs { get; set; }
private int TotalLogs { get; set; }
private int RoundLogs { get; set; }

/// <summary>
/// Storage of recieved logs
/// </summary>
private List<SharedAdminLog> RecievedLogs { get; set; }

public bool IncludeNonPlayerLogs { get; set; }

public HashSet<LogType> SelectedTypes { get; } = new();
Expand Down Expand Up @@ -239,22 +254,47 @@ private void UpdatePlayers()
private void UpdateLogs()
{
ShownLogs = 0;
var logsText = "";

foreach (var child in LogsContainer.Children)
// build logs string
for (var i = RecievedLogs.Count - 1; i >= 0; i--)
{
if (child is not AdminLogLabel log)
var log = RecievedLogs[i];
if (ShouldShowLog(log))
{
continue;
ShownLogs++;
logsText += string.Format(
"{0:HH:mm:ss} - {1}\n{2}\n\n",
log.Date,
log.Type,
log.Message
);
}

child.Visible = ShouldShowLog(log);
if (child.Visible)
}
// set new text in TextEdit and clear BB tags only in result log string to
// preserve original log messages for posible future use
AdminLogsTextEdit.TextRope = new Robust.Shared.Utility.Rope.Leaf(
Regex.Replace(logsText, BBCodeRegexPattern, "")
);
UpdateCount(ShownLogs, RecievedLogs.Count);
ScrollLogsToBottom();
}

/// <summary>
/// Try to scroll AdminLogsTextEdit to the end
/// </summary>
private void ScrollLogsToBottom()
{
// find scrollbar in TextEdit's children
// it must be at index 1, but may be changed in future
for (var i = 0; i < AdminLogsTextEdit.ChildCount; i++)
{
if (AdminLogsTextEdit.GetChild(i) is VScrollBar scrollbar)
{
ShownLogs++;
scrollbar.ValueTarget = float.PositiveInfinity;
break;
}
}

UpdateCount();
}

private bool ShouldShowType(AdminLogTypeButton button)
Expand All @@ -269,30 +309,30 @@ private bool ShouldShowPlayer(AdminLogPlayerButton button)
button.Text.Contains(PlayerSearch.Text, StringComparison.OrdinalIgnoreCase);
}

private bool LogMatchesPlayerFilter(AdminLogLabel label)
private bool LogMatchesPlayerFilter(SharedAdminLog log)
{
if (label.Log.Players.Length == 0)
if (log.Players.Length == 0)
return SelectedPlayers.Count == 0 || IncludeNonPlayerLogs;

return SelectedPlayers.Overlaps(label.Log.Players);
return SelectedPlayers.Overlaps(log.Players);
}

private bool ShouldShowLog(AdminLogLabel label)
private bool ShouldShowLog(SharedAdminLog log)
{
// Check log type
if (!SelectedTypes.Contains(label.Log.Type))
if (!SelectedTypes.Contains(log.Type))
return false;

// Check players
if (!LogMatchesPlayerFilter(label))
if (!LogMatchesPlayerFilter(log))
return false;

// Check impact
if (!SelectedImpacts.Contains(label.Log.Impact))
if (!SelectedImpacts.Contains(log.Impact))
return false;

// Check search
if (!label.Log.Message.Contains(LogSearch.Text, StringComparison.OrdinalIgnoreCase))
if (!log.Message.Contains(LogSearch.Text, StringComparison.OrdinalIgnoreCase))
return false;

return true;
Expand Down Expand Up @@ -458,32 +498,14 @@ public void SetPlayers(Dictionary<Guid, string> players)

public void AddLogs(List<SharedAdminLog> logs)
{
var span = CollectionsMarshal.AsSpan(logs);
for (var i = 0; i < span.Length; i++)
{
ref var log = ref span[i];
var separator = new HSeparator();
var label = new AdminLogLabel(ref log, separator);
label.Visible = ShouldShowLog(label);

TotalLogs++;
if (label.Visible)
{
ShownLogs++;
}

LogsContainer.AddChild(label);
LogsContainer.AddChild(separator);
}

UpdateCount();
RecievedLogs.AddRange(logs);
UpdateLogs();
}

public void SetLogs(List<SharedAdminLog> logs)
{
LogsContainer.RemoveAllChildren();
UpdateCount(0, 0);
AddLogs(logs);
RecievedLogs = logs;
UpdateLogs();
}

public void UpdateCount(int? shown = null, int? total = null, int? round = null)
Expand Down
Loading