~ruther/NosSmooth

11c5d9f159e5de5d2b70b363b405d7598632fa73 — František Boháček 3 years ago 91a0bbc
feat: pass event args to packet responders instead of plain packets
M Core/NosSmooth.Core/Packets/IPacketHandler.cs => Core/NosSmooth.Core/Packets/IPacketHandler.cs +4 -2
@@ 20,15 20,17 @@ public interface IPacketHandler
    /// Calls a responder for the given packet.
    /// </summary>
    /// <param name="packet">The packet.</param>
    /// <param name="packetString">The string of the packet.</param>
    /// <param name="ct">The cancellation token for cancelling the operation.</param>
    /// <returns>A result that may or may not have succeeded.</returns>
    public Task<Result> HandleReceivedPacketAsync(IPacket packet, CancellationToken ct = default);
    public Task<Result> HandleReceivedPacketAsync(IPacket packet, string packetString, CancellationToken ct = default);

    /// <summary>
    /// Calls a responder for the given packet.
    /// </summary>
    /// <param name="packet">The packet.</param>
    /// <param name="packetString">The string of the packet.</param>
    /// <param name="ct">The cancellation token for cancelling the operation.</param>
    /// <returns>A result that may or may not have succeeded.</returns>
    public Task<Result> HandleSentPacketAsync(IPacket packet, CancellationToken ct = default);
    public Task<Result> HandleSentPacketAsync(IPacket packet, string packetString, CancellationToken ct = default);
}
\ No newline at end of file

M Core/NosSmooth.Core/Packets/IPacketResponder.cs => Core/NosSmooth.Core/Packets/IPacketResponder.cs +2 -2
@@ 32,7 32,7 @@ public interface IPacketResponder<TPacket> : IPacketResponder
    /// <param name="packet">The packet to respond to.</param>
    /// <param name="ct">The cancellation token for cancelling the operation.</param>
    /// <returns>A result that may or may not have succeeded.</returns>
    public Task<Result> Respond(TPacket packet, CancellationToken ct = default);
    public Task<Result> Respond(PacketEventArgs<TPacket> packet, CancellationToken ct = default);
}

/// <summary>


@@ 47,6 47,6 @@ public interface IEveryPacketResponder : IPacketResponder
    /// <param name="ct">The cancellation token for cancelling the operation.</param>
    /// <typeparam name="TPacket">The type of the packet.</typeparam>
    /// <returns>A result that may or may not have succeeded.</returns>
    public Task<Result> Respond<TPacket>(TPacket packet, CancellationToken ct = default)
    public Task<Result> Respond<TPacket>(PacketEventArgs<TPacket> packet, CancellationToken ct = default)
        where TPacket : IPacket;
}
\ No newline at end of file

