14211
|
1 |
use nom::*;
|
|
2 |
use std::str;
|
14210
|
3 |
|
14211
|
4 |
#[derive(Debug, PartialEq)]
|
14210
|
5 |
pub enum KeystrokeAction {
|
|
6 |
Press,
|
|
7 |
Release,
|
|
8 |
}
|
|
9 |
|
14211
|
10 |
#[derive(Debug, PartialEq)]
|
14210
|
11 |
pub enum SyncedEngineMessage {
|
|
12 |
Left(KeystrokeAction),
|
|
13 |
Right(KeystrokeAction),
|
|
14 |
Up(KeystrokeAction),
|
|
15 |
Down(KeystrokeAction),
|
|
16 |
Precise(KeystrokeAction),
|
|
17 |
Attack(KeystrokeAction),
|
|
18 |
NextTurn,
|
|
19 |
Switch,
|
|
20 |
Timer(u8),
|
|
21 |
Slot(u8),
|
|
22 |
SetWeapon(u8),
|
|
23 |
Put(i32, i32),
|
|
24 |
HighJump,
|
|
25 |
LowJump,
|
|
26 |
Skip,
|
|
27 |
TeamControlGained(String),
|
|
28 |
TeamControlLost(String),
|
|
29 |
}
|
|
30 |
|
14211
|
31 |
#[derive(Debug, PartialEq)]
|
14210
|
32 |
pub enum UnsyncedEngineMessage {
|
|
33 |
Ping,
|
|
34 |
Pong,
|
|
35 |
Say(String),
|
|
36 |
Taunt(u8),
|
|
37 |
GameType(u8),
|
|
38 |
Warning(String),
|
|
39 |
StopSyncing,
|
|
40 |
GameOver,
|
|
41 |
GameInterrupted,
|
|
42 |
GameSetupChecksum(String),
|
|
43 |
}
|
|
44 |
|
14211
|
45 |
#[derive(Debug, PartialEq)]
|
14210
|
46 |
pub enum ConfigEngineMessage {
|
|
47 |
ConfigRequest,
|
|
48 |
SetAmmo(String),
|
|
49 |
SetScript(String),
|
|
50 |
SetScriptParam(String),
|
|
51 |
Spectate,
|
|
52 |
TeamLocality(bool),
|
|
53 |
SetMap(String),
|
|
54 |
SetTheme(String),
|
|
55 |
SetSeed(String),
|
|
56 |
SetTemplateFilter(String),
|
|
57 |
SetMapGenerator(String),
|
|
58 |
SetFeatureSize(u8),
|
|
59 |
SetDelay(u32),
|
|
60 |
SetReadyDelay(u32),
|
|
61 |
SetCratesFrequency(u8),
|
|
62 |
SetHealthCrateProbability(u8),
|
|
63 |
SetHealthCratesNumber(u8),
|
|
64 |
SetRoundsTilSuddenDeath(u8),
|
|
65 |
SetSuddenDeathWaterRiseSpeed(u8),
|
|
66 |
SetSuddenDeathHealthDecreaseRate(u8),
|
|
67 |
SetDamageMultiplier(u32),
|
|
68 |
SetRopeLength(u32),
|
|
69 |
SetGetawayTime(u32),
|
|
70 |
SetDudMinesPercent(u8),
|
|
71 |
SetMinesNumber(u32),
|
|
72 |
SetAirMinesNumber(u32),
|
|
73 |
SetBarrelsNumber(u32),
|
|
74 |
SetTurnTime(u32),
|
|
75 |
SetMinesTime(u32),
|
|
76 |
SetWorldEdge(u8),
|
14211
|
77 |
Draw,
|
|
78 |
// TODO
|
14210
|
79 |
SetVoicePack(String),
|
|
80 |
AddHedgehog(String, u8, u32),
|
|
81 |
AddTeam(String, u8),
|
|
82 |
SetHedgehogCoordinates(i32, i32),
|
|
83 |
SetFort(String),
|
|
84 |
SetGrave(String),
|
|
85 |
SetHat(String),
|
|
86 |
SetFlag(String),
|
|
87 |
SetOwner(String),
|
|
88 |
SetOneClanMode(bool),
|
|
89 |
SetMultishootMode(bool),
|
|
90 |
SetSolidLand(bool),
|
|
91 |
SetBorders(bool),
|
|
92 |
SetDivideTeams(bool),
|
|
93 |
SetLowGravity(bool),
|
|
94 |
SetLaserSight(bool),
|
|
95 |
SetInvulnerability(bool),
|
|
96 |
SetHealthReset(bool),
|
|
97 |
SetVampiric(bool),
|
|
98 |
SetKarma(bool),
|
|
99 |
SetArtilleryMode(bool),
|
|
100 |
SetHedgehogSwitch(bool),
|
|
101 |
SetRandomOrder(bool),
|
|
102 |
SetKingMode(bool),
|
|
103 |
SetPlaceHedgehog(bool),
|
|
104 |
SetSharedAmmo(bool),
|
|
105 |
SetGirdersEnabled(bool),
|
|
106 |
SetLandObjectsEnabled(bool),
|
|
107 |
SetAISurvivalMode(bool),
|
|
108 |
SetInfiniteAttack(bool),
|
|
109 |
SetResetWeapons(bool),
|
|
110 |
SetAmmoPerHedgehog(bool),
|
|
111 |
SetWindMode(u8),
|
|
112 |
SetTagTeam(bool),
|
|
113 |
SetBottomBorder(bool),
|
|
114 |
SetShoppaBorder(bool),
|
|
115 |
}
|
|
116 |
|
14211
|
117 |
#[derive(Debug, PartialEq)]
|
14210
|
118 |
pub enum EngineMessage {
|
|
119 |
Synced(SyncedEngineMessage, u32),
|
|
120 |
Unsynced(UnsyncedEngineMessage),
|
|
121 |
Config(ConfigEngineMessage),
|
14211
|
122 |
Unknown,
|
|
123 |
Empty,
|
14210
|
124 |
}
|
|
125 |
|
|
126 |
impl EngineMessage {
|
|
127 |
fn from_bytes(buf: &[u8]) -> Self {
|
|
128 |
unimplemented!()
|
|
129 |
}
|
|
130 |
|
|
131 |
fn to_bytes(&self) -> Vec<u8> {
|
|
132 |
unimplemented!()
|
|
133 |
}
|
|
134 |
}
|
|
135 |
|
14211
|
136 |
named!(length_specifier<&[u8], u16>, alt!(
|
|
137 |
verify!(map!(take!(1), |a : &[u8]| a[0] as u16), |l| l < 64)
|
|
138 |
| map!(take!(2), |a| (a[0] as u16 - 64) * 256 + a[1] as u16 + 64)
|
|
139 |
)
|
|
140 |
);
|
|
141 |
|
|
142 |
named!(unrecognized_message<&[u8], EngineMessage>,
|
|
143 |
do_parse!(rest >> (EngineMessage::Unknown))
|
|
144 |
);
|
|
145 |
|
|
146 |
named!(string_tail<&[u8], String>, map!(map_res!(rest, str::from_utf8), String::from));
|
|
147 |
|
|
148 |
named!(synced_message<&[u8], SyncedEngineMessage>, alt!(
|
|
149 |
do_parse!(tag!("+l") >> (SyncedEngineMessage::Left(KeystrokeAction::Press)))
|
|
150 |
));
|
|
151 |
|
|
152 |
named!(unsynced_message<&[u8], UnsyncedEngineMessage>, alt!(
|
|
153 |
do_parse!(tag!("?") >> (UnsyncedEngineMessage::Ping))
|
|
154 |
| do_parse!(tag!("!") >> (UnsyncedEngineMessage::Ping))
|
|
155 |
| do_parse!(tag!("esay ") >> s: string_tail >> (UnsyncedEngineMessage::Say(s)))
|
|
156 |
));
|
|
157 |
|
|
158 |
named!(config_message<&[u8], ConfigEngineMessage>, alt!(
|
|
159 |
do_parse!(tag!("C") >> (ConfigEngineMessage::ConfigRequest))
|
|
160 |
));
|
|
161 |
|
|
162 |
named!(empty_message<&[u8], EngineMessage>,
|
|
163 |
do_parse!(tag!("\0") >> (EngineMessage::Empty))
|
|
164 |
);
|
|
165 |
|
|
166 |
named!(non_empty_message<&[u8], EngineMessage>, length_value!(length_specifier,
|
|
167 |
alt!(
|
|
168 |
map!(synced_message, |m| EngineMessage::Synced(m, 0))
|
|
169 |
| map!(unsynced_message, |m| EngineMessage::Unsynced(m))
|
|
170 |
| map!(config_message, |m| EngineMessage::Config(m))
|
|
171 |
| unrecognized_message
|
|
172 |
)
|
|
173 |
));
|
|
174 |
|
|
175 |
named!(message<&[u8], EngineMessage>, alt!(
|
|
176 |
empty_message
|
|
177 |
| non_empty_message
|
|
178 |
)
|
|
179 |
);
|
|
180 |
|
|
181 |
named!(pub extract_messages<&[u8], Vec<EngineMessage> >, many0!(complete!(message)));
|
|
182 |
|
|
183 |
#[test]
|
|
184 |
fn parse_length() {
|
|
185 |
assert_eq!(length_specifier(b"\x01"), Ok((&b""[..], 1)));
|
|
186 |
assert_eq!(length_specifier(b"\x00"), Ok((&b""[..], 0)));
|
|
187 |
assert_eq!(length_specifier(b"\x3f"), Ok((&b""[..], 63)));
|
|
188 |
assert_eq!(length_specifier(b"\x40\x00"), Ok((&b""[..], 64)));
|
|
189 |
assert_eq!(length_specifier(b"\xff\xff"), Ok((&b""[..], 49215)));
|
14210
|
190 |
}
|
14211
|
191 |
|
|
192 |
#[test]
|
|
193 |
fn parse_synced_messages() {
|
|
194 |
assert_eq!(message(b"\x02+l"), Ok((&b""[..], EngineMessage::Synced(SyncedEngineMessage::Left(KeystrokeAction::Press), 0))));
|
|
195 |
}
|
|
196 |
|
|
197 |
#[test]
|
|
198 |
fn parse_unsynced_messages() {
|
|
199 |
assert_eq!(message(b"\x0aesay hello"), Ok((&b""[..], EngineMessage::Unsynced(UnsyncedEngineMessage::Say(String::from("hello"))))));
|
|
200 |
}
|
|
201 |
|
|
202 |
#[test]
|
|
203 |
fn parse_incorrect_messages() {
|
|
204 |
assert_eq!(message(b"\x00"), Ok((&b""[..], EngineMessage::Empty)));
|
|
205 |
assert_eq!(message(b"\x01\x00"), Ok((&b""[..], EngineMessage::Unknown)));
|
|
206 |
}
|
|
207 |
|
|
208 |
#[test]
|
|
209 |
fn parse_config_messages() {
|
|
210 |
assert_eq!(
|
|
211 |
message(b"\x01C"),
|
|
212 |
Ok((
|
|
213 |
&b""[..],
|
|
214 |
EngineMessage::Config(ConfigEngineMessage::ConfigRequest)
|
|
215 |
))
|
|
216 |
);
|
|
217 |
}
|
|
218 |
#[test]
|
|
219 |
fn parse_test_general() {
|
|
220 |
assert_eq!(string_tail(b"abc"), Ok((&b""[..], String::from("abc"))));
|
|
221 |
}
|