// // ClientPacketProvider.cs // // Copyright (c) František Boháček. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.ComponentModel; using System.Threading; using System.Threading.Tasks; using DynamicData; using DynamicData.Binding; using NosSmooth.Comms.Local; using NosSmooth.Core.Client; using NosSmooth.Core.Packets; using NosSmooth.PacketSerializer.Abstractions.Attributes; using ReactiveUI; using Remora.Results; namespace PacketLogger.Models.Packets; /// /// A packet provider using . /// public abstract class ClientPacketProvider : ReactiveObject, IPacketProvider { private readonly IDisposable _cleanUp; private readonly NostaleProcess _process; private readonly INostaleClient _client; private readonly CancellationTokenSource _ctSource; private long _currentIndex; private Task? _runTask; /// /// Initializes a new instance of the class. /// /// The process. /// The nostale client. public ClientPacketProvider(NostaleProcess process, INostaleClient client) { _ctSource = new CancellationTokenSource(); _process = process; _client = client; Packets = new SourceList(); _cleanUp = process.WhenPropertyChanged(x => x.CharacterString) .Subscribe ( _ => this.RaisePropertyChanged(nameof(Name)) ); } /// public string Name => (_process.BrowserManager.IsInGame.Get() ? _process.BrowserManager.PlayerManager.Get().Player.Name : null) ?? $"Not in game ({_process.Process.Id})"; /// /// Gets or sets title of document. /// public string DocumentTitle { get; set; } = string.Empty; /// public abstract bool IsOpen { get; } /// public SourceList Packets { get; } /// public bool LogReceived { get; set; } = true; /// public bool LogSent { get; set; } = true; /// public Task Open() { _runTask = Task.Run(() => _client.RunAsync(_ctSource.Token)); return Task.FromResult(Result.FromSuccess()); } /// public virtual Task Close() { _ctSource.Cancel(); if (_runTask is not null) { return _runTask; } return Task.FromResult(Result.FromSuccess()); } /// public void Clear() { Packets.Clear(); } /// public Task SendPacket(string packetString, CancellationToken ct = default) => _client.SendPacketAsync(packetString, ct); /// public Task ReceivePacket(string packetString, CancellationToken ct = default) => _client.ReceivePacketAsync(packetString, ct); /// /// Add the given packets from an event. /// /// The packet event args. internal void AddPacket(PacketEventArgs packetArgs) { var index = Interlocked.Increment(ref _currentIndex); if ((packetArgs.Source == PacketSource.Server && LogReceived) || (packetArgs.Source == PacketSource.Client && LogSent)) { Packets.Add(new PacketInfo(index, DateTime.Now, packetArgs.Source, packetArgs.PacketString)); } } /// public void Dispose() { } /// /// A dispose used instead of /// to prevent the service provider disposing. /// public void CustomDispose() { _ctSource.Dispose(); _cleanUp.Dispose(); Packets.Dispose(); } }