mirror of
https://github.com/Bubuni-Team/telegram-bot.git
synced 2026-07-31 00:29:24 +03:00
Merge pull request #26 from Bubuni-Team/feature/entertainment/guess-game
[entertainment] add guess game
This commit is contained in:
@@ -6,5 +6,6 @@ namespace Kruzya.TelegramBot.Core.Cache
|
|||||||
{
|
{
|
||||||
public bool TryGetValue(TKey key, out TValue value);
|
public bool TryGetValue(TKey key, out TValue value);
|
||||||
public void SetValue(TKey key, TValue value, int timeToLive);
|
public void SetValue(TKey key, TValue value, int timeToLive);
|
||||||
|
public TValue GetOr(TKey key, TValue value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,6 +72,17 @@ namespace Kruzya.TelegramBot.Core.Cache
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TValue GetOr(TKey key, TValue defValue = default)
|
||||||
|
{
|
||||||
|
var doesExist = TryGetValue(key, out var value);
|
||||||
|
if (!doesExist)
|
||||||
|
{
|
||||||
|
value = defValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
public void SetValue(TKey key, TValue value)
|
public void SetValue(TKey key, TValue value)
|
||||||
{
|
{
|
||||||
SetValue(key, value, _defaultTtl);
|
SetValue(key, value, _defaultTtl);
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
using Kruzya.TelegramBot.Core;
|
global using IGuessCache = Kruzya.TelegramBot.Core.Cache.ICacheStorage<Telegram.Bot.Types.ChatId, System.Collections.Concurrent.ConcurrentDictionary<int, West.Entertainment.Handler.GuessData>>;
|
||||||
|
global using GuessCache = Kruzya.TelegramBot.Core.Cache.MemoryCache<Telegram.Bot.Types.ChatId, System.Collections.Concurrent.ConcurrentDictionary<int, West.Entertainment.Handler.GuessData>>;
|
||||||
|
|
||||||
|
|
||||||
|
using Kruzya.TelegramBot.Core;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
|
||||||
namespace West.Entertainment
|
namespace West.Entertainment
|
||||||
{
|
{
|
||||||
public class Entertainment : Module
|
public class Entertainment : Module
|
||||||
{
|
{
|
||||||
public Entertainment(Core core) : base(core) { }
|
public Entertainment(Core core) : base(core) { }
|
||||||
|
|
||||||
|
public override void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddSingleton<IGuessCache, GuessCache>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
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;
|
||||||
|
|
||||||
|
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<DateTime>();
|
||||||
|
if (cooldown > DateTime.Now)
|
||||||
|
{
|
||||||
|
await Reply($"Следующее использование через {cooldown - DateTime.Now:hh\\:mm\\:ss}.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var guessDict = _guessCache.GetOr(Chat.Id, new ConcurrentDictionary<int, GuessData>());
|
||||||
|
|
||||||
|
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 message = await Bot.SendTextMessageAsync(Chat.Id, "Выберите число от 1 до 3.", replyToMessageId: messageId);
|
||||||
|
if (!guessDict.TryAdd(message.MessageId, guessData))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_guessCache.SetValue(Chat.Id, guessDict, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Message(InChat.Public, MessageFlag.IsReply)]
|
||||||
|
public async Task HandleGuessResponse()
|
||||||
|
{
|
||||||
|
var guessDict = _guessCache.GetOr(Chat.Id, new ConcurrentDictionary<int, GuessData>());
|
||||||
|
var messageId = RawUpdate.Message!.ReplyToMessage!.MessageId;
|
||||||
|
if (!guessDict.TryGetValue(messageId, out var data))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (From.Id != data.UserId)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!int.TryParse(RawUpdate.Message!.Text, out var responseNumber))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
guessDict.TryRemove(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 = "Вы угадали! Вам начислено 20 кармы.";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message = "Вы не угадали!";
|
||||||
|
}
|
||||||
|
|
||||||
|
await Bot.SendTextMessageAsync(Chat, message + postFix);
|
||||||
|
|
||||||
|
var cooldownOption = await _db.UserValues.FindOrCreateOption(Chat.Id, From.Id, "guessCooldown");
|
||||||
|
cooldownOption.SetValue(nextUse);
|
||||||
|
|
||||||
|
_db.AddOrUpdate(cooldownOption);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using Telegram.Bot.Types;
|
||||||
|
|
||||||
|
namespace West.Entertainment.Handler;
|
||||||
|
|
||||||
|
public class GuessData
|
||||||
|
{
|
||||||
|
public long UserId { get; set; }
|
||||||
|
public int Number { get; set; }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user