mirror of
https://github.com/Bubuni-Team/telegram-bot.git
synced 2026-07-31 00:29:24 +03:00
212 lines
6.3 KiB
C#
212 lines
6.3 KiB
C#
#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<string> RepUpChars = new()
|
|
{
|
|
"+",
|
|
"👍",
|
|
"👍🏼",
|
|
"👍🏽",
|
|
"👍🏾",
|
|
"👍🏿",
|
|
"👍🏻"
|
|
};
|
|
private static readonly List<string> RepDownChars = new()
|
|
{
|
|
"-",
|
|
"👎",
|
|
"👎🏼",
|
|
"👎🏽",
|
|
"👎🏾",
|
|
"👎🏿",
|
|
"👎🏻"
|
|
};
|
|
|
|
public Reputation(
|
|
CoreContext db,
|
|
UserService userService,
|
|
IReputation reputationService,
|
|
IAntiFlood antiFlood,
|
|
ILogger<Reputation> 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) && !await Bot.IsUserAdminAsync(Chat, From))
|
|
{
|
|
if (_antiFlood.IsUserFlooding(Chat, From))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_antiFlood.RecordAction(Chat, From);
|
|
if (_antiFlood.IsUserFlooding(Chat, From))
|
|
{
|
|
await Reply(new HtmlString()
|
|
.UserMention(From).Code(": пользователь отправлен в игнор.")
|
|
.ToString());
|
|
return;
|
|
}
|
|
}
|
|
|
|
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()}<code>({await GetUserReputation(From)}) " +
|
|
$"{action} репутацию </code>{receiver.ToHtml()}<code>({Math.Round(receiverRepCount, 2)})</code>");
|
|
}
|
|
}
|
|
|
|
[ParametrizedCommand(InChat.Public, "setrep", CommandParseMode.Both)]
|
|
public async Task HandleSetRep(double reputation)
|
|
{
|
|
if (!CanModifyUserReputation(RepliedUser))
|
|
{
|
|
return;
|
|
}
|
|
|
|
await SendReputationModifyResponse(
|
|
await _reputationService.SetUserReputationAsync(Chat, RepliedUser, reputation)
|
|
);
|
|
}
|
|
|
|
[ParametrizedCommand(InChat.Public, "addrep", CommandParseMode.Both)]
|
|
public async Task HandleAddRep(double reputation)
|
|
{
|
|
if (!CanModifyUserReputation(RepliedUser))
|
|
{
|
|
return;
|
|
}
|
|
|
|
await SendReputationModifyResponse(
|
|
await _reputationService.IncrementReputationAsync(Chat, RepliedUser, reputation)
|
|
);
|
|
}
|
|
|
|
[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))
|
|
{
|
|
// TODO: there are should be more correct fix, but I want to fix this now, West, 18:04, 07.05.2022
|
|
User user;
|
|
try
|
|
{
|
|
user = await _userService.GetUser(rep.UserId, rep.ChatId);
|
|
}
|
|
catch
|
|
{
|
|
continue;
|
|
}
|
|
|
|
msg.Text($"{i}. ")
|
|
.Text($"{user.FirstName} {user.LastName}".Trim().HtmlEncode())
|
|
.Text($" ({rep.Value})").Br();
|
|
i++;
|
|
}
|
|
|
|
await Bot.SendTextMessageAsync(Chat!, msg.ToString(), parseMode: ParseMode.Html,
|
|
disableNotification: true);
|
|
}
|
|
|
|
private async Task SendReputationModifyResponse(double reputation)
|
|
{
|
|
await Reply(
|
|
new HtmlString()
|
|
.Code("Пользователю ")
|
|
.UserMention(RepliedUser)
|
|
.Code($" установлена репутация: {reputation}")
|
|
.ToString()
|
|
);
|
|
}
|
|
|
|
private bool CanModifyUserReputation(User? user)
|
|
{
|
|
if (!_userService.IsUserSuper(From))
|
|
{
|
|
_logger.LogWarning("{User} attempted to modify reputation in {Chat}",
|
|
From.ToLog(),
|
|
Chat.ToLog()
|
|
);
|
|
return false;
|
|
}
|
|
|
|
return user is {IsBot: false};
|
|
}
|
|
|
|
private async Task<double> GetUserReputation(User user)
|
|
{
|
|
return await _reputationService.GetUserReputationAsync(Chat, user);
|
|
}
|
|
} |