rust/hedgewars-server/src/server/room.rs
changeset 14785 a1077e8d26f4
parent 14457 98ef2913ec73
child 14788 6dea1ca64992
equal deleted inserted replaced
14784:8390d5e4e39c 14785:a1077e8d26f4
     1 use crate::server::{
     1 use crate::server::{
     2     client::HWClient,
     2     client::HWClient,
     3     coretypes::{ClientId, GameCfg, GameCfg::*, RoomId, TeamInfo, Voting, MAX_HEDGEHOGS_PER_TEAM},
     3     coretypes::{
       
     4         ClientId, GameCfg, GameCfg::*, RoomConfig, RoomId, TeamInfo, Voting, MAX_HEDGEHOGS_PER_TEAM,
       
     5     },
     4 };
     6 };
     5 use bitflags::*;
     7 use bitflags::*;
     6 use serde::{Deserialize, Serialize};
     8 use serde::{Deserialize, Serialize};
     7 use serde_derive::{Deserialize, Serialize};
     9 use serde_derive::{Deserialize, Serialize};
     8 use serde_yaml;
    10 use serde_yaml;
     9 use std::{collections::HashMap, iter};
    11 use std::{collections::HashMap, iter};
    10 
    12 
    11 const MAX_TEAMS_IN_ROOM: u8 = 8;
    13 const MAX_TEAMS_IN_ROOM: u8 = 8;
    12 const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_HEDGEHOGS_PER_TEAM * MAX_HEDGEHOGS_PER_TEAM;
    14 const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_HEDGEHOGS_PER_TEAM * MAX_HEDGEHOGS_PER_TEAM;
    13 
       
    14 #[derive(Clone, Serialize, Deserialize)]
       
    15 struct Ammo {
       
    16     name: String,
       
    17     settings: Option<String>,
       
    18 }
       
    19 
       
    20 #[derive(Clone, Serialize, Deserialize)]
       
    21 struct Scheme {
       
    22     name: String,
       
    23     settings: Vec<String>,
       
    24 }
       
    25 
       
    26 #[derive(Clone, Serialize, Deserialize)]
       
    27 struct RoomConfig {
       
    28     feature_size: u32,
       
    29     map_type: String,
       
    30     map_generator: u32,
       
    31     maze_size: u32,
       
    32     seed: String,
       
    33     template: u32,
       
    34 
       
    35     ammo: Ammo,
       
    36     scheme: Scheme,
       
    37     script: String,
       
    38     theme: String,
       
    39     drawn_map: Option<String>,
       
    40 }
       
    41 
       
    42 impl RoomConfig {
       
    43     fn new() -> RoomConfig {
       
    44         RoomConfig {
       
    45             feature_size: 12,
       
    46             map_type: "+rnd+".to_string(),
       
    47             map_generator: 0,
       
    48             maze_size: 0,
       
    49             seed: "seed".to_string(),
       
    50             template: 0,
       
    51 
       
    52             ammo: Ammo {
       
    53                 name: "Default".to_string(),
       
    54                 settings: None,
       
    55             },
       
    56             scheme: Scheme {
       
    57                 name: "Default".to_string(),
       
    58                 settings: Vec::new(),
       
    59             },
       
    60             script: "Normal".to_string(),
       
    61             theme: "\u{1f994}".to_string(),
       
    62             drawn_map: None,
       
    63         }
       
    64     }
       
    65 }
       
    66 
    15 
    67 fn client_teams_impl(
    16 fn client_teams_impl(
    68     teams: &[(ClientId, TeamInfo)],
    17     teams: &[(ClientId, TeamInfo)],
    69     client_id: ClientId,
    18     client_id: ClientId,
    70 ) -> impl Iterator<Item = &TeamInfo> + Clone {
    19 ) -> impl Iterator<Item = &TeamInfo> + Clone {
    71     teams
    20     teams
    72         .iter()
    21         .iter()
    73         .filter(move |(id, _)| *id == client_id)
    22         .filter(move |(id, _)| *id == client_id)
    74         .map(|(_, t)| t)
    23         .map(|(_, t)| t)
    75 }
       
    76 
       
    77 fn map_config_from(c: &RoomConfig) -> Vec<String> {
       
    78     vec![
       
    79         c.feature_size.to_string(),
       
    80         c.map_type.to_string(),
       
    81         c.map_generator.to_string(),
       
    82         c.maze_size.to_string(),
       
    83         c.seed.to_string(),
       
    84         c.template.to_string(),
       
    85     ]
       
    86 }
       
    87 
       
    88 fn game_config_from(c: &RoomConfig) -> Vec<GameCfg> {
       
    89     use crate::server::coretypes::GameCfg::*;
       
    90     let mut v = vec![
       
    91         Ammo(c.ammo.name.to_string(), c.ammo.settings.clone()),
       
    92         Scheme(c.scheme.name.to_string(), c.scheme.settings.clone()),
       
    93         Script(c.script.to_string()),
       
    94         Theme(c.theme.to_string()),
       
    95     ];
       
    96     if let Some(ref m) = c.drawn_map {
       
    97         v.push(DrawnMap(m.to_string()))
       
    98     }
       
    99     v
       
   100 }
    24 }
   101 
    25 
   102 pub struct GameInfo {
    26 pub struct GameInfo {
   103     pub teams_in_game: u8,
    27     pub teams_in_game: u8,
   104     pub teams_at_start: Vec<(ClientId, TeamInfo)>,
    28     pub teams_at_start: Vec<(ClientId, TeamInfo)>,
   288         self.teams.iter().min_by_key(|(_, t)| t.color)
   212         self.teams.iter().min_by_key(|(_, t)| t.color)
   289             != self.teams.iter().max_by_key(|(_, t)| t.color)
   213             != self.teams.iter().max_by_key(|(_, t)| t.color)
   290     }
   214     }
   291 
   215 
   292     pub fn set_config(&mut self, cfg: GameCfg) {
   216     pub fn set_config(&mut self, cfg: GameCfg) {
   293         let c = &mut self.config;
   217         self.config.set_config(cfg);
   294         match cfg {
       
   295             FeatureSize(s) => c.feature_size = s,
       
   296             MapType(t) => c.map_type = t,
       
   297             MapGenerator(g) => c.map_generator = g,
       
   298             MazeSize(s) => c.maze_size = s,
       
   299             Seed(s) => c.seed = s,
       
   300             Template(t) => c.template = t,
       
   301 
       
   302             Ammo(n, s) => {
       
   303                 c.ammo = Ammo {
       
   304                     name: n,
       
   305                     settings: s,
       
   306                 }
       
   307             }
       
   308             Scheme(n, s) => {
       
   309                 c.scheme = Scheme {
       
   310                     name: n,
       
   311                     settings: s,
       
   312                 }
       
   313             }
       
   314             Script(s) => c.script = s,
       
   315             Theme(t) => c.theme = t,
       
   316             DrawnMap(m) => c.drawn_map = Some(m),
       
   317         };
       
   318     }
   218     }
   319 
   219 
   320     pub fn start_round(&mut self) {
   220     pub fn start_round(&mut self) {
   321         if self.game_info.is_none() {
   221         if self.game_info.is_none() {
   322             self.game_info = Some(GameInfo::new(self.teams.clone(), self.config.clone()));
   222             self.game_info = Some(GameInfo::new(self.teams.clone(), self.config.clone()));
   381             c.scheme.name.to_string(),
   281             c.scheme.name.to_string(),
   382             c.ammo.name.to_string(),
   282             c.ammo.name.to_string(),
   383         ]
   283         ]
   384     }
   284     }
   385 
   285 
       
   286     pub fn active_config(&self) -> &RoomConfig {
       
   287         match self.game_info {
       
   288             Some(ref info) => &info.config,
       
   289             None => &self.config,
       
   290         }
       
   291     }
       
   292 
   386     pub fn map_config(&self) -> Vec<String> {
   293     pub fn map_config(&self) -> Vec<String> {
   387         match self.game_info {
   294         match self.game_info {
   388             Some(ref info) => map_config_from(&info.config),
   295             Some(ref info) => info.config.to_map_config(),
   389             None => map_config_from(&self.config),
   296             None => self.config.to_map_config(),
   390         }
   297         }
   391     }
   298     }
   392 
   299 
   393     pub fn game_config(&self) -> Vec<GameCfg> {
   300     pub fn game_config(&self) -> Vec<GameCfg> {
   394         match self.game_info {
   301         match self.game_info {
   395             Some(ref info) => game_config_from(&info.config),
   302             Some(ref info) => info.config.to_game_config(),
   396             None => game_config_from(&self.config),
   303             None => self.config.to_game_config(),
   397         }
   304         }
   398     }
   305     }
   399 
   306 
   400     pub fn save_config(&mut self, name: String, location: String) {
   307     pub fn save_config(&mut self, name: String, location: String) {
   401         self.saves.insert(
   308         self.saves.insert(
   430                 self.greeting = greeting;
   337                 self.greeting = greeting;
   431                 self.saves = saves;
   338                 self.saves = saves;
   432             },
   339             },
   433         )
   340         )
   434     }
   341     }
   435 
   342 }
   436     pub fn team_info(owner: &HWClient, team: &TeamInfo) -> Vec<String> {
       
   437         let mut info = vec![
       
   438             team.name.clone(),
       
   439             team.grave.clone(),
       
   440             team.fort.clone(),
       
   441             team.voice_pack.clone(),
       
   442             team.flag.clone(),
       
   443             owner.nick.clone(),
       
   444             team.difficulty.to_string(),
       
   445         ];
       
   446         let hogs = team
       
   447             .hedgehogs
       
   448             .iter()
       
   449             .flat_map(|h| iter::once(h.name.clone()).chain(iter::once(h.hat.clone())));
       
   450         info.extend(hogs);
       
   451         info
       
   452     }
       
   453 }