From 7d0452f451a30aad4d360a7211701b389c5ad696 Mon Sep 17 00:00:00 2001 From: szymon Date: Sun, 16 Aug 2026 14:28:01 +0200 Subject: [PATCH] feat: add server update loop --- src/logic/math/position.rs | 4 +- src/network/client.rs | 1 + src/network/message.rs | 2 +- src/network/server.rs | 115 +++++++++++++++++++++---------------- 4 files changed, 69 insertions(+), 53 deletions(-) diff --git a/src/logic/math/position.rs b/src/logic/math/position.rs index 6dcaf6b..5b12c47 100644 --- a/src/logic/math/position.rs +++ b/src/logic/math/position.rs @@ -32,7 +32,9 @@ impl Position { trace!("Adding row: {} + {} = {}", self.row, delta.row, new_row); trace!( "Adding column: {} + {} = {}", - self.column, delta.column, new_column + self.column, + delta.column, + new_column ); Some(Position { diff --git a/src/network/client.rs b/src/network/client.rs index e69de29..8b13789 100644 --- a/src/network/client.rs +++ b/src/network/client.rs @@ -0,0 +1 @@ + diff --git a/src/network/message.rs b/src/network/message.rs index 7f1f483..cbdfad1 100644 --- a/src/network/message.rs +++ b/src/network/message.rs @@ -1,4 +1,4 @@ -use serde::{Deserialize, Serialize, de::DeserializeOwned}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use uuid::Uuid; use crate::logic::{ diff --git a/src/network/server.rs b/src/network/server.rs index 0f0718c..5bee189 100644 --- a/src/network/server.rs +++ b/src/network/server.rs @@ -4,7 +4,7 @@ use std::{ net::{IpAddr, Ipv4Addr, SocketAddr}, }; use tokio::{ - net::{TcpListener, TcpStream}, + net::TcpListener, sync::mpsc::{Receiver, Sender}, }; @@ -13,7 +13,7 @@ use crate::{ network::{ connection::{Connection, ConnectionType}, message::{ - ClientMessage::{self, AnswerHandshake, RequestCapture, RequestMove}, + ClientMessage::{self}, Message, ServerMessage, }, }, @@ -27,10 +27,14 @@ pub struct ServerSettings { } pub struct Server { - listener: TcpListener, + listener: Option, connections: HashMap>>, + reciever: Receiver<(SocketAddr, Message)>, sender: Sender<(SocketAddr, Message)>, + + welcoming_reciever: Option>)>>, + game_master: Option, settings: ServerSettings, } @@ -49,74 +53,83 @@ impl Server { // number Server { - listener: TcpListener::bind(settings.addr) - .await - .expect("Could not start the server"), // TODO! Handle this nicely, as this will + listener: Some( + TcpListener::bind(settings.addr) + .await + .expect("Could not start the server"), + ), // TODO! Handle this nicely, as this will // crash gui app connections: HashMap::new(), sender, reciever, + welcoming_reciever: None, game_master: None, settings, } } pub async fn start(&mut self) { - self.start_listening().await; - } + let (welcoming_tx, mut welcoming_rx) = + tokio::sync::mpsc::channel::<(SocketAddr, Sender>)>(10); - async fn start_listening(&mut self) { - // TODO! Maybe allow connection and then gently refuse with reason? - while self.connections.len() < self.settings.max_connections - && !self.settings.allow_spectators - { - match self.listener.accept().await { - Ok((socket, addr)) => { - self.handle_new_client(socket, addr); - } - Err(e) => { - error!("Error while accepting a new connection: {}", e); + self.welcoming_reciever = Some(welcoming_rx); + + let listener = self + .listener + .take() + .expect("Cannot start the server without tcp listener."); + + let sender = self.sender.clone(); + + tokio::spawn(async move { + loop { + if let Ok((socket, addr)) = listener.accept().await { + info!("New connection from: {:?}", addr); + let mut conn: Connection = + Connection::new(ConnectionType::Client, sender.clone()); + + conn.delegate(socket, addr); + + let sender = conn.get_sender(); + let _ = welcoming_tx.send((addr, sender)).await; + + tokio::spawn(async move { + conn.start_listening().await; + }); } } - } - } - - fn handle_new_client(&mut self, socket: TcpStream, addr: SocketAddr) { - info!("New connection from: {:?}", addr); - let mut conn: Connection = - Connection::new(ConnectionType::Client, self.sender.clone()); - - conn.delegate(socket, addr); - let sender = conn.get_sender(); - - self.connections.insert(addr, sender); - - self.listen_client(conn); - } - - fn listen_client(&mut self, mut conn: Connection) { - tokio::spawn(async move { - conn.start_listening().await; }); } /// Process incoming messages pub async fn update(&mut self) { - let Some(oldest_message) = self.reciever.recv().await else { - return; - }; + loop { + tokio::select! { + new_client_opt = self.welcoming_reciever.as_mut().expect("Welcoming reciever was not set. Was the server started?").recv() => { + if let Some((addr, sender)) = new_client_opt { + // TODO! Check size options etc + self.connections.insert(addr, sender); + self.request_handshake(addr).await; + } + } - let (addr, msg) = oldest_message; + msg_opt = self.reciever.recv() => { + if let Some(oldest_message) = msg_opt { + let (_addr, msg) = oldest_message; - match msg.content { - ClientMessage::AnswerHandshake { player_name } => { - self.process_handshake(); - } - ClientMessage::RequestCapture { capture_path } => { - self.process_capture(); - } - ClientMessage::RequestMove { from, to } => { - self.process_move(); + match msg.content { + ClientMessage::AnswerHandshake { player_name: _ } => { + self.process_handshake(); + } + ClientMessage::RequestCapture { capture_path: _ } => { + self.process_capture(); + } + ClientMessage::RequestMove { from: _, to: _ } => { + self.process_move(); + } + } + } + } } } }