#![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}"); } } _ => (), } } }); } }