diff --git a/src/bin/client.rs b/src/bin/client.rs index 7a58ae6..7e6f446 100644 --- a/src/bin/client.rs +++ b/src/bin/client.rs @@ -26,6 +26,12 @@ async fn main() -> Result<(), Box> { buffer = String::from("A").repeat(1024 * 1024 * 2); } + if buffer == "/ready\n" { + buffer.clear(); + client.signal_readiness().await; + continue; + } + client.send_text_message(buffer.clone()).await; buffer.clear(); } diff --git a/src/network/client.rs b/src/network/client.rs index 481b1dd..4b50f72 100644 --- a/src/network/client.rs +++ b/src/network/client.rs @@ -6,7 +6,7 @@ use tokio::sync::mpsc::{self, Receiver, Sender}; use crate::network::{ connection::{Connection, ConnectionType}, message::{ - ClientMessage::{self, TextMessage}, + ClientMessage::{self, SignalReadiness, TextMessage}, Message, ServerMessage, }, }; @@ -80,7 +80,10 @@ impl Client { let _ = sender.send(msg.unwrap()).await; } ServerMessage::AcceptHandshake { player_id } => todo!(), - ServerMessage::DeclineHandshake { reason } => todo!(), + ServerMessage::DeclineHandshake { reason } => { + error!("Server declined connection: {}", reason); + break; + } ServerMessage::AvailableCaptures { captures } => todo!(), ServerMessage::AvailableMoves { moves } => todo!(), ServerMessage::BroadcastBoardState { board } => todo!(), @@ -96,10 +99,17 @@ impl Client { } pub async fn send_text_message(&mut self, content: String) { + debug!("Seding text message: {}", content); let msg = Message::new(TextMessage(content)); self.send_message(msg).await; } + pub async fn signal_readiness(&mut self) { + debug!("Signaling readiness!"); + let msg = Message::new(SignalReadiness); + self.send_message(msg).await; + } + async fn send_message(&mut self, msg: Result, postcard::Error>) { debug!("Sending message to the server!"); let _ = match msg { diff --git a/src/network/message.rs b/src/network/message.rs index 08a7076..9d175eb 100644 --- a/src/network/message.rs +++ b/src/network/message.rs @@ -50,6 +50,7 @@ pub enum ServerMessage { #[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)] pub enum ClientMessage { AnswerHandshake { player_name: String }, + SignalReadiness, RequestCapture { capture_path: CapturePath }, RequestMove { from: Position, to: Position }, diff --git a/src/network/server.rs b/src/network/server.rs index b315957..f44ce54 100644 --- a/src/network/server.rs +++ b/src/network/server.rs @@ -26,6 +26,27 @@ pub struct ServerSettings { pub allow_spectators: bool, } +#[derive(PartialEq)] +enum ServerStage { + Lobby, + Game, + End, +} + +struct ServerState { + ready_count: usize, + stage: ServerStage, +} + +impl Default for ServerState { + fn default() -> Self { + Self { + ready_count: 0, + stage: ServerStage::Lobby, + } + } +} + pub struct Server { listener: Option, connections: HashMap>>, @@ -37,6 +58,8 @@ pub struct Server { game_master: Option, settings: ServerSettings, + + state: ServerState, } impl Server { @@ -65,6 +88,7 @@ impl Server { welcoming_reciever: None, game_master: None, settings, + state: ServerState::default(), } } @@ -109,9 +133,13 @@ impl Server { 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; + if self.state.stage == ServerStage::Lobby && self.connections.keys().len() < self.settings.max_connections && !self.settings.allow_spectators { + self.connections.insert(addr, sender); + self.request_handshake(addr).await; + } else { + let msg = Message::new(ServerMessage::DeclineHandshake { reason: "There is currently game going and it doesn't allow spectators".to_string() }); + self.send_message(addr, msg).await; + } } else { warn!("Welcoming reciever closed!"); break; @@ -126,12 +154,24 @@ impl Server { ClientMessage::AnswerHandshake { player_name } => { self.process_handshake(addr, player_name); } + + ClientMessage::SignalReadiness => { + self.state.ready_count += 1; + info!("{} signaled readiness. Currently ready: {}/{}", addr, self.state.ready_count, self.settings.max_connections); + if self.state.ready_count == self.settings.max_connections { + info!("All players are ready! Changing state to ServerStage::Game"); + self.state.stage = ServerStage::Game; + } + }, + ClientMessage::RequestCapture { capture_path: _ } => { self.process_capture(); } + ClientMessage::RequestMove { from: _, to: _ } => { self.process_move(); } + ClientMessage::TextMessage (content) => { info!("{} sent us a message: {}", addr, content); }