diff options
| author | historia <[not public]> | 2026-09-18 05:31:09 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-09-18 05:31:09 -0400 |
| commit | 153acb7f644d755c45533b7c5311e3ffa47e8973 (patch) | |
| tree | 7645e6f7b65bc3830b078e3b9336d2e6b199d584 /internal/game/cmd_bank.go | |
| parent | 87d08f0151e643951769e323995f1c5ed89ee200 (diff) | |
| download | thehouseoficarus-153acb7f644d755c45533b7c5311e3ffa47e8973.tar.gz | |
fix: harden engine across casino, economy, concurrency, security, and content
Diffstat (limited to 'internal/game/cmd_bank.go')
| -rw-r--r-- | internal/game/cmd_bank.go | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/internal/game/cmd_bank.go b/internal/game/cmd_bank.go index 6326700..468b173 100644 --- a/internal/game/cmd_bank.go +++ b/internal/game/cmd_bank.go @@ -2,6 +2,7 @@ package game import ( "fmt" + "log" "sort" "strconv" "strings" @@ -368,9 +369,13 @@ func (g *Game) doBankDepositCredits(sess *net.Session, parts []string) { sess.WriteLine("You don't have that many credits.") return } + creditsBefore, bankedBefore := p.Credits, p.BankedCredits p.Credits -= amount p.BankedCredits += amount - g.saveCharacter(p) + if !g.persistBankCredits(p, creditsBefore, bankedBefore) { + sess.WriteLine("The bank terminal could not record the transfer; nothing was moved.") + return + } sess.WriteLine(g.colorize(sess, "currency_pickup", fmt.Sprintf("You deposit %s credits. (Banked: %s)", formatInt(amount), formatInt(p.BankedCredits)))) g.showBankBrowse(sess) } @@ -396,13 +401,33 @@ func (g *Game) doBankWithdrawCredits(sess *net.Session, parts []string) { sess.WriteLine("Your wallet cannot hold that many credits.") return } + creditsBefore, bankedBefore := p.Credits, p.BankedCredits p.BankedCredits -= amount p.Credits += amount - g.saveCharacter(p) + if !g.persistBankCredits(p, creditsBefore, bankedBefore) { + sess.WriteLine("The bank terminal could not record the transfer; nothing was moved.") + return + } sess.WriteLine(g.colorize(sess, "currency_pickup", fmt.Sprintf("You withdraw %s credits.", formatInt(amount)))) g.showBankBrowse(sess) } +// persistBankCredits makes a credit move between the on-hand wallet and the +// bank durable, reverting it in memory when the save fails. A best-effort +// save here would leave the in-memory balance ahead of the durable file, and +// a wager taken from that phantom balance journals checkpoints the file can +// never match — recovery then leaves the stake permanently ambiguous instead +// of refunding or settling it. Reports whether the move may be announced. +func (g *Game) persistBankCredits(p *player.Player, creditsBefore, bankedBefore int) bool { + if err := g.AccountStore.SaveCharacter(p); err != nil { + log.Printf("bank credit transfer %s: %v", p.Name, err) + p.Credits = creditsBefore + p.BankedCredits = bankedBefore + return false + } + return true +} + func (g *Game) canUseBank(p *player.Player) bool { instances := g.World.FindObjInstances(p.RoomID, "bank booth") return len(instances) > 0 |
