Add log tracer window

This commit is contained in:
pizzaboxer 2023-07-20 18:17:25 +01:00
parent 05185e9e9a
commit 53a64881cd
No known key found for this signature in database
GPG Key ID: 59D4A1DBAD0F2BA8
8 changed files with 145 additions and 31 deletions

View File

@ -17,12 +17,15 @@
private int _logEntriesRead = 0;
public event EventHandler<string>? OnLogEntry;
public event EventHandler? OnGameJoin;
public event EventHandler? OnGameLeave;
public event EventHandler<GameMessage>? OnGameMessage;
private Dictionary<string, string> GeolcationCache = new();
public string LogFilename = null!;
// these are values to use assuming the player isn't currently in a game
// keep in mind ActivityIsTeleport is only reset by DiscordRichPresence when it's done accessing it
// because of the weird chronology of where the teleporting entry is outputted, there's no way to reset it in here
@ -72,8 +75,9 @@
await Task.Delay(1000);
}
LogFilename = logFileInfo.Name;
FileStream logFileStream = logFileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
App.Logger.WriteLine($"[RobloxActivity::StartWatcher] Opened {logFileInfo.Name}");
App.Logger.WriteLine($"[RobloxActivity::StartWatcher] Opened {LogFilename}");
AutoResetEvent logUpdatedEvent = new(false);
FileSystemWatcher logWatcher = new()
@ -99,7 +103,8 @@
private void ExamineLogEntry(string entry)
{
// App.Logger.WriteLine(entry);
OnLogEntry?.Invoke(this, entry);
_logEntriesRead += 1;
// debug stats to ensure that the log reader is working correctly

View File

@ -0,0 +1,38 @@
<ui:UiWindow x:Class="Bloxstrap.UI.Elements.ContextMenu.LogTracer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.ContextMenu"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels.ContextMenu"
d:DataContext="{d:DesignInstance Type=models:LogTracerViewModel}"
mc:Ignorable="d"
Title="Log tracer"
Width="800"
Height="480"
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
ExtendsContentIntoTitleBar="True"
WindowStartupLocation="CenterScreen">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ui:TitleBar Grid.Row="0" Grid.ColumnSpan="2" Padding="8" x:Name="RootTitleBar" Title="Log tracer" ShowMinimize="True" ShowMaximize="True" CanMaximize="True" KeyboardNavigation.TabNavigation="None" Icon="pack://application:,,,/Bloxstrap.ico" />
<TextBlock Grid.Row="1" Padding="12" Text="{Binding LogLocation, Mode=OneWay, StringFormat='Tracing \{0\}'}" />
<ScrollViewer x:Name="ScrollViewer" Grid.Row="2">
<RichTextBox Grid.Row="1" Block.LineHeight="2" IsReadOnly="True" Background="Transparent" BorderThickness="0" TextChanged="RichTextBox_TextChanged">
<FlowDocument x:Name="FlowDocument">
<Paragraph FontFamily="Courier New" FontSize="14">
<Run Text="{Binding LogContents, Mode=OneWay}" />
</Paragraph>
</FlowDocument>
</RichTextBox>
</ScrollViewer>
</Grid>
</ui:UiWindow>

View File

@ -0,0 +1,24 @@
using System.Windows.Controls;
using Bloxstrap.UI.ViewModels.ContextMenu;
namespace Bloxstrap.UI.Elements.ContextMenu
{
/// <summary>
/// Interaction logic for LogTracer.xaml
/// </summary>
public partial class LogTracer
{
private readonly LogTracerViewModel _viewModel;
public LogTracer(RobloxActivity activityWatcher)
{
_viewModel = new LogTracerViewModel(this, activityWatcher);
DataContext = _viewModel;
InitializeComponent();
}
private void RichTextBox_TextChanged(object sender, TextChangedEventArgs e) => ScrollViewer.ScrollToEnd();
}
}

View File

@ -22,6 +22,7 @@
<Separator />
<MenuItem x:Name="RichPresenceMenuItem" Header="Discord Rich Presence" IsCheckable="True" IsChecked="True" Visibility="Collapsed" />
<MenuItem x:Name="ServerDetailsMenuItem" Header="See server details" Visibility="Collapsed" />
<MenuItem x:Name="LogTracerMenuItem" Header="Open log tracer" Visibility="Collapsed" />
</ContextMenu>
</ui:UiWindow.ContextMenu>
</ui:UiWindow>

View File

@ -17,7 +17,6 @@
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
ExtendsContentIntoTitleBar="True"
WindowStartupLocation="CenterScreen">
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
@ -42,5 +41,4 @@
</StackPanel>
</Border>
</Grid>
</Grid>
</ui:UiWindow>

View File

@ -18,7 +18,7 @@ namespace Bloxstrap.UI
private DiscordRichPresence? _richPresenceHandler;
private ServerInformation? _serverInformationWindow;
private LogTracer? _logTracerWindow;
EventHandler? _alertClickHandler;
@ -58,6 +58,9 @@ namespace Bloxstrap.UI
_activityWatcher = activityWatcher;
_activityWatcher.OnGameJoin += (_, _) => Task.Run(OnGameJoin);
_activityWatcher.OnGameLeave += OnGameLeave;
if (App.Settings.Prop.OhHeyYouFoundMe && _menuContainer is not null)
_menuContainer.Dispatcher.Invoke(() => _menuContainer.LogTracerMenuItem.Visibility = Visibility.Visible);
}
#endregion
@ -69,8 +72,9 @@ namespace Bloxstrap.UI
_menuContainer = new();
_menuContainer.Dispatcher.BeginInvoke(_menuContainer.ShowDialog);
_menuContainer.ServerDetailsMenuItem.Click += (_, _) => ShowServerInformationWindow();
_menuContainer.RichPresenceMenuItem.Click += (_, _) => _richPresenceHandler?.SetVisibility(_menuContainer.RichPresenceMenuItem.IsChecked);
_menuContainer.ServerDetailsMenuItem.Click += (_, _) => ShowServerInformationWindow();
_menuContainer.LogTracerMenuItem.Click += (_, _) => ShowLogTracerWindow();
_menuContainer.Closing += (_, _) => App.Logger.WriteLine("[NotifyIconWrapper::NotifyIconWrapper] Context menu container closed");
}
@ -84,6 +88,7 @@ namespace Bloxstrap.UI
}
#endregion
#region Activity handlers
public async void OnGameJoin()
{
if (_menuContainer is not null)
@ -98,14 +103,14 @@ namespace Bloxstrap.UI
public void OnGameLeave(object? sender, EventArgs e)
{
if (_menuContainer is not null)
_menuContainer.Dispatcher.Invoke(() => _menuContainer.ServerDetailsMenuItem.Visibility = Visibility.Collapsed);
_menuContainer?.Dispatcher.Invoke(() => _menuContainer.ServerDetailsMenuItem.Visibility = Visibility.Collapsed);
if (_serverInformationWindow is not null && _serverInformationWindow.IsVisible)
_serverInformationWindow.Dispatcher.Invoke(_serverInformationWindow.Close);
}
#endregion
#region Window handlers
public void ShowServerInformationWindow()
{
if (_serverInformationWindow is null)
@ -120,6 +125,21 @@ namespace Bloxstrap.UI
_serverInformationWindow.Activate();
}
public void ShowLogTracerWindow()
{
if (_logTracerWindow is null)
{
_logTracerWindow = new LogTracer(_activityWatcher!);
_logTracerWindow.Closed += (_, _) => _logTracerWindow = null;
}
if (!_logTracerWindow.IsVisible)
_logTracerWindow.Show();
_logTracerWindow.Activate();
}
#endregion
public void ShowAlert(string caption, string message, int duration, EventHandler? clickHandler)
{
string id = Guid.NewGuid().ToString()[..8];

View File

@ -0,0 +1,30 @@
using System.Windows;
using System.Windows.Input;
using CommunityToolkit.Mvvm.Input;
namespace Bloxstrap.UI.ViewModels.ContextMenu
{
internal class LogTracerViewModel : NotifyPropertyChangedViewModel
{
private readonly Window _window;
private readonly RobloxActivity _activityWatcher;
public ICommand CloseWindowCommand => new RelayCommand(_window.Close);
public string LogLocation => _activityWatcher.LogFilename;
public string LogContents { get; private set; } = "";
public LogTracerViewModel(Window window, RobloxActivity activityWatcher)
{
_window = window;
_activityWatcher = activityWatcher;
_activityWatcher.OnLogEntry += (_, message) =>
{
LogContents += message += "\r\n";
OnPropertyChanged(nameof(LogContents));
};
}
}
}

View File

@ -3,13 +3,11 @@ using System.Windows.Input;
using CommunityToolkit.Mvvm.Input;
using Bloxstrap.UI.Elements.ContextMenu;
namespace Bloxstrap.UI.ViewModels.ContextMenu
{
internal class ServerInformationViewModel : NotifyPropertyChangedViewModel
{
private readonly ServerInformation _window;
private readonly Window _window;
private readonly RobloxActivity _activityWatcher;
public string InstanceId => _activityWatcher.ActivityJobId;
@ -18,7 +16,7 @@ namespace Bloxstrap.UI.ViewModels.ContextMenu
public ICommand CopyInstanceIdCommand => new RelayCommand(CopyInstanceId);
public ICommand CloseWindowCommand => new RelayCommand(_window.Close);
public ServerInformationViewModel(ServerInformation window, RobloxActivity activityWatcher)
public ServerInformationViewModel(Window window, RobloxActivity activityWatcher)
{
_window = window;
_activityWatcher = activityWatcher;