using Common.Utils; using Microsoft.AspNetCore.SignalR; using System.Collections.Concurrent; namespace ChessGameHost.Middleware { public class MovementFilter : IHubFilter { public async ValueTask InvokeMethodAsync( HubInvocationContext context, Func> next) { var arguments = context.HubMethodArguments; { //if (context.HubMethodName == "ChangeUserData" ) //{ // var obj = arguments[0].ToJson().ToObject(); // if (obj.Type == 8 || obj.Type == 6 || obj.Type == 7 || obj.Type == 4) // { // if (!RateLimiter.Allow(context.Context.ConnectionId)) // { // } // } //} } return await next(context); } } public static class RateLimiter { private static readonly ConcurrentDictionary _rates = new(); public static bool Allow(string connectionId) { var now = DateTime.UtcNow; var rate = _rates.GetOrAdd(connectionId, id => new RateData()); if (rate.Tokens < 30) { rate.Tokens++; rate.LastUpdate = now; return true; } if ((now - rate.LastUpdate).TotalMilliseconds > 33) { rate.Tokens = 1; rate.LastUpdate = now; return true; } return false; } private class RateData { public int Tokens { get; set; } = 30; public DateTime LastUpdate { get; set; } = DateTime.UtcNow; } } }