~ruther/NosTale-PacketLogger

ref: 1ac87d8e49a6ebb1fa3b619a0538dc828ab7fd73 NosTale-PacketLogger/src/PacketLogger/Models/Packets/ClientPacketProvider.cs -rw-r--r-- 4.0 KiB
1ac87d8e — Rutherther feat: add pcap support 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//
//  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;

/// <summary>
/// A packet provider using <see cref="INostaleClient"/>.
/// </summary>
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<Result>? _runTask;

    /// <summary>
    /// Initializes a new instance of the <see cref="ClientPacketProvider"/> class.
    /// </summary>
    /// <param name="process">The process.</param>
    /// <param name="client">The nostale client.</param>
    public ClientPacketProvider(NostaleProcess process, INostaleClient client)
    {
        _ctSource = new CancellationTokenSource();
        _process = process;
        _client = client;
        Packets = new SourceList<PacketInfo>();
        _cleanUp = process.WhenPropertyChanged(x => x.CharacterString)
            .Subscribe
            (
                _ => this.RaisePropertyChanged(nameof(Name))
            );
    }

    /// <inheritdoc />
    public event PropertyChangedEventHandler? PropertyChanged;

    /// <inheritdoc />
    public string Name => (_process.BrowserManager.IsInGame
        ? _process.BrowserManager.PlayerManager.Player.Name
        : null) ?? $"Not in game ({_process.Process.Id})";

    /// <inheritdoc />
    public abstract bool IsOpen { get; }

    /// <inheritdoc />
    public SourceList<PacketInfo> Packets { get; }

    /// <inheritdoc />
    public bool LogReceived { get; set; } = true;

    /// <inheritdoc />
    public bool LogSent { get; set; } = true;

    /// <inheritdoc />
    public Task<Result> Open()
    {
        _runTask = Task.Run(() => _client.RunAsync(_ctSource.Token));
        return Task.FromResult(Result.FromSuccess());
    }

    /// <inheritdoc />
    public virtual Task<Result> Close()
    {
        _ctSource.Cancel();
        if (_runTask is not null)
        {
            return _runTask;
        }

        return Task.FromResult(Result.FromSuccess());
    }

    /// <inheritdoc />
    public void Clear()
    {
        Packets.Clear();
    }

    /// <inheritdoc />
    public Task<Result> SendPacket(string packetString, CancellationToken ct = default)
        => _client.SendPacketAsync(packetString, ct);

    /// <inheritdoc />
    public Task<Result> ReceivePacket(string packetString, CancellationToken ct = default)
        => _client.ReceivePacketAsync(packetString, ct);

    /// <summary>
    /// Add the given packets from an event.
    /// </summary>
    /// <param name="packetArgs">The packet event args.</param>
    /// <typeparam name="TPacket">The type of the deserialized packet.</typeparam>
    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));
        }
    }

    /// <inheritdoc />
    public void Dispose()
    {
    }

    /// <summary>
    /// A dispose used instead of <see cref="Dispose"/>
    /// to prevent the service provider disposing.
    /// </summary>
    public void CustomDispose()
    {
        _ctSource.Dispose();
        _cleanUp.Dispose();
        Packets.Dispose();
    }
}
Do not follow this link