From 70d70c28517dbd44d5dca5ead2e9dab08d393221 Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Sun, 16 Oct 2022 18:25:59 +0200 Subject: [PATCH] Handle bug that happens when a player leaves the game in an early stage --- rust/cli_player/src/main.rs | 1 + rust/sea_battle_backend/src/game.rs | 17 +++++++++++++++-- rust/sea_battle_backend/src/human_player.rs | 1 + rust/sea_battle_backend/src/human_player_ws.rs | 3 ++- rust/sea_battle_backend/src/server.rs | 2 ++ 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/rust/cli_player/src/main.rs b/rust/cli_player/src/main.rs index ee6b5ed..d75f214 100644 --- a/rust/cli_player/src/main.rs +++ b/rust/cli_player/src/main.rs @@ -132,6 +132,7 @@ async fn run_app(terminal: &mut Terminal) -> Res { #[tokio::main] pub async fn main() -> Result<(), Box> { env_logger::Builder::from_env(Env::default()).init(); + cli_args(); // Avoid a crash if help argument is triggered // setup terminal enable_raw_mode()?; diff --git a/rust/sea_battle_backend/src/game.rs b/rust/sea_battle_backend/src/game.rs index 6380d36..afc02ff 100644 --- a/rust/sea_battle_backend/src/game.rs +++ b/rust/sea_battle_backend/src/game.rs @@ -68,6 +68,14 @@ enum GameStatus { RematchRejected, } +impl GameStatus { + pub fn can_game_continue_with_bot(&self) -> bool { + *self != GameStatus::Finished + && *self != GameStatus::RematchRejected + && *self != GameStatus::RematchRejected + } +} + pub struct Game { rules: GameRules, players: Vec>, @@ -363,7 +371,9 @@ impl Handler for Game { self.players[opponent(offline_player)].opponent_left_game(); // If the other player is a bot or if the game is not running, stop the game - if self.status != GameStatus::Started || self.players[opponent(offline_player)].is_bot() { + if !self.status.can_game_continue_with_bot() + || self.players[opponent(offline_player)].is_bot() + { ctx.stop(); } else { // Replace the player with a bot @@ -371,8 +381,11 @@ impl Handler for Game { Arc::new(BotPlayer::new(self.rules.bot_type, ctx.address())); self.players[opponent(offline_player)].opponent_replaced_by_bot(); - if self.turn == offline_player { + // Re-do current action + if self.status == GameStatus::Started { self.request_fire(); + } else if self.status == GameStatus::WaitingForBoatsDisposition { + self.players[offline_player].query_boats_layout(&self.rules); } } } diff --git a/rust/sea_battle_backend/src/human_player.rs b/rust/sea_battle_backend/src/human_player.rs index 418337c..8d2c7f4 100644 --- a/rust/sea_battle_backend/src/human_player.rs +++ b/rust/sea_battle_backend/src/human_player.rs @@ -109,6 +109,7 @@ impl Player for HumanPlayer { impl HumanPlayer { pub fn handle_client_message(&self, msg: ClientMessage) { + log::debug!("Got message from client: {:?}", msg); match msg { ClientMessage::StopGame => self.game.do_send(PlayerLeftGame(self.uuid)), ClientMessage::BoatsLayout { layout } => { diff --git a/rust/sea_battle_backend/src/human_player_ws.rs b/rust/sea_battle_backend/src/human_player_ws.rs index 3eaf608..1d625cb 100644 --- a/rust/sea_battle_backend/src/human_player_ws.rs +++ b/rust/sea_battle_backend/src/human_player_ws.rs @@ -222,7 +222,7 @@ impl StreamHandler> for HumanPlayerWS { log::warn!("Got unsupported continuation message!"); } Ok(Message::Pong(_)) => { - log::info!("Got pong message"); + log::debug!("Got pong message"); self.hb = Instant::now(); } Ok(Message::Close(reason)) => { @@ -238,6 +238,7 @@ impl Handler for HumanPlayerWS { type Result = (); fn handle(&mut self, msg: ServerMessage, ctx: &mut Self::Context) -> Self::Result { + log::debug!("Send message through WS: {:?}", msg); ctx.text(serde_json::to_string(&msg).unwrap()); } } diff --git a/rust/sea_battle_backend/src/server.rs b/rust/sea_battle_backend/src/server.rs index e3ac334..4510408 100644 --- a/rust/sea_battle_backend/src/server.rs +++ b/rust/sea_battle_backend/src/server.rs @@ -131,6 +131,8 @@ async fn start_random( resp } pub async fn start_server(args: Args) -> std::io::Result<()> { + log::info!("Start to listen on {}", args.listen_address); + let args_clone = args.clone(); let dispatcher_actor = DispatcherActor::default().start();