using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using BotFramework.Attributes; using BotFramework.Enums; using Kruzya.TelegramBot.Core; using Kruzya.TelegramBot.Core.Data; using Kruzya.TelegramBot.Core.Extensions; using Kruzya.TelegramBot.Core.Service; using Telegram.Bot; using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.ReplyMarkups; namespace West.Entertainment.Handler; public class Guess : CommonHandler { private readonly IGuessCache _guessCache; private readonly ThreadSafeRandom _rng; private readonly IReputation _reputationService; private readonly CoreContext _db; public Guess(IGuessCache guessCache, ThreadSafeRandom rng, IReputation reputationService, CoreContext db) : base(db) { _guessCache = guessCache; _rng = rng; _reputationService = reputationService; _db = db; } [Command(InChat.Public, "guess", CommandParseMode.Both)] public async Task HandleGuess() { var cooldownOption = await _db.UserValues.FindOrCreateOption(Chat.Id, From.Id, "guessCooldown"); var cooldown = cooldownOption.GetValue(); if (cooldown > DateTime.Now) { await Reply($"Следующее использование через {cooldown - DateTime.Now:hh\\:mm\\:ss}."); return; } var guessDict = _guessCache.GetOr(Chat.Id, new ConcurrentDictionary()); var doesExist = guessDict.Any(pair => pair.Value.UserId == From.Id); if (doesExist) { await Bot.SendTextMessageAsync(Chat, "Вы уже запустили игру."); return; } var messageId = RawUpdate.Message!.MessageId; var guessedNumber = _rng.Next(1, 4); // Console.WriteLine(guessedNumber); var guessData = new GuessData { Number = guessedNumber, UserId = From.Id }; var keyBoard = new InlineKeyboardMarkup(new List { new("1") { CallbackData = $"guess|{From.Id}|answer|1" }, new("2") { CallbackData = $"guess|{From.Id}|answer|2" }, new("3") { CallbackData = $"guess|{From.Id}|answer|3" } }); var message = await Bot.SendTextMessageAsync(Chat.Id, "Выберите число от 1 до 3.", replyToMessageId: messageId, replyMarkup: keyBoard ); if (!guessDict.TryAdd(message.MessageId, guessData)) { return; } _guessCache.SetValue(Chat.Id, guessDict, -1); } [Update(InChat.Public, UpdateFlag.CallbackQuery)] public async Task HandleGuessResponse() { var messageId = CallbackQuery.Message?.MessageId; if (messageId == null || CallbackQuery.Data == null) { return; } var fromUser = CallbackQuery.From; var fromId = fromUser.Id; var callbackData = CallbackQuery.Data.Split('|'); if (callbackData.Length < 4 || callbackData[0] != "guess" || callbackData[1] != fromId.ToString() || callbackData[2] != "answer") { return; } var guessDict = _guessCache.GetOr(Chat.Id, new ConcurrentDictionary()); if (!guessDict.TryGetValue((int) messageId, out var data) || fromId != data.UserId) { return; } if (!int.TryParse(callbackData[3], out var responseNumber)) { return; } await Bot.AnswerCallbackQueryAsync(CallbackQuery.Id); guessDict.TryRemove((int) messageId, out _); _guessCache.SetValue(Chat.Id, guessDict, -1); var nextUse = DateTime.Now.AddHours(1); var postFix = $"\nСледующая попытка через: {nextUse - DateTime.Now:hh\\:mm\\:ss}"; string message; if (responseNumber == data.Number) { await _reputationService.IncrementReputationAsync(Chat, From, 20); message = $"{fromUser.ToHtml()} угадал! +20 кармы."; } else { message = $"{fromUser.ToHtml()} не угадал!\nЗагаданное число: {data.Number}."; } var cooldownOption = await _db.UserValues.FindOrCreateOption(Chat.Id, From.Id, "guessCooldown"); cooldownOption.SetValue(nextUse); _db.AddOrUpdate(cooldownOption); await Bot.EditMessageTextAsync(Chat, (int) messageId, message + postFix, parseMode: ParseMode.Html); } }