fixed bug in findmatch, added a new command in test client, refactored how the server sends messages to the client
This commit is contained in:
@@ -68,6 +68,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
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!();
|
||||
}
|
||||
|
||||
@@ -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<String>,
|
||||
match_id: Option<String>,
|
||||
opponent: Option<String>,
|
||||
color: Option<String>,
|
||||
reason: Option<String>,
|
||||
fen: Option<String>,
|
||||
}
|
||||
|
||||
#[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<String>,
|
||||
pub move_history: Vec<Step>,
|
||||
}
|
||||
|
||||
// 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<dyn std::error::Error>> {
|
||||
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<dyn std::error::Error>> {
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user