~ruther/NosTale-PacketLogger

ref: ecad72bc5574f2333e9786bcd62fa37a37fa0eb3 NosTale-PacketLogger/src/PacketLogger/Models/Packets/ClientPacketProvider.cs -rw-r--r-- 3.9 KiB
ecad72bc — František Boháček chore: update dependencies 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
136
//
//  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 string Name => (_process.BrowserManager.IsInGame.Get()
        ? _process.BrowserManager.PlayerManager.Get().Player.Name
        : null) ?? $"Not in game ({_process.Process.Id})";

    /// <summary>
    /// Gets or sets title of document.
    /// </summary>
    public string DocumentTitle { get; set; } = string.Empty;

    /// <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>
    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