~ruther/Nostale-Anonymizer

ref: f56393bbc61224da75465542183e478910640a70 Nostale-Anonymizer/src/Anonymizer/PacketProcessor.cs -rw-r--r-- 4.3 KiB
f56393bb — František Boháček feat: add new movers 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
//
//  PacketProcessor.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.Diagnostics;
using Anonymizer.Filters;
using Anonymizer.Movers;
using Anonymizer.Sinks;
using Microsoft.Extensions.Options;
using NosSmooth.Packets;
using NosSmooth.PacketSerializer;
using NosSmooth.PacketSerializer.Abstractions.Attributes;
using Remora.Results;

namespace Anonymizer;

/// <summary>
/// Processes packets, anonymizes or filters them.
/// </summary>
public class PacketProcessor
{
    private readonly IPacketSerializer _packetSerializer;
    private readonly IAnonymizer _anonymizer;
    private readonly RegisteredMovers _registeredMovers;
    private readonly IReadOnlyList<IFilter> _filters;
    private readonly IReadOnlyList<IMover> _movers;

    /// <summary>
    /// Initializes a new instance of the <see cref="PacketProcessor"/> class.
    /// </summary>
    /// <param name="packetSerializer">The packet serializer.</param>
    /// <param name="anonymizer">The anonymizer.</param>
    /// <param name="filters">The filters.</param>
    /// <param name="movers">The movers.</param>
    /// <param name="registeredMovers">The registered movers.</param>
    public PacketProcessor
    (
        IPacketSerializer packetSerializer,
        IAnonymizer anonymizer,
        IEnumerable<IFilter> filters,
        IEnumerable<IMover> movers,
        IOptions<RegisteredMovers> registeredMovers
    )
    {
        _packetSerializer = packetSerializer;
        _anonymizer = anonymizer;
        _registeredMovers = registeredMovers.Value;
        _filters = filters.ToList();
        _movers = movers.ToList();
    }

    /// <summary>
    /// Process one packet, anonymize it.
    /// </summary>
    /// <param name="packetInfo">The packet to anonymize.</param>
    /// <returns>The processed packet.</returns>
    public Result<ProcessedPacket> ProcessPacket(PacketInfo packetInfo)
    {
        foreach (var filter in _filters)
        {
            if (!filter.Filter(packetInfo))
            {
                return new ProcessedPacket(packetInfo.Packet, packetInfo.Packet, false);
            }
        }

        var header = packetInfo.Packet.Split(' ')[0];
        if (!_registeredMovers.ShouldMove(header))
        {
            return new ProcessedPacket(packetInfo.Packet, packetInfo.Packet, true);
        }

        var packetResult = _packetSerializer.Deserialize(packetInfo.Packet, packetInfo.Source);
        if (!packetResult.IsDefined(out var packet))
        {
            return Result<ProcessedPacket>.FromError(packetResult);
        }

        foreach (var mover in _movers)
        {
            if (mover.ShouldHandle(packet))
            {
                var movedPacket = mover.Move(_anonymizer, packet);
                var serializedResult = _packetSerializer.Serialize(movedPacket);
                if (!serializedResult.IsDefined(out var serialized))
                {
                    return Result<ProcessedPacket>.FromError(serializedResult);
                }

                return new ProcessedPacket(packetInfo.Packet, serialized, true);
            }
        }

        return new ProcessedPacket(packetInfo.Packet, packetInfo.Packet, true);
    }

    /// <summary>
    /// Process the whole source and put the processed packets into the given destination.
    /// </summary>
    /// <param name="source">The source to get packets from.</param>
    /// <param name="destination">The destination to put processed packets into.</param>
    /// <param name="ct">The cancellation token for cancelling the operation.</param>
    /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
    public async Task<Result> ProcessSourceDestination(IPacketSource source, IPacketDestination destination, CancellationToken ct = default)
    {
        while (await source.TryGetNextPacketAsync(out var packet, ct))
        {
            var processedPacketResult = ProcessPacket(packet!);
            if (!processedPacketResult.IsDefined(out var processedPacket))
            {
                return Result.FromError(processedPacketResult);
            }

            if (processedPacket.Keep)
            {
                await destination.WritePacketAsync(processedPacket.NewPacketString);
            }
        }

        return Result.FromSuccess();
    }
}
Do not follow this link