From 088a47056fb85ff7330ec09dc90241e7016c9cd8 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Wed, 15 Feb 2023 10:12:14 +0100 Subject: [PATCH] feat: add client closed indicator --- src/PacketLogger/Models/NostaleProcess.cs | 11 +++++++ src/PacketLogger/Models/NostaleProcesses.cs | 22 ++++++++++++-- .../Models/Packets/ClientPacketProvider.cs | 14 ++++++++- .../ViewModels/DocumentViewModel.cs | 30 ++++++++++++++----- 4 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/PacketLogger/Models/NostaleProcess.cs b/src/PacketLogger/Models/NostaleProcess.cs index 6887718..1a6457e 100644 --- a/src/PacketLogger/Models/NostaleProcess.cs +++ b/src/PacketLogger/Models/NostaleProcess.cs @@ -55,6 +55,11 @@ public class NostaleProcess : ObservableObject /// public NosBrowserManager BrowserManager { get; init; } + /// + /// Gets whether the process has been closed. + /// + public bool Closed { get; private set; } + /// /// Look for changes in the process, fire property changed. /// @@ -62,6 +67,12 @@ public class NostaleProcess : ObservableObject { try { + if (Process.HasExited) + { + Closed = true; + return; + } + if (BrowserManager.IsInGame.Get() != _wasInGame) { OnPropertyChanging(nameof(BrowserManager)); diff --git a/src/PacketLogger/Models/NostaleProcesses.cs b/src/PacketLogger/Models/NostaleProcesses.cs index dd72508..242adf5 100644 --- a/src/PacketLogger/Models/NostaleProcesses.cs +++ b/src/PacketLogger/Models/NostaleProcesses.cs @@ -14,6 +14,7 @@ using System.Reactive.Concurrency; using System.Reactive.Linq; using System.Runtime.InteropServices; using System.Security.Principal; +using System.Threading; using System.Threading.Tasks; using NosSmooth.Comms.Local; using NosSmooth.Core.Extensions; @@ -31,6 +32,7 @@ namespace PacketLogger.Models; public class NostaleProcesses : IDisposable { private readonly IDisposable? _cleanUp; + private readonly SemaphoreSlim _semaphore; private readonly ManagementEventWatcher? _processStartWatcher; private readonly ManagementEventWatcher? _processStopWatcher; @@ -39,6 +41,7 @@ public class NostaleProcesses : IDisposable /// public NostaleProcesses() { + _semaphore = new SemaphoreSlim(1, 1); Processes = new ObservableCollection(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -123,7 +126,13 @@ public class NostaleProcesses : IDisposable if (nosBrowserManager.IsModuleLoaded()) { RxApp.MainThreadScheduler.Schedule - (() => Processes.Add(new NostaleProcess(process, nosBrowserManager))); + (() => + { + _semaphore.Wait(); + Processes.Add(new NostaleProcess(process, nosBrowserManager)); + _semaphore.Release(); + } + ); } else { @@ -143,7 +152,14 @@ public class NostaleProcesses : IDisposable if (process is not null) { RxApp.MainThreadScheduler.Schedule - (() => Processes.Remove(process)); + (() => + { + process.ObserveChanges(); + _semaphore.Wait(); + Processes.Remove(process); + _semaphore.Release(); + } + ); } } } @@ -175,9 +191,11 @@ public class NostaleProcesses : IDisposable private void UpdateNames() { + _semaphore.Wait(); foreach (var process in Processes) { process.ObserveChanges(); } + _semaphore.Release(); } } \ No newline at end of file diff --git a/src/PacketLogger/Models/Packets/ClientPacketProvider.cs b/src/PacketLogger/Models/Packets/ClientPacketProvider.cs index 2497f85..cacb203 100644 --- a/src/PacketLogger/Models/Packets/ClientPacketProvider.cs +++ b/src/PacketLogger/Models/Packets/ClientPacketProvider.cs @@ -6,6 +6,8 @@ using System; using System.ComponentModel; +using System.Reactive.Disposables; +using System.Reactive.Linq; using System.Threading; using System.Threading.Tasks; using DynamicData; @@ -42,11 +44,16 @@ public abstract class ClientPacketProvider : ReactiveObject, IPacketProvider _process = process; _client = client; Packets = new SourceList(); - _cleanUp = process.WhenPropertyChanged(x => x.CharacterString) + var cleanUp1 = process.WhenPropertyChanged(x => x.CharacterString) .Subscribe ( _ => this.RaisePropertyChanged(nameof(Name)) ); + + var cleanUp2 = process.WhenAnyValue(x => x.Closed) + .ObserveOn(RxApp.MainThreadScheduler) + .Subscribe(_ => this.RaisePropertyChanged(nameof(Closed))); + _cleanUp = new CompositeDisposable(cleanUp1, cleanUp2); } /// @@ -54,6 +61,11 @@ public abstract class ClientPacketProvider : ReactiveObject, IPacketProvider ? _process.BrowserManager.PlayerManager.Get().Player.Name : null) ?? $"Not in game ({_process.Process.Id})"; + /// + /// Gets whether the process has been closed. + /// + public bool Closed => _process.Closed; + /// /// Gets or sets title of document. /// diff --git a/src/PacketLogger/ViewModels/DocumentViewModel.cs b/src/PacketLogger/ViewModels/DocumentViewModel.cs index 9e99703..33089a8 100644 --- a/src/PacketLogger/ViewModels/DocumentViewModel.cs +++ b/src/PacketLogger/ViewModels/DocumentViewModel.cs @@ -85,7 +85,9 @@ public class DocumentViewModel : Document, INotifyPropertyChanged, IDisposable ); _cleanUp = this.WhenAnyValue(x => x.Title) - .Subscribe(title => + .Subscribe + ( + title => { if (_packetProvider is not null) { @@ -207,7 +209,8 @@ public class DocumentViewModel : Document, INotifyPropertyChanged, IDisposable if (!runClientContractResult.IsDefined(out var runClientResponse)) { repository.Remove(connection.Client); - Error = "An error has occurred upon sending run client: " + runClientContractResult.ToFullString(); + Error = "An error has occurred upon sending run client: " + + runClientContractResult.ToFullString(); Loading = false; return; } @@ -220,7 +223,8 @@ public class DocumentViewModel : Document, INotifyPropertyChanged, IDisposable return; } - if (runClientResponse.BindingManagerResult is not null && !runClientResponse.BindingManagerResult.Value.IsSuccess) + if (runClientResponse.BindingManagerResult is not null + && !runClientResponse.BindingManagerResult.Value.IsSuccess) { Console.WriteLine("There was an error in binding initialization."); Console.WriteLine(runClientResponse.BindingManagerResult.Value.ToFullString()); @@ -229,7 +233,8 @@ public class DocumentViewModel : Document, INotifyPropertyChanged, IDisposable if (!runClientResponse.InitializationResult.Value.IsSuccess) { repository.Remove(connection.Client); - Error = "An error has occurred during starting client: " + runClientResponse.InitializationResult.ToFullString(); + Error = "An error has occurred during starting client: " + + runClientResponse.InitializationResult.ToFullString(); Loading = false; return; } @@ -239,7 +244,14 @@ public class DocumentViewModel : Document, INotifyPropertyChanged, IDisposable _titleHandle = titleGenerator.AddTitle ( title => Title = title, - provider.WhenAnyValue(x => x.Name).ObserveOn(RxApp.MainThreadScheduler), + provider + .WhenAnyValue(x => x.Name, x => x.Closed) + .ObserveOn(RxApp.MainThreadScheduler) + .Select + ( + (x) => (x.Item2 ? "Closed (" : string.Empty) + x.Item1 + + (x.Item2 ? ")" : string.Empty) + ), provider.Name ); @@ -276,9 +288,13 @@ public class DocumentViewModel : Document, INotifyPropertyChanged, IDisposable ( title => Title = title, provider - .WhenAnyValue(x => x.Name) + .WhenAnyValue(x => x.Name, x => x.Closed) .ObserveOn(RxApp.MainThreadScheduler) - .Select(x => x + " - sniff"), + .Select + ( + (x) => (x.Item2 ? "Closed (" : string.Empty) + (x.Item1 + " - sniff") + + (x.Item2 ? ")" : string.Empty) + ), provider.Name ); await provider.Open(); -- 2.48.1