using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Configuration; using Telegram.Bot.Types; namespace Kruzya.TelegramBot.Core.Service; public class MemoryAntiFloodService : IAntiFlood { private IDictionary> _floodUsers; private IDictionary _bannedUsers; private int _floodStartsAfter = 3; private TimeSpan _banningTimeSpan; public MemoryAntiFloodService(IConfiguration configuration) { _floodUsers = new Dictionary>(); _bannedUsers = new Dictionary(); _floodStartsAfter = configuration.GetValue("FloodActions"); _banningTimeSpan = TimeSpan.FromMinutes(configuration.GetValue("FloodBanTime")); } public bool IsUserFlooding(Chat chat, User user) { var dictKey = DictKey(chat, user); if (_bannedUsers.TryGetValue(dictKey, out var expirationTime)) { if (DateTime.UtcNow <= expirationTime) { expirationTime = DateTime.MinValue; _bannedUsers.Remove(dictKey); } } return (DateTime.UtcNow < expirationTime); } public void RecordAction(Chat chat, User user) { var dictKey = DictKey(chat, user); if (!_floodUsers.TryGetValue(dictKey, out var actionTimeList)) { actionTimeList = new List(); } actionTimeList.Add(DateTime.UtcNow); actionTimeList = actionTimeList.Where(e => e.Subtract(_banningTimeSpan) <= DateTime.UtcNow).ToList(); _floodUsers[dictKey] = actionTimeList; if (actionTimeList.Count > _floodStartsAfter) { actionTimeList.Clear(); _bannedUsers[dictKey] = DateTime.UtcNow.Add(_banningTimeSpan); } } private string DictKey(Chat chat, User user) { return $"{chat.Id}-{user.Id}"; } }