#nullable enable using BotFramework.Attributes; using BotFramework.Enums; using BotFramework.Utils; using Kruzya.TelegramBot.Core; using Kruzya.TelegramBot.Core.Data; using Kruzya.TelegramBot.Core.Extensions; using Kruzya.TelegramBot.Core.Service; using Microsoft.Extensions.Logging; using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; namespace West.TelegramBot.Reputation.Handler; public class Reputation : CommonHandler { private readonly UserService _userService; private readonly ILogger _logger; private readonly IReputation _reputationService; private readonly IAntiFlood _antiFlood; private static readonly List RepUpChars = new() { "+", "👍", "👍🏼", "👍🏽", "👍🏾", "👍🏿", "👍🏻" }; private static readonly List RepDownChars = new() { "-", "👎", "👎🏼", "👎🏽", "👎🏾", "👎🏿", "👎🏻" }; public Reputation( CoreContext db, UserService userService, IReputation reputationService, IAntiFlood antiFlood, ILogger logger) : base(db) { _reputationService = reputationService; _userService = userService; _antiFlood = antiFlood; _logger = logger; } [Message(InChat.Public, MessageFlag.HasText | MessageFlag.HasSticker)] public async Task HandleReputation() { var text = Message?.Text; if (string.IsNullOrEmpty(text)) { text = Message?.Sticker?.Emoji; } if (text == null) { return; } var receiver = RepliedUser; var canChangeRep = receiver is { IsBot: false } && !From.IsBot && receiver.Id != From.Id; if (canChangeRep && (RepUpChars.Contains(text) || RepDownChars.Contains(text))) { 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() .Code("Ты не можешь голосовать с отрицательной репутацией.") .ToString() ); return; } var diff = await _reputationService.GetReputationDiffAsync(Chat, From, receiver); _logger.LogDebug("Calculated diff: {Diff}", diff); string action; if (RepUpChars.Contains(text)) { action = "увеличил"; } else { diff *= -1; action = "уменьшил"; } await _reputationService.IncrementReputationAsync(Chat, receiver, diff); var receiverRepCount = await GetUserReputation(receiver!); _logger.LogDebug("Updated value: {Value}", receiverRepCount); await Reply($"{From.ToHtml()}({await GetUserReputation(From)}) " + $"{action} репутацию {receiver.ToHtml()}({Math.Round(receiverRepCount, 2)})"); } } [ParametrizedCommand(InChat.Public, "setrep", CommandParseMode.Both)] public async Task HandleSetRep(double reputation) { if (!_userService.IsUserSuper(From)) { _logger.LogInformation("{User} attempted to call /setrep in {Chat}", From, Chat.Title); return; } if (RepliedUser == null || RepliedUser.IsBot) { return; } reputation = await _reputationService.SetUserReputationAsync(Chat, RepliedUser, reputation); await Reply( new HtmlString() .Code("Пользователю ") .UserMention(RepliedUser) .Code($" установлена репутация: {reputation}") .ToString() ); } [Command(InChat.Public, "top", CommandParseMode.Both)] public async Task HandleTop() { var msg = new HtmlString(); msg.TextBr("Топ репутации чата: "); var i = 1; foreach (var rep in await _reputationService.GetChatRatingAsync(Chat)) { var user = await _userService.GetUser(rep.UserId, rep.ChatId); msg.Text($"{i}. ").UserMention(user).Text($" ({rep.Value})").Br(); i++; } await Bot.SendTextMessageAsync(Chat!, msg.ToString(), ParseMode.Html, disableNotification: true); } private async Task GetUserReputation(User user) { return await _reputationService.GetUserReputationAsync(Chat, user); } }