--- 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"
--- 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<String>) {
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::<String>()],
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],
--- 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<Option<String>> for Option<Ascii>{
fn into2(self) -> Option<String> { self.map(|x| {x.0}) }
}
+impl Into2<Option<Vec<String>>> for Option<Vec<Ascii>>{
+ fn into2(self) -> Option<Vec<String>> { 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<Ascii>;
}
+impl Arbitrary for GameCfg {
+ type Parameters = ();
+
+ fn arbitrary_with(args: <Self as Arbitrary>::Parameters) -> <Self as Arbitrary>::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<Ascii>),
+ 7 => Scheme(Ascii, Option<Vec<Ascii>>),
+ 8 => Script(Ascii),
+ 9 => Theme(Ascii),
+ 10 => DrawnMap(Ascii))
+ }).boxed()
+ }
+
+ type Strategy = BoxedStrategy<GameCfg>;
+}
+
+impl Arbitrary for TeamInfo {
+ type Parameters = ();
+
+ fn arbitrary_with(args: <Self as Arbitrary>::Parameters) -> <Self as Arbitrary>::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<TeamInfo>;
+}
+
pub fn gen_proto_msg() -> BoxedStrategy<HWProtocolMessage> 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<Ascii>),
- //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),
--- 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 {
--- 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()