From 058432130628d00764663ecf819a9adc6793768d Mon Sep 17 00:00:00 2001 From: salmonik Date: Sun, 8 Nov 2026 03:29:35 +0100 Subject: 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. --- src/bin/server/tls.rs | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'src/bin/server/tls.rs') diff --git a/src/bin/server/tls.rs b/src/bin/server/tls.rs index 420b5b4..eb94637 100644 --- a/src/bin/server/tls.rs +++ b/src/bin/server/tls.rs @@ -1,7 +1,7 @@ use std::io::{Read, Write}; use std::net::TcpStream; -use zagan_bet::protocol::LineBuffer; +use zagan_bet::protocol::{FrameBuffer, write_frame}; #[derive(Clone)] pub struct TlsServer { @@ -44,34 +44,31 @@ impl TlsServer { pub struct TlsStream { stream: native_tls::TlsStream, - lines: LineBuffer, + frames: FrameBuffer, } impl TlsStream { pub fn new(stream: native_tls::TlsStream) -> Self { Self { stream, - lines: LineBuffer::new(), + frames: FrameBuffer::new(), } } - pub fn read_line(&mut self, s: &mut String) -> std::io::Result { - match self.lines.read_line(&mut self.stream)? { - Some(line) => { - s.push_str(&line); - s.push('\n'); - Ok(line.len() + 1) + /// Read one protocol frame. `Ok(0)` is EOF with no partial frame. + pub fn read_frame(&mut self, out: &mut String) -> std::io::Result { + match self.frames.read_frame(&mut self.stream)? { + Some(frame) => { + let length = frame.len(); + out.push_str(&frame); + Ok(length) } None => Ok(0), } } - pub fn write_line(&mut self, msg: &str) -> std::io::Result<()> { - use std::io::Write; - self.stream.write_all(msg.as_bytes())?; - self.stream.write_all(b"\n")?; - self.stream.flush()?; - Ok(()) + pub fn write_frame(&mut self, msg: &str) -> std::io::Result<()> { + write_frame(&mut self.stream, msg) } pub fn peer_addr(&self) -> std::io::Result { -- cgit v1.2.3