mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-12 02:08:27 -04:00
.bank withdraw <expression> will now correctly use bank amount for calculations. Fixed .br giving double win amounts
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using NadekoBot.Db;
|
||||
using NadekoBot.Modules.Gambling.Services;
|
||||
using NCalc;
|
||||
using OneOf;
|
||||
|
||||
namespace NadekoBot.Common.TypeReaders;
|
||||
|
||||
public class BaseShmartInputAmountReader
|
||||
{
|
||||
private static readonly Regex _percentRegex = new(@"^((?<num>100|\d{1,2})%)$", RegexOptions.Compiled);
|
||||
protected readonly DbService _db;
|
||||
protected readonly GamblingConfigService _gambling;
|
||||
|
||||
public BaseShmartInputAmountReader(DbService db, GamblingConfigService gambling)
|
||||
{
|
||||
_db = db;
|
||||
_gambling = gambling;
|
||||
}
|
||||
|
||||
public async ValueTask<OneOf<long, OneOf.Types.Error<string>>> ReadAsync(ICommandContext context, string input)
|
||||
{
|
||||
var i = input.Trim().ToUpperInvariant();
|
||||
|
||||
i = i.Replace("K", "000");
|
||||
|
||||
//can't add m because it will conflict with max atm
|
||||
|
||||
if (await TryHandlePercentage(context, i) is long num)
|
||||
{
|
||||
return num;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var expr = new Expression(i, EvaluateOptions.IgnoreCase);
|
||||
expr.EvaluateParameter += (str, ev) => EvaluateParam(str, ev, context).GetAwaiter().GetResult();
|
||||
return (long)decimal.Parse(expr.Evaluate().ToString()!);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return new OneOf.Types.Error<string>($"Invalid input: {input}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task EvaluateParam(string name, ParameterArgs args, ICommandContext ctx)
|
||||
{
|
||||
switch (name.ToUpperInvariant())
|
||||
{
|
||||
case "PI":
|
||||
args.Result = Math.PI;
|
||||
break;
|
||||
case "E":
|
||||
args.Result = Math.E;
|
||||
break;
|
||||
case "ALL":
|
||||
case "ALLIN":
|
||||
args.Result = await Cur(ctx);
|
||||
break;
|
||||
case "HALF":
|
||||
args.Result = await Cur(ctx) / 2;
|
||||
break;
|
||||
case "MAX":
|
||||
args.Result = await Max(ctx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual async Task<long> Cur(ICommandContext ctx)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
return await uow.DiscordUser.GetUserCurrencyAsync(ctx.User.Id);
|
||||
}
|
||||
|
||||
protected virtual async Task<long> Max(ICommandContext ctx)
|
||||
{
|
||||
var settings = _gambling.Data;
|
||||
var max = settings.MaxBet;
|
||||
return max == 0 ? await Cur(ctx) : max;
|
||||
}
|
||||
|
||||
private async Task<long?> TryHandlePercentage(ICommandContext ctx, string input)
|
||||
{
|
||||
var m = _percentRegex.Match(input);
|
||||
|
||||
if (m.Captures.Count == 0)
|
||||
return null;
|
||||
|
||||
if (!long.TryParse(m.Groups["num"].ToString(), out var percent))
|
||||
return null;
|
||||
|
||||
return (long)(await Cur(ctx) * (percent / 100.0f));
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
#nullable disable
|
||||
using NadekoBot.Modules.Gambling.Bank;
|
||||
using NadekoBot.Modules.Gambling.Services;
|
||||
|
||||
namespace NadekoBot.Common.TypeReaders;
|
||||
|
||||
public sealed class ShmartBankAmountTypeReader : NadekoTypeReader<ShmartBankAmount>
|
||||
{
|
||||
private readonly IBankService _bank;
|
||||
private readonly ShmartBankInputAmountReader _tr;
|
||||
|
||||
public ShmartBankAmountTypeReader(IBankService bank, DbService db, GamblingConfigService gambling)
|
||||
{
|
||||
_bank = bank;
|
||||
_tr = new ShmartBankInputAmountReader(bank, db, gambling);
|
||||
}
|
||||
|
||||
public override async ValueTask<TypeReaderResult<ShmartBankAmount>> ReadAsync(ICommandContext ctx, string input)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
return TypeReaderResult.FromError<ShmartBankAmount>(CommandError.ParseFailed, "Input is empty.");
|
||||
|
||||
var result = await _tr.ReadAsync(ctx, input);
|
||||
|
||||
if (result.TryPickT0(out var val, out var err))
|
||||
{
|
||||
return TypeReaderResult.FromSuccess<ShmartBankAmount>(new(val));
|
||||
}
|
||||
|
||||
return TypeReaderResult.FromError<ShmartBankAmount>(CommandError.Unsuccessful, err.Value);
|
||||
}
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
using NadekoBot.Modules.Gambling.Bank;
|
||||
using NadekoBot.Modules.Gambling.Services;
|
||||
|
||||
namespace NadekoBot.Common.TypeReaders;
|
||||
|
||||
public sealed class ShmartBankInputAmountReader : BaseShmartInputAmountReader
|
||||
{
|
||||
private readonly IBankService _bank;
|
||||
|
||||
public ShmartBankInputAmountReader(IBankService bank, DbService db, GamblingConfigService gambling)
|
||||
: base(db, gambling)
|
||||
{
|
||||
_bank = bank;
|
||||
}
|
||||
|
||||
protected override Task<long> Cur(ICommandContext ctx)
|
||||
=> _bank.GetBalanceAsync(ctx.User.Id);
|
||||
|
||||
protected override Task<long> Max(ICommandContext ctx)
|
||||
=> Cur(ctx);
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
#nullable disable
|
||||
using NadekoBot.Modules.Gambling.Services;
|
||||
|
||||
namespace NadekoBot.Common.TypeReaders;
|
||||
|
||||
public sealed class ShmartNumberTypeReader : NadekoTypeReader<ShmartNumber>
|
||||
{
|
||||
private readonly BaseShmartInputAmountReader _tr;
|
||||
|
||||
public ShmartNumberTypeReader(DbService db, GamblingConfigService gambling)
|
||||
{
|
||||
_tr = new BaseShmartInputAmountReader(db, gambling);
|
||||
}
|
||||
|
||||
public override async ValueTask<TypeReaderResult<ShmartNumber>> ReadAsync(ICommandContext ctx, string input)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
return TypeReaderResult.FromError<ShmartNumber>(CommandError.ParseFailed, "Input is empty.");
|
||||
|
||||
var result = await _tr.ReadAsync(ctx, input);
|
||||
|
||||
if (result.TryPickT0(out var val, out var err))
|
||||
{
|
||||
return TypeReaderResult.FromSuccess<ShmartNumber>(new(val));
|
||||
}
|
||||
|
||||
return TypeReaderResult.FromError<ShmartNumber>(CommandError.Unsuccessful, err.Value);
|
||||
}
|
||||
}
|
@@ -1,100 +0,0 @@
|
||||
#nullable disable
|
||||
using NadekoBot.Db;
|
||||
using NadekoBot.Modules.Gambling.Services;
|
||||
using NCalc;
|
||||
using System.Text.RegularExpressions;
|
||||
using Nadeko.Common;
|
||||
|
||||
namespace NadekoBot.Common.TypeReaders;
|
||||
|
||||
public sealed class ShmartNumberTypeReader : NadekoTypeReader<ShmartNumber>
|
||||
{
|
||||
private static readonly Regex _percentRegex = new(@"^((?<num>100|\d{1,2})%)$", RegexOptions.Compiled);
|
||||
private readonly DbService _db;
|
||||
private readonly GamblingConfigService _gambling;
|
||||
|
||||
public ShmartNumberTypeReader(DbService db, GamblingConfigService gambling)
|
||||
{
|
||||
_db = db;
|
||||
_gambling = gambling;
|
||||
}
|
||||
|
||||
public override ValueTask<TypeReaderResult<ShmartNumber>> ReadAsync(ICommandContext context, string input)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
return new(TypeReaderResult.FromError<ShmartNumber>(CommandError.ParseFailed, "Input is empty."));
|
||||
|
||||
var i = input.Trim().ToUpperInvariant();
|
||||
|
||||
i = i.Replace("K", "000");
|
||||
|
||||
//can't add m because it will conflict with max atm
|
||||
|
||||
if (TryHandlePercentage(context, i, out var num))
|
||||
return new(TypeReaderResult.FromSuccess(new ShmartNumber(num, i)));
|
||||
try
|
||||
{
|
||||
var expr = new Expression(i, EvaluateOptions.IgnoreCase);
|
||||
expr.EvaluateParameter += (str, ev) => EvaluateParam(str, ev, context);
|
||||
var lon = (long)decimal.Parse(expr.Evaluate().ToString());
|
||||
return new(TypeReaderResult.FromSuccess(new ShmartNumber(lon, input)));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return ValueTask.FromResult(
|
||||
TypeReaderResult.FromError<ShmartNumber>(CommandError.ParseFailed, $"Invalid input: {input}"));
|
||||
}
|
||||
}
|
||||
|
||||
private void EvaluateParam(string name, ParameterArgs args, ICommandContext ctx)
|
||||
{
|
||||
switch (name.ToUpperInvariant())
|
||||
{
|
||||
case "PI":
|
||||
args.Result = Math.PI;
|
||||
break;
|
||||
case "E":
|
||||
args.Result = Math.E;
|
||||
break;
|
||||
case "ALL":
|
||||
case "ALLIN":
|
||||
args.Result = Cur(ctx);
|
||||
break;
|
||||
case "HALF":
|
||||
args.Result = Cur(ctx) / 2;
|
||||
break;
|
||||
case "MAX":
|
||||
args.Result = Max(ctx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private long Cur(ICommandContext ctx)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
return uow.DiscordUser.GetUserCurrency(ctx.User.Id);
|
||||
}
|
||||
|
||||
private long Max(ICommandContext ctx)
|
||||
{
|
||||
var settings = _gambling.Data;
|
||||
var max = settings.MaxBet;
|
||||
return max == 0 ? Cur(ctx) : max;
|
||||
}
|
||||
|
||||
private bool TryHandlePercentage(ICommandContext ctx, string input, out long num)
|
||||
{
|
||||
num = 0;
|
||||
var m = _percentRegex.Match(input);
|
||||
if (m.Captures.Count != 0)
|
||||
{
|
||||
if (!long.TryParse(m.Groups["num"].ToString(), out var percent))
|
||||
return false;
|
||||
|
||||
num = (long)(Cur(ctx) * (percent / 100.0f));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user