~ruther/NosSmooth

ref: 8933958f2f42f4a8e52a3f9d31ea8267caa65b0e NosSmooth/Samples/FileClient/Client.cs -rw-r--r-- 4.2 KiB
8933958f — Rutherther 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
137
138
139
//
//  Client.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.Text.RegularExpressions;
using Microsoft.Extensions.Logging;
using NosSmooth.Core.Client;
using NosSmooth.Core.Commands;
using NosSmooth.Core.Extensions;
using NosSmooth.Core.Packets;
using NosSmooth.Packets;
using NosSmooth.Packets.Errors;
using NosSmooth.PacketSerializer.Abstractions.Attributes;
using Remora.Results;

namespace FileClient;

/// <summary>
/// A NosTale client using stream to read lines.
/// </summary>
public class Client : BaseNostaleClient
{
    private const string LineRegex = ".*\\[(Recv|Send)\\]\t(.*)";
    private readonly PacketHandler _packetHandler;
    private readonly IPacketSerializer _packetSerializer;
    private readonly ILogger<Client> _logger;
    private readonly Stream _stream;

    /// <summary>
    /// Initializes a new instance of the <see cref="Client"/> class.
    /// </summary>
    /// <param name="stream">The stream with packets.</param>
    /// <param name="packetHandler">The packet handler.</param>
    /// <param name="commandProcessor">The command processor.</param>
    /// <param name="packetSerializer">The packet serializer.</param>
    /// <param name="logger">The logger.</param>
    public Client
    (
        Stream stream,
        PacketHandler packetHandler,
        CommandProcessor commandProcessor,
        IPacketSerializer packetSerializer,
        ILogger<Client> logger
    )
        : base(commandProcessor, packetSerializer)
    {
        _stream = stream;
        _packetHandler = packetHandler;
        _packetSerializer = packetSerializer;
        _logger = logger;
    }

    /// <inheritdoc />
    public override async Task<Result> RunAsync(CancellationToken stopRequested = default)
    {
        using var reader = new StreamReader(_stream);
        var regex = new Regex(LineRegex);
        while (!reader.EndOfStream)
        {
            stopRequested.ThrowIfCancellationRequested();
            var line = await reader.ReadLineAsync();
            if (line is null)
            {
                continue;
            }

            var match = regex.Match(line);
            if (!match.Success)
            {
                _logger.LogError("Could not find match on line {Line}", line);
                continue;
            }

            var type = match.Groups[1].Value;
            var packetStr = match.Groups[2].Value;

            var source = type == "Recv" ? PacketSource.Server : PacketSource.Client;
            var packet = CreatePacket(packetStr, source);
            Result result = await _packetHandler.HandlePacketAsync
            (
                this,
                source,
                packet,
                packetStr,
                stopRequested
            );
            if (!result.IsSuccess)
            {
                _logger.LogResultError(result);
            }
        }

        return Result.FromSuccess();
    }

    /// <inheritdoc/>
    public override async Task<Result> SendPacketAsync(string packetString, CancellationToken ct = default)
    {
        return await _packetHandler.HandlePacketAsync
        (
            this,
            PacketSource.Client,
            CreatePacket(packetString, PacketSource.Client),
            packetString,
            ct
        );
    }

    /// <inheritdoc/>
    public override async Task<Result> ReceivePacketAsync(string packetString, CancellationToken ct = default)
    {
        return await _packetHandler.HandlePacketAsync
        (
            this,
            PacketSource.Server,
            CreatePacket(packetString, PacketSource.Server),
            packetString,
            ct
        );
    }

    private IPacket CreatePacket(string packetStr, PacketSource source)
    {
        var packetResult = _packetSerializer.Deserialize(packetStr, source);
        if (!packetResult.IsSuccess)
        {
            if (packetResult.Error is PacketConverterNotFoundError err)
            {
                return new UnresolvedPacket(err.Header, packetStr);
            }

            return new ParsingFailedPacket(packetResult, packetStr);
        }

        return packetResult.Entity;
    }
}
Do not follow this link