using System; using System.Collections.Generic; using System.Linq; namespace SharpChat { public enum ChatRateLimitState { None, Warning, Kick, } public class ChatRateLimiter { private const int FLOOD_PROTECTION_AMOUNT = 30; private const int FLOOD_PROTECTION_THRESHOLD = 10; private readonly Queue TimePoints = new Queue(); public ChatRateLimitState State { get { lock (TimePoints) { if (TimePoints.Count == FLOOD_PROTECTION_AMOUNT) { if ((TimePoints.Last() - TimePoints.First()).TotalSeconds <= FLOOD_PROTECTION_THRESHOLD) return ChatRateLimitState.Kick; if ((TimePoints.Last() - TimePoints.Skip(5).First()).TotalSeconds <= FLOOD_PROTECTION_THRESHOLD) return ChatRateLimitState.Warning; } return ChatRateLimitState.None; } } } public void AddTimePoint(DateTimeOffset? dto = null) { if (!dto.HasValue) dto = DateTimeOffset.Now; lock (TimePoints) { if (TimePoints.Count >= FLOOD_PROTECTION_AMOUNT) TimePoints.Dequeue(); TimePoints.Enqueue(dto.Value); } } } }