fix editing teams while a game is in progress
authoralfadur
Sun, 17 May 2020 04:07:10 +0300
changeset 15591 4b2f3228f13b
parent 15590 de1b31c2d2f2
child 15592 d524b7450576
fix editing teams while a game is in progress
rust/hedgewars-server/src/core/client.rs
rust/hedgewars-server/src/core/room.rs
rust/hedgewars-server/src/core/server.rs
rust/hedgewars-server/src/handlers/common.rs
rust/hedgewars-server/src/handlers/inroom.rs
--- a/rust/hedgewars-server/src/core/client.rs	Sat May 16 04:43:11 2020 +0200
+++ b/rust/hedgewars-server/src/core/client.rs	Sun May 17 04:07:10 2020 +0300
@@ -7,10 +7,9 @@
         const IS_MASTER = 0b0000_0010;
         const IS_READY = 0b0000_0100;
         const IS_IN_GAME = 0b0000_1000;
-        const IS_JOINED_MID_GAME = 0b0001_0000;
-        const IS_CONTRIBUTOR = 0b0010_0000;
-        const HAS_SUPER_POWER = 0b0100_0000;
-        const IS_REGISTERED = 0b1000_0000;
+        const IS_CONTRIBUTOR = 0b0001_0000;
+        const HAS_SUPER_POWER = 0b0010_0000;
+        const IS_REGISTERED = 0b0100_0000;
 
         const NONE = 0b0000_0000;
         const DEFAULT = Self::NONE.bits;
@@ -62,9 +61,6 @@
     pub fn is_in_game(&self) -> bool {
         self.contains(ClientFlags::IS_IN_GAME)
     }
-    pub fn is_joined_mid_game(&self) -> bool {
-        self.contains(ClientFlags::IS_JOINED_MID_GAME)
-    }
     pub fn is_contributor(&self) -> bool {
         self.contains(ClientFlags::IS_CONTRIBUTOR)
     }
@@ -87,9 +83,6 @@
     pub fn set_is_in_game(&mut self, value: bool) {
         self.set(ClientFlags::IS_IN_GAME, value)
     }
-    pub fn set_is_joined_mid_game(&mut self, value: bool) {
-        self.set(ClientFlags::IS_JOINED_MID_GAME, value)
-    }
     pub fn set_is_contributor(&mut self, value: bool) {
         self.set(ClientFlags::IS_CONTRIBUTOR, value)
     }
--- a/rust/hedgewars-server/src/core/room.rs	Sat May 16 04:43:11 2020 +0200
+++ b/rust/hedgewars-server/src/core/room.rs	Sun May 17 04:07:10 2020 +0300
@@ -26,7 +26,6 @@
 pub struct GameInfo {
     pub original_teams: Vec<(ClientId, TeamInfo)>,
     pub left_teams: Vec<String>,
-    pub ingame_teams_count: u8,
     pub msg_log: Vec<String>,
     pub sync_msg: Option<String>,
     pub is_paused: bool,
@@ -40,7 +39,6 @@
             msg_log: Vec::new(),
             sync_msg: None,
             is_paused: false,
-            ingame_teams_count: teams.len() as u8,
             original_teams: teams,
             original_config: config,
         }
@@ -49,6 +47,23 @@
     pub fn client_teams(&self, client_id: ClientId) -> impl Iterator<Item = &TeamInfo> + Clone {
         client_teams_impl(&self.original_teams, client_id)
     }
+
+    pub fn mark_left_teams<'a, I>(&mut self, team_names: I)
+    where
+        I: Iterator<Item = &'a String>,
+    {
+        if let Some(m) = &self.sync_msg {
+            self.msg_log.push(m.clone());
+            self.sync_msg = None
+        }
+
+        for team_name in team_names {
+            self.left_teams.push(team_name.clone());
+
+            let remove_msg = crate::utils::to_engine_msg(iter::once(b'F').chain(team_name.bytes()));
+            self.msg_log.push(remove_msg);
+        }
+    }
 }
 
 #[derive(Serialize, Deserialize)]
