Handle bug that happens when a player leaves the game in an early stage
This commit is contained in:
		@@ -132,6 +132,7 @@ async fn run_app<B: Backend>(terminal: &mut Terminal<B>) -> Res {
 | 
				
			|||||||
#[tokio::main]
 | 
					#[tokio::main]
 | 
				
			||||||
pub async fn main() -> Result<(), Box<dyn Error>> {
 | 
					pub async fn main() -> Result<(), Box<dyn Error>> {
 | 
				
			||||||
    env_logger::Builder::from_env(Env::default()).init();
 | 
					    env_logger::Builder::from_env(Env::default()).init();
 | 
				
			||||||
 | 
					    cli_args(); // Avoid a crash if help argument is triggered
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // setup terminal
 | 
					    // setup terminal
 | 
				
			||||||
    enable_raw_mode()?;
 | 
					    enable_raw_mode()?;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,6 +68,14 @@ enum GameStatus {
 | 
				
			|||||||
    RematchRejected,
 | 
					    RematchRejected,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl GameStatus {
 | 
				
			||||||
 | 
					    pub fn can_game_continue_with_bot(&self) -> bool {
 | 
				
			||||||
 | 
					        *self != GameStatus::Finished
 | 
				
			||||||
 | 
					            && *self != GameStatus::RematchRejected
 | 
				
			||||||
 | 
					            && *self != GameStatus::RematchRejected
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct Game {
 | 
					pub struct Game {
 | 
				
			||||||
    rules: GameRules,
 | 
					    rules: GameRules,
 | 
				
			||||||
    players: Vec<Arc<dyn Player>>,
 | 
					    players: Vec<Arc<dyn Player>>,
 | 
				
			||||||
@@ -363,7 +371,9 @@ impl Handler<PlayerLeftGame> for Game {
 | 
				
			|||||||
        self.players[opponent(offline_player)].opponent_left_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 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();
 | 
					            ctx.stop();
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            // Replace the player with a bot
 | 
					            // Replace the player with a bot
 | 
				
			||||||
@@ -371,8 +381,11 @@ impl Handler<PlayerLeftGame> for Game {
 | 
				
			|||||||
                Arc::new(BotPlayer::new(self.rules.bot_type, ctx.address()));
 | 
					                Arc::new(BotPlayer::new(self.rules.bot_type, ctx.address()));
 | 
				
			||||||
            self.players[opponent(offline_player)].opponent_replaced_by_bot();
 | 
					            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();
 | 
					                self.request_fire();
 | 
				
			||||||
 | 
					            } else if self.status == GameStatus::WaitingForBoatsDisposition {
 | 
				
			||||||
 | 
					                self.players[offline_player].query_boats_layout(&self.rules);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -109,6 +109,7 @@ impl Player for HumanPlayer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl HumanPlayer {
 | 
					impl HumanPlayer {
 | 
				
			||||||
    pub fn handle_client_message(&self, msg: ClientMessage) {
 | 
					    pub fn handle_client_message(&self, msg: ClientMessage) {
 | 
				
			||||||
 | 
					        log::debug!("Got message from client: {:?}", msg);
 | 
				
			||||||
        match msg {
 | 
					        match msg {
 | 
				
			||||||
            ClientMessage::StopGame => self.game.do_send(PlayerLeftGame(self.uuid)),
 | 
					            ClientMessage::StopGame => self.game.do_send(PlayerLeftGame(self.uuid)),
 | 
				
			||||||
            ClientMessage::BoatsLayout { layout } => {
 | 
					            ClientMessage::BoatsLayout { layout } => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -222,7 +222,7 @@ impl StreamHandler<Result<ws::Message, ProtocolError>> for HumanPlayerWS {
 | 
				
			|||||||
                log::warn!("Got unsupported continuation message!");
 | 
					                log::warn!("Got unsupported continuation message!");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Ok(Message::Pong(_)) => {
 | 
					            Ok(Message::Pong(_)) => {
 | 
				
			||||||
                log::info!("Got pong message");
 | 
					                log::debug!("Got pong message");
 | 
				
			||||||
                self.hb = Instant::now();
 | 
					                self.hb = Instant::now();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Ok(Message::Close(reason)) => {
 | 
					            Ok(Message::Close(reason)) => {
 | 
				
			||||||
@@ -238,6 +238,7 @@ impl Handler<ServerMessage> for HumanPlayerWS {
 | 
				
			|||||||
    type Result = ();
 | 
					    type Result = ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn handle(&mut self, msg: ServerMessage, ctx: &mut Self::Context) -> Self::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());
 | 
					        ctx.text(serde_json::to_string(&msg).unwrap());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -131,6 +131,8 @@ async fn start_random(
 | 
				
			|||||||
    resp
 | 
					    resp
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
pub async fn start_server(args: Args) -> std::io::Result<()> {
 | 
					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 args_clone = args.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let dispatcher_actor = DispatcherActor::default().start();
 | 
					    let dispatcher_actor = DispatcherActor::default().start();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user