M Core/NosSmooth.Core/Packets/PacketHandler.cs => Core/NosSmooth.Core/Packets/PacketHandler.cs +28 -8
@@ 31,12 31,20 @@ public class PacketHandler : IPacketHandler
    }

    /// <inheritdoc />
    public Task<Result> HandleReceivedPacketAsync(IPacket packet, CancellationToken ct) => HandlePacketAsync(packet, ct);
    public Task<Result> HandleReceivedPacketAsync(IPacket packet, string packetString, CancellationToken ct)
        => HandlePacketAsync(PacketType.Received, packet, packetString, ct);

    /// <inheritdoc />
    public Task<Result> HandleSentPacketAsync(IPacket packet, CancellationToken ct) => HandlePacketAsync(packet, ct);
    public Task<Result> HandleSentPacketAsync(IPacket packet, string packetString, CancellationToken ct)
        => HandlePacketAsync(PacketType.Sent, packet, packetString, ct);

    private Task<Result> HandlePacketAsync(IPacket packet, CancellationToken ct = default)
    private Task<Result> HandlePacketAsync
    (
        PacketType packetType,
        IPacket packet,
        string packetString,
        CancellationToken ct = default
    )
    {
        var processMethod = GetType().GetMethod
        (


@@ 50,18 58,30 @@ public class PacketHandler : IPacketHandler
        }

        var boundProcessMethod = processMethod.MakeGenericMethod(packet.GetType());
        return (Task<Result>)boundProcessMethod.Invoke(this, new object[] { packet, ct })!;
        return (Task<Result>)boundProcessMethod.Invoke(this, new object[]
        {
            packetType,
            packet,
            packetString,
            ct
        })!;
    }

    private async Task<Result> DispatchResponder<TPacket>(TPacket packet, CancellationToken ct)
    private async Task<Result> DispatchResponder<TPacket>(
        PacketType packetType,
        TPacket packet,
        string packetString,
        CancellationToken ct
    )
        where TPacket : class, IPacket
    {
        using var scope = _provider.CreateScope();
        var packetResponders = scope.ServiceProvider.GetServices<IPacketResponder<TPacket>>();
        var genericPacketResponders = scope.ServiceProvider.GetServices<IEveryPacketResponder>();

        var tasks = packetResponders.Select(responder => responder.Respond(packet, ct)).ToList();
        tasks.AddRange(genericPacketResponders.Select(responder => responder.Respond(packet, ct)));
        var packetEventArgs = new PacketEventArgs<TPacket>(packetType, packet, packetString);
        var tasks = packetResponders.Select(responder => responder.Respond(packetEventArgs, ct)).ToList();
        tasks.AddRange(genericPacketResponders.Select(responder => responder.Respond(packetEventArgs, ct)));

        var results = await Task.WhenAll(tasks);



@@ 78,7 98,7 @@ public class PacketHandler : IPacketHandler
        {
            0 => Result.FromSuccess(),
            1 => errors[0],
            _ => new AggregateError(errors.Cast<IResult>().ToList())
            _ => new AggregateError(errors.Cast<IResult>().ToArray())
        };
    }
}
\ No newline at end of file

M Local/NosSmooth.LocalClient/NostaleLocalClient.cs => Local/NosSmooth.LocalClient/NostaleLocalClient.cs +5 -9
@@ 9,6 9,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NosSmooth.Core.Client;
using NosSmooth.Core.Commands;
using NosSmooth.Core.Extensions;
using NosSmooth.Core.Packets;
using NosSmoothCore;
using Remora.Results;


@@ 170,22 171,17 @@ public class NostaleLocalClient : BaseNostaleClient
        Result result;
        if (type == PacketType.Received)
        {
            result = await _packetHandler.HandleReceivedPacketAsync(packet.Entity);
            result = await _packetHandler.HandleReceivedPacketAsync(packet.Entity, packetString);
        }
        else
        {
            result = await _packetHandler.HandleSentPacketAsync(packet.Entity);
            result = await _packetHandler.HandleSentPacketAsync(packet.Entity, packetString);
        }

        if (!result.IsSuccess)
        {
            _logger.LogWarning($"There was an error whilst handling packet {packetString}. Error: {result.Error.Message}");
            _logger.LogError("There was an error whilst handling packet");
            _logger.LogResultError(result);
        }
    }

    private enum PacketType
    {
        Sent,
        Received,
    }
}
\ No newline at end of file

M Samples/SimpleChat/SayResponder.cs => Samples/SimpleChat/SayResponder.cs +3 -3
@@ 31,7 31,7 @@ public class SayResponder : IPacketResponder<SayPacket>, IPacketResponder<MsgPac
    }

    /// <inheritdoc />
    public Task<Result> Respond(SayPacket packet, CancellationToken ct = default)
    public Task<Result> Respond(PacketEventArgs<SayPacket> packet, CancellationToken ct = default)
    {
        return _client.ReceivePacketAsync(
            new SayPacket()


@@ 41,8 41,8 @@ public class SayResponder : IPacketResponder<SayPacket>, IPacketResponder<MsgPac
            ct);
    }

    /// <inheritdoc/>
    public Task<Result> Respond(MsgPacket packet, CancellationToken ct = default)
    /// <inheritdoc />
    public Task<Result> Respond(PacketEventArgs<MsgPacket> packet, CancellationToken ct = default)
    {
        return _client.ReceivePacketAsync(
            new SayPacket()

Do not follow this link