summaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-07-14 21:00:54 +0200
committermetamuffin <metamuffin@disroot.org>2024-07-14 21:00:54 +0200
commitf6cc57f29fc65a33219b1266b3508dc40536f3c2 (patch)
tree3a5ee5897f778fd1e0547a3026060e579a4c7c56 /server/src
parent721b9ecb282f84839eb096de4d269176f8ab389f (diff)
downloadhurrycurry-f6cc57f29fc65a33219b1266b3508dc40536f3c2.tar
hurrycurry-f6cc57f29fc65a33219b1266b3508dc40536f3c2.tar.bz2
hurrycurry-f6cc57f29fc65a33219b1266b3508dc40536f3c2.tar.zst
add binary protocol support
Diffstat (limited to 'server/src')
-rw-r--r--server/src/main.rs92
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");