rust/hedgewars-server/src/server/demo.rs
changeset 15581 ab095fc0256c
parent 15580 98482c4ccf4b
child 15796 2939d8599418
equal deleted inserted replaced
15580:98482c4ccf4b 15581:ab095fc0256c
     1 use crate::{
     1 use crate::{
     2     core::types::{GameCfg, HedgehogInfo, TeamInfo},
     2     core::types::{GameCfg, HedgehogInfo, TeamInfo},
     3     server::haskell::HaskellValue,
     3     server::haskell::HaskellValue,
     4 };
     4 };
     5 use std::{
     5 use std::{
       
     6     collections::HashMap,
     6     fs,
     7     fs,
     7     io::{self, BufReader, Read, Write},
     8     io::{self, BufReader, Read, Write},
     8     str::FromStr,
     9     str::FromStr,
     9 };
    10 };
    10 
    11 
    11 #[derive(PartialEq, Debug)]
    12 #[derive(PartialEq, Debug)]
    12 struct Demo {
    13 pub struct Demo {
    13     teams: Vec<TeamInfo>,
    14     teams: Vec<TeamInfo>,
    14     config: Vec<GameCfg>,
    15     config: Vec<GameCfg>,
    15     messages: Vec<String>,
    16     messages: Vec<String>,
    16 }
    17 }
    17 
    18 
    18 impl Demo {
    19 impl Demo {
    19     fn save(&self, file: String) -> io::Result<()> {
    20     fn save(self, filename: String) -> io::Result<()> {
    20         Ok(unimplemented!())
    21         let text = format!("{}", demo_to_haskell(self));
       
    22         let mut file = fs::File::open(filename)?;
       
    23         file.write(text.as_bytes())?;
       
    24         Ok(())
    21     }
    25     }
    22 
    26 
    23     fn load(filename: String) -> io::Result<Self> {
    27     fn load(filename: String) -> io::Result<Self> {
    24         let mut file = fs::File::open(filename)?;
    28         let mut file = fs::File::open(filename)?;
    25         let mut bytes = vec![];
    29         let mut bytes = vec![];
   267             messages,
   271             messages,
   268         })
   272         })
   269     }
   273     }
   270 }
   274 }
   271 
   275 
       
   276 fn demo_to_haskell(mut demo: Demo) -> HaskellValue {
       
   277     use HaskellValue as Hs;
       
   278 
       
   279     let mut teams = Vec::with_capacity(demo.teams.len());
       
   280     for team in demo.teams {
       
   281         let mut fields = HashMap::<String, HaskellValue>::new();
       
   282 
       
   283         fields.insert("teamowner".to_string(), Hs::String(team.owner));
       
   284         fields.insert("teamname".to_string(), Hs::String(team.name));
       
   285         fields.insert("teamcolor".to_string(), Hs::Number(team.color));
       
   286         fields.insert("teamgrave".to_string(), Hs::String(team.grave));
       
   287         fields.insert("teamvoicepack".to_string(), Hs::String(team.voice_pack));
       
   288         fields.insert("teamflag".to_string(), Hs::String(team.flag));
       
   289         fields.insert("difficulty".to_string(), Hs::Number(team.difficulty));
       
   290         fields.insert("hhnum".to_string(), Hs::Number(team.hedgehogs_number));
       
   291 
       
   292         let hogs = team
       
   293             .hedgehogs
       
   294             .iter()
       
   295             .map(|hog| Hs::AnonStruct {
       
   296                 name: "HedgehogInfo".to_string(),
       
   297                 fields: vec![Hs::String(hog.name.clone()), Hs::String(hog.hat.clone())],
       
   298             })
       
   299             .collect();
       
   300 
       
   301         fields.insert("hedgehogs".to_string(), Hs::List(hogs));
       
   302 
       
   303         teams.push(Hs::Struct {
       
   304             name: "TeamInfo".to_string(),
       
   305             fields,
       
   306         })
       
   307     }
       
   308 
       
   309     let mut map_config = vec![];
       
   310     let mut game_config = vec![];
       
   311 
       
   312     let mut save_map_config = |name: &str, value: String| {
       
   313         map_config.push(Hs::Tuple(vec![
       
   314             Hs::String(name.to_string()),
       
   315             Hs::String(value),
       
   316         ]));
       
   317     };
       
   318 
       
   319     for config_item in &demo.config {
       
   320         match config_item {
       
   321             GameCfg::FeatureSize(size) => save_map_config("FEATURE_SIZE", size.to_string()),
       
   322             GameCfg::MapType(map_type) => save_map_config("MAP", map_type.clone()),
       
   323             GameCfg::MapGenerator(generator) => save_map_config("MAPGEN", generator.to_string()),
       
   324             GameCfg::MazeSize(size) => save_map_config("MAZE_SIZE", size.to_string()),
       
   325             GameCfg::Seed(seed) => save_map_config("SEED", seed.clone()),
       
   326             GameCfg::Template(template) => save_map_config("TEMPLATE", template.to_string()),
       
   327             GameCfg::DrawnMap(map) => save_map_config("DRAWNMAP", map.clone()),
       
   328             _ => (),
       
   329         }
       
   330     }
       
   331 
       
   332     let mut save_game_config = |name: &str, mut value: Vec<String>| {
       
   333         map_config.push(Hs::Tuple(vec![
       
   334             Hs::String(name.to_string()),
       
   335             Hs::List(value.drain(..).map(Hs::String).collect()),
       
   336         ]));
       
   337     };
       
   338 
       
   339     for config_item in &demo.config {
       
   340         match config_item {
       
   341             GameCfg::Ammo(name, Some(ammo)) => {
       
   342                 save_game_config("AMMO", vec![name.clone(), ammo.clone()])
       
   343             }
       
   344             GameCfg::Ammo(name, None) => save_game_config("AMMO", vec![name.clone()]),
       
   345             GameCfg::Scheme(name, scheme) => {
       
   346                 let mut values = vec![name.clone()];
       
   347                 values.extend_from_slice(&scheme);
       
   348                 save_game_config("SCHEME", values);
       
   349             }
       
   350             GameCfg::Script(script) => save_game_config("SCRIPT", vec![script.clone()]),
       
   351             GameCfg::Theme(theme) => save_game_config("THEME", vec![theme.clone()]),
       
   352             _ => (),
       
   353         }
       
   354     }
       
   355 
       
   356     Hs::Tuple(vec![
       
   357         Hs::List(teams),
       
   358         Hs::List(map_config),
       
   359         Hs::List(game_config),
       
   360         Hs::List(demo.messages.drain(..).map(Hs::String).collect()),
       
   361     ])
       
   362 }
       
   363 
   272 fn haskell_to_demo(value: HaskellValue) -> Option<Demo> {
   364 fn haskell_to_demo(value: HaskellValue) -> Option<Demo> {
   273     use HaskellValue::*;
   365     use HaskellValue::*;
   274     let mut lists = value.into_tuple()?;
   366     let mut lists = value.into_tuple()?;
   275     let mut lists_iter = lists.drain(..);
   367     let mut lists_iter = lists.drain(..);
   276 
   368