Commit Graph
4 Commits
Author SHA1 Message Date
jwinterm 89398335c7 feat: productionize paid modes and PvP capture 2026-07-21 20:41:27 -04:00
jwinterm a62eefb47b fix: resolve security/correctness review + AAA graphics pass
Backend (Tier 0/1/3): single-payout double-pay -> needs_review; admin-retry tx_hash guard; UNIQUE index on games.payment_id (migration 023) + atomic claim; reconnect no longer resets block-timeout; completeGame keys on user_id+dungeon_seed (not socket_id); token-gated /api/user/:socketId/* endpoints; payout min/max enforcement; orphaned-active-game boot recovery; sessionManager cleanup FK fix; XFF rightmost-hop; global uncaughtException/unhandledRejection guard; server binds 127.0.0.1; provably-fair client-seed (HMAC) + RNG [0,1) bound; difficulty preset ranges reach the digger; chat no longer leaks full socket.id; removed dangerous-keyword SQL theater.

Match mode (Tier 2, still MATCH_ENABLED-gated): fixed match_queue/match_move crash paths + scheduler dead-code + leaked ceiling timer; pot collected before start with abort+refund; BigInt/basis-point fee math, capped payout; no-address winner claimable; winnerId==placement[0]; finalize schema + payout-first isolation; reconnect re-key with ownership; refunds on all cancel paths; real countdown; map/timer cleanup. +16 tests.

Graphics: new overlay FX layer (torch light, vignette, embers, sparkle/burst/flash/shake, self-suspending rAF); gameplay juice; atmospheric screens; CSS design-token chrome with framed modals; richer Kenney tile renderer; imported Kenney dungeon/interior sheets + fx particles.

Verification: 45 suites / 312 tests pass; 40 changed JS files parse; 20 server modules load clean; no regressions.
2026-07-09 17:46:58 -04:00
jwinterm d8d10728ba fix: gate direct (entry-fee) payouts behind DIRECT_PAYOUTS_ENABLED
completeGame only gated PAID_CREDITS payouts (on creditsPayoutEnabled); a
PAID_SINGLE win paid out unconditionally, so DIRECT_PAYOUTS_ENABLED=false did
NOT actually stop direct payouts — a no-payout instance (mainnet legitimacy)
would still send crypto on an entry-fee win. Caught during deploy verification.

- Add this.directPayoutEnabled (from DIRECT_PAYOUTS_ENABLED env / direct rule
  enabled in the config snapshot), mirroring creditsPayoutEnabled.
- completeGame now gates the PAID_SINGLE payout on directPayoutEnabled.
- The derived directPayoutsEnabled flags (getGameModeInfo / effective mode)
  and /api/game-modes PAID_SINGLE.payoutMultiplier now respect it (show 0 when
  off) instead of inferring from multipliers > 0.

Adds a regression test: a PAID_SINGLE win with directPayoutEnabled=false
queues no payout. Full suite: 22 suites / 159 tests.
2026-05-31 15:25:46 -04:00
jwinterm 473a4091d4 fix: snapshot payout terms at game start (what-you-saw-is-what-you-get)
Payouts were computed at completion from LIVE config, so an admin changing
multipliers mid-game would change the payout of an already-in-progress game.

- Migration 016 adds payout_escape_amount/payout_treasure_amount (BIGINT) and
  the corresponding multipliers to the games table.
- Both game-start paths stamp the resolved payout amounts (computed from the
  config in effect at entry) onto the game row.
- completeGame pays from the snapshot, falling back to live calculation only
  for legacy games that predate the snapshot columns.

Adds payoutSnapshot.test.js proving a mid-game config change cannot alter an
in-flight payout. Full suite: 15 suites / 131 tests.
2026-05-31 09:55:45 -04:00