mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-12 02:08:27 -04:00
Restructured the project structure back to the way it was, there's no reasonable way to split the modules
This commit is contained in:
19
src/NadekoBot/Modules/Gambling/_common/Decks/QuadDeck.cs
Normal file
19
src/NadekoBot/Modules/Gambling/_common/Decks/QuadDeck.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Nadeko.Econ;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling.Common;
|
||||
|
||||
public class QuadDeck : Deck
|
||||
{
|
||||
protected override void RefillPool()
|
||||
{
|
||||
CardPool = new(52 * 4);
|
||||
for (var j = 1; j < 14; j++)
|
||||
for (var i = 1; i < 5; i++)
|
||||
{
|
||||
CardPool.Add(new((CardSuit)i, j));
|
||||
CardPool.Add(new((CardSuit)i, j));
|
||||
CardPool.Add(new((CardSuit)i, j));
|
||||
CardPool.Add(new((CardSuit)i, j));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
using LinqToDB;
|
||||
using NadekoBot.Db.Models;
|
||||
using Nadeko.Bot.Db.Models;
|
||||
|
||||
namespace Nadeko.Bot.Modules.Gambling.Gambling._Common;
|
||||
|
||||
public class GamblingCleanupService : IGamblingCleanupService, INService
|
||||
{
|
||||
private readonly DbService _db;
|
||||
|
||||
public GamblingCleanupService(DbService db)
|
||||
{
|
||||
_db = db;
|
||||
}
|
||||
|
||||
public async Task DeleteWaifus()
|
||||
{
|
||||
await using var ctx = _db.GetDbContext();
|
||||
await ctx.Set<WaifuInfo>().DeleteAsync();
|
||||
await ctx.Set<WaifuItem>().DeleteAsync();
|
||||
await ctx.Set<WaifuUpdate>().DeleteAsync();
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteWaifu(ulong userId)
|
||||
{
|
||||
await using var ctx = _db.GetDbContext();
|
||||
await ctx.Set<WaifuUpdate>()
|
||||
.Where(x => x.User.UserId == userId)
|
||||
.DeleteAsync();
|
||||
await ctx.Set<WaifuItem>()
|
||||
.Where(x => x.WaifuInfo.Waifu.UserId == userId)
|
||||
.DeleteAsync();
|
||||
await ctx.Set<WaifuInfo>()
|
||||
.Where(x => x.Claimer.UserId == userId)
|
||||
.UpdateAsync(old => new WaifuInfo()
|
||||
{
|
||||
ClaimerId = null,
|
||||
});
|
||||
await ctx.Set<WaifuInfo>()
|
||||
.Where(x => x.Waifu.UserId == userId)
|
||||
.DeleteAsync();
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteCurrency()
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
await uow.Set<DiscordUser>().UpdateAsync(_ => new DiscordUser()
|
||||
{
|
||||
CurrencyAmount = 0
|
||||
});
|
||||
|
||||
await uow.Set<CurrencyTransaction>().DeleteAsync();
|
||||
await uow.Set<PlantedCurrency>().DeleteAsync();
|
||||
await uow.Set<BankUser>().DeleteAsync();
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
namespace Nadeko.Bot.Modules.Gambling.Gambling._Common;
|
||||
|
||||
public interface IGamblingCleanupService
|
||||
{
|
||||
Task DeleteWaifus();
|
||||
Task DeleteWaifu(ulong userId);
|
||||
Task DeleteCurrency();
|
||||
}
|
18
src/NadekoBot/Modules/Gambling/_common/IGamblingService.cs
Normal file
18
src/NadekoBot/Modules/Gambling/_common/IGamblingService.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
#nullable disable
|
||||
using Nadeko.Econ.Gambling;
|
||||
using Nadeko.Econ.Gambling.Betdraw;
|
||||
using Nadeko.Econ.Gambling.Rps;
|
||||
using OneOf;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling;
|
||||
|
||||
public interface IGamblingService
|
||||
{
|
||||
Task<OneOf<LuLaResult, GamblingError>> LulaAsync(ulong userId, long amount);
|
||||
Task<OneOf<BetrollResult, GamblingError>> BetRollAsync(ulong userId, long amount);
|
||||
Task<OneOf<BetflipResult, GamblingError>> BetFlipAsync(ulong userId, long amount, byte guess);
|
||||
Task<OneOf<SlotResult, GamblingError>> SlotAsync(ulong userId, long amount);
|
||||
Task<FlipResult[]> FlipAsync(int count);
|
||||
Task<OneOf<RpsResult, GamblingError>> RpsAsync(ulong userId, long amount, byte pick);
|
||||
Task<OneOf<BetdrawResult, GamblingError>> BetDrawAsync(ulong userId, long amount, byte? guessValue, byte? guessColor);
|
||||
}
|
279
src/NadekoBot/Modules/Gambling/_common/NewGamblingService.cs
Normal file
279
src/NadekoBot/Modules/Gambling/_common/NewGamblingService.cs
Normal file
@@ -0,0 +1,279 @@
|
||||
#nullable disable
|
||||
using Nadeko.Econ.Gambling;
|
||||
using Nadeko.Econ.Gambling.Betdraw;
|
||||
using Nadeko.Econ.Gambling.Rps;
|
||||
using NadekoBot.Modules.Gambling.Services;
|
||||
using OneOf;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling;
|
||||
|
||||
public sealed class NewGamblingService : IGamblingService, INService
|
||||
{
|
||||
private readonly GamblingConfigService _bcs;
|
||||
private readonly ICurrencyService _cs;
|
||||
|
||||
public NewGamblingService(GamblingConfigService bcs, ICurrencyService cs)
|
||||
{
|
||||
_bcs = bcs;
|
||||
_cs = cs;
|
||||
}
|
||||
|
||||
public async Task<OneOf<LuLaResult, GamblingError>> LulaAsync(ulong userId, long amount)
|
||||
{
|
||||
if (amount < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(amount));
|
||||
|
||||
if (amount > 0)
|
||||
{
|
||||
var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("lula", "bet"));
|
||||
|
||||
if (!isTakeSuccess)
|
||||
{
|
||||
return GamblingError.InsufficientFunds;
|
||||
}
|
||||
}
|
||||
|
||||
var game = new LulaGame(_bcs.Data.LuckyLadder.Multipliers);
|
||||
var result = game.Spin(amount);
|
||||
|
||||
var won = (long)result.Won;
|
||||
if (won > 0)
|
||||
{
|
||||
await _cs.AddAsync(userId, won, new("lula", "win"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<OneOf<BetrollResult, GamblingError>> BetRollAsync(ulong userId, long amount)
|
||||
{
|
||||
if (amount < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(amount));
|
||||
|
||||
if (amount > 0)
|
||||
{
|
||||
var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("betroll", "bet"));
|
||||
|
||||
if (!isTakeSuccess)
|
||||
{
|
||||
return GamblingError.InsufficientFunds;
|
||||
}
|
||||
}
|
||||
|
||||
var game = new BetrollGame(_bcs.Data.BetRoll.Pairs
|
||||
.Select(x => (x.WhenAbove, (decimal)x.MultiplyBy))
|
||||
.ToList());
|
||||
|
||||
var result = game.Roll(amount);
|
||||
|
||||
var won = (long)result.Won;
|
||||
if (won > 0)
|
||||
{
|
||||
await _cs.AddAsync(userId, won, new("betroll", "win"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<OneOf<BetflipResult, GamblingError>> BetFlipAsync(ulong userId, long amount, byte guess)
|
||||
{
|
||||
if (amount < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(amount));
|
||||
|
||||
if (guess > 1)
|
||||
throw new ArgumentOutOfRangeException(nameof(guess));
|
||||
|
||||
if (amount > 0)
|
||||
{
|
||||
var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("betflip", "bet"));
|
||||
|
||||
if (!isTakeSuccess)
|
||||
{
|
||||
return GamblingError.InsufficientFunds;
|
||||
}
|
||||
}
|
||||
|
||||
var game = new BetflipGame(_bcs.Data.BetFlip.Multiplier);
|
||||
var result = game.Flip(guess, amount);
|
||||
|
||||
var won = (long)result.Won;
|
||||
if (won > 0)
|
||||
{
|
||||
await _cs.AddAsync(userId, won, new("betflip", "win"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<OneOf<BetdrawResult, GamblingError>> BetDrawAsync(ulong userId, long amount, byte? guessValue, byte? guessColor)
|
||||
{
|
||||
if (amount < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(amount));
|
||||
|
||||
if (guessColor is null && guessValue is null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
if (guessColor > 1)
|
||||
throw new ArgumentOutOfRangeException(nameof(guessColor));
|
||||
|
||||
if (guessValue > 1)
|
||||
throw new ArgumentOutOfRangeException(nameof(guessValue));
|
||||
|
||||
if (amount > 0)
|
||||
{
|
||||
var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("betdraw", "bet"));
|
||||
|
||||
if (!isTakeSuccess)
|
||||
{
|
||||
return GamblingError.InsufficientFunds;
|
||||
}
|
||||
}
|
||||
|
||||
var game = new BetdrawGame();
|
||||
var result = game.Draw((BetdrawValueGuess?)guessValue, (BetdrawColorGuess?)guessColor, amount);
|
||||
|
||||
var won = (long)result.Won;
|
||||
if (won > 0)
|
||||
{
|
||||
await _cs.AddAsync(userId, won, new("betdraw", "win"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<OneOf<SlotResult, GamblingError>> SlotAsync(ulong userId, long amount)
|
||||
{
|
||||
if (amount < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(amount));
|
||||
|
||||
if (amount > 0)
|
||||
{
|
||||
var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("slot", "bet"));
|
||||
|
||||
if (!isTakeSuccess)
|
||||
{
|
||||
return GamblingError.InsufficientFunds;
|
||||
}
|
||||
}
|
||||
|
||||
var game = new SlotGame();
|
||||
var result = game.Spin(amount);
|
||||
|
||||
var won = (long)result.Won;
|
||||
if (won > 0)
|
||||
{
|
||||
await _cs.AddAsync(userId, won, new("slot", "won"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Task<FlipResult[]> FlipAsync(int count)
|
||||
{
|
||||
if (count < 1)
|
||||
throw new ArgumentOutOfRangeException(nameof(count));
|
||||
|
||||
var game = new BetflipGame(0);
|
||||
|
||||
var results = new FlipResult[count];
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
results[i] = new()
|
||||
{
|
||||
Side = game.Flip(0, 0).Side
|
||||
};
|
||||
}
|
||||
|
||||
return Task.FromResult(results);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// private readonly ConcurrentDictionary<ulong, Deck> _decks = new ConcurrentDictionary<ulong, Deck>();
|
||||
//
|
||||
// public override Task<DeckShuffleReply> DeckShuffle(DeckShuffleRequest request, ServerCallContext context)
|
||||
// {
|
||||
// _decks.AddOrUpdate(request.Id, new Deck(), (key, old) => new Deck());
|
||||
// return Task.FromResult(new DeckShuffleReply { });
|
||||
// }
|
||||
//
|
||||
// public override Task<DeckDrawReply> DeckDraw(DeckDrawRequest request, ServerCallContext context)
|
||||
// {
|
||||
// if (request.Count < 1 || request.Count > 10)
|
||||
// throw new ArgumentOutOfRangeException(nameof(request.Id));
|
||||
//
|
||||
// var deck = request.UseNew
|
||||
// ? new Deck()
|
||||
// : _decks.GetOrAdd(request.Id, new Deck());
|
||||
//
|
||||
// var list = new List<Deck.Card>(request.Count);
|
||||
// for (int i = 0; i < request.Count; i++)
|
||||
// {
|
||||
// var card = deck.DrawNoRestart();
|
||||
// if (card is null)
|
||||
// {
|
||||
// if (i == 0)
|
||||
// {
|
||||
// deck.Restart();
|
||||
// list.Add(deck.DrawNoRestart());
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// list.Add(card);
|
||||
// }
|
||||
//
|
||||
// var cards = list
|
||||
// .Select(x => new Card
|
||||
// {
|
||||
// Name = x.ToString().ToLowerInvariant().Replace(' ', '_'),
|
||||
// Number = x.Number,
|
||||
// Suit = (CardSuit) x.Suit
|
||||
// });
|
||||
//
|
||||
// var toReturn = new DeckDrawReply();
|
||||
// toReturn.Cards.AddRange(cards);
|
||||
//
|
||||
// return Task.FromResult(toReturn);
|
||||
// }
|
||||
//
|
||||
|
||||
public async Task<OneOf<RpsResult, GamblingError>> RpsAsync(ulong userId, long amount, byte pick)
|
||||
{
|
||||
if (amount < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(amount));
|
||||
|
||||
if (pick > 2)
|
||||
throw new ArgumentOutOfRangeException(nameof(pick));
|
||||
|
||||
if (amount > 0)
|
||||
{
|
||||
var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("rps", "bet"));
|
||||
|
||||
if (!isTakeSuccess)
|
||||
{
|
||||
return GamblingError.InsufficientFunds;
|
||||
}
|
||||
}
|
||||
|
||||
var rps = new RpsGame();
|
||||
var result = rps.Play((RpsPick)pick, amount);
|
||||
|
||||
var won = (long)result.Won;
|
||||
if (won > 0)
|
||||
{
|
||||
var extra = result.Result switch
|
||||
{
|
||||
RpsResultType.Draw => "draw",
|
||||
RpsResultType.Win => "win",
|
||||
_ => "lose"
|
||||
};
|
||||
|
||||
await _cs.AddAsync(userId, won, new("rps", extra));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
139
src/NadekoBot/Modules/Gambling/_common/RollDuelGame.cs
Normal file
139
src/NadekoBot/Modules/Gambling/_common/RollDuelGame.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
#nullable disable
|
||||
namespace NadekoBot.Modules.Gambling.Common;
|
||||
|
||||
public class RollDuelGame
|
||||
{
|
||||
public enum Reason
|
||||
{
|
||||
Normal,
|
||||
NoFunds,
|
||||
Timeout
|
||||
}
|
||||
|
||||
public enum State
|
||||
{
|
||||
Waiting,
|
||||
Running,
|
||||
Ended
|
||||
}
|
||||
|
||||
public event Func<RollDuelGame, Task> OnGameTick;
|
||||
public event Func<RollDuelGame, Reason, Task> OnEnded;
|
||||
|
||||
public ulong P1 { get; }
|
||||
public ulong P2 { get; }
|
||||
|
||||
public long Amount { get; }
|
||||
|
||||
public List<(int, int)> Rolls { get; } = new();
|
||||
public State CurrentState { get; private set; }
|
||||
public ulong Winner { get; private set; }
|
||||
|
||||
private readonly ulong _botId;
|
||||
|
||||
private readonly ICurrencyService _cs;
|
||||
|
||||
private readonly Timer _timeoutTimer;
|
||||
private readonly NadekoRandom _rng = new();
|
||||
private readonly SemaphoreSlim _locker = new(1, 1);
|
||||
|
||||
public RollDuelGame(
|
||||
ICurrencyService cs,
|
||||
ulong botId,
|
||||
ulong p1,
|
||||
ulong p2,
|
||||
long amount)
|
||||
{
|
||||
P1 = p1;
|
||||
P2 = p2;
|
||||
_botId = botId;
|
||||
Amount = amount;
|
||||
_cs = cs;
|
||||
|
||||
_timeoutTimer = new(async delegate
|
||||
{
|
||||
await _locker.WaitAsync();
|
||||
try
|
||||
{
|
||||
if (CurrentState != State.Waiting)
|
||||
return;
|
||||
CurrentState = State.Ended;
|
||||
await OnEnded?.Invoke(this, Reason.Timeout);
|
||||
}
|
||||
catch { }
|
||||
finally
|
||||
{
|
||||
_locker.Release();
|
||||
}
|
||||
},
|
||||
null,
|
||||
TimeSpan.FromSeconds(15),
|
||||
TimeSpan.FromMilliseconds(-1));
|
||||
}
|
||||
|
||||
public async Task StartGame()
|
||||
{
|
||||
await _locker.WaitAsync();
|
||||
try
|
||||
{
|
||||
if (CurrentState != State.Waiting)
|
||||
return;
|
||||
_timeoutTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
CurrentState = State.Running;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_locker.Release();
|
||||
}
|
||||
|
||||
if (!await _cs.RemoveAsync(P1, Amount, new("rollduel", "bet")))
|
||||
{
|
||||
await OnEnded?.Invoke(this, Reason.NoFunds);
|
||||
CurrentState = State.Ended;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!await _cs.RemoveAsync(P2, Amount, new("rollduel", "bet")))
|
||||
{
|
||||
await _cs.AddAsync(P1, Amount, new("rollduel", "refund"));
|
||||
await OnEnded?.Invoke(this, Reason.NoFunds);
|
||||
CurrentState = State.Ended;
|
||||
return;
|
||||
}
|
||||
|
||||
int n1, n2;
|
||||
do
|
||||
{
|
||||
n1 = _rng.Next(0, 5);
|
||||
n2 = _rng.Next(0, 5);
|
||||
Rolls.Add((n1, n2));
|
||||
if (n1 != n2)
|
||||
{
|
||||
if (n1 > n2)
|
||||
Winner = P1;
|
||||
else
|
||||
Winner = P2;
|
||||
var won = (long)(Amount * 2 * 0.98f);
|
||||
await _cs.AddAsync(Winner, won, new("rollduel", "win"));
|
||||
|
||||
await _cs.AddAsync(_botId, (Amount * 2) - won, new("rollduel", "fee"));
|
||||
}
|
||||
|
||||
try { await OnGameTick?.Invoke(this); }
|
||||
catch { }
|
||||
|
||||
await Task.Delay(2500);
|
||||
if (n1 != n2)
|
||||
break;
|
||||
} while (true);
|
||||
|
||||
CurrentState = State.Ended;
|
||||
await OnEnded?.Invoke(this, Reason.Normal);
|
||||
}
|
||||
}
|
||||
|
||||
public struct RollDuelChallenge
|
||||
{
|
||||
public ulong Player1 { get; set; }
|
||||
public ulong Player2 { get; set; }
|
||||
}
|
@@ -0,0 +1,95 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using NadekoBot.Db;
|
||||
using NadekoBot.Db.Models;
|
||||
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.Set<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,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,57 @@
|
||||
#nullable disable
|
||||
using NadekoBot.Modules.Gambling.Bank;
|
||||
using NadekoBot.Modules.Gambling.Services;
|
||||
|
||||
namespace NadekoBot.Common.TypeReaders;
|
||||
|
||||
public sealed class BalanceTypeReader : TypeReader
|
||||
{
|
||||
private readonly BaseShmartInputAmountReader _tr;
|
||||
|
||||
public BalanceTypeReader(DbService db, GamblingConfigService gambling)
|
||||
{
|
||||
_tr = new BaseShmartInputAmountReader(db, gambling);
|
||||
}
|
||||
|
||||
public override async Task<Discord.Commands.TypeReaderResult> ReadAsync(
|
||||
ICommandContext context,
|
||||
string input,
|
||||
IServiceProvider services)
|
||||
{
|
||||
|
||||
var result = await _tr.ReadAsync(context, input);
|
||||
|
||||
if (result.TryPickT0(out var val, out var err))
|
||||
{
|
||||
return Discord.Commands.TypeReaderResult.FromSuccess(val);
|
||||
}
|
||||
|
||||
return Discord.Commands.TypeReaderResult.FromError(CommandError.Unsuccessful, err.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class BankBalanceTypeReader : TypeReader
|
||||
{
|
||||
private readonly ShmartBankInputAmountReader _tr;
|
||||
|
||||
public BankBalanceTypeReader(IBankService bank, DbService db, GamblingConfigService gambling)
|
||||
{
|
||||
_tr = new ShmartBankInputAmountReader(bank, db, gambling);
|
||||
}
|
||||
|
||||
public override async Task<Discord.Commands.TypeReaderResult> ReadAsync(
|
||||
ICommandContext context,
|
||||
string input,
|
||||
IServiceProvider services)
|
||||
{
|
||||
|
||||
var result = await _tr.ReadAsync(context, input);
|
||||
|
||||
if (result.TryPickT0(out var val, out var err))
|
||||
{
|
||||
return Discord.Commands.TypeReaderResult.FromSuccess(val);
|
||||
}
|
||||
|
||||
return Discord.Commands.TypeReaderResult.FromError(CommandError.Unsuccessful, err.Value);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user