// // CommsPacketProvider.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.Data; using System.Threading; using System.Threading.Tasks; using DynamicData; using DynamicData.Binding; using NosSmooth.Comms.Local; using NosSmooth.Core.Packets; using NosSmooth.PacketSerializer.Abstractions.Attributes; using ReactiveUI; using Remora.Results; namespace PacketLogger.Models.Packets; /// /// A packet provider using a connection to a nostale client. /// public class CommsPacketProvider : ReactiveObject, IPacketProvider { private readonly IDisposable _cleanUp; private readonly NostaleProcess _process; private readonly Comms _comms; private long _currentIndex; /// /// Initializes a new instance of the class. /// /// The process. /// The comms. public CommsPacketProvider(NostaleProcess process, Comms comms) { _process = process; _comms = comms; Packets = new SourceList(); _cleanUp = process.WhenPropertyChanged(x => x.CharacterString) .Subscribe ( _ => this.RaisePropertyChanged(nameof(Name)) ); } /// public event PropertyChangedEventHandler? PropertyChanged; /// public string Name => (_process.BrowserManager.IsInGame ? _process.BrowserManager.PlayerManager.Player.Name : null) ?? $"Not in game ({_process.Process.Id})"; /// public bool IsOpen => _comms.Connection.Connection.State == ConnectionState.Open; /// public SourceList Packets { get; } /// public bool LogReceived { get; set; } = true; /// public bool LogSent { get; set; } = true; /// public Task Open() => Task.FromResult(Result.FromSuccess()); /// public Task Close() { _comms.Connection.Connection.Disconnect(); return Task.FromResult(Result.FromSuccess()); } /// public void Clear() { Packets.Clear(); } /// public Task SendPacket(string packetString, CancellationToken ct = default) => _comms.Client.SendPacketAsync(packetString, ct); /// public Task ReceivePacket(string packetString, CancellationToken ct = default) => _comms.Client.ReceivePacketAsync(packetString, ct); /// /// Add the given packets from an event. /// /// The packet event args. /// The type of the deserialized packet. 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() { _cleanUp.Dispose(); Packets.Dispose(); } }