# HG changeset patch # User alfadur # Date 1549312878 -10800 # Node ID b87c71ccd17d4ffc7a055c5c14e537dc713d6b5f # Parent 08a8605bafaf3f65e713fc01f85897ab940c4cf4 Server action refactoring part 5 of N diff -r 08a8605bafaf -r b87c71ccd17d rust/hedgewars-server/src/server/core.rs --- a/rust/hedgewars-server/src/server/core.rs Mon Feb 04 20:25:35 2019 +0300 +++ b/rust/hedgewars-server/src/server/core.rs Mon Feb 04 23:41:18 2019 +0300 @@ -62,15 +62,6 @@ } pub fn remove_client(&mut self, client_id: ClientId) { - let client = &self.clients[client_id]; - let nick = client.nick.clone(); - - if let Some(id) = client.room_id { - if id != self.lobby_id { - //MoveToLobby(format!("quit: {}", msg.clone())) - } - } - self.removed_clients.push(client_id); if self.clients.contains(client_id) { self.clients.remove(client_id); diff -r 08a8605bafaf -r b87c71ccd17d rust/hedgewars-server/src/server/handlers/common.rs --- a/rust/hedgewars-server/src/server/handlers/common.rs Mon Feb 04 20:25:35 2019 +0300 +++ b/rust/hedgewars-server/src/server/handlers/common.rs Mon Feb 04 23:41:18 2019 +0300 @@ -1,11 +1,18 @@ +use crate::server::client::HWClient; +use crate::server::room::HWRoom; +use crate::utils::to_engine_msg; use crate::{ protocol::messages::{ HWProtocolMessage::{self, Rnd}, - HWServerMessage::{self, ChatMsg}, + HWServerMessage::{ + self, Bye, ChatMsg, ClientFlags, ForwardEngineMessage, LobbyLeft, RoomLeft, RoomRemove, + RoomUpdated, TeamRemove, + }, }, server::{actions::Action, core::HWServer}, }; use rand::{self, thread_rng, Rng}; +use std::iter::once; pub fn rnd_reply(options: &[String]) -> HWServerMessage { let mut rng = thread_rng(); @@ -21,13 +28,97 @@ } } +pub fn remove_teams(room: &mut HWRoom, client: &HWClient, response: &mut super::Response) { + let team_names: Vec<_> = room + .client_teams(client.id) + .map(|t| t.name.clone()) + .collect(); + + if let Some(ref mut info) = room.game_info { + for team_name in &team_names { + info.left_teams.push(team_name.clone()); + + if client.is_in_game() { + let msg = once(b'F').chain(team_name.bytes()); + response.add( + ForwardEngineMessage(vec![to_engine_msg(msg)]) + .send_all() + .in_room(room.id) + .but_self(), + ); + + info.teams_in_game -= 1; + if info.teams_in_game == 0 { + //FinishRoomGame(room.id) + } + + let remove_msg = to_engine_msg(once(b'F').chain(team_name.bytes())); + if let Some(m) = &info.sync_msg { + info.msg_log.push(m.clone()); + info.sync_msg = None + } + info.msg_log.push(remove_msg.clone()); + + response.add( + ForwardEngineMessage(vec![remove_msg]) + .send_all() + .in_room(room.id) + .but_self(), + ); + } + } + } + + for team_name in team_names { + room.remove_team(&team_name); + response.add(TeamRemove(team_name).send_all().in_room(room.id)); + } +} + pub fn remove_client(server: &mut HWServer, response: &mut super::Response, msg: String) { - use HWServerMessage::*; - let nick = server.clients[response.client_id()].nick.clone(); + let client_id = response.client_id(); + let lobby_id = server.lobby_id; + let client = &mut server.clients[client_id]; + let (nick, room_id) = (client.nick.clone(), client.room_id); + + if let Some(room_id) = room_id { + let room = &mut server.rooms[room_id]; + + if room.players_number > 1 || room.is_fixed() { + room.players_number -= 1; + if client.is_ready() && room.ready_players_number > 0 { + room.ready_players_number -= 1; + } + + remove_teams(room, client, response); + + if room.players_number > 1 { + response.add( + RoomLeft(client.nick.clone(), msg.clone()) + .send_all() + .in_room(room.id) + .but_self(), + ); + } + + //ChangeMaster(room.id, None)); + } + + let update_msg = if room.players_number == 0 && !room.is_fixed() { + RoomRemove(room.name.clone()) + } else { + RoomUpdated(room.name.clone(), room.info(Some(&client))) + }; + response.add(update_msg.send_all().with_protocol(room.protocol_number)); + + response.add(ClientFlags("-i".to_string(), vec![nick.clone()]).send_all()); + client.room_id = Some(lobby_id); + } + + server.remove_client(client_id); + response.add(LobbyLeft(nick, msg.to_string()).send_all()); response.add(Bye("User quit: ".to_string() + &msg).send_self()); - - server.remove_client(response.client_id()); } #[cfg(test)]