mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-12 18:28:27 -04:00
Gambling moved to a separate project. Project builds
This commit is contained in:
228
src/Nadeko.Bot.Modules.Gambling/Gambling/Slot/SlotCommands.cs
Normal file
228
src/Nadeko.Bot.Modules.Gambling/Gambling/Slot/SlotCommands.cs
Normal file
@@ -0,0 +1,228 @@
|
||||
#nullable disable warnings
|
||||
using NadekoBot.Db.Models;
|
||||
using NadekoBot.Modules.Gambling.Common;
|
||||
using NadekoBot.Modules.Gambling.Services;
|
||||
using SixLabors.Fonts;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Drawing.Processing;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using System.Text;
|
||||
using Nadeko.Econ.Gambling;
|
||||
using NadekoBot.Common.TypeReaders;
|
||||
using Color = SixLabors.ImageSharp.Color;
|
||||
using Image = SixLabors.ImageSharp.Image;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling;
|
||||
|
||||
public enum GamblingError
|
||||
{
|
||||
InsufficientFunds,
|
||||
}
|
||||
|
||||
public partial class Gambling
|
||||
{
|
||||
[Group]
|
||||
public partial class SlotCommands : GamblingSubmodule<IGamblingService>
|
||||
{
|
||||
private static decimal totalBet;
|
||||
private static decimal totalPaidOut;
|
||||
|
||||
private readonly IImageCache _images;
|
||||
private readonly FontProvider _fonts;
|
||||
private readonly DbService _db;
|
||||
private object _slotStatsLock = new();
|
||||
|
||||
public SlotCommands(
|
||||
IImageCache images,
|
||||
FontProvider fonts,
|
||||
DbService db,
|
||||
GamblingConfigService gamb)
|
||||
: base(gamb)
|
||||
{
|
||||
_images = images;
|
||||
_fonts = fonts;
|
||||
_db = db;
|
||||
}
|
||||
|
||||
public Task Test()
|
||||
=> Task.CompletedTask;
|
||||
|
||||
[Cmd]
|
||||
public async Task Slot([OverrideTypeReader(typeof(BalanceTypeReader))] long amount)
|
||||
{
|
||||
if (!await CheckBetMandatory(amount))
|
||||
return;
|
||||
|
||||
// var slotInteraction = CreateSlotInteractionIntenal(amount);
|
||||
|
||||
await ctx.Channel.TriggerTypingAsync();
|
||||
|
||||
if (await InternalSlotAsync(amount) is not SlotResult result)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
|
||||
return;
|
||||
}
|
||||
|
||||
var text = GetSlotMessageTextInternal(result);
|
||||
|
||||
using var image = await GenerateSlotImageAsync(amount, result);
|
||||
await using var imgStream = await image.ToStreamAsync();
|
||||
|
||||
|
||||
var eb = _eb.Create(ctx)
|
||||
.WithAuthor(ctx.User)
|
||||
.WithDescription(Format.Bold(text))
|
||||
.WithImageUrl($"attachment://result.png")
|
||||
.WithOkColor();
|
||||
|
||||
var bb = new ButtonBuilder(emote: Emoji.Parse("🔁"), customId: "slot:again", label: "Pull Again");
|
||||
var si = new SimpleInteraction<long>(bb, (_, amount) => Slot(amount), amount);
|
||||
|
||||
var inter = _inter.Create(ctx.User.Id, si);
|
||||
var msg = await ctx.Channel.SendFileAsync(imgStream,
|
||||
"result.png",
|
||||
embed: eb.Build(),
|
||||
components: inter.CreateComponent()
|
||||
);
|
||||
await inter.RunAsync(msg);
|
||||
}
|
||||
|
||||
// private SlotInteraction CreateSlotInteractionIntenal(long amount)
|
||||
// {
|
||||
// return new SlotInteraction((DiscordSocketClient)ctx.Client,
|
||||
// ctx.User.Id,
|
||||
// async (smc) =>
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// if (await InternalSlotAsync(amount) is not SlotResult result)
|
||||
// {
|
||||
// await smc.RespondErrorAsync(_eb, GetText(strs.not_enough(CurrencySign)), true);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// var msg = GetSlotMessageInternal(result);
|
||||
//
|
||||
// using var image = await GenerateSlotImageAsync(amount, result);
|
||||
// await using var imgStream = await image.ToStreamAsync();
|
||||
//
|
||||
// var guid = Guid.NewGuid();
|
||||
// var imgName = $"result_{guid}.png";
|
||||
//
|
||||
// var slotInteraction = CreateSlotInteractionIntenal(amount).GetInteraction();
|
||||
//
|
||||
// await smc.Message.ModifyAsync(m =>
|
||||
// {
|
||||
// m.Content = msg;
|
||||
// m.Attachments = new[]
|
||||
// {
|
||||
// new FileAttachment(imgStream, imgName)
|
||||
// };
|
||||
// m.Components = slotInteraction.CreateComponent();
|
||||
// });
|
||||
//
|
||||
// _ = slotInteraction.RunAsync(smc.Message);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Log.Error(ex, "Error pulling slot again");
|
||||
// }
|
||||
// // finally
|
||||
// // {
|
||||
// // await Task.Delay(1000);
|
||||
// // _runningUsers.TryRemove(ctx.User.Id);
|
||||
// // }
|
||||
// });
|
||||
// }
|
||||
|
||||
private string GetSlotMessageTextInternal(SlotResult result)
|
||||
{
|
||||
var multi = result.Multiplier.ToString("0.##");
|
||||
var msg = result.WinType switch
|
||||
{
|
||||
SlotWinType.SingleJoker => GetText(strs.slot_single(CurrencySign, multi)),
|
||||
SlotWinType.DoubleJoker => GetText(strs.slot_two(CurrencySign, multi)),
|
||||
SlotWinType.TrippleNormal => GetText(strs.slot_three(multi)),
|
||||
SlotWinType.TrippleJoker => GetText(strs.slot_jackpot(multi)),
|
||||
_ => GetText(strs.better_luck),
|
||||
};
|
||||
return msg;
|
||||
}
|
||||
|
||||
private async Task<SlotResult?> InternalSlotAsync(long amount)
|
||||
{
|
||||
var maybeResult = await _service.SlotAsync(ctx.User.Id, amount);
|
||||
|
||||
if (!maybeResult.TryPickT0(out var result, out var error))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
lock (_slotStatsLock)
|
||||
{
|
||||
totalBet += amount;
|
||||
totalPaidOut += result.Won;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Image<Rgba32>> GenerateSlotImageAsync(long amount, SlotResult result)
|
||||
{
|
||||
long ownedAmount;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
ownedAmount = uow.Set<DiscordUser>().FirstOrDefault(x => x.UserId == ctx.User.Id)?.CurrencyAmount
|
||||
?? 0;
|
||||
}
|
||||
|
||||
var slotBg = await _images.GetSlotBgAsync();
|
||||
var bgImage = Image.Load<Rgba32>(slotBg, out _);
|
||||
var numbers = new int[3];
|
||||
result.Rolls.CopyTo(numbers, 0);
|
||||
|
||||
Color fontColor = Config.Slots.CurrencyFontColor;
|
||||
|
||||
bgImage.Mutate(x => x.DrawText(new TextOptions(_fonts.DottyFont.CreateFont(65))
|
||||
{
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
WrappingLength = 140,
|
||||
Origin = new(298, 100)
|
||||
},
|
||||
((long)result.Won).ToString(),
|
||||
fontColor));
|
||||
|
||||
var bottomFont = _fonts.DottyFont.CreateFont(50);
|
||||
|
||||
bgImage.Mutate(x => x.DrawText(new TextOptions(bottomFont)
|
||||
{
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
WrappingLength = 135,
|
||||
Origin = new(196, 480)
|
||||
},
|
||||
amount.ToString(),
|
||||
fontColor));
|
||||
|
||||
bgImage.Mutate(x => x.DrawText(new(bottomFont)
|
||||
{
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
Origin = new(393, 480)
|
||||
},
|
||||
ownedAmount.ToString(),
|
||||
fontColor));
|
||||
//sw.PrintLap("drew red text");
|
||||
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
using var img = Image.Load(await _images.GetSlotEmojiAsync(numbers[i]));
|
||||
bgImage.Mutate(x => x.DrawImage(img, new Point(148 + (105 * i), 217), 1f));
|
||||
}
|
||||
|
||||
return bgImage;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user