use std::net::TcpListener; use std::thread; use std::sync::{Arc, Mutex}; use tungstenite::protocol::Message; use sha2::{Sha256, Digest}; fn main() { let code_generator = Arc::new(Mutex::new(CodeGenerator { counter: 0, salt: [0; 32], // TODO have this be randomized on startup })); let server = TcpListener::bind("127.0.0.1:8080").unwrap(); for stream in server.incoming() { thread::spawn ( { let code_generator = Arc::clone(&code_generator); move || { let mut ws = tungstenite::accept(stream.unwrap()).unwrap(); println!("New client!"); ws.write_message(Message::Text("HOSTJOIN:".to_string())).unwrap(); loop { let message = ws.read_message(); println!("{:?}", message); match message { Err(_) => break, Ok(Message::Text(msg)) => match msg.as_str().trim() { "HOST:" => { ws.write_message(Message::Text(code_generator.lock().unwrap().generate())).unwrap(); }, _ => unimplemented!(), }, _ => unimplemented!(), } } }}); } } struct Room { players: Vec, } struct Player { name: String, } struct CodeGenerator { counter: u64, salt: [u8; 32], } impl CodeGenerator { fn generate(&mut self) -> String { let count = self.counter; self.counter += 1; let mut hasher = Sha256::new(); hasher.update(self.salt); hasher.update(count.to_be_bytes()); format!("{:x}", hasher.finalize())[..6].to_string() } }