forked from EllieBotDevs/elliebot
222 lines
No EOL
7.9 KiB
C#
222 lines
No EOL
7.9 KiB
C#
#nullable disable warnings
|
|
using EllieBot.Db.Models;
|
|
using EllieBot.Modules.Gambling.Common;
|
|
using EllieBot.Modules.Gambling.Services;
|
|
using SixLabors.Fonts;
|
|
using SixLabors.ImageSharp;
|
|
using SixLabors.ImageSharp.Drawing.Processing;
|
|
using SixLabors.ImageSharp.PixelFormats;
|
|
using SixLabors.ImageSharp.Processing;
|
|
using EllieBot.Common.TypeReaders;
|
|
using Color = SixLabors.ImageSharp.Color;
|
|
using Image = SixLabors.ImageSharp.Image;
|
|
|
|
namespace EllieBot.Modules.Gambling;
|
|
|
|
public enum GamblingError
|
|
{
|
|
InsufficientFunds,
|
|
}
|
|
|
|
public partial class Gambling
|
|
{
|
|
[Group]
|
|
public partial class SlotCommands : GamblingSubmodule<IGamblingService>
|
|
{
|
|
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 Response().Error(strs.not_enough(CurrencySign)).SendAsync();
|
|
return;
|
|
}
|
|
|
|
var text = GetSlotMessageTextInternal(result);
|
|
|
|
using var image = await GenerateSlotImageAsync(amount, result);
|
|
await using var imgStream = await image.ToStreamAsync();
|
|
|
|
|
|
var eb = _sender.CreateEmbed()
|
|
.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 inter = _inter.Create(ctx.User.Id,
|
|
bb,
|
|
smc =>
|
|
{
|
|
smc.DeferAsync();
|
|
return Slot(amount);
|
|
});
|
|
|
|
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;
|
|
}
|
|
|
|
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);
|
|
var numbers = new int[3];
|
|
result.Rolls.CopyTo(numbers, 0);
|
|
|
|
Color fontColor = Config.Slots.CurrencyFontColor;
|
|
|
|
bgImage.Mutate<Rgba32>(x => x.DrawText(new RichTextOptions(_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 RichTextOptions(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;
|
|
}
|
|
}
|
|
} |