mirror of
https://github.com/barelyprofessional/KfChatDotNet.git
synced 2026-04-30 03:22:04 -04:00
164 lines
7.3 KiB
C#
164 lines
7.3 KiB
C#
using System.Text.RegularExpressions;
|
|
using KfChatDotNetBot.Extensions;
|
|
using KfChatDotNetBot.Models;
|
|
using KfChatDotNetBot.Models.DbModels;
|
|
using KfChatDotNetBot.Services;
|
|
using KfChatDotNetBot.Settings;
|
|
using KfChatDotNetWsClient.Models.Events;
|
|
namespace KfChatDotNetBot.Commands.Kasino;
|
|
|
|
[KasinoCommand]
|
|
[WagerCommand]
|
|
public class RainCommand : ICommand
|
|
{
|
|
public List<Regex> Patterns => [
|
|
new Regex(@"^rain (?<amount>\d+(?:\.\d+)?)$", RegexOptions.IgnoreCase),
|
|
new Regex(@"^rain", RegexOptions.IgnoreCase)
|
|
];
|
|
|
|
public string? HelpText => "!rain <amount> to start a rain, !rain to join all active rains";
|
|
public UserRight RequiredRight => UserRight.Loser;
|
|
public TimeSpan Timeout => TimeSpan.FromSeconds(90);
|
|
public RateLimitOptionsModel? RateLimitOptions => null;
|
|
public bool WhisperCanInvoke => false;
|
|
|
|
public async Task RunCommand(ChatBot botInstance, BotCommandMessageModel message, UserDbModel user, GroupCollection arguments,
|
|
CancellationToken ctx)
|
|
{
|
|
var settings = await SettingsProvider.GetMultipleValuesAsync([
|
|
BuiltIn.Keys.KasinoGameDisabledMessageCleanupDelay, BuiltIn.Keys.KasinoRainCountdownDuration,
|
|
BuiltIn.Keys.KasinoRainEnabled
|
|
]);
|
|
|
|
// Check if rain is enabled
|
|
var rainEnabled = (settings[BuiltIn.Keys.KasinoRainEnabled]).ToBoolean();
|
|
if (!rainEnabled)
|
|
{
|
|
var gameDisabledCleanupDelay= TimeSpan.FromMilliseconds(settings[BuiltIn.Keys.KasinoGameDisabledMessageCleanupDelay].ToType<int>());
|
|
await botInstance.SendChatMessageAsync(
|
|
$"{user.FormatUsername()}, rain is currently disabled.",
|
|
true, autoDeleteAfter: gameDisabledCleanupDelay);
|
|
return;
|
|
}
|
|
|
|
var cleanupDelay = TimeSpan.FromSeconds(30);
|
|
if (botInstance.BotServices.KasinoRain == null || !botInstance.BotServices.KasinoRain.IsInitialized())
|
|
{
|
|
await botInstance.SendChatMessageAsync($"{user.FormatUsername()}, rain is not available at this time", true,
|
|
autoDeleteAfter: cleanupDelay);
|
|
return;
|
|
}
|
|
|
|
var rain = await botInstance.BotServices.KasinoRain.GetRainState();
|
|
var gambler = await Money.GetGamblerEntityAsync(user.Id, ct: ctx);
|
|
if (gambler == null)
|
|
{
|
|
throw new InvalidOperationException($"Caught a null when retrieving gambler for {user.KfUsername}");
|
|
}
|
|
if (!arguments.TryGetValue("amount", out var amount)) //if you're trying to join a rain
|
|
{
|
|
if (rain == null) //if there are no lobbies
|
|
{
|
|
await botInstance.SendChatMessageAsync(
|
|
$"{user.FormatUsername()}, there's no rain currently running. !rain <amount> to start a new rain",
|
|
true, autoDeleteAfter: cleanupDelay);
|
|
return;
|
|
}
|
|
|
|
if (rain.Participants.Contains(user.Id))
|
|
{
|
|
await botInstance.SendChatMessageAsync(
|
|
$"{user.FormatUsername()}, you're already participating in this rain!", true,
|
|
autoDeleteAfter: cleanupDelay);
|
|
return;
|
|
}
|
|
|
|
if (rain.Creator == user.Id)
|
|
{
|
|
await botInstance.SendChatMessageAsync(
|
|
$"{user.FormatUsername()}, you can't participate in your own rain!", true,
|
|
autoDeleteAfter: cleanupDelay);
|
|
return;
|
|
}
|
|
|
|
if ((DateTimeOffset.UtcNow - gambler.Created).TotalHours < 4)
|
|
{
|
|
await botInstance.SendChatMessageAsync($"{user.FormatUsername()}, you're too fresh for a rain", true, autoDeleteAfter: cleanupDelay);
|
|
return;
|
|
}
|
|
|
|
await botInstance.BotServices.KasinoRain.AddParticipant(user.Id);
|
|
var pluralSuffix = string.Empty;
|
|
if (rain.Participants.Count > 0) pluralSuffix = "s";
|
|
await botInstance.SendChatMessageAsync(
|
|
$"LFG {user.FormatUsername()} is now a participant! There's now {rain.Participants.Count + 1} participant{pluralSuffix}! Type [ditto]!rain[/ditto] to participate",
|
|
true, autoDeleteAfter: cleanupDelay);
|
|
return;
|
|
}
|
|
//if you're trying to start the rain
|
|
if (rain != null)
|
|
{
|
|
await botInstance.SendChatMessageAsync($"{user.FormatUsername()}, there's already a rain in progress.",
|
|
true, autoDeleteAfter: cleanupDelay);
|
|
return;
|
|
}
|
|
|
|
decimal decAmount = Convert.ToDecimal(amount.Value);
|
|
if (decAmount <= 0)
|
|
{
|
|
await botInstance.SendChatMessageAsync($"{user.FormatUsername()}, you can't make it rain with nothing.",
|
|
true, autoDeleteAfter: cleanupDelay);
|
|
return;
|
|
}
|
|
if (gambler.Balance < decAmount)
|
|
{
|
|
await botInstance.SendChatMessageAsync(
|
|
$"{user.FormatUsername()}, your balance {await gambler.Balance.FormatKasinoCurrencyAsync()} is not enough to make it rain for {await decAmount.FormatKasinoCurrencyAsync()}.",
|
|
true, autoDeleteAfter: cleanupDelay);
|
|
return;
|
|
}
|
|
|
|
var rainMin = (await SettingsProvider.GetValueAsync(BuiltIn.Keys.KasinoRainMinimum)).ToType<decimal>();
|
|
if (decAmount < rainMin)
|
|
{
|
|
await botInstance.SendChatMessageAsync($"{user.FormatUsername()}, rain at least {await rainMin.FormatKasinoCurrencyAsync()}", true,
|
|
autoDeleteAfter: cleanupDelay);
|
|
return;
|
|
}
|
|
|
|
rain = new KasinoRainModel
|
|
{
|
|
Participants = [],
|
|
Creator = user.Id,
|
|
Started = DateTimeOffset.UtcNow,
|
|
RainAmount = decAmount,
|
|
PayoutWhen = DateTimeOffset.MaxValue
|
|
};
|
|
var rainCountdown = settings[BuiltIn.Keys.KasinoRainCountdownDuration].ToType<int>();
|
|
var timer = rainCountdown;
|
|
var msg = await botInstance.SendChatMessageAsync(
|
|
$"🌧️🌧️ {user.FormatUsername()} is making it rain with {await decAmount.FormatKasinoCurrencyAsync()}! Type [ditto]!rain[/ditto] in the next {timer} seconds to join.",
|
|
true);
|
|
var result = await botInstance.WaitForChatMessageAsync(msg, ct: ctx);
|
|
if (!result)
|
|
{
|
|
throw new InvalidOperationException("Failed to send chat message for the rain. Not going to proceed with it");
|
|
}
|
|
|
|
// Wait to set a real payout deadline only when chyat echoes the message out of fairness
|
|
// (and also so the timer doesn't overlap with the payout deadline)
|
|
rain.PayoutWhen = DateTimeOffset.UtcNow.AddSeconds(rainCountdown);
|
|
await botInstance.BotServices.KasinoRain.SaveRainState(rain);
|
|
while (timer > 0)
|
|
{
|
|
timer--;
|
|
await Task.Delay(1000, ctx);
|
|
await botInstance.KfClient.EditMessageAsync(msg.ChatMessageUuid!,
|
|
$"🌧️🌧️ {user.FormatUsername()} is making it rain with {await decAmount.FormatKasinoCurrencyAsync()}! Type [ditto]!rain[/ditto] in the next {timer} seconds to join.");
|
|
}
|
|
|
|
await Task.Delay(100, ctx);
|
|
await botInstance.KfClient.DeleteMessageAsync(msg.ChatMessageUuid!);
|
|
// At this point the timer should take care of things but truthfully it's a disaster and probably won't work
|
|
}
|
|
} |