mirror of
https://github.com/Bubuni-Team/telegram-bot.git
synced 2026-07-31 00:29:24 +03:00
Merge branch 'feature/antiflood' into dev
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace Kruzya.TelegramBot.Core.Service;
|
||||
|
||||
public interface IAntiFlood
|
||||
{
|
||||
public bool IsUserFlooding(Chat chat, User user);
|
||||
public void RecordAction(Chat chat, User user);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
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<string, IList<DateTime>> _floodUsers;
|
||||
private IDictionary<string, DateTime> _bannedUsers;
|
||||
private int _floodStartsAfter = 3;
|
||||
private TimeSpan _banningTimeSpan;
|
||||
|
||||
public MemoryAntiFloodService(IConfiguration configuration)
|
||||
{
|
||||
_floodUsers = new Dictionary<string, IList<DateTime>>();
|
||||
_bannedUsers = new Dictionary<string, DateTime>();
|
||||
_floodStartsAfter = configuration.GetValue<int>("FloodActions");
|
||||
_banningTimeSpan = TimeSpan.FromMinutes(configuration.GetValue<double>("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<DateTime>();
|
||||
}
|
||||
|
||||
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}";
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,7 @@ namespace Kruzya.TelegramBot.Core
|
||||
services.AddSingleton<ICacheStorage<long, User>, MemoryCache<long, User>>();
|
||||
|
||||
services.AddSingleton<UserService>();
|
||||
services.AddSingleton<IAntiFlood, MemoryAntiFloodService>();
|
||||
|
||||
// Trigger module handlers.
|
||||
_core.Modules.ConfigureServices(services);
|
||||
|
||||
@@ -19,6 +19,7 @@ public class Reputation : CommonHandler
|
||||
private readonly UserService _userService;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IReputation _reputationService;
|
||||
private readonly IAntiFlood _antiFlood;
|
||||
|
||||
private static readonly List<string> RepUpChars = new()
|
||||
{
|
||||
@@ -45,10 +46,12 @@ public class Reputation : CommonHandler
|
||||
CoreContext db,
|
||||
UserService userService,
|
||||
IReputation reputationService,
|
||||
IAntiFlood antiFlood,
|
||||
ILogger<Reputation> logger) : base(db)
|
||||
{
|
||||
_reputationService = reputationService;
|
||||
_userService = userService;
|
||||
_antiFlood = antiFlood;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@@ -71,8 +74,17 @@ public class Reputation : CommonHandler
|
||||
|
||||
if (canChangeRep && (RepUpChars.Contains(text) || RepDownChars.Contains(text)))
|
||||
{
|
||||
var senderRepCount = await GetUserReputation(From);
|
||||
if (!_userService.IsUserSuper(From))
|
||||
{
|
||||
if (_antiFlood.IsUserFlooding(Chat, From))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_antiFlood.RecordAction(Chat, From);
|
||||
}
|
||||
|
||||
var senderRepCount = await GetUserReputation(From);
|
||||
if (senderRepCount < 0)
|
||||
{
|
||||
await Reply(new HtmlString()
|
||||
@@ -143,7 +155,7 @@ public class Reputation : CommonHandler
|
||||
i++;
|
||||
}
|
||||
|
||||
await Bot.SendTextMessageAsync(Chat, msg.ToString(), ParseMode.Html,
|
||||
await Bot.SendTextMessageAsync(Chat!, msg.ToString(), ParseMode.Html,
|
||||
disableNotification: true);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user