rust/hedgewars-engine-messages/src/parser.rs
changeset 14211 0f7b92397b9e
parent 14210 1c55c54013c4
child 14214 77b95406631e
--- a/rust/hedgewars-engine-messages/src/parser.rs	Wed Nov 14 16:32:42 2018 +0100
+++ b/rust/hedgewars-engine-messages/src/parser.rs	Wed Nov 14 16:58:22 2018 +0100
@@ -1,9 +1,20 @@
-use nom::{*};
+use nom::{*, Err::Error};
 use std::str;
 
 use super::messages::{*, EngineMessage::*, UnsyncedEngineMessage::*, SyncedEngineMessage::*, ConfigEngineMessage::*, KeystrokeAction::*};
 
 
+macro_rules! eof_slice (
+  ($i:expr,) => (
+    {
+      if ($i).input_len() == 0 {
+        Ok(($i, $i))
+      } else {
+        Err(Error(error_position!($i, ErrorKind::Eof::<u32>)))
+      }
+    }
+  );
+);
 
 named!(unrecognized_message<&[u8], EngineMessage>,
     do_parse!(rest >> (Unknown))
@@ -17,25 +28,54 @@
 
 named!(synced_message<&[u8], SyncedEngineMessage>, alt!(
       do_parse!(tag!("L") >> (Left(Press)))
+      | do_parse!(tag!("l") >> ( Left(Release) ))
+      | do_parse!(tag!("R") >> ( Right(Press) ))
+      | do_parse!(tag!("r") >> ( Right(Release) ))
+      | do_parse!(tag!("U") >> ( Up(Press) ))
+      | do_parse!(tag!("u") >> ( Up(Release) ))
+      | do_parse!(tag!("D") >> ( Down(Press) ))
+      | do_parse!(tag!("d") >> ( Down(Release) ))
+      | do_parse!(tag!("Z") >> ( Precise(Press) ))
+      | do_parse!(tag!("z") >> ( Precise(Release) ))
+      | do_parse!(tag!("A") >> ( Attack(Press) ))
+      | do_parse!(tag!("a") >> ( Attack(Release) ))
+      | do_parse!(tag!("N") >> ( NextTurn ))
+      | do_parse!(tag!("j") >> ( LongJump ))
+      | do_parse!(tag!("J") >> ( HighJump ))
+      | do_parse!(tag!("S") >> ( Switch ))
+      | do_parse!(tag!(",") >> ( Skip ))
+      | do_parse!(tag!("1") >> ( Timer(1) ))
+      | do_parse!(tag!("2") >> ( Timer(2) ))
+      | do_parse!(tag!("3") >> ( Timer(3) ))
+      | do_parse!(tag!("4") >> ( Timer(4) ))
+      | do_parse!(tag!("5") >> ( Timer(5) ))
+      | do_parse!(tag!("p") >> x: be_i24 >> y: be_i24 >> ( Put(x, y) ))
+      | do_parse!(tag!("P") >> x: be_i24 >> y: be_i24 >> ( CursorMove(x, y) ))
+      | do_parse!(tag!("f") >> s: string_tail >> ( SyncedEngineMessage::TeamControlLost(s) ))
+      | do_parse!(tag!("g") >> s: string_tail >> ( SyncedEngineMessage::TeamControlGained(s) ))
+      /*
+    Slot(u8),
+    SetWeapon(u8),
+          */
 ));
 
-named!(timestamped_message<&[u8], (SyncedEngineMessage, u16)>,
-    do_parse!(msg: length_value!(length_without_timestamp, synced_message)
-        >> timestamp: be_u16
-        >> ((msg, timestamp))
-    )
-);
-
 named!(unsynced_message<&[u8], UnsyncedEngineMessage>, alt!(
       do_parse!(tag!("?") >> (Ping))
     | do_parse!(tag!("!") >> (Ping))
-    | do_parse!(tag!("esay ") >> s: string_tail  >> (Say(s)))
+    | do_parse!(tag!("esay ") >> s: string_tail >> (Say(s)))
 ));
 
 named!(config_message<&[u8], ConfigEngineMessage>, alt!(
     do_parse!(tag!("C") >> (ConfigRequest))
 ));
 
+named!(timestamped_message<&[u8], (SyncedEngineMessage, u16)>,
+    do_parse!(msg: length_value!(length_without_timestamp, terminated!(synced_message, eof_slice!()))
+        >> timestamp: be_u16
+        >> ((msg, timestamp))
+    )
+);
+
 named!(unwrapped_message<&[u8], EngineMessage>,
     alt!(
         map!(timestamped_message, |(m, t)| Synced(m, t as u32))
@@ -58,7 +98,7 @@
 );
 
 named!(non_empty_message<&[u8], EngineMessage>,
-    length_value!(length_specifier, unwrapped_message));
+    length_value!(length_specifier, terminated!(unwrapped_message, eof_slice!())));
 
 named!(message<&[u8], EngineMessage>, alt!(
       empty_message
@@ -80,6 +120,7 @@
 #[test]
 fn parse_synced_messages() {
     assert_eq!(message(b"\x03L\x01\x02"), Ok((&b""[..], Synced(Left(Press), 258))));
+    assert_eq!(message(b"\x01#"), Ok((&b""[..], Synced(TimeWrap, 65535))));
 }
 
 #[test]
@@ -91,6 +132,9 @@
 fn parse_incorrect_messages() {
     assert_eq!(message(b"\x00"), Ok((&b""[..], Empty)));
     assert_eq!(message(b"\x01\x00"), Ok((&b""[..], Unknown)));
+
+    // garbage after correct message
+    assert_eq!(message(b"\x04La\x01\x02"), Ok((&b""[..], Unknown)));
 }
 
 #[test]