# HG changeset patch # User alfadur # Date 1530668536 -10800 # Node ID c4f917c6be519358a281a2f030121308f6cf51f2 # Parent da71e0d88a1cab2668982067128076a4366bff6a add missing message tests diff -r da71e0d88a1c -r c4f917c6be51 gameServer2/Cargo.toml --- a/gameServer2/Cargo.toml Wed Jul 04 00:01:25 2018 +0300 +++ b/gameServer2/Cargo.toml Wed Jul 04 04:42:16 2018 +0300 @@ -8,7 +8,7 @@ mio = "0.6" slab = "0.4" netbuf = "0.4.0" -nom = "3.2" +nom = "4.0" env_logger = "0.4" log = "0.4" proptest = "0.8" diff -r da71e0d88a1c -r c4f917c6be51 gameServer2/src/protocol/messages.rs --- a/gameServer2/src/protocol/messages.rs Wed Jul 04 00:01:25 2018 +0300 +++ b/gameServer2/src/protocol/messages.rs Wed Jul 04 04:42:16 2018 +0300 @@ -1,7 +1,5 @@ use server::coretypes::{ServerVar, GameCfg, TeamInfo, HedgehogInfo}; -use std; -use std::ops; -use std::convert::From; +use std::{ops, convert::From, iter::once}; #[derive(PartialEq, Eq, Clone, Debug)] pub enum HWProtocolMessage { @@ -104,30 +102,35 @@ } impl GameCfg { - pub fn into_server_msg(self) -> HWServerMessage { - use self::HWServerMessage::ConfigEntry; + pub fn to_protocol(&self) -> (String, Vec) { use server::coretypes::GameCfg::*; match self { - FeatureSize(s) => ConfigEntry("FEATURE_SIZE".to_string(), vec![s.to_string()]), - MapType(t) => ConfigEntry("MAP".to_string(), vec![t.to_string()]), - MapGenerator(g) => ConfigEntry("MAPGEN".to_string(), vec![g.to_string()]), - MazeSize(s) => ConfigEntry("MAZE_SIZE".to_string(), vec![s.to_string()]), - Seed(s) => ConfigEntry("SEED".to_string(), vec![s.to_string()]), - Template(t) => ConfigEntry("TEMPLATE".to_string(), vec![t.to_string()]), + FeatureSize(s) => ("FEATURE_SIZE".to_string(), vec![s.to_string()]), + MapType(t) => ("MAP".to_string(), vec![t.to_string()]), + MapGenerator(g) => ("MAPGEN".to_string(), vec![g.to_string()]), + MazeSize(s) => ("MAZE_SIZE".to_string(), vec![s.to_string()]), + Seed(s) => ("SEED".to_string(), vec![s.to_string()]), + Template(t) => ("TEMPLATE".to_string(), vec![t.to_string()]), - Ammo(n, None) => ConfigEntry("AMMO".to_string(), vec![n.to_string()]), - Ammo(n, Some(s)) => ConfigEntry("AMMO".to_string(), vec![n.to_string(), s.to_string()]), - Scheme(n, None) => ConfigEntry("SCHEME".to_string(), vec![n.to_string()]), - Scheme(n, Some(s)) => ConfigEntry("SCHEME".to_string(), { + Ammo(n, None) => ("AMMO".to_string(), vec![n.to_string()]), + Ammo(n, Some(s)) => ("AMMO".to_string(), vec![n.to_string(), s.to_string()]), + Scheme(n, None) => ("SCHEME".to_string(), vec![n.to_string()]), + Scheme(n, Some(s)) => ("SCHEME".to_string(), { let mut v = vec![n.to_string()]; - v.extend(s.into_iter()); + v.extend(s.clone().into_iter()); v }), - Script(s) => ConfigEntry("SCRIPT".to_string(), vec![s.to_string()]), - Theme(t) => ConfigEntry("THEME".to_string(), vec![t.to_string()]), - DrawnMap(m) => ConfigEntry("DRAWNMAP".to_string(), vec![m.to_string()]) + Script(s) => ("SCRIPT".to_string(), vec![s.to_string()]), + Theme(t) => ("THEME".to_string(), vec![t.to_string()]), + DrawnMap(m) => ("DRAWNMAP".to_string(), vec![m.to_string()]) } } + + pub fn to_server_msg(&self) -> HWServerMessage { + use self::HWServerMessage::ConfigEntry; + let (name, args) = self.to_protocol(); + HWServerMessage::ConfigEntry(name, args) + } } macro_rules! const_braces { @@ -140,6 +143,11 @@ }; } +macro_rules! several { + [$part: expr] => { once($part) }; + [$part: expr, $($other: expr),*] => { once($part).chain(several![$($other),*]) }; +} + impl HWProtocolMessage { /** Converts the message to a raw `String`, which can be sent over the network. * @@ -188,11 +196,18 @@ Stats => msg!["CMD", "STATS"], Part(None) => msg!["PART"], Part(Some(msg)) => msg!["PART", msg], - //Cfg(GameCfg) => - //AddTeam(info) => + Cfg(config) => { + let (name, args) = config.to_protocol(); + msg!["CFG", name, args.join("\n")] + }, + AddTeam(info) => + msg![info.name, info.color, info.grave, info.fort, + info.voice_pack, info.flag, info.difficulty, + info.hedgehogs.iter().flat_map(|h| + several![&h.name[..], "\n", &h.hat[..]]).collect::()], RemoveTeam(name) => msg!["REMOVE_TEAM", name], - //SetHedgehogsNumber(team, number), ?? - //SetTeamColor(team, color), ?? + SetHedgehogsNumber(team, number) => msg!["HH_NUM", team, number], + SetTeamColor(team, color) => msg!["TEAM_COLOR", team, color], ToggleReady => msg!["TOGGLE_READY"], StartGame => msg!["START_GAME"], EngineMessage(msg) => msg!["EM", msg], diff -r da71e0d88a1c -r c4f917c6be51 gameServer2/src/protocol/test.rs --- a/gameServer2/src/protocol/test.rs Wed Jul 04 00:01:25 2018 +0300 +++ b/gameServer2/src/protocol/test.rs Wed Jul 04 04:42:16 2018 +0300 @@ -2,9 +2,11 @@ test_runner::{TestRunner, Reason}, arbitrary::{any, any_with, Arbitrary, StrategyFor}, strategy::{Strategy, BoxedStrategy, Just, Filter, ValueTree}, - string::RegexGeneratorValueTree + string::RegexGeneratorValueTree, }; +use server::coretypes::{GameCfg, TeamInfo, HedgehogInfo}; + use super::messages::{ HWProtocolMessage, HWProtocolMessage::* }; @@ -21,6 +23,9 @@ impl Into2> for Option{ fn into2(self) -> Option { self.map(|x| {x.0}) } } +impl Into2>> for Option>{ + fn into2(self) -> Option> { self.map(|x| {x.into2()}) } +} macro_rules! proto_msg_case { ($val: ident()) => @@ -34,7 +39,7 @@ } macro_rules! proto_msg_match { - ($var: expr, def = $default: ident, $($num: expr => $constr: ident $res: tt),*) => ( + ($var: expr, def = $default: expr, $($num: expr => $constr: ident $res: tt),*) => ( match $var { $($num => (proto_msg_case!($constr $res)).boxed()),*, _ => Just($default).boxed() @@ -63,6 +68,51 @@ type Strategy = BoxedStrategy; } +impl Arbitrary for GameCfg { + type Parameters = (); + + fn arbitrary_with(args: ::Parameters) -> ::Strategy { + use server::coretypes::GameCfg::*; + (0..10).no_shrink().prop_flat_map(|i| { + proto_msg_match!(i, def = FeatureSize(0), + 0 => FeatureSize(u32), + 1 => MapType(Ascii), + 2 => MapGenerator(u32), + 3 => MazeSize(u32), + 4 => Seed(Ascii), + 5 => Template(u32), + 6 => Ammo(Ascii, Option), + 7 => Scheme(Ascii, Option>), + 8 => Script(Ascii), + 9 => Theme(Ascii), + 10 => DrawnMap(Ascii)) + }).boxed() + } + + type Strategy = BoxedStrategy; +} + +impl Arbitrary for TeamInfo { + type Parameters = (); + + fn arbitrary_with(args: ::Parameters) -> ::Strategy { + ("[a-z]+", 0u8..127u8, "[a-z]+", "[a-z]+", "[a-z]+", "[a-z]+", 0u8..127u8) + .prop_map(|(name, color, grave, fort, voice_pack, flag, difficulty)| { + fn hog(n: u8) -> HedgehogInfo { + HedgehogInfo { name: format!("hog{}", n), hat: format!("hat{}", n)} + } + let hedgehogs = [hog(1), hog(2), hog(3), hog(4), hog(5), hog(6), hog(7), hog(8)]; + TeamInfo { + name, color, grave, fort, + voice_pack, flag,difficulty, + hedgehogs, hedgehogs_number: 0 + } + }).boxed() + } + + type Strategy = BoxedStrategy; +} + pub fn gen_proto_msg() -> BoxedStrategy where { let res = (0..58).no_shrink().prop_flat_map(|i| { proto_msg_match!(i, def = Malformed, @@ -96,11 +146,11 @@ 27 => RestartServer(), 28 => Stats(), 29 => Part(Option), - //30 => Cfg(GameCfg), - //31 => AddTeam(TeamInfo), + 30 => Cfg(GameCfg), + 31 => AddTeam(TeamInfo), 32 => RemoveTeam(Ascii), - //33 => SetHedgehogsNumber(String, u8), - //34 => SetTeamColor(String, u8), + 33 => SetHedgehogsNumber(Ascii, u8), + 34 => SetTeamColor(Ascii, u8), 35 => ToggleReady(), 36 => StartGame(), 37 => EngineMessage(Ascii), diff -r da71e0d88a1c -r c4f917c6be51 gameServer2/src/server/actions.rs --- a/gameServer2/src/server/actions.rs Wed Jul 04 00:01:25 2018 +0300 +++ b/gameServer2/src/server/actions.rs Wed Jul 04 04:42:16 2018 +0300 @@ -287,7 +287,7 @@ actions.push(ConfigEntry("FULLMAPCONFIG".to_string(), r.map_config()) .send(to).action()); for cfg in r.game_config().into_iter() { - actions.push(cfg.into_server_msg().send(to).action()); + actions.push(cfg.to_server_msg().send(to).action()); } } if teams { diff -r da71e0d88a1c -r c4f917c6be51 gameServer2/src/server/handlers/inroom.rs --- a/gameServer2/src/server/handlers/inroom.rs Wed Jul 04 00:01:25 2018 +0300 +++ b/gameServer2/src/server/handlers/inroom.rs Wed Jul 04 04:42:16 2018 +0300 @@ -221,9 +221,10 @@ if !c.is_master { vec![ProtocolError("You're not the room master!".to_string())] } else { - r.set_config(cfg.clone()); - vec![cfg.into_server_msg() - .send_all().in_room(r.id).but_self().action()] + let v = vec![cfg.to_server_msg() + .send_all().in_room(r.id).but_self().action()]; + r.set_config(cfg); + v } } else { Vec::new()