@@ -145,19 +160,6 @@
     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.ingame_teams_count -= 1;
-                info.left_teams.push(team_name.to_string());
-
-                if let Some(m) = &info.sync_msg {
-                    info.msg_log.push(m.clone());
-                    info.sync_msg = None
-                }
-                let remove_msg =
-                    crate::utils::to_engine_msg(iter::once(b'F').chain(team_name.bytes()));
-                info.msg_log.push(remove_msg.clone());
-            }
         }
     }
 
@@ -176,7 +178,9 @@
     }
 
     pub fn teams_in_game(&self) -> Option<u8> {
-        self.game_info.as_ref().map(|info| info.ingame_teams_count)
+        self.game_info
+            .as_ref()
+            .map(|info| (info.original_teams.len() - info.left_teams.len()) as u8)
     }
 
     pub fn find_team_and_owner_mut<F>(&mut self, f: F) -> Option<(ClientId, &mut TeamInfo)>
@@ -302,6 +306,10 @@
         ]
     }
 
+    pub fn config(&self) -> &RoomConfig {
+        &self.config
+    }
+
     pub fn active_config(&self) -> &RoomConfig {
         match self.game_info {
             Some(ref info) => &info.original_config,
--- a/rust/hedgewars-server/src/core/server.rs	Sat May 16 04:43:11 2020 +0200
+++ b/rust/hedgewars-server/src/core/server.rs	Sun May 17 04:07:10 2020 +0300
@@ -128,7 +128,6 @@
 
 #[derive(Debug)]
 pub struct EndGameResult {
-    pub joined_mid_game_clients: Vec<ClientId>,
     pub left_teams: Vec<String>,
     pub unreadied_nicks: Vec<String>,
 }
@@ -607,13 +606,20 @@
                 room.ready_players_number -= 1;
             }
 
-            removed_teams = room
-                .client_teams(client.id)
-                .map(|t| t.name.clone())
-                .collect();
-
-            for team_name in &removed_teams {
-                room.remove_team(team_name);
+            if let Some(ref mut info) = room.game_info {
+                removed_teams = info
+                    .client_teams(client.id)
+                    .map(|t| t.name.clone())
+                    .collect();
+                info.mark_left_teams(removed_teams.iter());
+            } else {
+                removed_teams = room
+                    .client_teams(client.id)
+                    .map(|t| t.name.clone())
+                    .collect();
+                for team_name in &removed_teams {
+                    room.remove_team(team_name);
+                }
             }
 
             if client.is_master() && !is_fixed {
@@ -995,20 +1001,8 @@
                     .map(|t| t.name.clone())
                     .collect();
 
-                info.left_teams.extend(team_names.iter().cloned());
-                info.ingame_teams_count -= team_names.len() as u8;
+                info.mark_left_teams(team_names.iter());
 
-                for team_name in &team_names {
-                    let remove_msg =
-                        utils::to_engine_msg(std::iter::once(b'F').chain(team_name.bytes()));
-                    if let Some(m) = &info.sync_msg {
-                        info.msg_log.push(m.clone());
-                    }
-                    if info.sync_msg.is_some() {
-                        info.sync_msg = None
-                    }
-                    info.msg_log.push(remove_msg);
-                }
                 Some(team_names)
             } else {
                 None
@@ -1028,14 +1022,6 @@
                 room.remove_team(team_name);
             }
 
-            let joined_mid_game_clients = self
-                .server
-                .clients
-                .iter()
-                .filter(|(_, c)| c.room_id == Some(self.room_id) && c.is_joined_mid_game())
-                .map(|(_, c)| c.id)
-                .collect();
-
             let unreadied_nicks: Vec<_> = self
                 .server
                 .clients
@@ -1043,7 +1029,6 @@
                 .filter(|(_, c)| c.room_id == Some(room_id))
                 .map(|(_, c)| {
                     c.set_is_ready(c.is_master());
-                    c.set_is_joined_mid_game(false);
                     c
                 })
                 .filter_map(|c| {
@@ -1056,7 +1041,6 @@
                 .collect();
 
             Some(EndGameResult {
-                joined_mid_game_clients,
                 left_teams: replace(&mut info.left_teams, vec![]),
                 unreadied_nicks,
             })
@@ -1103,7 +1087,6 @@
     client.set_is_master(true);
     client.set_is_ready(true);
     client.set_is_in_game(false);
-    client.set_is_joined_mid_game(false);
     client.clan = None;
     client.teams_in_game = 0;
     client.team_indices = vec![];
@@ -1117,7 +1100,6 @@
     room.players_number += 1;
 
     client.room_id = Some(room.id);
-    client.set_is_joined_mid_game(room.game_info.is_some());
     client.set_is_in_game(room.game_info.is_some());
 
     if let Some(ref mut info) = room.game_info {
@@ -1128,7 +1110,6 @@
 
         if !team_names.is_empty() {
             info.left_teams.retain(|name| !team_names.contains(&name));
-            info.ingame_teams_count += team_names.len() as u8;
         }
     }
 }
--- a/rust/hedgewars-server/src/handlers/common.rs	Sat May 16 04:43:11 2020 +0200
+++ b/rust/hedgewars-server/src/handlers/common.rs	Sun May 17 04:07:10 2020 +0300
@@ -209,6 +209,22 @@
         if info.is_paused {
             response.add(ForwardEngineMessage(vec![to_engine_msg(once(b'I'))]).send_self());
         }
+
+        for (_, original_team) in &info.original_teams {
+            if let Some(team) = room.find_team(|team| team.name == original_team.name) {
+                if team.color != original_team.color {
+                    response.add(TeamColor(team.name.clone(), team.color).send_self());
+                }
+                if team.hedgehogs_number != original_team.hedgehogs_number {
+                    response
+                        .add(HedgehogsNumber(team.name.clone(), team.hedgehogs_number).send_self());
+                }
+            } else {
+                response.add(TeamRemove(original_team.name.clone()).send_self());
+            }
+        }
+
+        get_room_config_impl(room.config(), Destination::ToSelf, response);
     }
 }
 
@@ -608,22 +624,10 @@
         result
             .left_teams
             .iter()
+            .filter(|name| room.find_team(|t| t.name == **name).is_some())
             .map(|name| TeamRemove(name.clone()).send_all().in_room(room.id)),
     );
 
