rust/hedgewars-engine-messages/src/messages.rs
changeset 14254 9f4d75fa4a2c
parent 14214 77b95406631e
child 14255 a239e4243cf9
equal deleted inserted replaced
14253:084af6d2685f 14254:9f4d75fa4a2c
       
     1 use byteorder::{BigEndian, WriteBytesExt};
       
     2 
     1 #[derive(Debug, PartialEq)]
     3 #[derive(Debug, PartialEq)]
     2 pub enum KeystrokeAction {
     4 pub enum KeystrokeAction {
     3     Press,
     5     Press,
     4     Release,
     6     Release,
     5 }
     7 }
    48     GameOver,
    50     GameOver,
    49     GameInterrupted,
    51     GameInterrupted,
    50     GameSetupChecksum(String),
    52     GameSetupChecksum(String),
    51     PauseToggled,
    53     PauseToggled,
    52 }
    54 }
       
    55 
    53 #[derive(Debug, PartialEq)]
    56 #[derive(Debug, PartialEq)]
    54 pub enum ConfigEngineMessage {
    57 pub enum ConfigEngineMessage {
    55     GameType(u8),
    58     GameType(u8),
    56     ConfigRequest,
    59     ConfigRequest,
    57     SetAmmo(String),
    60     SetAmmo(String),
   133     Config(ConfigEngineMessage),
   136     Config(ConfigEngineMessage),
   134 }
   137 }
   135 
   138 
   136 macro_rules! em {
   139 macro_rules! em {
   137     [$msg: expr] => {
   140     [$msg: expr] => {
   138         vec![($msg) as u8]
   141         vec![($msg)]
   139     };
   142     };
   140 }
   143 }
   141 
   144 
   142 macro_rules! ems {
   145 macro_rules! ems {
   143     [$msg: expr, $param: expr] => {
   146     [$msg: expr, $param: expr] => {
   144         {
   147         {
   145             let mut v = vec![($msg) as u8];
   148             let mut v = vec![($msg)];
   146             v.extend(String::into_bytes($param.to_string()).iter());
   149             v.extend(String::into_bytes($param.to_string()).iter());
   147             v
   150             v
   148         }
   151         }
   149     };
   152     };
   150 }
   153 }
   152 impl SyncedEngineMessage {
   155 impl SyncedEngineMessage {
   153     fn to_bytes(&self) -> Vec<u8> {
   156     fn to_bytes(&self) -> Vec<u8> {
   154         use self::KeystrokeAction::*;
   157         use self::KeystrokeAction::*;
   155         use self::SyncedEngineMessage::*;
   158         use self::SyncedEngineMessage::*;
   156         match self {
   159         match self {
   157             Left(Press) => em!['L'],
   160             Left(Press) => em![b'L'],
   158             Left(Release) => em!['l'],
   161             Left(Release) => em![b'l'],
   159             Right(Press) => em!['R'],
   162             Right(Press) => em![b'R'],
   160             Right(Release) => em!['r'],
   163             Right(Release) => em![b'r'],
   161             Up(Press) => em!['U'],
   164             Up(Press) => em![b'U'],
   162             Up(Release) => em!['u'],
   165             Up(Release) => em![b'u'],
   163             Down(Press) => em!['D'],
   166             Down(Press) => em![b'D'],
   164             Down(Release) => em!['d'],
   167             Down(Release) => em![b'd'],
   165             Precise(Press) => em!['Z'],
   168             Precise(Press) => em![b'Z'],
   166             Precise(Release) => em!['z'],
   169             Precise(Release) => em![b'z'],
   167             Attack(Press) => em!['A'],
   170             Attack(Press) => em![b'A'],
   168             Attack(Release) => em!['a'],
   171             Attack(Release) => em![b'a'],
   169             NextTurn => em!['N'],
   172             NextTurn => em![b'N'],
   170             Switch => em!['S'],
   173             Switch => em![b'S'],
   171             Timer(t) => vec!['0' as u8 + t],
   174             Timer(t) => vec![b'0' + t],
   172             Slot(s) => vec!['~' as u8, *s],
   175             Slot(s) => vec![b'~' , *s],
   173             SetWeapon(s) => vec!['~' as u8, *s],
   176             SetWeapon(s) => vec![b'~', *s],
   174             Put(x, y) => unimplemented!(),
   177             Put(x, y) => {
   175             CursorMove(x, y) => unimplemented!(),
   178                 let mut v = vec![b'p'];
   176             HighJump => em!['J'],
   179                 v.write_i24::<BigEndian>(*x).unwrap();
   177             LongJump => em!['j'],
   180                 v.write_i24::<BigEndian>(*y).unwrap();
   178             Skip => em![','],
   181 
   179             TeamControlGained(str) => ems!['g', str],
   182                 v
   180             TeamControlLost(str) => ems!['f', str],
   183             },
   181             Taunt(s) => vec!['t' as u8, *s],
   184             CursorMove(x, y) => {
   182             HogSay(str) => ems!['h', str],
   185                 let mut v = vec![b'P'];
   183             Heartbeat => em!['+'],
   186                 v.write_i24::<BigEndian>(*x).unwrap();
       
   187                 v.write_i24::<BigEndian>(*y).unwrap();
       
   188 
       
   189                 v
       
   190             },
       
   191             HighJump => em![b'J'],
       
   192             LongJump => em![b'j'],
       
   193             Skip => em![b','],
       
   194             TeamControlGained(str) => ems![b'g', str],
       
   195             TeamControlLost(str) => ems![b'f', str],
       
   196             Taunt(s) => vec![b't', *s],
       
   197             HogSay(str) => ems![b'h', str],
       
   198             Heartbeat => em![b'+'],
   184             TimeWrap => unreachable!(),
   199             TimeWrap => unreachable!(),
   185         }
   200         }
   186     }
   201     }
   187 }
   202 }
   188 
   203 
   189 impl UnsyncedEngineMessage {
   204 impl UnsyncedEngineMessage {
   190     fn to_bytes(&self) -> Vec<u8> {
   205     fn to_bytes(&self) -> Vec<u8> {
   191         use self::UnsyncedEngineMessage::*;
   206         use self::UnsyncedEngineMessage::*;
   192         match self {
   207         match self {
   193             TeamControlGained(str) => ems!['G', str],
   208             TeamControlGained(str) => ems![b'G', str],
   194             TeamControlLost(str) => ems!['F', str],
   209             TeamControlLost(str) => ems![b'F', str],
   195         }
   210         }
   196     }
   211     }
   197 }
   212 }
   198 
   213 
   199 impl UnorderedEngineMessage {
   214 impl UnorderedEngineMessage {
   200     fn to_bytes(&self) -> Vec<u8> {
   215     fn to_bytes(&self) -> Vec<u8> {
   201         unimplemented!()
   216         use self::UnorderedEngineMessage::*;
       
   217         match self {
       
   218             Ping => em![b'?'],
       
   219             Pong => em![b'!'],
       
   220             ChatMessage(str) => ems![b's', str],
       
   221             TeamMessage(str) => ems![b'b', str],
       
   222             Error(str) => ems![b'E', str],
       
   223             Warning(str) => unreachable!(),
       
   224             StopSyncing => unreachable!(),
       
   225             GameOver => em![b'q'],
       
   226             GameInterrupted => em![b'Q'],
       
   227             GameSetupChecksum(str) => ems![b'M', str],
       
   228             PauseToggled => unreachable!(),
       
   229         }
   202     }
   230     }
   203 }
   231 }
   204 
   232 
   205 impl ConfigEngineMessage {
   233 impl ConfigEngineMessage {
   206     fn to_bytes(&self) -> Vec<u8> {
   234     fn to_bytes(&self) -> Vec<u8> {
   207         unimplemented!()
   235         unreachable!()
   208     }
   236     }
   209 }
   237 }
   210 
   238 
   211 impl EngineMessage {
   239 impl EngineMessage {
   212     pub const MAX_LEN: u16 = 49215;
   240     pub const MAX_LEN: u16 = 49215;
   214     fn to_unwrapped(&self) -> Vec<u8> {
   242     fn to_unwrapped(&self) -> Vec<u8> {
   215         use self::EngineMessage::*;
   243         use self::EngineMessage::*;
   216         match self {
   244         match self {
   217             Unknown => unreachable!("you're not supposed to construct such messages"),
   245             Unknown => unreachable!("you're not supposed to construct such messages"),
   218             Empty => unreachable!("you're not supposed to construct such messages"),
   246             Empty => unreachable!("you're not supposed to construct such messages"),
   219             Synced(SyncedEngineMessage::TimeWrap, _) => vec!['#' as u8, 0xff, 0xff],
   247             Synced(SyncedEngineMessage::TimeWrap, _) => vec![b'#', 0xff, 0xff],
   220             Synced(msg, timestamp) => {
   248             Synced(msg, timestamp) => {
   221                 let mut v = msg.to_bytes();
   249                 let mut v = msg.to_bytes();
   222                 v.push((*timestamp / 256) as u8);
   250                 v.push((*timestamp / 256) as u8);
   223                 v.push(*timestamp as u8);
   251                 v.push(*timestamp as u8);
   224 
   252 
   253 
   281 
   254 #[test]
   282 #[test]
   255 fn message_contruction() {
   283 fn message_contruction() {
   256     assert_eq!(
   284     assert_eq!(
   257         EngineMessage::Synced(SyncedEngineMessage::TimeWrap, 0).to_bytes(),
   285         EngineMessage::Synced(SyncedEngineMessage::TimeWrap, 0).to_bytes(),
   258         vec![3, '#' as u8, 255, 255]
   286         vec![3, b'#', 255, 255]
   259     );
   287     );
   260     assert_eq!(
   288     assert_eq!(
   261         EngineMessage::Synced(SyncedEngineMessage::NextTurn, 258).to_bytes(),
   289         EngineMessage::Synced(SyncedEngineMessage::NextTurn, 258).to_bytes(),
   262         vec![3, 'N' as u8, 1, 2]
   290         vec![3, b'N', 1, 2]
   263     );
   291     );
   264 }
   292 
       
   293     assert_eq!(
       
   294         EngineMessage::Synced(SyncedEngineMessage::Put(-31337, 65538), 0).to_bytes(),
       
   295         vec![9, b'p', 255, 133, 151, 1, 0, 2, 0, 0]
       
   296     );
       
   297 }