Return new balance when it's modified and use that for display so it accounts for concurrent games

This commit is contained in:
barelyprofessional
2025-12-09 23:40:15 -06:00
parent 5af2015d46
commit 4671bb3d25
6 changed files with 20 additions and 24 deletions
@@ -50,19 +50,18 @@ public class DiceCommand : ICommand
return; return;
} }
var rolled = Money.GetRandomDouble(gambler); var rolled = Money.GetRandomDouble(gambler);
decimal newBalance;
var colors = var colors =
await SettingsProvider.GetMultipleValuesAsync([ await SettingsProvider.GetMultipleValuesAsync([
BuiltIn.Keys.KiwiFarmsGreenColor, BuiltIn.Keys.KiwiFarmsRedColor BuiltIn.Keys.KiwiFarmsGreenColor, BuiltIn.Keys.KiwiFarmsRedColor
]); ]);
// print dice game slider // print dice game slider
await botInstance.SendChatMessageAsync($"{ConstructDiceGameOutput(rolled)}",true, autoDeleteAfter: cleanupDelay); await botInstance.SendChatMessageAsync($"{ConstructDiceGameOutput(rolled)}",true, autoDeleteAfter: cleanupDelay);
decimal newBalance;
if (rolled > 0.5 + _houseEdge) if (rolled > 0.5 + _houseEdge)
{ {
// you win dice // you win dice
var effect = wager; var effect = wager;
await Money.NewWagerAsync(gambler.Id, wager, effect, WagerGame.Dice, ct: ctx); newBalance = await Money.NewWagerAsync(gambler.Id, wager, effect, WagerGame.Dice, ct: ctx);
newBalance = gambler.Balance + effect;
await botInstance.SendChatMessageAsync( await botInstance.SendChatMessageAsync(
$"{user.FormatUsername()}, you rolled a {rolled * 100:N2} and [B][COLOR={colors[BuiltIn.Keys.KiwiFarmsGreenColor].Value}]WON![/COLOR][/B] " + $"{user.FormatUsername()}, you rolled a {rolled * 100:N2} and [B][COLOR={colors[BuiltIn.Keys.KiwiFarmsGreenColor].Value}]WON![/COLOR][/B] " +
$"You won {await effect.FormatKasinoCurrencyAsync()} and your balance is now {await newBalance.FormatKasinoCurrencyAsync()}", $"You won {await effect.FormatKasinoCurrencyAsync()} and your balance is now {await newBalance.FormatKasinoCurrencyAsync()}",
@@ -71,8 +70,7 @@ public class DiceCommand : ICommand
else else
{ {
// you lose dice // you lose dice
await Money.NewWagerAsync(gambler.Id, wager, -wager, WagerGame.Dice, ct: ctx); newBalance = await Money.NewWagerAsync(gambler.Id, wager, -wager, WagerGame.Dice, ct: ctx);
newBalance = gambler.Balance - wager;
await botInstance.SendChatMessageAsync( await botInstance.SendChatMessageAsync(
$"{user.FormatUsername()}, you rolled a {rolled * 100:N2} and [B][COLOR={colors[BuiltIn.Keys.KiwiFarmsRedColor].Value}]LOST![/COLOR][/B] " + $"{user.FormatUsername()}, you rolled a {rolled * 100:N2} and [B][COLOR={colors[BuiltIn.Keys.KiwiFarmsRedColor].Value}]LOST![/COLOR][/B] " +
$"Your balance is now {await newBalance.FormatKasinoCurrencyAsync()}", $"Your balance is now {await newBalance.FormatKasinoCurrencyAsync()}",
@@ -58,16 +58,14 @@ public class GuessWhatNumberCommand : ICommand
if (guess == answer) if (guess == answer)
{ {
var effect = wager * 9; var effect = wager * 9;
await Money.NewWagerAsync(gambler.Id, wager, effect, WagerGame.GuessWhatNumber, ct: ctx); newBalance = await Money.NewWagerAsync(gambler.Id, wager, effect, WagerGame.GuessWhatNumber, ct: ctx);
newBalance = gambler.Balance + effect;
await botInstance.SendChatMessageAsync( await botInstance.SendChatMessageAsync(
$"{user.FormatUsername()}, [color={colors[BuiltIn.Keys.KiwiFarmsGreenColor].Value}]correct![/color] You won {await effect.FormatKasinoCurrencyAsync()} and your balance is now {await newBalance.FormatKasinoCurrencyAsync()}", $"{user.FormatUsername()}, [color={colors[BuiltIn.Keys.KiwiFarmsGreenColor].Value}]correct![/color] You won {await effect.FormatKasinoCurrencyAsync()} and your balance is now {await newBalance.FormatKasinoCurrencyAsync()}",
true, autoDeleteAfter: cleanupDelay); true, autoDeleteAfter: cleanupDelay);
return; return;
} }
await Money.NewWagerAsync(gambler.Id, wager, -wager, WagerGame.GuessWhatNumber, ct: ctx); newBalance = await Money.NewWagerAsync(gambler.Id, wager, -wager, WagerGame.GuessWhatNumber, ct: ctx);
newBalance = gambler.Balance - wager;
await botInstance.SendChatMessageAsync( await botInstance.SendChatMessageAsync(
$"{user.FormatUsername()}, [color={colors[BuiltIn.Keys.KiwiFarmsRedColor].Value}]wrong![/color] I was thinking of {answer}. Your balance is now {await newBalance.FormatKasinoCurrencyAsync()}", $"{user.FormatUsername()}, [color={colors[BuiltIn.Keys.KiwiFarmsRedColor].Value}]wrong![/color] I was thinking of {answer}. Your balance is now {await newBalance.FormatKasinoCurrencyAsync()}",
true, autoDeleteAfter: cleanupDelay); true, autoDeleteAfter: cleanupDelay);
@@ -90,10 +90,10 @@ public class KenoCommand : ICommand
await SettingsProvider.GetMultipleValuesAsync([ await SettingsProvider.GetMultipleValuesAsync([
BuiltIn.Keys.KiwiFarmsGreenColor, BuiltIn.Keys.KiwiFarmsRedColor BuiltIn.Keys.KiwiFarmsGreenColor, BuiltIn.Keys.KiwiFarmsRedColor
]); ]);
var newBalance = gambler.Balance - wager; decimal newBalance;
if (payoutMulti == 0) //you lose if (payoutMulti == 0) //you lose
{ {
await Money.NewWagerAsync(gambler.Id, wager, -wager, WagerGame.Keno, ct: ctx); newBalance = await Money.NewWagerAsync(gambler.Id, wager, -wager, WagerGame.Keno, ct: ctx);
await botInstance.SendChatMessageAsync( await botInstance.SendChatMessageAsync(
$"{user.FormatUsername()}, you [color={colors[BuiltIn.Keys.KiwiFarmsRedColor].Value}]lost {await wager.FormatKasinoCurrencyAsync()}[/color]. Your balance is now: {await newBalance.FormatKasinoCurrencyAsync()}.", $"{user.FormatUsername()}, you [color={colors[BuiltIn.Keys.KiwiFarmsRedColor].Value}]lost {await wager.FormatKasinoCurrencyAsync()}[/color]. Your balance is now: {await newBalance.FormatKasinoCurrencyAsync()}.",
true, autoDeleteAfter: cleanupDelay); true, autoDeleteAfter: cleanupDelay);
@@ -104,8 +104,7 @@ public class KenoCommand : ICommand
//you win //you win
var win = wager * (decimal)payoutMulti; var win = wager * (decimal)payoutMulti;
// Required to avoid compiler errors when trying to format it in the win message // Required to avoid compiler errors when trying to format it in the win message
newBalance = gambler.Balance + win; newBalance = await Money.NewWagerAsync(gambler.Id, wager, wager * (decimal)payoutMulti, WagerGame.Keno, ct: ctx);
await Money.NewWagerAsync(gambler.Id, wager, wager * (decimal)payoutMulti, WagerGame.Keno, ct: ctx);
await botInstance.SendChatMessageAsync( await botInstance.SendChatMessageAsync(
$"{user.FormatUsername()}, you [color={colors[BuiltIn.Keys.KiwiFarmsGreenColor].Value}]won {await win.FormatKasinoCurrencyAsync()} with a {payoutMulti}x multi![/color]. Your balance is now: {await newBalance.FormatKasinoCurrencyAsync()}.", $"{user.FormatUsername()}, you [color={colors[BuiltIn.Keys.KiwiFarmsGreenColor].Value}]won {await win.FormatKasinoCurrencyAsync()} with a {payoutMulti}x multi![/color]. Your balance is now: {await newBalance.FormatKasinoCurrencyAsync()}.",
true, autoDeleteAfter: cleanupDelay); true, autoDeleteAfter: cleanupDelay);
@@ -247,15 +247,13 @@ public class LambchopCommand : ICommand
{ {
var multi = LambchopPayoutMultiplier(targetTile); var multi = LambchopPayoutMultiplier(targetTile);
var lambchopPayout = Math.Round(wager * multi - wager, 2); var lambchopPayout = Math.Round(wager * multi - wager, 2);
await Money.NewWagerAsync(gambler.Id, wager, lambchopPayout, WagerGame.LambChop, ct: ctx); newBalance = await Money.NewWagerAsync(gambler.Id, wager, lambchopPayout, WagerGame.LambChop, ct: ctx);
newBalance = gambler.Balance + lambchopPayout;
lambchopResultMessage = $"{user.FormatUsername()}, you [B][COLOR={colors[BuiltIn.Keys.KiwiFarmsGreenColor].Value}]WON[/COLOR][/B]" + lambchopResultMessage = $"{user.FormatUsername()}, you [B][COLOR={colors[BuiltIn.Keys.KiwiFarmsGreenColor].Value}]WON[/COLOR][/B]" +
$" | Multi {multi} | Balance {await newBalance.FormatKasinoCurrencyAsync()}"; $" | Multi {multi} | Balance {await newBalance.FormatKasinoCurrencyAsync()}";
} }
else else
{ {
await Money.NewWagerAsync(gambler.Id, wager, -wager, WagerGame.LambChop, ct: ctx); newBalance = await Money.NewWagerAsync(gambler.Id, wager, -wager, WagerGame.LambChop, ct: ctx);
newBalance = gambler.Balance - wager;
lambchopResultMessage = $"{user.FormatUsername()}, you [B][COLOR={colors[BuiltIn.Keys.KiwiFarmsGreenColor].Value}]LOST[/COLOR][/B]" + lambchopResultMessage = $"{user.FormatUsername()}, you [B][COLOR={colors[BuiltIn.Keys.KiwiFarmsGreenColor].Value}]LOST[/COLOR][/B]" +
$", better luck next time | Balance {await newBalance.FormatKasinoCurrencyAsync()}"; $", better luck next time | Balance {await newBalance.FormatKasinoCurrencyAsync()}";
@@ -239,12 +239,11 @@ public class Planes : ICommand
await SettingsProvider.GetMultipleValuesAsync([ await SettingsProvider.GetMultipleValuesAsync([
BuiltIn.Keys.KiwiFarmsGreenColor, BuiltIn.Keys.KiwiFarmsRedColor BuiltIn.Keys.KiwiFarmsGreenColor, BuiltIn.Keys.KiwiFarmsRedColor
]); ]);
var newBalance = gambler.Balance - wager; decimal newBalance;
if ((fullCounter - 3) % carrierCount == 0) //if you landed on the carrier if ((fullCounter - 3) % carrierCount == 0) //if you landed on the carrier
{ {
var win = plane.MultiTracker * wager; var win = plane.MultiTracker * wager;
newBalance = gambler.Balance + win; newBalance = await Money.NewWagerAsync(gambler.Id, wager, win, WagerGame.Planes, ct: ctx);
await Money.NewWagerAsync(gambler.Id, wager, win, WagerGame.Planes, ct: ctx);
planesDisplay = GetGameBoard(fullCounter, planesBoards, plane, carrierCount, noseUp); planesDisplay = GetGameBoard(fullCounter, planesBoards, plane, carrierCount, noseUp);
await botInstance.KfClient.EditMessageAsync(msgId.ChatMessageId!.Value, planesDisplay); await botInstance.KfClient.EditMessageAsync(msgId.ChatMessageId!.Value, planesDisplay);
await botInstance.SendChatMessageAsync( await botInstance.SendChatMessageAsync(
@@ -254,7 +253,7 @@ public class Planes : ICommand
return; return;
} }
plane.Crash(); plane.Crash();
await Money.NewWagerAsync(gambler.Id, wager, -wager, WagerGame.Planes, ct: ctx); newBalance = await Money.NewWagerAsync(gambler.Id, wager, -wager, WagerGame.Planes, ct: ctx);
planesDisplay = GetGameBoard(fullCounter, planesBoards, plane, carrierCount, noseUp); planesDisplay = GetGameBoard(fullCounter, planesBoards, plane, carrierCount, noseUp);
await Task.Delay(TimeSpan.FromMilliseconds(frameLength), ctx); await Task.Delay(TimeSpan.FromMilliseconds(frameLength), ctx);
await botInstance.KfClient.EditMessageAsync(msgId.ChatMessageId!.Value, planesDisplay); await botInstance.KfClient.EditMessageAsync(msgId.ChatMessageId!.Value, planesDisplay);
+7 -3
View File
@@ -282,7 +282,8 @@ public static class Money
/// <param name="comment">Optional comment to provide for the transaction</param> /// <param name="comment">Optional comment to provide for the transaction</param>
/// <param name="fromId">If applicable, who sent the transaction (e.g. if a juicer)</param> /// <param name="fromId">If applicable, who sent the transaction (e.g. if a juicer)</param>
/// <param name="ct">Cancellation token</param> /// <param name="ct">Cancellation token</param>
public static async Task ModifyBalanceAsync(int gamblerId, decimal effect, /// <returns>New balance after modification</returns>
public static async Task<decimal> ModifyBalanceAsync(int gamblerId, decimal effect,
TransactionSourceEventType eventSource, string? comment = null, int? fromId = null, TransactionSourceEventType eventSource, string? comment = null, int? fromId = null,
CancellationToken ct = default) CancellationToken ct = default)
{ {
@@ -308,6 +309,7 @@ public static class Money
TimeUnixEpochSeconds = DateTimeOffset.UtcNow.ToUnixTimeSeconds() TimeUnixEpochSeconds = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
}, ct); }, ct);
await db.SaveChangesAsync(ct); await db.SaveChangesAsync(ct);
return gambler.Balance;
} }
/// <summary> /// <summary>
@@ -328,7 +330,8 @@ public static class Money
/// <param name="isComplete">Whether the game is 'complete'. Set to false for wagers with unknown outcomes. /// <param name="isComplete">Whether the game is 'complete'. Set to false for wagers with unknown outcomes.
/// NOTE: wagerEffect will be ignored, instead value will be derived from the wagerAmount</param> /// NOTE: wagerEffect will be ignored, instead value will be derived from the wagerAmount</param>
/// <param name="ct">Cancellation token</param> /// <param name="ct">Cancellation token</param>
public static async Task NewWagerAsync(int gamblerId, decimal wagerAmount, decimal wagerEffect, /// <returns>Returns the gambler's balance</returns>
public static async Task<decimal> NewWagerAsync(int gamblerId, decimal wagerAmount, decimal wagerEffect,
WagerGame game, bool autoModifyBalance = true, dynamic? gameMeta = null, bool isComplete = true, WagerGame game, bool autoModifyBalance = true, dynamic? gameMeta = null, bool isComplete = true,
CancellationToken ct = default) CancellationToken ct = default)
{ {
@@ -378,8 +381,8 @@ public static class Money
}, ct); }, ct);
await db.SaveChangesAsync(ct); await db.SaveChangesAsync(ct);
_logger.Info($"Added wager row with ID {wager.Entity.Id}"); _logger.Info($"Added wager row with ID {wager.Entity.Id}");
if (!autoModifyBalance) return gambler.Balance;
gambler.Balance += wagerEffect; gambler.Balance += wagerEffect;
if (!autoModifyBalance) return;
var txn = await db.Transactions.AddAsync(new TransactionDbModel var txn = await db.Transactions.AddAsync(new TransactionDbModel
{ {
@@ -394,6 +397,7 @@ public static class Money
}, ct); }, ct);
await db.SaveChangesAsync(ct); await db.SaveChangesAsync(ct);
_logger.Info($"Added transaction with ID {txn.Entity.Id}"); _logger.Info($"Added transaction with ID {txn.Entity.Id}");
return gambler.Balance;
} }
/// <summary> /// <summary>