rust/hedgewars-server/src/core/room.rs
changeset 15540 479911540e17
parent 15536 a798e6441a36
child 15541 d122b65bdf6f
equal deleted inserted replaced
15539:d8326878e933 15540:479911540e17
    11 use std::{collections::HashMap, iter};
    11 use std::{collections::HashMap, iter};
    12 
    12 
    13 pub const MAX_TEAMS_IN_ROOM: u8 = 8;
    13 pub const MAX_TEAMS_IN_ROOM: u8 = 8;
    14 pub const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_TEAMS_IN_ROOM * MAX_HEDGEHOGS_PER_TEAM;
    14 pub const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_TEAMS_IN_ROOM * MAX_HEDGEHOGS_PER_TEAM;
    15 
    15 
       
    16 fn client_teams_impl(
       
    17     teams: &[(ClientId, TeamInfo)],
       
    18     client_id: ClientId,
       
    19 ) -> impl Iterator<Item = &TeamInfo> + Clone {
       
    20     teams
       
    21         .iter()
       
    22         .filter(move |(id, _)| *id == client_id)
       
    23         .map(|(_, t)| t)
       
    24 }
       
    25 
    16 pub struct GameInfo {
    26 pub struct GameInfo {
       
    27     pub teams_in_game: u8,
       
    28     pub teams_at_start: Vec<(ClientId, TeamInfo)>,
    17     pub left_teams: Vec<String>,
    29     pub left_teams: Vec<String>,
    18     pub msg_log: Vec<String>,
    30     pub msg_log: Vec<String>,
    19     pub sync_msg: Option<String>,
    31     pub sync_msg: Option<String>,
    20     pub is_paused: bool,
    32     pub is_paused: bool,
    21     config: RoomConfig,
    33     config: RoomConfig,
    26         GameInfo {
    38         GameInfo {
    27             left_teams: Vec::new(),
    39             left_teams: Vec::new(),
    28             msg_log: Vec::new(),
    40             msg_log: Vec::new(),
    29             sync_msg: None,
    41             sync_msg: None,
    30             is_paused: false,
    42             is_paused: false,
       
    43             teams_in_game: teams.len() as u8,
       
    44             teams_at_start: teams,
    31             config,
    45             config,
    32         }
    46         }
       
    47     }
       
    48 
       
    49     pub fn client_teams(&self, client_id: ClientId) -> impl Iterator<Item = &TeamInfo> + Clone {
       
    50         client_teams_impl(&self.teams_at_start, client_id)
    33     }
    51     }
    34 }
    52 }
    35 
    53 
    36 #[derive(Serialize, Deserialize)]
    54 #[derive(Serialize, Deserialize)]
    37 pub struct RoomSave {
    55 pub struct RoomSave {
   124         &self.teams.last().unwrap().1
   142         &self.teams.last().unwrap().1
   125     }
   143     }
   126 
   144 
   127     pub fn remove_team(&mut self, team_name: &str) {
   145     pub fn remove_team(&mut self, team_name: &str) {
   128         if let Some(index) = self.teams.iter().position(|(_, t)| t.name == team_name) {
   146         if let Some(index) = self.teams.iter().position(|(_, t)| t.name == team_name) {
       
   147             self.teams.remove(index);
       
   148 
   129             if let Some(info) = &mut self.game_info {
   149             if let Some(info) = &mut self.game_info {
   130                 info.left_teams.push(team_name.to_string());
   150                 info.left_teams.push(team_name.to_string());
       
   151                 info.teams_in_game -= 1;
   131 
   152 
   132                 if let Some(m) = &info.sync_msg {
   153                 if let Some(m) = &info.sync_msg {
   133                     info.msg_log.push(m.clone());
   154                     info.msg_log.push(m.clone());
   134                     info.sync_msg = None
   155                     info.sync_msg = None
   135                 }
   156                 }
   136                 let remove_msg =
   157                 let remove_msg =
   137                     crate::utils::to_engine_msg(iter::once(b'F').chain(team_name.bytes()));
   158                     crate::utils::to_engine_msg(iter::once(b'F').chain(team_name.bytes()));
   138                 info.msg_log.push(remove_msg.clone());
   159                 info.msg_log.push(remove_msg.clone());
   139             } else {
       
   140                 self.teams.remove(index);
       
   141             }
   160             }
   142         }
   161         }
   143     }
   162     }
   144 
   163 
   145     pub fn set_hedgehogs_number(&mut self, n: u8) -> Vec<String> {
   164     pub fn set_hedgehogs_number(&mut self, n: u8) -> Vec<String> {
   146         let mut names = Vec::new();
   165         let mut names = Vec::new();
   147         let teams = &mut self.teams;
   166         let teams = match self.game_info {
       
   167             Some(ref mut info) => &mut info.teams_at_start,
       
   168             None => &mut self.teams,
       
   169         };
       
   170 
   148         if teams.len() as u8 * n <= MAX_HEDGEHOGS_IN_ROOM {
   171         if teams.len() as u8 * n <= MAX_HEDGEHOGS_IN_ROOM {
   149             for (_, team) in teams.iter_mut() {
   172             for (_, team) in teams.iter_mut() {
   150                 team.hedgehogs_number = n;
   173                 team.hedgehogs_number = n;
   151                 names.push(team.name.clone())
   174                 names.push(team.name.clone())
   152             }
   175             }
   153             self.default_hedgehog_number = n;
   176             self.default_hedgehog_number = n;
   154         }
   177         }
   155         names
   178         names
   156     }
   179     }
   157 
   180 
   158     pub fn teams_in_game(&self) -> Option<u8> {
       
   159         self.game_info
       
   160             .as_ref()
       
   161             .map(|info| (self.teams.len() - info.left_teams.len()) as u8)
       
   162     }
       
   163 
       
   164     pub fn find_team_and_owner_mut<F>(&mut self, f: F) -> Option<(ClientId, &mut TeamInfo)>
   181     pub fn find_team_and_owner_mut<F>(&mut self, f: F) -> Option<(ClientId, &mut TeamInfo)>
   165     where
   182     where
   166         F: Fn(&TeamInfo) -> bool,
   183         F: Fn(&TeamInfo) -> bool,
   167     {
   184     {
   168         self.teams
   185         self.teams
   178         self.teams
   195         self.teams
   179             .iter()
   196             .iter()
   180             .find_map(|(_, t)| Some(t).filter(|t| f(&t)))
   197             .find_map(|(_, t)| Some(t).filter(|t| f(&t)))
   181     }
   198     }
   182 
   199 
   183     pub fn client_teams(&self, client_id: ClientId) -> impl Iterator<Item = &TeamInfo> + Clone {
   200     pub fn client_teams(&self, client_id: ClientId) -> impl Iterator<Item = &TeamInfo> {
   184         self.teams
   201         client_teams_impl(&self.teams, client_id)
   185             .iter()
       
   186             .filter(move |(id, _)| *id == client_id)
       
   187             .map(|(_, t)| t)
       
   188     }
   202     }
   189 
   203 
   190     pub fn client_team_indices(&self, client_id: ClientId) -> Vec<u8> {
   204     pub fn client_team_indices(&self, client_id: ClientId) -> Vec<u8> {
   191         self.teams
   205         self.teams
   192             .iter()
   206             .iter()