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