diff options
Diffstat (limited to 'server/respack_ws')
-rw-r--r-- | server/respack_ws/Cargo.toml | 13 | ||||
-rw-r--r-- | server/respack_ws/src/main.rs | 78 |
2 files changed, 91 insertions, 0 deletions
diff --git a/server/respack_ws/Cargo.toml b/server/respack_ws/Cargo.toml new file mode 100644 index 0000000..389b2fa --- /dev/null +++ b/server/respack_ws/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "respack_ws" +version = "0.1.0" +edition = "2024" + +[dependencies] +anyhow = "1.0.97" +clap = { version = "4.5.32", features = ["derive"] } +env_logger = "0.11.7" +log = "0.4.26" +weareshared = { path = "../../shared" } +hex = "0.4.3" +tungstenite = "0.26.2"
\ No newline at end of file diff --git a/server/respack_ws/src/main.rs b/server/respack_ws/src/main.rs new file mode 100644 index 0000000..d263b9c --- /dev/null +++ b/server/respack_ws/src/main.rs @@ -0,0 +1,78 @@ +#![feature(slice_as_array)] +use anyhow::Result; +use clap::Parser; +use log::{error, warn}; +use std::{ + marker::PhantomData, + net::{IpAddr, SocketAddr, TcpListener}, + path::PathBuf, + sync::Arc, + thread::spawn, +}; +use tungstenite::{Message, accept}; +use weareshared::{packets::Resource, store::ResourceStore}; + +#[derive(Parser, Debug)] +struct Args { + #[arg(short, long, default_value = "::")] + bind_addr: IpAddr, + #[arg(short, long, default_value = "28557")] + port: u16, + + pack: PathBuf, +} + +fn main() -> Result<()> { + env_logger::init_from_env("LOG"); + let args = Args::parse(); + let listener = TcpListener::bind(SocketAddr::new(args.bind_addr, args.port)).unwrap(); + let store = Arc::new(ResourceStore::new_respack_file(&args.pack)?); + + loop { + let (stream, _) = listener.accept()?; + let store = store.clone(); + spawn(move || { + let mut websocket = accept(stream).unwrap(); + loop { + let Ok(msg) = websocket.read() else { break }; + match msg { + Message::Text(a) => { + let a = a.to_string(); + let r = if a == "entry" { + if let ResourceStore::Respack(pack) = &*store { + let pack = pack.lock().unwrap(); + if let Some(entry) = pack.entry() { + websocket.send(Message::Binary(entry.0.to_vec().into())) + } else { + websocket.send(Message::Text("no_entry".into())) + } + } else { + unreachable!() + } + } else { + websocket.send(Message::Text("unknown_packet".into())) + }; + if let Err(e) = r { + warn!("{e}"); + } + } + Message::Binary(bytes) if bytes.len() == 32 => { + let res = Resource(*bytes.as_array().unwrap(), PhantomData); + let r = match store.get_raw(res) { + Ok(Some(data)) => websocket.send(Message::Binary(data.into())), + Ok(None) => websocket.send(Message::Text("not_found".into())), + Err(e) => { + error!("{e}"); + websocket.send(Message::Text("error".into())) + } + }; + if let Err(e) = r { + warn!("{e}"); + } + } + _ => (), + } + } + }); + } +} |