diff --git a/src/bin/client.rs b/src/bin/client.rs index 74f5341..44ed9cf 100644 --- a/src/bin/client.rs +++ b/src/bin/client.rs @@ -5,12 +5,9 @@ use std::{ use checkers::{ logic::board::pawn::{CapturePath, MovePath}, - network::{ - client::{Client, ClientData}, - network_identity::NetworkIdentity, - }, + network::{client::Client, message::ServerMessage, network_identity::NetworkIdentity}, }; -use log::{error, info, warn}; +use log::{error, warn}; use tokio::sync::mpsc; const QUIT_COMMAND: &str = "/quit"; @@ -86,9 +83,6 @@ async fn main() -> Result<(), Box> { return Ok(()); }; - let (client_sender, mut client_receiver) = mpsc::channel(1024); - - client.set_update_sender(client_sender); client.update(); let (stdin_sender, mut stdin_receiver) = mpsc::channel(1024); @@ -108,6 +102,10 @@ async fn main() -> Result<(), Box> { } }); + let mut client_receiver = client + .get_update_receiver() + .expect("Could not get update receiver from the network client"); + let help_msg: String = format!( "\n┌────Help──────────────────────────── │\t {} - quit @@ -122,61 +120,64 @@ async fn main() -> Result<(), Box> { QUIT_COMMAND, HELP_COMMAND, READY_COMMAND, SEND_COMMAND, CAPTURE_COMMAND, MOVE_COMMAND ); - info!("───────Type /help for help───────"); + println!("───────Type /help for help───────"); loop { tokio::select! { msg = client_receiver.recv() => { match msg { - Some(ClientData::GameStart { + Some(ServerMessage::GameStart { identity, }) => { - info!( + println!( "Got new identity: {}", identity ); context.identity = Some(identity); } - Some(ClientData::BoardView(view)) => { - info!("New board state:\n{}", view.to_string(&context.identity.as_ref().unwrap().id)); - + Some(ServerMessage::BroadcastBoardState{board}) => { + println!("New board state:\n{}", board.to_string(&context.identity.as_ref().unwrap().id)); } - Some(ClientData::CurrentTurn(current_turn)) => { - context.is_my_turn = current_turn == context.identity.as_ref().expect("Server sent us new current turn without telling us who we are!").id; + Some(ServerMessage::BroadcastCurrentTurn{active_player}) => { + context.is_my_turn = active_player == context.identity.as_ref().expect("Server sent us new current turn without telling us who we are!").id; if context.is_my_turn { - info!("It's our turn!"); + println!("It's our turn!"); } else { - info!("It's the turn of our enemy!"); + println!("It's the turn of our enemy!"); } } - Some(ClientData::AvailableCaptures(capture_paths)) => { - info!("Available captures paths: {:?}", capture_paths); + Some(ServerMessage::AvailableCaptures{captures}) => { + println!("Available captures paths: {:?}", captures); context.available_moves = None; - context.available_captures = Some(capture_paths); + context.available_captures = Some(captures); } - Some(ClientData::AvailableMoves(move_paths)) => { - info!("Available moves: {:?}", move_paths); - context.available_moves = Some(move_paths); + Some(ServerMessage::AvailableMoves{moves}) => { + println!("Available moves: {:?}", moves); + context.available_moves = Some(moves); context.available_captures = None; }, - Some(ClientData::TextMessage {sender, content}) => { - info!("[{}] - {}", sender, content); + Some(ServerMessage::BroadCastTextMessage {sender, content}) => { + println!("[{}] - {}", sender, content); } - Some(ClientData::GameEnd(game_result)) => { - info!("Game has ended with the result: {:?}", game_result); + Some(ServerMessage::GameEnd{result}) => { + println!("Game has ended with the result: {:?}", result); } + Some(_) => { + error!("This shouldn't happen"); + } // ignore messages already handled by the network client + None => { warn!("Connection broken! Stopping"); break Ok(()); } } - } + } buffer_opt = stdin_receiver.recv() => { if let Some(mut buffer) = buffer_opt { @@ -189,11 +190,11 @@ async fn main() -> Result<(), Box> { match CliCommands::try_from(cmd) { Ok(cmd) => match cmd { CliCommands::Quit => { - info!("Bye bye"); + println!("Bye bye"); std::process::exit(0); } CliCommands::Help => { - info!("{}", help_msg); + println!("{}", help_msg); } CliCommands::Ready => { client.signal_readiness().await; diff --git a/src/network/client.rs b/src/network/client.rs index 9fe4b44..a397473 100644 --- a/src/network/client.rs +++ b/src/network/client.rs @@ -1,25 +1,16 @@ use std::net::SocketAddr; -use log::{debug, error, info, warn}; +use log::{debug, error, info}; use tokio::sync::mpsc::{self, Receiver, Sender}; -use uuid::Uuid; use crate::{ - logic::{ - board::{ - board_view::BoardView, - pawn::{CapturePath, MovePath}, - }, - game_master::GameResult, - math::position::Position, - }, + logic::{board::pawn::CapturePath, math::position::Position}, network::{ connection::{Connection, ConnectionType}, message::{ - ClientMessage::{self, SignalReadiness, TextMessage}, + ClientMessage::{self}, Message, ServerMessage, }, - network_identity::NetworkIdentity, }, settings::{client_settings::ClientSettings, general_settings::SettingsLike}, }; @@ -31,30 +22,13 @@ pub enum ClientCommands { SendReady, } -/// Data that network client gives to normal client. I have no better idea for this name, hence this -/// comment -pub enum ClientData { - GameStart { identity: NetworkIdentity }, - GameEnd(GameResult), - - AvailableCaptures(Vec), - AvailableMoves(Vec), - - BoardView(BoardView), - CurrentTurn(Uuid), - - TextMessage { sender: String, content: String }, -} - pub struct Client { conn_reciever_incoming: Option)>>, conn_sender_outgoing: Sender>, settings: ClientSettings, - commands_sender: Option>, - commands_receiver: Option>, - - update_sender: Option>, + update_sender: Sender, + update_receiver: Option>, } impl Client { @@ -67,7 +41,7 @@ impl Client { Connection::new(ConnectionType::Server, conn_sender); let conn_sender_outgoing = conn.get_sender(); - let (commands_sender, commands_receiver) = mpsc::channel(1024); + let (update_sender, update_receiver) = mpsc::channel(1024); if !conn.connect_to_server(settings.server_url).await { error!("Could not connect with the server: {}", settings.server_url); @@ -84,29 +58,11 @@ impl Client { settings, - commands_receiver: Some(commands_receiver), - commands_sender: Some(commands_sender), - - update_sender: None, + update_sender, + update_receiver: Some(update_receiver), }) } - pub fn get_commands_sender(&mut self) -> Option> { - if self.commands_sender.is_none() { - warn!("Tried taking commands sender a second time! This shouldn't happen"); - } - self.commands_sender.take() - } - - pub fn set_update_sender(&mut self, sender: Sender) { - if self.update_sender.is_some() { - warn!("Cannot set update sender a second time!"); - return; - } - - self.update_sender = Some(sender); - } - pub fn update(&mut self) { let Some(mut conn_reciever_incoming) = self.conn_reciever_incoming.take() else { error!("Tried updating, but there's no conn_reciever of incoming messages!"); @@ -115,17 +71,8 @@ impl Client { let conn_sender = self.conn_sender_outgoing.clone(); - let Some(update_sender) = self.update_sender.take() else { - error!("Update sender is missing. Cannot update!"); - return; - }; - - let Some(mut commands_receiver) = self.commands_receiver.take() else { - error!("Commands receiver is missing! Cannot update."); - return; - }; - let settings = self.settings.clone(); + let update_sender = self.update_sender.clone(); tokio::spawn(async move { loop { @@ -154,131 +101,63 @@ impl Client { break; } - ServerMessage::GameStart { - identity, - } => { - debug!("Got GameStart message! Identity: {}", identity); - let _ = update_sender.send(ClientData::GameStart { identity }).await; + _ => { // Pass all messages that require player intervention to the + // local client + let _ = update_sender.send(msg.content).await; } - - ServerMessage::BroadcastCurrentTurn { active_player } => { - let _ = update_sender.send(ClientData::CurrentTurn(active_player)).await; - }, - ServerMessage::BroadcastBoardState { board } => { - let _ = update_sender.send(ClientData::BoardView(board)).await; - }, - - ServerMessage::BroadCastTextMessage {sender, content} => { - let _ = update_sender.send(ClientData::TextMessage {sender, content}).await; - } - - - ServerMessage::AvailableCaptures { captures } => { - let _ = update_sender.send(ClientData::AvailableCaptures(captures)).await; - }, - - ServerMessage::AvailableMoves { moves } => { - let _ = update_sender.send(ClientData::AvailableMoves(moves)).await; - }, - - ServerMessage::GameEnd { result } => { - let _ = update_sender.send(ClientData::GameEnd(result)).await; - }, } } else { error!("Connection broken!"); break; } } - - oldest_cmd = commands_receiver.recv() => { - if let Some(oldest_cmd) = oldest_cmd { - match oldest_cmd { - ClientCommands::SendCapture(capture_path) => { - debug!("Sending capture path: {:?}", capture_path); - let msg = Message::new(ClientMessage::RequestCapture { capture_path }); - send_message(msg, &conn_sender).await; - }, - - ClientCommands::SendMove { from, to } => { - debug!("Sending move from: {} to: {}", from, to); - let msg = Message::new(ClientMessage::RequestMove { from, to}); - send_message(msg, &conn_sender).await; - }, - - ClientCommands::SendText(content) => { - debug!("Seding text message: {}", content); - let msg = Message::new(TextMessage(content)); - send_message(msg, &conn_sender).await; - }, - - ClientCommands::SendReady => { - debug!("Signaling readiness!"); - let msg = Message::new(SignalReadiness); - send_message(msg, &conn_sender).await; - }, - } - } else { - error!("Couldn't decipher the command!"); - break; - } - } - } } }); } - pub async fn send_capture(&mut self, capture: CapturePath) { - debug!("Requesting sending capture: {:?}", capture); - if let Some(sender) = &self.commands_sender { - let _ = sender.send(ClientCommands::SendCapture(capture)).await; - } else { - error!("Command sender not set!"); - } + async fn send_message(&mut self, msg: Result, postcard::Error>) { + debug!("Sending message to the server!"); + let _ = match msg { + Err(e) => { + error!("There was an error while creating the message: {}", e); + return; + } + Ok(msg) => { + if let Err(e) = self.conn_sender_outgoing.send(msg).await { + error!("Error while sending a message to connection thread: {}", e); + return; + } + } + }; + } + + pub async fn send_capture(&mut self, capture_path: CapturePath) { + debug!("Requesting sending capture: {:?}", capture_path); + + let msg = Message::new(ClientMessage::RequestCapture { capture_path }); + self.send_message(msg).await; } pub async fn send_move(&mut self, from: Position, to: Position) { debug!("Requested sending move from: {} to: {}", from, to); - if let Some(sender) = &self.commands_sender { - let _ = sender.send(ClientCommands::SendMove { from, to }).await; - } else { - error!("Command sender not set!"); - } + let msg = Message::new(ClientMessage::RequestMove { from, to }); + self.send_message(msg).await; } pub async fn send_text_message(&mut self, content: String) { - if let Some(sender) = &self.commands_sender { - let _ = sender.send(ClientCommands::SendText(content)).await; - } else { - error!("Command sender not set!"); - } + debug!("Sending text message with content: [{}]", content); + let msg = Message::new(ClientMessage::TextMessage(content)); + self.send_message(msg).await; } pub async fn signal_readiness(&mut self) { - if let Some(sender) = &self.commands_sender { - let _ = sender.send(ClientCommands::SendReady).await; - } else { - error!("Command sender not set!"); - } + debug!("Signaling readiness to the server..."); + let msg = Message::new(ClientMessage::SignalReadiness); + self.send_message(msg).await; + } + + pub fn get_update_receiver(&mut self) -> Option> { + self.update_receiver.take() } } - -async fn send_message( - msg: Result, postcard::Error>, - sender: &Sender>, -) { - debug!("Sending message to the server!"); - let _ = match msg { - Err(e) => { - error!("There was an error while creating the message: {}", e); - return; - } - Ok(msg) => { - if let Err(e) = sender.send(msg).await { - error!("Error while sending a message to connection thread: {}", e); - return; - } - } - }; -}