rust/hedgewars-server/src/core/room.rs
changeset 15540 479911540e17
parent 15536 a798e6441a36
child 15541 d122b65bdf6f
--- a/rust/hedgewars-server/src/core/room.rs	Tue Jan 07 15:17:22 2020 +0100
+++ b/rust/hedgewars-server/src/core/room.rs	Sat Jan 11 00:44:25 2020 +0300
@@ -13,7 +13,19 @@
 pub const MAX_TEAMS_IN_ROOM: u8 = 8;
 pub const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_TEAMS_IN_ROOM * MAX_HEDGEHOGS_PER_TEAM;
 
+fn client_teams_impl(
+    teams: &[(ClientId, TeamInfo)],
+    client_id: ClientId,
+) -> impl Iterator<Item = &TeamInfo> + Clone {
+    teams
+        .iter()
+        .filter(move |(id, _)| *id == client_id)
+        .map(|(_, t)| t)
+}
+
 pub struct GameInfo {
+    pub teams_in_game: u8,
+    pub teams_at_start: Vec<(ClientId, TeamInfo)>,
     pub left_teams: Vec<String>,
     pub msg_log: Vec<String>,
     pub sync_msg: Option<String>,
@@ -28,9 +40,15 @@
             msg_log: Vec::new(),
             sync_msg: None,
             is_paused: false,
+            teams_in_game: teams.len() as u8,
+            teams_at_start: teams,
             config,
         }
     }
+
+    pub fn client_teams(&self, client_id: ClientId) -> impl Iterator<Item = &TeamInfo> + Clone {
+        client_teams_impl(&self.teams_at_start, client_id)
+    }
 }
 
 #[derive(Serialize, Deserialize)]
@@ -126,8 +144,11 @@
 
     pub fn remove_team(&mut self, team_name: &str) {
         if let Some(index) = self.teams.iter().position(|(_, t)| t.name == team_name) {
+            self.teams.remove(index);
+
             if let Some(info) = &mut self.game_info {
                 info.left_teams.push(team_name.to_string());
+                info.teams_in_game -= 1;
 
                 if let Some(m) = &info.sync_msg {
                     info.msg_log.push(m.clone());
@@ -136,15 +157,17 @@
                 let remove_msg =
                     crate::utils::to_engine_msg(iter::once(b'F').chain(team_name.bytes()));
                 info.msg_log.push(remove_msg.clone());
-            } else {
-                self.teams.remove(index);
             }
         }
     }
 
     pub fn set_hedgehogs_number(&mut self, n: u8) -> Vec<String> {
         let mut names = Vec::new();
-        let teams = &mut self.teams;
+        let teams = match self.game_info {
+            Some(ref mut info) => &mut info.teams_at_start,
+            None => &mut self.teams,
+        };
+
         if teams.len() as u8 * n <= MAX_HEDGEHOGS_IN_ROOM {
             for (_, team) in teams.iter_mut() {
                 team.hedgehogs_number = n;
@@ -155,12 +178,6 @@
         names
     }
 
-    pub fn teams_in_game(&self) -> Option<u8> {
-        self.game_info
-            .as_ref()
-            .map(|info| (self.teams.len() - info.left_teams.len()) as u8)
-    }
-
     pub fn find_team_and_owner_mut<F>(&mut self, f: F) -> Option<(ClientId, &mut TeamInfo)>
     where
         F: Fn(&TeamInfo) -> bool,
@@ -180,11 +197,8 @@
             .find_map(|(_, t)| Some(t).filter(|t| f(&t)))
     }
 
-    pub fn client_teams(&self, client_id: ClientId) -> impl Iterator<Item = &TeamInfo> + Clone {
-        self.teams
-            .iter()
-            .filter(move |(id, _)| *id == client_id)
-            .map(|(_, t)| t)
+    pub fn client_teams(&self, client_id: ClientId) -> impl Iterator<Item = &TeamInfo> {
+        client_teams_impl(&self.teams, client_id)
     }
 
     pub fn client_team_indices(&self, client_id: ClientId) -> Vec<u8> {