summaryrefslogtreecommitdiffstats
path: root/web/play/index.html
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-11-08 03:29:35 +0100
committersalmonik <salmonik@tuta.io>2026-11-08 03:29:35 +0100
commit058432130628d00764663ecf819a9adc6793768d (patch)
treed3f49f111fbfaa48647cca2600adcf9017af2d30 /web/play/index.html
parentweb: serve latest.php through PHP and refuse stray PHP files (diff)
downloadzagan-bet-058432130628d00764663ecf819a9adc6793768d.tar.gz
zagan-bet-058432130628d00764663ecf819a9adc6793768d.zip
v5.0.0: protocol v5 and the browser frontend
Protocol v5 replaces newline lines with bounded [u32 len][text] frames and REQ/RES/EVT envelopes. Requests carry correlation ids and the server replays the last 256 replies per connection, so a gateway retry cannot double-debit and a late reply cannot clobber a newer request. HELLO/PONG carry server time; crash rounds announce started_at and push coalesced 10 Hz ticks. Crash now commits sha256(seed) before a round and reveals the seed when it ends, so clients recompute the crash point. Adds the webd/ gateway: one blocking thread, one ClientCore and one pinned upstream TLS connection per session, an HttpOnly session cookie, takeover, and a 60-second grace window. The browser sends Command JSON and renders View JSON; it never speaks the game protocol or stores credentials. Adds the vanilla TypeScript browser app at /play/ (login, lobby, all four games, history, notices, crash verification), the nginx /play and /ws routes, and the headless DOM smoke test. webd and the app stay out of the TUI/GUI/server build graph. The client/server version moves to 5.0.0 in lockstep; v4 peers are refused at HELLO.
Diffstat (limited to 'web/play/index.html')
-rw-r--r--web/play/index.html112
1 files changed, 112 insertions, 0 deletions
diff --git a/web/play/index.html b/web/play/index.html
new file mode 100644
index 0000000..e9d4b79
--- /dev/null
+++ b/web/play/index.html
@@ -0,0 +1,112 @@
1<!doctype html>
2<html lang="en">
3<head>
4<meta charset="utf-8">
5<meta name="viewport" content="width=device-width, initial-scale=1">
6<title>Play — żagań.bet</title>
7<meta name="description" content="Play slots, roulette, blackjack and crash with play credits. No real money.">
8<meta name="color-scheme" content="dark">
9<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: wss:; img-src 'self' data:; base-uri 'none'; form-action 'self'">
10<link rel="stylesheet" href="style.css">
11</head>
12<body>
13<div class="shell">
14 <header class="topbar">
15 <a class="brand" href="/">żagań<span>.bet</span></a>
16 <span class="tagline">Play credits · no real money</span>
17 <span class="spacer"></span>
18 <div id="session-bar" class="session" hidden>
19 <span class="who">Signed in as <strong id="account-name"></strong></span>
20 <span id="account-balance" class="balance">— Kr</span>
21 <button id="logout" class="btn ghost small" type="button">Log out</button>
22 </div>
23 </header>
24
25 <main>
26 <section id="auth-screen" hidden>
27 <div class="auth-wrap">
28 <div class="auth-card">
29 <h1>Play żagań.bet</h1>
30 <p class="muted" style="margin: 6px 0 20px">Play-money casino. Your balance is play credit; nothing here is real money.</p>
31 <div class="auth-tabs" role="tablist">
32 <button id="tab-login" class="auth-tab active" type="button" role="tab">Log in</button>
33 <button id="tab-register" class="auth-tab" type="button" role="tab">Register</button>
34 </div>
35 <form id="auth-form">
36 <label class="field">
37 <span class="label">Username</span>
38 <input id="auth-user" class="input" type="text" autocomplete="username" maxlength="32" required>
39 </label>
40 <label class="field">
41 <span class="label">Password</span>
42 <input id="auth-pass" class="input" type="password" autocomplete="current-password" required>
43 </label>
44 <p id="auth-error" class="error-text" style="margin: 0; min-height: 18px"></p>
45 <button id="auth-submit" class="btn primary wide big" type="submit">Log in</button>
46 </form>
47 <p class="auth-foot">Registration gives you 1 000 Kr of play credit. No deposits, no withdrawals, no personal data beyond a username.</p>
48 </div>
49 </div>
50 </section>
51
52 <section id="lobby-screen" hidden>
53 <div class="lobby-head">
54 <div>
55 <h1>Lobby</h1>
56 <p class="muted" style="margin: 4px 0 0">Choose a game. Bets are play credits.</p>
57 </div>
58 <span class="spacer"></span>
59 <button id="show-history" class="btn ghost" type="button">Play history</button>
60 <button id="refresh-lobby" class="btn ghost" type="button">Refresh</button>
61 </div>
62 <div id="game-grid" class="game-grid"></div>
63 </section>
64
65 <section id="game-screen" hidden>
66 <div class="game-head">
67 <button id="leave-game" class="btn ghost" type="button">← Lobby</button>
68 <h1 id="game-title">Game</h1>
69 <span class="spacer"></span>
70 <span id="game-badge" class="label"></span>
71 </div>
72 <div class="game-body">
73 <div id="game-board" class="board"></div>
74 <aside id="game-side" class="sidebar"></aside>
75 </div>
76 </section>
77
78 <section id="history-screen" hidden>
79 <div class="lobby-head">
80 <div>
81 <h1>Play history</h1>
82 <p class="muted" style="margin: 4px 0 0">The last plays on your account.</p>
83 </div>
84 <span class="spacer"></span>
85 <button id="history-back" class="btn ghost" type="button">← Lobby</button>
86 </div>
87 <div id="history-body"></div>
88 </section>
89 </main>
90</div>
91
92<div id="toasts" aria-live="polite"></div>
93
94<div id="replaced-overlay" class="overlay" hidden>
95 <div class="modal">
96 <h2>Opened in another tab</h2>
97 <p>This game was opened somewhere else. Only one tab can play a session at a time.</p>
98 <button id="reload-replaced" class="btn primary" type="button">Reload this tab</button>
99 </div>
100</div>
101
102<div id="reconnect-overlay" class="overlay" hidden>
103 <div class="modal">
104 <h2>Connection lost</h2>
105 <p id="reconnect-message">Trying to reach the game server…</p>
106 <button id="reload-reconnect" class="btn ghost" type="button">Reload</button>
107 </div>
108</div>
109
110<script src="app.js" defer></script>
111</body>
112</html>