@@ 11,6 11,7 @@ using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
+using NosSmooth.Core.Client;
using NosSmooth.Packets;
using NosSmooth.PacketSerializer.Abstractions.Attributes;
using Remora.Results;
@@ 32,15 33,28 @@ public class PacketHandler : IPacketHandler
}
/// <inheritdoc />
- public Task<Result> HandleReceivedPacketAsync(IPacket packet, string packetString, CancellationToken ct)
- => HandlePacketAsync(PacketSource.Server, packet, packetString, ct);
+ public Task<Result> HandleReceivedPacketAsync
+ (
+ INostaleClient client,
+ IPacket packet,
+ string packetString,
+ CancellationToken ct
+ )
+ => HandlePacketAsync(client, PacketSource.Server, packet, packetString, ct);
/// <inheritdoc />
- public Task<Result> HandleSentPacketAsync(IPacket packet, string packetString, CancellationToken ct)
- => HandlePacketAsync(PacketSource.Client, packet, packetString, ct);
+ public Task<Result> HandleSentPacketAsync
+ (
+ INostaleClient client,
+ IPacket packet,
+ string packetString,
+ CancellationToken ct
+ )
+ => HandlePacketAsync(client, PacketSource.Client, packet, packetString, ct);
private Task<Result> HandlePacketAsync
(
+ INostaleClient client,
PacketSource packetType,
IPacket packet,
string packetString,
@@ 59,16 73,23 @@ public class PacketHandler : IPacketHandler
}
var boundProcessMethod = processMethod.MakeGenericMethod(packet.GetType());
- return (Task<Result>)boundProcessMethod.Invoke(this, new object[]
- {
- packetType,
- packet,
- packetString,
- ct
- })!;
+ return (Task<Result>)boundProcessMethod.Invoke
+ (
+ this,
+ new object[]
+ {
+ client,
+ packetType,
+ packet,
+ packetString,
+ ct
+ }
+ )!;
}
- private async Task<Result> DispatchResponder<TPacket>(
+ private async Task<Result> DispatchResponder<TPacket>
+ (
+ INostaleClient client,
PacketSource packetType,
TPacket packet,
string packetString,
@@ 77,10 98,17 @@ public class PacketHandler : IPacketHandler
where TPacket : class, IPacket
{
using var scope = _provider.CreateScope();
+ var packetEventArgs = new PacketEventArgs<TPacket>(packetType, packet, packetString);
+
+ var preExecutionResult = await ExecuteBeforeExecutionAsync(scope.ServiceProvider, client, packetEventArgs, ct);
+ if (!preExecutionResult.IsSuccess)
+ {
+ return preExecutionResult;
+ }
+
var packetResponders = scope.ServiceProvider.GetServices<IPacketResponder<TPacket>>();
var genericPacketResponders = scope.ServiceProvider.GetServices<IEveryPacketResponder>();
- 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)));
@@ 95,6 123,12 @@ public class PacketHandler : IPacketHandler
}
}
+ var postExecutionResult = await ExecuteAfterExecutionAsync(scope.ServiceProvider, client, packetEventArgs, results, ct);
+ if (!postExecutionResult.IsSuccess)
+ {
+ errors.Add(postExecutionResult);
+ }
+
return errors.Count switch
{
0 => Result.FromSuccess(),
@@ 102,4 136,69 @@ public class PacketHandler : IPacketHandler
_ => new AggregateError(errors.Cast<IResult>().ToArray())
};
}
-}
+
+ private async Task<Result> ExecuteBeforeExecutionAsync<TPacket>
+ (
+ IServiceProvider services,
+ INostaleClient client,
+ PacketEventArgs<TPacket> eventArgs,
+ CancellationToken ct
+ )
+ where TPacket : IPacket
+ {
+ var results = await Task.WhenAll
+ (
+ services.GetServices<IPreExecutionEvent>()
+ .Select(x => x.ExecuteBeforeExecutionAsync(client, eventArgs, ct))
+ );
+
+ var errorResults = new List<Result>();
+ foreach (var result in results)
+ {
+ if (!result.IsSuccess)
+ {
+ errorResults.Add(result);
+ }
+ }
+
+ return errorResults.Count switch
+ {
+ 1 => errorResults[0],
+ 0 => Result.FromSuccess(),
+ _ => new AggregateError(errorResults.Cast<IResult>().ToArray())
+ };
+ }
+
+ private async Task<Result> ExecuteAfterExecutionAsync<TPacket>
+ (
+ IServiceProvider services,
+ INostaleClient client,
+ PacketEventArgs<TPacket> eventArgs,
+ IReadOnlyList<Result> executionResults,
+ CancellationToken ct
+ )
+ where TPacket : IPacket
+ {
+ var results = await Task.WhenAll
+ (
+ services.GetServices<IPostExecutionEvent>()
+ .Select(x => x.ExecuteAfterExecutionAsync(client, eventArgs, executionResults, ct))
+ );
+
+ var errorResults = new List<Result>();
+ foreach (var result in results)
+ {
+ if (!result.IsSuccess)
+ {
+ errorResults.Add(result);
+ }
+ }
+
+ return errorResults.Count switch
+ {
+ 1 => errorResults[0],
+ 0 => Result.FromSuccess(),
+ _ => new AggregateError(errorResults.Cast<IResult>().ToArray())
+ };
+ }
+}<
\ No newline at end of file