use std::net::SocketAddr; use serde::Deserialize; use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter}; use tokio::net::{TcpListener, TcpStream}; use tokio::sync::oneshot::channel; use crate::core::player::{PlayerRegistry, Updates}; use crate::prelude::*; use crate::protos::irc::*; use crate::util::Terminator; #[derive(Deserialize, Debug)] pub struct ServerConfig { pub listen_on: SocketAddr, } async fn handle_socket( mut stream: TcpStream, socket_addr: SocketAddr, mut players: PlayerRegistry, ) { let (reader, writer) = stream.split(); let mut reader = BufReader::new(reader); let mut writer = BufWriter::new(writer); let mut buffer = vec![]; // let (player_id, mut player_handle) = players.create_player().await; // let mut sub = player_handle.subscribe().await; loop { select! { biased; res = reader.read_until(b'\n', &mut buffer) => { match res { Ok(len) => if len == 0 { log::info!("Terminating socket"); break; }, Err(err) => log::warn!("Failed to read from socket: {err}"), } let parsed = parse_client_message(&buffer[..]); match parsed { Ok((rest, msg)) => { log::info!("Incoming IRC message: {msg:?}"); }, Err(err) => { log::warn!("Failed to parse IRC message: {err}"); }, } buffer.clear(); }, } } } pub async fn launch(config: &ServerConfig, players: PlayerRegistry) -> Result { log::info!("Starting IRC projection"); let (signal, mut rx) = channel(); let listener = TcpListener::bind(config.listen_on).await?; log::debug!("Listener started"); let handle = tokio::task::spawn(async move { loop { select! { biased; _ = &mut rx => break, new_conn = listener.accept() => { match new_conn { Ok((stream, socket_addr)) => { log::debug!("Incoming connection from {socket_addr}"); let handle = tokio::task::spawn(handle_socket(stream, socket_addr, players.clone())); }, Err(err) => log::warn!("Failed to accept new connection: {err}"), } }, } } log::info!("Stopping IRC projection"); Ok(()) }); let terminator = Terminator::from_raw(signal, handle); Ok(terminator) }