#nullable enable using System; using System.Collections.Generic; using System.Threading.Tasks; using BotFramework.Attributes; using BotFramework.Enums; using BotFramework.Utils; 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.ChatManagement.Handler { public class Reputation : ManagementHandler { private readonly UserService _userService; private readonly ILogger _logger; private static readonly List RepUpChars = new() { "+", "👍", "👍🏼", "👍🏽", "👍🏾", "👍🏿", "👍🏻" }; private static readonly List RepDownChars = new() { "-", "👎", "👎🏼", "👎🏽", "👎🏾", "👎🏿", "👎🏻" }; public Reputation(CoreContext db, UserService userService, ILogger logger) : base(db) { _userService = userService; _logger = logger; } [Command("whois", CommandParseMode.Both)] public async Task HandleWhois() { var user = RepliedUser ?? From; var message = $"{user.ToHtml()}\n"; if (user.IsBot) { message += "Бот"; } else { message += $"{await GetChatMemberStatusString(user)}\n"; message += $"Репутация: {await GetUserReputation(user)}\n"; message += $"Предупреждения: {(await GetWarnOption(user)).GetValue()}"; } await Reply(message); } [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))) { var receiverRepOption = await GetReputationOption(receiver!); var receiverRepCount = receiverRepOption.GetValue(); var senderRepCount = (await GetReputationOption(From)).GetValue(); if (senderRepCount < 0) { await Reply(new HtmlString() .Code("Ты не можешь голосовать с отрицательной репутацией.") .ToString() ); return; } var diff = Math.Round(senderRepCount == 0 ? 1 : Math.Sqrt(senderRepCount), 2); string action; if (RepUpChars.Contains(text)) { receiverRepCount += diff; action = "увеличил"; } else { receiverRepCount -= diff; action = "уменьшил"; } receiverRepOption.SetValue(receiverRepCount); Db.MarkAsModified(receiverRepOption); 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 = Math.Round(reputation, 2); var opt = await GetReputationOption(RepliedUser); opt.SetValue(reputation); Db.MarkAsModified(opt); await Reply( new HtmlString() .Code("Пользователю ") .UserMention(RepliedUser) .Code($" установлена репутация: {reputation}") .ToString() ); } private async Task GetUserReputation(User user) { return Math.Round((await GetReputationOption(user)).GetValue(), 2); } private async Task GetReputationOption(User user) { return await Db.UserValues.FindOrCreateOption(Chat.Id, user.Id, "reputation"); } private async Task GetChatMemberStatusString(User user) { var chatMember = await Bot.GetChatMemberAsync(Chat.Id, user.Id); var customStatus = _userService.GetUserCustomStatus(user.Id); if (customStatus != null) { return customStatus; } return chatMember.Status switch { ChatMemberStatus.Creator => "Владелец", ChatMemberStatus.Restricted => "Заблокированный", ChatMemberStatus.Administrator => "Администратор", _ => "Пользователь" }; } } }