rust/hedgewars-server/src/core/room.rs
changeset 16000 d9f1b239b6d7
parent 15804 747278149393
equal deleted inserted replaced
15999:d73e6cb37f83 16000:d9f1b239b6d7
    12 use std::{collections::HashMap, iter};
    12 use std::{collections::HashMap, iter};
    13 
    13 
    14 pub const MAX_TEAMS_IN_ROOM: u8 = 8;
    14 pub const MAX_TEAMS_IN_ROOM: u8 = 8;
    15 pub const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_TEAMS_IN_ROOM * MAX_HEDGEHOGS_PER_TEAM;
    15 pub const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_TEAMS_IN_ROOM * MAX_HEDGEHOGS_PER_TEAM;
    16 
    16 
       
    17 #[derive(Clone, Debug)]
       
    18 pub struct OwnedTeam {
       
    19     pub owner_id: ClientId,
       
    20     pub owner_nick: String,
       
    21     pub info: TeamInfo,
       
    22 }
       
    23 
    17 fn client_teams_impl(
    24 fn client_teams_impl(
    18     teams: &[(ClientId, TeamInfo)],
    25     teams: &[OwnedTeam],
    19     client_id: ClientId,
    26     owner_id: ClientId,
    20 ) -> impl Iterator<Item = &TeamInfo> + Clone {
    27 ) -> impl Iterator<Item = &TeamInfo> + Clone {
    21     teams
    28     teams
    22         .iter()
    29         .iter()
    23         .filter(move |(id, _)| *id == client_id)
    30         .filter(move |team| team.owner_id == owner_id)
    24         .map(|(_, t)| t)
    31         .map(|team| &team.info)
    25 }
    32 }
    26 
    33 
    27 pub struct GameInfo {
    34 pub struct GameInfo {
    28     pub original_teams: Vec<(ClientId, TeamInfo)>,
    35     pub original_teams: Vec<OwnedTeam>,
    29     pub left_teams: Vec<String>,
    36     pub left_teams: Vec<String>,
    30     pub msg_log: Vec<String>,
    37     pub msg_log: Vec<String>,
    31     pub sync_msg: Option<String>,
    38     pub sync_msg: Option<String>,
    32     pub is_paused: bool,
    39     pub is_paused: bool,
    33     original_config: RoomConfig,
    40     original_config: RoomConfig,
    34 }
    41 }
    35 
    42 
    36 impl GameInfo {
    43 impl GameInfo {
    37     fn new(teams: Vec<(ClientId, TeamInfo)>, config: RoomConfig) -> GameInfo {
    44     fn new(teams: Vec<OwnedTeam>, config: RoomConfig) -> GameInfo {
    38         GameInfo {
    45         GameInfo {
    39             left_teams: Vec::new(),
    46             left_teams: Vec::new(),
    40             msg_log: Vec::new(),
    47             msg_log: Vec::new(),
    41             sync_msg: None,
    48             sync_msg: None,
    42             is_paused: false,
    49             is_paused: false,
    43             original_teams: teams,
    50             original_teams: teams,
    44             original_config: config,
    51             original_config: config,
    45         }
    52         }
    46     }
    53     }
    47 
    54 
    48     pub fn client_teams(&self, client_id: ClientId) -> impl Iterator<Item = &TeamInfo> + Clone {
    55     pub fn client_teams(&self, owner_id: ClientId) -> impl Iterator<Item = &TeamInfo> + Clone {
    49         client_teams_impl(&self.original_teams, client_id)
    56         client_teams_impl(&self.original_teams, owner_id)
       
    57     }
       
    58 
       
    59     pub fn client_teams_by_nick<'a>(
       
    60         &'a self,
       
    61         owner_nick: &'a str,
       
    62     ) -> impl Iterator<Item = &TeamInfo> + Clone + 'a {
       
    63         self.original_teams
       
    64             .iter()
       
    65             .filter(move |team| team.owner_nick == owner_nick)
       
    66             .map(|team| &team.info)
    50     }
    67     }
    51 
    68 
    52     pub fn mark_left_teams<'a, I>(&mut self, team_names: I)
    69     pub fn mark_left_teams<'a, I>(&mut self, team_names: I)
    53     where
    70     where
    54         I: Iterator<Item = &'a String>,
    71         I: Iterator<Item = &'a String>,
    93 
   110 
    94     pub players_number: u8,
   111     pub players_number: u8,
    95     pub default_hedgehog_number: u8,
   112     pub default_hedgehog_number: u8,
    96     pub max_teams: u8,
   113     pub max_teams: u8,
    97     pub ready_players_number: u8,
   114     pub ready_players_number: u8,
    98     pub teams: Vec<(ClientId, TeamInfo)>,
   115     pub teams: Vec<OwnedTeam>,
    99     config: RoomConfig,
   116     config: RoomConfig,
   100     pub voting: Option<Voting>,
   117     pub voting: Option<Voting>,
   101     pub saves: HashMap<String, RoomSave>,
   118     pub saves: HashMap<String, RoomSave>,
   102     pub game_info: Option<GameInfo>,
   119     pub game_info: Option<GameInfo>,
   103 }
   120 }
   123             game_info: None,
   140             game_info: None,
   124         }
   141         }
   125     }
   142     }
   126 
   143 
   127     pub fn hedgehogs_number(&self) -> u8 {
   144     pub fn hedgehogs_number(&self) -> u8 {
   128         self.teams.iter().map(|(_, t)| t.hedgehogs_number).sum()
   145         self.teams
       
   146             .iter()
       
   147             .map(|team| team.info.hedgehogs_number)
       
   148             .sum()
   129     }
   149     }
   130 
   150 
   131     pub fn addable_hedgehogs(&self) -> u8 {
   151     pub fn addable_hedgehogs(&self) -> u8 {
   132         MAX_HEDGEHOGS_IN_ROOM - self.hedgehogs_number()
   152         MAX_HEDGEHOGS_IN_ROOM - self.hedgehogs_number()
   133     }
   153     }
   134 
   154 
   135     pub fn add_team(
   155     pub fn add_team(
   136         &mut self,
   156         &mut self,
   137         owner_id: ClientId,
   157         owner: &HwClient,
   138         mut team: TeamInfo,
   158         mut team: TeamInfo,
   139         preserve_color: bool,
   159         preserve_color: bool,
   140     ) -> &TeamInfo {
   160     ) -> &TeamInfo {
   141         if !preserve_color {
   161         if !preserve_color {
   142             team.color = iter::repeat(())
   162             team.color = iter::repeat(())
   143                 .enumerate()
   163                 .enumerate()
   144                 .map(|(i, _)| i as u8)
   164                 .map(|(i, _)| i as u8)
   145                 .take(u8::max_value() as usize + 1)
   165                 .take(u8::MAX as usize + 1)
   146                 .find(|i| self.teams.iter().all(|(_, t)| t.color != *i))
   166                 .find(|i| self.teams.iter().all(|team| team.info.color != *i))
   147                 .unwrap_or(0u8)
   167                 .unwrap_or(0u8)
   148         };
   168         };
   149         team.hedgehogs_number = if self.teams.is_empty() {
   169         team.hedgehogs_number = if self.teams.is_empty() {
   150             self.default_hedgehog_number
   170             self.default_hedgehog_number
   151         } else {
   171         } else {
   152             self.teams[0]
   172             self.teams[0]
   153                 .1
   173                 .info
   154                 .hedgehogs_number
   174                 .hedgehogs_number
   155                 .min(self.addable_hedgehogs())
   175                 .min(self.addable_hedgehogs())
   156         };
   176         };
   157         self.teams.push((owner_id, team));
   177         self.teams.push(OwnedTeam {
   158         &self.teams.last().unwrap().1
   178             owner_id: owner.id,
       
   179             owner_nick: owner.nick.clone(),
       
   180             info: team,
       
   181         });
       
   182         &self.teams.last().unwrap().info
   159     }
   183     }
   160 
   184 
   161     pub fn remove_team(&mut self, team_name: &str) {
   185     pub fn remove_team(&mut self, team_name: &str) {
   162         if let Some(index) = self.teams.iter().position(|(_, t)| t.name == team_name) {
   186         if let Some(index) = self
       
   187             .teams
       
   188             .iter()
       
   189             .position(|team| team.info.name == team_name)
       
   190         {
   163             self.teams.remove(index);
   191             self.teams.remove(index);
   164         }
   192         }
   165     }
   193     }
   166 
   194 
   167     pub fn set_hedgehogs_number(&mut self, n: u8) -> Vec<String> {
   195     pub fn set_hedgehogs_number(&mut self, n: u8) -> Vec<String> {
   168         let mut names = Vec::new();
   196         let mut names = Vec::new();
   169         let teams = &mut self.teams;
   197         let teams = &mut self.teams;
   170 
   198 
   171         if teams.len() as u8 * n <= MAX_HEDGEHOGS_IN_ROOM {
   199         if teams.len() as u8 * n <= MAX_HEDGEHOGS_IN_ROOM {
   172             for (_, team) in teams.iter_mut() {
   200             for team in teams.iter_mut() {
   173                 team.hedgehogs_number = n;
   201                 team.info.hedgehogs_number = n;
   174                 names.push(team.name.clone())
   202                 names.push(team.info.name.clone())
   175             }
   203             }
   176             self.default_hedgehog_number = n;
   204             self.default_hedgehog_number = n;
   177         }
   205         }
   178         names
   206         names
   179     }
   207     }
   188     where
   216     where
   189         F: Fn(&TeamInfo) -> bool,
   217         F: Fn(&TeamInfo) -> bool,
   190     {
   218     {
   191         self.teams
   219         self.teams
   192             .iter_mut()
   220             .iter_mut()
   193             .find(|(_, t)| f(t))
   221             .find(|team| f(&team.info))
   194             .map(|(id, t)| (*id, t))
   222             .map(|team| (team.owner_id, &mut team.info))
   195     }
   223     }
   196 
   224 
   197     pub fn find_team<F>(&self, f: F) -> Option<&TeamInfo>
   225     pub fn find_team<F>(&self, f: F) -> Option<&TeamInfo>
   198     where
   226     where
   199         F: Fn(&TeamInfo) -> bool,
   227         F: Fn(&TeamInfo) -> bool,
   200     {
   228     {
   201         self.teams
   229         self.teams
   202             .iter()
   230             .iter()
   203             .find_map(|(_, t)| Some(t).filter(|t| f(&t)))
   231             .find_map(|team| Some(&team.info).filter(|t| f(&t)))
   204     }
   232     }
   205 
   233 
   206     pub fn client_teams(&self, client_id: ClientId) -> impl Iterator<Item = &TeamInfo> {
   234     pub fn client_teams(&self, owner_id: ClientId) -> impl Iterator<Item = &TeamInfo> {
   207         client_teams_impl(&self.teams, client_id)
   235         client_teams_impl(&self.teams, owner_id)
   208     }
   236     }
   209 
   237 
   210     pub fn client_team_indices(&self, client_id: ClientId) -> Vec<u8> {
   238     pub fn client_team_indices(&self, client_id: ClientId) -> Vec<u8> {
   211         self.teams
   239         self.teams
   212             .iter()
   240             .iter()
   213             .enumerate()
   241             .enumerate()
   214             .filter(move |(_, (id, _))| *id == client_id)
   242             .filter(move |(_, team)| team.owner_id == client_id)
   215             .map(|(i, _)| i as u8)
   243             .map(|(i, _)| i as u8)
   216             .collect()
   244             .collect()
   217     }
   245     }
   218 
   246 
   219     pub fn clan_team_owners(&self, color: u8) -> impl Iterator<Item = ClientId> + '_ {
   247     pub fn clan_team_owners(&self, color: u8) -> impl Iterator<Item = ClientId> + '_ {
   220         self.teams
   248         self.teams
   221             .iter()
   249             .iter()
   222             .filter(move |(_, t)| t.color == color)
   250             .filter(move |team| team.info.color == color)
   223             .map(|(id, _)| *id)
   251             .map(|team| team.owner_id)
   224     }
   252     }
   225 
   253 
   226     pub fn find_team_owner(&self, team_name: &str) -> Option<(ClientId, &str)> {
   254     pub fn find_team_owner(&self, team_name: &str) -> Option<(ClientId, &str)> {
   227         self.teams
   255         self.teams
   228             .iter()
   256             .iter()
   229             .find(|(_, t)| t.name == team_name)
   257             .find(|team| team.info.name == team_name)
   230             .map(|(id, t)| (*id, &t.name[..]))
   258             .map(|team| (team.owner_id, &team.info.name[..]))
   231     }
   259     }
   232 
   260 
   233     pub fn find_team_color(&self, owner_id: ClientId) -> Option<u8> {
   261     pub fn find_team_color(&self, owner_id: ClientId) -> Option<u8> {
   234         self.client_teams(owner_id).nth(0).map(|t| t.color)
   262         self.client_teams(owner_id).nth(0).map(|t| t.color)
   235     }
   263     }
   236 
   264 
   237     pub fn has_multiple_clans(&self) -> bool {
   265     pub fn has_multiple_clans(&self) -> bool {
   238         self.teams.iter().min_by_key(|(_, t)| t.color)
   266         let colors = self.teams.iter().map(|team| team.info.color);
   239             != self.teams.iter().max_by_key(|(_, t)| t.color)
   267         colors.clone().min() != colors.max()
   240     }
   268     }
   241 
   269 
   242     pub fn set_config(&mut self, cfg: GameCfg) {
   270     pub fn set_config(&mut self, cfg: GameCfg) {
   243         self.config.set_config(cfg);
   271         self.config.set_config(cfg);
   244     }
   272     }