summaryrefslogtreecommitdiffstats
path: root/src/bin/server
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/bin/server/handler.rs47
-rw-r--r--src/bin/server/tls.rs27
2 files changed, 44 insertions, 30 deletions
diff --git a/src/bin/server/handler.rs b/src/bin/server/handler.rs
index dffae69..e6b623f 100644
--- a/src/bin/server/handler.rs
+++ b/src/bin/server/handler.rs
@@ -1,6 +1,7 @@
1use std::time::Duration; 1use std::time::Duration;
2 2
3use crate::tls::TlsStream; 3use crate::tls::TlsStream;
4use zagan_bet::protocol::{event_line, parse_request, reply_line};
4use zagan_bet::server::core::{ConnectionState, ServerCore}; 5use zagan_bet::server::core::{ConnectionState, ServerCore};
5 6
6/// How long the connection waits for a request before advancing timed games. 7/// How long the connection waits for a request before advancing timed games.
@@ -30,24 +31,35 @@ pub fn handle_client_tls(mut stream: TlsStream) {
30 } 31 }
31 32
32 let mut state = ConnectionState::default(); 33 let mut state = ConnectionState::default();
34 let mut event_seq = 0u64;
33 println!("[TLS Client connected] {client_addr}"); 35 println!("[TLS Client connected] {client_addr}");
34 36
35 'connection: loop { 37 'connection: loop {
36 let mut line = String::new(); 38 let mut frame = String::new();
37 match stream.read_line(&mut line) { 39 match stream.read_frame(&mut frame) {
38 Ok(0) => break, 40 Ok(0) => break,
39 Ok(_) => { 41 Ok(_) => {
40 let line = line.trim(); 42 let user = state.user().unwrap_or("guest").to_string();
41 if !line.is_empty() { 43 println!("[{user} @ {client_addr}] Received: {frame}");
42 let user = state.user().unwrap_or("guest").to_string(); 44 match parse_request(&frame) {
43 println!("[{user} @ {client_addr}] Received: {line}"); 45 Ok(request) => {
44 let response = core.handle_message(&mut state, line); 46 let response = core.handle_request(&mut state, &request);
45 if let Err(error) = stream.write_line(&response) { 47 let reply = reply_line(request.id, &response);
46 eprintln!("Write error: {error}"); 48 if let Err(error) = stream.write_frame(&reply) {
47 break; 49 eprintln!("Write error: {error}");
50 break;
51 }
52 let user = state.user().unwrap_or("guest");
53 println!("[{user} @ {client_addr}] Sent: {reply}");
54 }
55 Err(message) => {
56 let reply = reply_line(0, &format!("ERROR {message}"));
57 if let Err(error) = stream.write_frame(&reply) {
58 eprintln!("Write error: {error}");
59 break;
60 }
61 eprintln!("Malformed request from {client_addr}: {reply}");
48 } 62 }
49 let user = state.user().unwrap_or("guest");
50 println!("[{user} @ {client_addr}] Sent: {response}");
51 } 63 }
52 } 64 }
53 Err(error) 65 Err(error)
@@ -65,12 +77,17 @@ pub fn handle_client_tls(mut stream: TlsStream) {
65 } 77 }
66 78
67 for push in core.poll(&state) { 79 for push in core.poll(&state) {
68 if let Err(error) = stream.write_line(&push) { 80 event_seq = event_seq.wrapping_add(1);
81 let event = event_line(event_seq, &push);
82 if let Err(error) = stream.write_frame(&event) {
69 eprintln!("Write error: {error}"); 83 eprintln!("Write error: {error}");
70 break 'connection; 84 break 'connection;
71 } 85 }
72 let user = state.user().unwrap_or("guest"); 86 // Ticks are 10 Hz per live round; logging them floods the disk.
73 println!("[{user} @ {client_addr}] Pushed: {push}"); 87 if !push.starts_with("crash.tick ") {
88 let user = state.user().unwrap_or("guest");
89 println!("[{user} @ {client_addr}] Pushed: {event}");
90 }
74 } 91 }
75 } 92 }
76 93
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 @@
1use std::io::{Read, Write}; 1use std::io::{Read, Write};
2use std::net::TcpStream; 2use std::net::TcpStream;
3 3
4use zagan_bet::protocol::LineBuffer; 4use zagan_bet::protocol::{FrameBuffer, write_frame};
5 5
6#[derive(Clone)] 6#[derive(Clone)]
7pub struct TlsServer { 7pub struct TlsServer {
@@ -44,34 +44,31 @@ impl TlsServer {
44 44
45pub struct TlsStream { 45pub struct TlsStream {
46 stream: native_tls::TlsStream<TcpStream>, 46 stream: native_tls::TlsStream<TcpStream>,
47 lines: LineBuffer, 47 frames: FrameBuffer,
48} 48}
49 49
50impl TlsStream { 50impl TlsStream {
51 pub fn new(stream: native_tls::TlsStream<TcpStream>) -> Self { 51 pub fn new(stream: native_tls::TlsStream<TcpStream>) -> Self {
52 Self { 52 Self {
53 stream, 53 stream,
54 lines: LineBuffer::new(), 54 frames: FrameBuffer::new(),
55 } 55 }
56 } 56 }
57 57
58 pub fn read_line(&mut self, s: &mut String) -> std::io::Result<usize> { 58 /// Read one protocol frame. `Ok(0)` is EOF with no partial frame.
59 match self.lines.read_line(&mut self.stream)? { 59 pub fn read_frame(&mut self, out: &mut String) -> std::io::Result<usize> {
60 Some(line) => { 60 match self.frames.read_frame(&mut self.stream)? {
61 s.push_str(&line); 61 Some(frame) => {
62 s.push('\n'); 62 let length = frame.len();
63 Ok(line.len() + 1) 63 out.push_str(&frame);
64 Ok(length)
64 } 65 }
65 None => Ok(0), 66 None => Ok(0),
66 } 67 }
67 } 68 }
68 69
69 pub fn write_line(&mut self, msg: &str) -> std::io::Result<()> { 70 pub fn write_frame(&mut self, msg: &str) -> std::io::Result<()> {
70 use std::io::Write; 71 write_frame(&mut self.stream, msg)
71 self.stream.write_all(msg.as_bytes())?;
72 self.stream.write_all(b"\n")?;
73 self.stream.flush()?;
74 Ok(())
75 } 72 }
76 73
77 pub fn peer_addr(&self) -> std::io::Result<std::net::SocketAddr> { 74 pub fn peer_addr(&self) -> std::io::Result<std::net::SocketAddr> {