aboutsummaryrefslogtreecommitdiff
path: root/internal/game/casino.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/casino.go')
-rw-r--r--internal/game/casino.go37
1 files changed, 33 insertions, 4 deletions
diff --git a/internal/game/casino.go b/internal/game/casino.go
index c52e5eb..58e1e69 100644
--- a/internal/game/casino.go
+++ b/internal/game/casino.go
@@ -116,9 +116,14 @@ func (w casinoWallet) ResolveStakes() {
if len(w.p.PendingWagers) == 0 {
return
}
+ before := append([]player.PendingWager(nil), w.p.PendingWagers...)
w.p.PendingWagers = nil
if err := w.g.AccountStore.SaveCharacter(w.p); err != nil {
- fmt.Fprintf(os.Stderr, "casino resolve stakes: save for %s: %v\n", w.p.Name, err)
+ // Keep the in-memory ledger consistent with the durable file: the
+ // stakes are still pending on disk, so restore them for a later
+ // retry or startup recovery instead of silently diverging.
+ w.p.PendingWagers = before
+ fmt.Fprintf(os.Stderr, "casino resolve stakes: save for %s: %v (ledger restored in memory)\n", w.p.Name, err)
}
}
@@ -127,11 +132,18 @@ func (w casinoWallet) ResolveStakes() {
// already removed it (PayCredits) makes this a no-op, so no redundant
// save is paid.
func (w casinoWallet) ResolveStake(stakeID string) {
- if stakeID == "" || !removePendingWager(w.p, stakeID) {
+ if stakeID == "" {
+ return
+ }
+ removed := takePendingWagers(w.p, []string{stakeID})
+ if len(removed) == 0 {
return
}
if err := w.g.AccountStore.SaveCharacter(w.p); err != nil {
- fmt.Fprintf(os.Stderr, "casino resolve stake: save for %s: %v\n", w.p.Name, err)
+ // The durable file still lists the stake, so restore it in memory to
+ // keep the two records consistent for a later retry/recovery.
+ w.p.PendingWagers = append(w.p.PendingWagers, removed...)
+ fmt.Fprintf(os.Stderr, "casino resolve stake: save for %s: %v (ledger restored in memory)\n", w.p.Name, err)
}
}
@@ -260,8 +272,25 @@ func (g *Game) casinoMachine(roomID int, gameName string) (*casino.Machine, bool
if casino.ValidateRoomConfigs(room.CasinoTables, room.CasinoMachines) != nil {
return nil, false
}
+ // Prefer an exact variant match first: a room may host several variants of
+ // one game, where a bare game name is ambiguous.
+ for _, cfg := range room.CasinoMachines {
+ if cfg.Variant != "" && strings.EqualFold(cfg.Variant, gameName) {
+ machine := g.Casino.EnsureMachine(roomID, cfg)
+ return machine, machine != nil
+ }
+ }
+ // Then a bare game name: prefer a variant-less machine so a machine that
+ // declares its own variant is reached by that variant, and a sole machine
+ // of a game is still reachable by the game name.
+ for _, cfg := range room.CasinoMachines {
+ if cfg.Variant == "" && strings.EqualFold(string(cfg.Game), gameName) {
+ machine := g.Casino.EnsureMachine(roomID, cfg)
+ return machine, machine != nil
+ }
+ }
for _, cfg := range room.CasinoMachines {
- if strings.EqualFold(string(cfg.Game), gameName) || strings.EqualFold(cfg.Variant, gameName) {
+ if strings.EqualFold(string(cfg.Game), gameName) {
machine := g.Casino.EnsureMachine(roomID, cfg)
return machine, machine != nil
}