use anyhow::Result; use log::{debug, info}; use std::{sync::Arc, time::Duration}; use tokio::{ io::{AsyncBufReadExt, AsyncWriteExt, BufReader}, net::TcpListener, spawn, sync::{broadcast, RwLock}, time::sleep, }; use undercooked::{ game::Game, protocol::{PacketC, PacketS}, }; #[tokio::main] async fn main() -> Result<()> { env_logger::init_from_env("LOG"); let listener = TcpListener::bind("0.0.0.0:27031").await?; info!("listening on {}", listener.local_addr()?); let game = Arc::new(RwLock::new(Game::new())); let (tx, rx) = broadcast::channel::(1024); { let game = game.clone(); spawn(async move { { let mut g = game.write().await; while let Some(p) = g.packet_out() { debug!("-> {p:?}"); let _ = tx.send(p); } } sleep(Duration::from_millis(10)).await; }); } for id in 0.. { let (sock, addr) = listener.accept().await?; let (read, mut write) = sock.into_split(); let game = game.clone(); let mut rx = rx.resubscribe(); info!("{addr} connected"); spawn(async move { while let Ok(packet) = rx.recv().await { write .write_all(serde_json::to_string(&packet).unwrap().as_bytes()) .await .unwrap(); write.write_all(b"\n").await.unwrap(); } }); spawn(async move { let mut read = BufReader::new(read).lines(); while let Ok(Some(line)) = read.next_line().await { let packet: PacketS = serde_json::from_str(&line).unwrap(); debug!("<- {id} {packet:?}"); game.write().await.packet_in(id, packet).unwrap(); } }); } Ok(()) }