diff --git a/Knightly prezentáció.pptx b/Knightly prezentáció.pptx deleted file mode 100644 index 30e4819..0000000 Binary files a/Knightly prezentáció.pptx and /dev/null differ diff --git a/server/src/bin/client.rs b/server/src/bin/client.rs index a6586b8..2817eea 100644 --- a/server/src/bin/client.rs +++ b/server/src/bin/client.rs @@ -68,6 +68,14 @@ async fn main() -> Result<(), Box> { println!("Welcome! Your player ID: {}", player_id); } } + "match_found" => { + println!( + "opponent: {}, match_id: {}, color: {}", + parsed.opponent.unwrap(), + parsed.match_id.unwrap(), + parsed.color.unwrap() + ); + } _ => { println!("cucc: {:?}", parsed); } @@ -199,5 +207,6 @@ fn print_help() { println!(" resign - Resign from current game"); println!(" help - Show this help"); println!(" quit - Exit the client"); + println!(" requestmoves - Request the legal moves"); println!(); } diff --git a/server/src/connection.rs b/server/src/connection.rs index 0b9a534..650a1cb 100644 --- a/server/src/connection.rs +++ b/server/src/connection.rs @@ -28,18 +28,30 @@ pub fn new_waiting_queue() -> WaitingQueue { Arc::new(Mutex::new(VecDeque::new())) } -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct Step { pub from: String, pub to: String, } +#[derive(Serialize, Deserialize, Debug)] +struct ServerMessage { + #[serde(rename = "type")] + message_type: String, + player_id: Option, + match_id: Option, + opponent: Option, + color: Option, + reason: Option, + fen: Option, +} + #[derive(Serialize, Deserialize, Debug)] #[serde(tag = "type")] enum ClientEvent { Join { username: String }, FindMatch, - Move { from: String, to: String }, + Move { fen: String }, Resign, Chat { text: String }, RequestLegalMoves { fen: String }, @@ -64,23 +76,19 @@ pub struct GameMatch { pub player_white: Uuid, pub player_black: Uuid, pub board_state: String, - pub move_history: Vec, + pub move_history: Vec, } // Message sending utilities -pub async fn send_message_to_player( - connections: &ConnectionMap, - player_id: Uuid, +pub async fn send_message_to_player_connection( + connection: &mut PlayerConnection, message: &str, -) -> Result<(), Box> { - let mut connections_lock = connections.lock().await; - if let Some(connection) = connections_lock.get_mut(&player_id) { - connection - .tx - .send(Message::Text(message.to_string())) - .await?; - } - Ok(()) +) -> Result<(), tokio_tungstenite::tungstenite::Error> { + println!("sending message to: {}", connection.id); + + let res = connection.tx.send(Message::Text(message.to_string())).await; + + res } pub async fn broadcast_to_all(connections: &ConnectionMap, message: &str) { @@ -108,8 +116,24 @@ pub async fn broadcast_to_match( ) -> Result<(), Box> { let matches_lock = matches.lock().await; if let Some(game_match) = matches_lock.get(&match_id) { - send_message_to_player(connections, game_match.player_white, message).await?; - send_message_to_player(connections, game_match.player_black, message).await?; + send_message_to_player_connection( + connections + .lock() + .await + .get_mut(&game_match.player_white) + .unwrap(), + message, + ) + .await?; + send_message_to_player_connection( + connections + .lock() + .await + .get_mut(&game_match.player_black) + .unwrap(), + message, + ) + .await?; } Ok(()) } @@ -144,14 +168,6 @@ pub async fn handle_connection( println!("New connection: {}", player_id); - // Send welcome message - let _ = send_message_to_player( - &connections, - player_id, - &format!(r#"{{"type": "welcome", "player_id": "{}"}}"#, player_id), - ) - .await; - // Message processing loop while let Some(Ok(message)) = read.next().await { if message.is_text() { @@ -178,9 +194,9 @@ pub async fn handle_connection( println!("response: {:?}", response); - let _ = send_message_to_player( - &connections, - player_id, + let mut conn_map = connections.lock().await; + let _ = send_message_to_player_connection( + conn_map.get_mut(&player_id).unwrap(), &serde_json::to_string(&response).unwrap(), ) .await; @@ -191,12 +207,21 @@ pub async fn handle_connection( println!("Appended {} to the waiting queue", player_id); println!("queue {:?}", wait_queue); } - Move { from, to } => {} + Move { fen } => { + let match_id = connections + .lock() + .await + .get(&player_id) + .unwrap() + .current_match + .unwrap(); + + let _ = broadcast_to_match(&connections, &matches, match_id, &fen).await; + } RequestLegalMoves { fen } => { let moves = get_available_moves(&fen); - let _ = send_message_to_player( - &connections, - player_id, + let _ = send_message_to_player_connection( + connections.lock().await.get_mut(&player_id).unwrap(), &serde_json::to_string(&moves).unwrap(), ) .await; @@ -239,7 +264,11 @@ mod tests { let connections = new_connection_map(); let player_id = Uuid::new_v4(); - let result = send_message_to_player(&connections, player_id, "test message").await; + let result = send_message_to_player_connection( + connections.lock().await.get_mut(&player_id).unwrap(), + &"test message", + ) + .await; assert!(result.is_ok(), "Should handle missing player gracefully"); } diff --git a/server/src/matchmaking.rs b/server/src/matchmaking.rs index de7eca0..d18590e 100644 --- a/server/src/matchmaking.rs +++ b/server/src/matchmaking.rs @@ -1,4 +1,4 @@ -use crate::connection::{ConnectionMap, GameMatch, MatchMap, WaitingQueue}; +use crate::connection::{ConnectionMap, GameMatch, MatchMap, WaitingQueue, broadcast_to_match}; use rand::random; use uuid::Uuid; @@ -20,7 +20,7 @@ impl MatchmakingSystem { pub async fn run(&self) { loop { self.try_create_match().await; - tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + tokio::time::sleep(tokio::time::Duration::from_millis(500)).await; } } @@ -61,42 +61,50 @@ impl MatchmakingSystem { } // Notify players + println!( + "Notifying player for a match: {:?} | {:?}", + white_player, black_player + ); self.notify_players(white_player, black_player, match_id) .await; } } async fn notify_players(&self, white: Uuid, black: Uuid, match_id: Uuid) { - let conn_map = self.connections.lock().await; - - // Get opponent names - let white_name = conn_map - .get(&black) - .and_then(|c| c.username.as_deref()) - .unwrap_or("Opponent"); - let black_name = conn_map - .get(&white) - .and_then(|c| c.username.as_deref()) - .unwrap_or("Opponent"); + let mut conn_map = self.connections.lock().await; // Notify white player if let Some(_) = conn_map.get(&white) { let message = format!( r#"{{"type": "match_found", "match_id": "{}", "opponent": "{}", "color": "white"}}"#, - match_id, black_name + match_id, + conn_map + .get(&white) + .and_then(|c| c.username.as_deref()) + .unwrap_or("Opponent") ); - let _ = - crate::connection::send_message_to_player(&self.connections, white, &message).await; + let _ = crate::connection::send_message_to_player_connection( + conn_map.get_mut(&white).unwrap(), + &message, + ) + .await; } // Notify black player if let Some(_) = conn_map.get(&black) { let message = format!( r#"{{"type": "match_found", "match_id": "{}", "opponent": "{}", "color": "black"}}"#, - match_id, white_name + match_id, + conn_map + .get(&black) + .and_then(|c| c.username.as_deref()) + .unwrap_or("Opponent") ); - let _ = - crate::connection::send_message_to_player(&self.connections, black, &message).await; + let _ = crate::connection::send_message_to_player_connection( + conn_map.get_mut(&black).unwrap(), + &message, + ) + .await; } println!("Match created: {} (white) vs {} (black)", white, black);