using BotFramework.Attributes; using BotFramework.Enums; using System.Threading.Tasks; using System; using System.Collections.Generic; using System.Linq; 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 Kruzya.TelegramBot.Core.AutoDelete; using System.Collections.Concurrent; using Telegram.Bot.Types.Enums; using Telegram.Bot.Types; using Microsoft.AspNetCore.Components.Forms; using Kruzya.TelegramBot.Core.Handler; namespace West.Entertainment.Handler; public class Roll : CommonHandler { private readonly ILogger _logger; private readonly ThreadSafeRandom _rng; private readonly IReputation _reputation; private readonly UserService _userService; private readonly ConcurrentBag _requests; [InChat(InChat.Public)] [Command("roll", CommandParseMode.Both)] public async Task HandleRoll() { var cdOption = await Db.UserValues.FindOrCreateOption(Chat.Id, From.Id, "rollNextUse"); var cd = cdOption.GetValue(); _logger.LogInformation("[{Datetime}] {User} used /roll in {Chat}. Cooldown is: {Cooldown}", DateTime.Now, From.ToLog(), Chat.ToLog(), cd ); // Drop user message. _requests.Add(new DeleteRequest { ChatId = Chat.Id, DeleteAt = DateTime.UtcNow.AddSeconds(20), MessageId = Message.MessageId }); if (cd > DateTime.Now) { await Reply($"Следующее использование через {cd - DateTime.Now:hh\\:mm\\:ss}."); return; } var newRep = _rng.Next(-20, 80); await Reply($"Вы получили {newRep} кармы."); await _reputation.IncrementReputationAsync(Chat, From, newRep); _logger.LogInformation("[{Datetime}] Added {Count} reputation to {User} in {Chat} from /roll", DateTime.Now, newRep, From.ToLog(), Chat.ToLog() ); cdOption.SetValue(DateTime.Now.AddDays(1)); Db.AddOrUpdate(cdOption); _logger.LogInformation("[{Datetime}] Updated /roll cooldown for {User} in {Chat} to {Cooldown}", DateTime.Now, From.ToLog(), Chat.ToLog(), cdOption.GetValue() ); } [InChat(InChat.Public)] [Command("reset_roll", CommandParseMode.Both)] public async Task HandleResetRoll() { if (!_userService.IsUserSuper(From)) { _logger.LogWarning("{User} attempted to use super-user command /reset_roll in {Chat}", From.ToLog(), Chat.ToLog() ); return; } var cooldownList = Db.UserValues .Where(q => q.BotUser.ChatId == Chat.Id && q.Name == "rollNextUse"); Db.UserValues.RemoveRange(cooldownList); await Db.SaveChangesAsync(); _logger.LogInformation("/roll cooldowns have been reset for {Chat} by {User}", Chat.ToLog(), From.ToLog()); await Reply($"Кулдаун /roll сброшен для чата \"{Chat.Title}\"."); } [InChat(InChat.Public)] [ParametrizedCommand("rng_test", CommandParseMode.Both)] public async Task HandleRngTest(int minValue, int maxValue) { if (!_userService.IsUserSuper(From)) { _logger.LogWarning("{User} attempted to use super-user command /rng_test in {Chat}", From.ToLog(), Chat.ToLog() ); return; } var positive = 0; var negative = 0; for (var i = 0; i < 100; i++) { var number = _rng.Next(minValue, maxValue); if (number > 0) { positive++; } else { negative++; } } await Bot.SendTextMessageAsync(Chat, $"Positive: {positive}.\nNegative: {negative}"); } protected override async Task Reply(string text) { // TODO: move feature with autocleaning to Core CommonHandler. var message = await Bot.SendTextMessageAsync(Chat.Id, text, replyToMessageId: Message?.MessageId, parseMode: ParseMode.Html); _requests.Add(new DeleteRequest { ChatId = Chat.Id, DeleteAt = DateTime.UtcNow.AddSeconds(20), MessageId = message.MessageId }); return message; } public Roll(CoreContext db, IReputation reputation, UserService userService, ILogger logger, ThreadSafeRandom rng, ConcurrentBag requests) : base(db) { _reputation = reputation; _userService = userService; _logger = logger; _rng = rng; _requests = requests; } }