2023-01-18 02:07:48 +02:00
|
|
|
using System;
|
|
|
|
|
using System.Collections.Concurrent;
|
2023-01-18 15:49:51 +02:00
|
|
|
using System.Collections.Generic;
|
2023-01-18 02:07:48 +02:00
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using BotFramework.Attributes;
|
|
|
|
|
using BotFramework.Enums;
|
|
|
|
|
using Kruzya.TelegramBot.Core;
|
2023-01-29 10:05:44 +03:00
|
|
|
using Kruzya.TelegramBot.Core.AutoDelete;
|
2023-01-18 02:07:48 +02:00
|
|
|
using Kruzya.TelegramBot.Core.Data;
|
|
|
|
|
using Kruzya.TelegramBot.Core.Extensions;
|
|
|
|
|
using Kruzya.TelegramBot.Core.Service;
|
|
|
|
|
using Telegram.Bot;
|
2023-01-29 10:11:55 +03:00
|
|
|
using Telegram.Bot.Types;
|
2023-01-18 15:49:51 +02:00
|
|
|
using Telegram.Bot.Types.Enums;
|
|
|
|
|
using Telegram.Bot.Types.ReplyMarkups;
|
2023-01-18 02:07:48 +02:00
|
|
|
|
|
|
|
|
namespace West.Entertainment.Handler;
|
|
|
|
|
|
|
|
|
|
public class Guess : CommonHandler
|
|
|
|
|
{
|
|
|
|
|
private readonly IGuessCache _guessCache;
|
|
|
|
|
private readonly ThreadSafeRandom _rng;
|
|
|
|
|
private readonly IReputation _reputationService;
|
|
|
|
|
private readonly CoreContext _db;
|
2023-01-29 10:05:44 +03:00
|
|
|
private readonly ConcurrentBag<DeleteRequest> _requests;
|
2023-01-18 02:07:48 +02:00
|
|
|
|
2023-01-29 10:05:44 +03:00
|
|
|
public Guess(IGuessCache guessCache, ThreadSafeRandom rng, IReputation reputationService, CoreContext db, ConcurrentBag<DeleteRequest> requests) : base(db)
|
2023-01-18 02:07:48 +02:00
|
|
|
{
|
|
|
|
|
_guessCache = guessCache;
|
|
|
|
|
_rng = rng;
|
|
|
|
|
_reputationService = reputationService;
|
|
|
|
|
_db = db;
|
2023-01-29 10:05:44 +03:00
|
|
|
_requests = requests;
|
2023-01-18 02:07:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Command(InChat.Public, "guess", CommandParseMode.Both)]
|
|
|
|
|
public async Task HandleGuess()
|
|
|
|
|
{
|
2023-01-29 10:11:55 +03:00
|
|
|
// Drop user message.
|
|
|
|
|
_requests.Add(new DeleteRequest
|
|
|
|
|
{
|
|
|
|
|
ChatId = Chat.Id,
|
|
|
|
|
DeleteAt = DateTime.UtcNow.AddSeconds(20),
|
|
|
|
|
MessageId = Message.MessageId
|
|
|
|
|
});
|
|
|
|
|
|
2023-01-18 02:07:48 +02:00
|
|
|
var cooldownOption = await _db.UserValues.FindOrCreateOption(Chat.Id, From.Id, "guessCooldown");
|
|
|
|
|
var cooldown = cooldownOption.GetValue<DateTime>();
|
2023-01-18 16:03:41 +02:00
|
|
|
if (cooldown > DateTime.Now)
|
|
|
|
|
{
|
|
|
|
|
await Reply($"Следующее использование через {cooldown - DateTime.Now:hh\\:mm\\:ss}.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-01-18 02:07:48 +02:00
|
|
|
|
2023-01-18 02:20:37 +02:00
|
|
|
var guessDict = _guessCache.GetOr(Chat.Id, new ConcurrentDictionary<int, GuessData>());
|
|
|
|
|
|
2023-01-18 02:07:48 +02:00
|
|
|
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);
|
2023-01-18 15:49:51 +02:00
|
|
|
// Console.WriteLine(guessedNumber);
|
2023-01-18 02:07:48 +02:00
|
|
|
var guessData = new GuessData
|
|
|
|
|
{
|
|
|
|
|
Number = guessedNumber,
|
|
|
|
|
UserId = From.Id
|
|
|
|
|
};
|
2023-01-18 15:49:51 +02:00
|
|
|
|
|
|
|
|
var keyBoard = new InlineKeyboardMarkup(new List<InlineKeyboardButton>
|
|
|
|
|
{
|
|
|
|
|
new("1") { CallbackData = $"guess|{From.Id}|answer|1" },
|
|
|
|
|
new("2") { CallbackData = $"guess|{From.Id}|answer|2" },
|
|
|
|
|
new("3") { CallbackData = $"guess|{From.Id}|answer|3" }
|
|
|
|
|
});
|
2023-01-18 02:07:48 +02:00
|
|
|
|
2023-01-18 15:49:51 +02:00
|
|
|
var message = await Bot.SendTextMessageAsync(Chat.Id, "Выберите число от 1 до 3.",
|
|
|
|
|
replyToMessageId: messageId,
|
|
|
|
|
replyMarkup: keyBoard
|
|
|
|
|
);
|
|
|
|
|
|
2023-01-18 02:07:48 +02:00
|
|
|
if (!guessDict.TryAdd(message.MessageId, guessData))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
_guessCache.SetValue(Chat.Id, guessDict, -1);
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-18 15:49:51 +02:00
|
|
|
[Update(InChat.Public, UpdateFlag.CallbackQuery)]
|
2023-01-18 02:07:48 +02:00
|
|
|
public async Task HandleGuessResponse()
|
|
|
|
|
{
|
2023-01-18 15:49:51 +02:00
|
|
|
var messageId = CallbackQuery.Message?.MessageId;
|
2023-01-18 16:29:18 +02:00
|
|
|
if (messageId == null || CallbackQuery.Data == null)
|
2023-01-18 15:49:51 +02:00
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-01-18 16:29:18 +02:00
|
|
|
|
2023-01-18 15:49:51 +02:00
|
|
|
var fromUser = CallbackQuery.From;
|
|
|
|
|
var fromId = fromUser.Id;
|
|
|
|
|
var callbackData = CallbackQuery.Data.Split('|');
|
|
|
|
|
|
2023-01-18 16:29:18 +02:00
|
|
|
if (callbackData.Length < 4
|
|
|
|
|
|| callbackData[0] != "guess"
|
|
|
|
|
|| callbackData[1] != fromId.ToString()
|
|
|
|
|
|| callbackData[2] != "answer")
|
2023-01-18 02:07:48 +02:00
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-18 16:29:18 +02:00
|
|
|
var guessDict = _guessCache.GetOr(Chat.Id, new ConcurrentDictionary<int, GuessData>());
|
|
|
|
|
if (!guessDict.TryGetValue((int) messageId, out var data)
|
|
|
|
|
|| fromId != data.UserId)
|
2023-01-18 02:07:48 +02:00
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-18 15:49:51 +02:00
|
|
|
if (!int.TryParse(callbackData[3], out var responseNumber))
|
2023-01-18 02:07:48 +02:00
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-18 15:49:51 +02:00
|
|
|
await Bot.AnswerCallbackQueryAsync(CallbackQuery.Id);
|
|
|
|
|
|
|
|
|
|
guessDict.TryRemove((int) messageId, out _);
|
2023-01-18 02:07:48 +02:00
|
|
|
_guessCache.SetValue(Chat.Id, guessDict, -1);
|
|
|
|
|
|
2023-01-18 17:17:28 +02:00
|
|
|
var now = DateTime.Now;
|
|
|
|
|
var nextUse = now.AddHours(1);
|
|
|
|
|
var postFix = $"\nЗагаданное число: {data.Number}.\nСледующая попытка через: {nextUse - now:hh\\:mm\\:ss}";
|
2023-01-18 02:07:48 +02:00
|
|
|
|
|
|
|
|
string message;
|
|
|
|
|
if (responseNumber == data.Number)
|
|
|
|
|
{
|
|
|
|
|
await _reputationService.IncrementReputationAsync(Chat, From, 20);
|
2023-01-18 16:51:07 +02:00
|
|
|
message = $"{fromUser.ToHtml()} угадал! +20 кармы.\n";
|
2023-01-18 02:07:48 +02:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-01-18 16:51:07 +02:00
|
|
|
message = $"{fromUser.ToHtml()} не угадал!\n\nОтвет: {responseNumber}.";
|
2023-01-18 02:07:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var cooldownOption = await _db.UserValues.FindOrCreateOption(Chat.Id, From.Id, "guessCooldown");
|
|
|
|
|
cooldownOption.SetValue(nextUse);
|
2023-01-18 16:29:18 +02:00
|
|
|
|
2023-01-18 02:07:48 +02:00
|
|
|
_db.AddOrUpdate(cooldownOption);
|
2023-01-18 16:29:18 +02:00
|
|
|
|
|
|
|
|
await Bot.EditMessageTextAsync(Chat, (int) messageId, message + postFix, parseMode: ParseMode.Html);
|
2023-01-29 10:05:44 +03:00
|
|
|
|
|
|
|
|
// Drop bot message.
|
|
|
|
|
_requests.Add(new DeleteRequest
|
|
|
|
|
{
|
|
|
|
|
ChatId = Chat.Id,
|
|
|
|
|
DeleteAt = DateTime.UtcNow.AddSeconds(20),
|
|
|
|
|
MessageId = (int) messageId
|
|
|
|
|
});
|
2023-01-18 02:07:48 +02:00
|
|
|
}
|
2023-01-29 10:11:55 +03:00
|
|
|
|
|
|
|
|
protected override async Task<Message> 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;
|
|
|
|
|
}
|
2023-01-18 02:07:48 +02:00
|
|
|
}
|