diff --git a/backend/src/main.rs b/backend/src/main.rs index 0c2bd9c..caa36ec 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -50,7 +50,6 @@ impl AppState { #[derive(Deserialize)] struct RoomQuery { room: String, - team: Option, } #[derive(Serialize)] @@ -95,74 +94,43 @@ async fn ws_handler( Query(query): Query, State(state): State>, ) -> impl IntoResponse { - ws.on_upgrade(move |socket| handle_socket(socket, state, query.room, query.team)) + ws.on_upgrade(move |socket| handle_socket(socket, state, query.room)) } async fn handle_socket( socket: WebSocket, state: Arc, room_id: String, - preferred_team: Option, ) { let room = state.get_or_create_room(&room_id).await; let (mut sender, receiver) = socket.split(); - if try_join_room(&room).await.is_err() { - let err = serde_json::to_string(&ServerMessage::Error { - message: "Room is full".to_string(), - }) - .unwrap(); - let _ = sender.send(Message::Text(Utf8Bytes::from(err))).await; - return; + { + let mut room_guard = room.lock().await; + if matches!(room_guard.game.game_state_message(), ServerMessage::GameState { phase: Phase::Waiting, .. }) { + room_guard.game.start(); + } } - let player_id = Uuid::new_v4().to_string(); - let team = register_player(&room, &player_id, preferred_team).await; - let joined = serde_json::to_string(&ServerMessage::Joined { room: room_id.clone(), - team, }) .unwrap(); - let _ = sender.send(Message::Text(Utf8Bytes::from(joined))).await; + if sender.send(Message::Text(Utf8Bytes::from(joined))).await.is_err() { + return; + } let tx = { room.lock().await.tx.clone() }; let send_task = spawn_forwarder(sender, tx.subscribe()); broadcast_room_state(&room, &tx).await; - let recv_task = spawn_message_handler(room.clone(), player_id.clone(), tx, receiver); + let recv_task = spawn_message_handler(room.clone(), tx, receiver); tokio::select! { _ = send_task => {} _ = recv_task => {} } - - remove_player(&room, &player_id).await; -} - -async fn try_join_room(room: &Arc>) -> Result<(), ()> { - let room_guard = room.lock().await; - if room_guard.game.can_start() { - return Err(()); - } - Ok(()) -} - -async fn register_player( - room: &Arc>, - player_id: &str, - preferred_team: Option, -) -> Team { - let mut room_guard = room.lock().await; - let team = room_guard - .game - .add_player(player_id.to_string(), preferred_team) - .unwrap_or(Team::Red); - if room_guard.game.can_start() { - room_guard.game.start(); - } - team } fn spawn_forwarder( @@ -192,33 +160,25 @@ async fn broadcast_room_state( tx: &tokio::sync::broadcast::Sender, ) { let room_guard = room.lock().await; - let msg = if room_guard.game.can_start() { - room_guard.game.game_state_message() - } else { - ServerMessage::Waiting { - message: "Waiting for other player".to_string(), - } - }; - let _ = tx.send(msg); + let _ = tx.send(room_guard.game.game_state_message()); } fn spawn_message_handler( room: Arc>, - player_id: String, tx: tokio::sync::broadcast::Sender, mut receiver: WsReceiver, ) -> tokio::task::JoinHandle<()> { tokio::spawn(async move { while let Some(Ok(msg)) = receiver.next().await { - let Message::Text(text) = msg else { continue; }; + let Message::Text(text) = msg else { continue }; let text_ref = text.as_str(); let parsed: Result = serde_json::from_str(text_ref); match parsed { - Ok(ClientMessage::Throw { broom_x, broom_y, weight, curl, friction }) => { + Ok(ClientMessage::Throw { team, broom_x, broom_y, weight, curl, friction }) => { let mut room_guard = room.lock().await; match room_guard .game - .process_throw(&player_id, broom_x, broom_y, weight, curl, friction) + .process_throw(team, broom_x, broom_y, weight, curl, friction) { Ok(ThrowOutcome { trajectory, @@ -226,7 +186,7 @@ fn spawn_message_handler( state_message, game_over, }) => { - let _ = tx.send(ServerMessage::Trajectory { path: trajectory }); + let _ = tx.send(ServerMessage::Trajectory { paths: trajectory }); if let Some(scored) = end_scored { let _ = tx.send(scored); } @@ -247,8 +207,3 @@ fn spawn_message_handler( } }) } - -async fn remove_player(room: &Arc>, player_id: &str) { - let mut room_guard = room.lock().await; - room_guard.game.remove_player(player_id); -}