diff options
author | metamuffin <metamuffin@disroot.org> | 2024-07-14 21:00:54 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-07-14 21:00:54 +0200 |
commit | f6cc57f29fc65a33219b1266b3508dc40536f3c2 (patch) | |
tree | 3a5ee5897f778fd1e0547a3026060e579a4c7c56 /server/src/main.rs | |
parent | 721b9ecb282f84839eb096de4d269176f8ab389f (diff) | |
download | hurrycurry-f6cc57f29fc65a33219b1266b3508dc40536f3c2.tar hurrycurry-f6cc57f29fc65a33219b1266b3508dc40536f3c2.tar.bz2 hurrycurry-f6cc57f29fc65a33219b1266b3508dc40536f3c2.tar.zst |
add binary protocol support
Diffstat (limited to 'server/src/main.rs')
-rw-r--r-- | server/src/main.rs | 92 |
1 files changed, 58 insertions, 34 deletions
diff --git a/server/src/main.rs b/server/src/main.rs index 90d090d8..6f73851a 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -18,10 +18,19 @@ use anyhow::{anyhow, Result}; use clap::Parser; use futures_util::{SinkExt, StreamExt}; -use hurrycurry_protocol::{PacketC, PacketS, PlayerID, VERSION}; +use hurrycurry_protocol::{PacketC, PacketS, PlayerID, BINCODE_CONFIG, VERSION}; use hurrycurry_server::{data::DATA_DIR, state::State}; use log::{debug, info, trace, warn, LevelFilter}; -use std::{path::PathBuf, process::exit, str::FromStr, sync::Arc, time::Duration}; +use std::{ + path::PathBuf, + process::exit, + str::FromStr, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, + time::Duration, +}; use tokio::{ net::TcpListener, spawn, @@ -121,9 +130,14 @@ async fn run() -> anyhow::Result<()> { PacketC::Version { major: VERSION.0, minor: VERSION.1, + supports_bincode: true, }, ); init.insert(1, PacketC::Init { id }); + + let supports_binary = Arc::new(AtomicBool::new(false)); + let supports_binary2 = supports_binary.clone(); + spawn(async move { for p in init { if let Err(e) = write @@ -154,52 +168,62 @@ async fn run() -> anyhow::Result<()> { info!("client outbound sender dropped. closing connection"); break; }; - if let Err(e) = write - .send(tokio_tungstenite::tungstenite::Message::Text( - serde_json::to_string(&packet).unwrap(), - )) - .await - { + let message = if supports_binary.load(Ordering::Relaxed) { + Message::Binary(bincode::encode_to_vec(&packet, BINCODE_CONFIG).unwrap()) + } else { + Message::Text(serde_json::to_string(&packet).unwrap()) + }; + if let Err(e) = write.send(message).await { warn!("ws error: {e}"); break; } } }); + spawn(async move { info!("{id:?} joined"); while let Some(Ok(message)) = read.next().await { - match message { - Message::Text(line) => { - let packet = match serde_json::from_str(&line) { - Ok(p) => p, - Err(e) => { - warn!("invalid packet: {e}"); - break; - } - }; - if matches!( - packet, - PacketS::Position { .. } | PacketS::ReplayTick { .. } - ) { - trace!("<- {id:?} {packet:?}"); - } else { - debug!("<- {id:?} {packet:?}"); + let packet = match message { + Message::Text(line) => match serde_json::from_str(&line) { + Ok(p) => p, + Err(e) => { + warn!("invalid json packet: {e}"); + break; } - let packet_out = match state.write().await.packet_in(id, packet).await { - Ok(packets) => packets, + }, + Message::Binary(packet) => { + supports_binary2.store(true, Ordering::Relaxed); + match bincode::decode_from_slice::<PacketS, _>(&packet, BINCODE_CONFIG) { + Ok((p, _size)) => p, Err(e) => { - warn!("client error: {e}"); - vec![PacketC::Error { - message: format!("{e}"), - }] + warn!("invalid binary packet: {e}"); + break; } - }; - for packet in packet_out { - let _ = error_tx.send(packet).await; } } Message::Close(_) => break, - _ => (), + _ => continue, + }; + + if matches!( + packet, + PacketS::Position { .. } | PacketS::ReplayTick { .. } + ) { + trace!("<- {id:?} {packet:?}"); + } else { + debug!("<- {id:?} {packet:?}"); + } + let packet_out = match state.write().await.packet_in(id, packet).await { + Ok(packets) => packets, + Err(e) => { + warn!("client error: {e}"); + vec![PacketC::Error { + message: format!("{e}"), + }] + } + }; + for packet in packet_out { + let _ = error_tx.send(packet).await; } } info!("{id:?} left"); |