-    let midgame_destination = Destination::ToIds(result.joined_mid_game_clients);
-    for (_, team) in &room.teams {
-        response.add(
-            HedgehogsNumber(team.name.clone(), team.hedgehogs_number)
-                .send_to_destination(midgame_destination.clone()),
-        );
-        response.add(
-            TeamColor(team.name.clone(), team.color)
-                .send_to_destination(midgame_destination.clone()),
-        );
-    }
-    super::common::get_active_room_config(room, midgame_destination.clone(), response);
-
     if !result.unreadied_nicks.is_empty() {
         response.add(
             ClientFlags(remove_flags(&[Flags::Ready]), result.unreadied_nicks)
--- a/rust/hedgewars-server/src/handlers/inroom.rs	Sat May 16 04:43:11 2020 +0200
+++ b/rust/hedgewars-server/src/handlers/inroom.rs	Sun May 17 04:07:10 2020 +0300
@@ -244,23 +244,7 @@
                     let (client, room) = room_control.get();
 
                     let removed_teams = vec![name];
-                    super::common::get_remove_teams_data(
-                        room_id,
-                        client.is_in_game(),
-                        removed_teams,
-                        response,
-                    );
-
-                    if let Some(0) = room.teams_in_game() {
-                        if let Some(result) = room_control.end_game() {
-                            super::common::get_end_game_result(
-                                room_control.server(),
-                                room_id,
-                                result,
-                                response,
-                            );
-                        }
-                    }
+                    super::common::get_remove_teams_data(room_id, false, removed_teams, response);
                 }
                 Err(RemoveTeamError::NoTeam) => response.warn(NO_TEAM_TO_REMOVE),
                 Err(RemoveTeamError::TeamNotOwned) => response.warn(TEAM_NOT_OWNED),