rust/hedgewars-engine-messages/src/messages.rs
changeset 14214 77b95406631e
parent 14211 0f7b92397b9e
child 14254 9f4d75fa4a2c
equal deleted inserted replaced
14213:09dacb61d526 14214:77b95406631e
    23     LongJump,
    23     LongJump,
    24     Skip,
    24     Skip,
    25     TeamControlGained(String),
    25     TeamControlGained(String),
    26     TeamControlLost(String),
    26     TeamControlLost(String),
    27     TimeWrap,
    27     TimeWrap,
       
    28     Taunt(u8),
       
    29     HogSay(String),
       
    30     Heartbeat,
    28 }
    31 }
    29 
    32 
    30 #[derive(Debug, PartialEq)]
    33 #[derive(Debug, PartialEq)]
    31 pub enum UnsyncedEngineMessage {
    34 pub enum UnsyncedEngineMessage {
       
    35     TeamControlGained(String),
       
    36     TeamControlLost(String),
       
    37 }
       
    38 
       
    39 #[derive(Debug, PartialEq)]
       
    40 pub enum UnorderedEngineMessage {
    32     Ping,
    41     Ping,
    33     Pong,
    42     Pong,
    34     Say(String),
    43     ChatMessage(String),
    35     Taunt(u8),
    44     TeamMessage(String),
    36     GameType(u8),
    45     Error(String),
    37     Warning(String),
    46     Warning(String),
    38     StopSyncing,
    47     StopSyncing,
    39     GameOver,
    48     GameOver,
    40     GameInterrupted,
    49     GameInterrupted,
    41     GameSetupChecksum(String),
    50     GameSetupChecksum(String),
    42     TeamControlGained(String),
    51     PauseToggled,
    43     TeamControlLost(String),
    52 }
    44 }
       
    45 
       
    46 #[derive(Debug, PartialEq)]
    53 #[derive(Debug, PartialEq)]
    47 pub enum ConfigEngineMessage {
    54 pub enum ConfigEngineMessage {
       
    55     GameType(u8),
    48     ConfigRequest,
    56     ConfigRequest,
    49     SetAmmo(String),
    57     SetAmmo(String),
    50     SetScript(String),
    58     SetScript(String),
    51     SetScriptParam(String),
    59     SetScriptParam(String),
    52     Spectate,
    60     Spectate,
   115     SetShoppaBorder(bool),
   123     SetShoppaBorder(bool),
   116 }
   124 }
   117 
   125 
   118 #[derive(Debug, PartialEq)]
   126 #[derive(Debug, PartialEq)]
   119 pub enum EngineMessage {
   127 pub enum EngineMessage {
       
   128     Unknown,
       
   129     Empty,
   120     Synced(SyncedEngineMessage, u32),
   130     Synced(SyncedEngineMessage, u32),
   121     Unsynced(UnsyncedEngineMessage),
   131     Unsynced(UnsyncedEngineMessage),
       
   132     Unordered(UnorderedEngineMessage),
   122     Config(ConfigEngineMessage),
   133     Config(ConfigEngineMessage),
   123     Unknown,
   134 }
   124     Empty,
   135 
       
   136 macro_rules! em {
       
   137     [$msg: expr] => {
       
   138         vec![($msg) as u8]
       
   139     };
       
   140 }
       
   141 
       
   142 macro_rules! ems {
       
   143     [$msg: expr, $param: expr] => {
       
   144         {
       
   145             let mut v = vec![($msg) as u8];
       
   146             v.extend(String::into_bytes($param.to_string()).iter());
       
   147             v
       
   148         }
       
   149     };
       
   150 }
       
   151 
       
   152 impl SyncedEngineMessage {
       
   153     fn to_bytes(&self) -> Vec<u8> {
       
   154         use self::KeystrokeAction::*;
       
   155         use self::SyncedEngineMessage::*;
       
   156         match self {
       
   157             Left(Press) => em!['L'],
       
   158             Left(Release) => em!['l'],
       
   159             Right(Press) => em!['R'],
       
   160             Right(Release) => em!['r'],
       
   161             Up(Press) => em!['U'],
       
   162             Up(Release) => em!['u'],
       
   163             Down(Press) => em!['D'],
       
   164             Down(Release) => em!['d'],
       
   165             Precise(Press) => em!['Z'],
       
   166             Precise(Release) => em!['z'],
       
   167             Attack(Press) => em!['A'],
       
   168             Attack(Release) => em!['a'],
       
   169             NextTurn => em!['N'],
       
   170             Switch => em!['S'],
       
   171             Timer(t) => vec!['0' as u8 + t],
       
   172             Slot(s) => vec!['~' as u8, *s],
       
   173             SetWeapon(s) => vec!['~' as u8, *s],
       
   174             Put(x, y) => unimplemented!(),
       
   175             CursorMove(x, y) => unimplemented!(),
       
   176             HighJump => em!['J'],
       
   177             LongJump => em!['j'],
       
   178             Skip => em![','],
       
   179             TeamControlGained(str) => ems!['g', str],
       
   180             TeamControlLost(str) => ems!['f', str],
       
   181             Taunt(s) => vec!['t' as u8, *s],
       
   182             HogSay(str) => ems!['h', str],
       
   183             Heartbeat => em!['+'],
       
   184             TimeWrap => unreachable!(),
       
   185         }
       
   186     }
       
   187 }
       
   188 
       
   189 impl UnsyncedEngineMessage {
       
   190     fn to_bytes(&self) -> Vec<u8> {
       
   191         use self::UnsyncedEngineMessage::*;
       
   192         match self {
       
   193             TeamControlGained(str) => ems!['G', str],
       
   194             TeamControlLost(str) => ems!['F', str],
       
   195         }
       
   196     }
       
   197 }
       
   198 
       
   199 impl UnorderedEngineMessage {
       
   200     fn to_bytes(&self) -> Vec<u8> {
       
   201         unimplemented!()
       
   202     }
       
   203 }
       
   204 
       
   205 impl ConfigEngineMessage {
       
   206     fn to_bytes(&self) -> Vec<u8> {
       
   207         unimplemented!()
       
   208     }
   125 }
   209 }
   126 
   210 
   127 impl EngineMessage {
   211 impl EngineMessage {
   128     fn from_bytes(buf: &[u8]) -> Self {
   212     pub const MAX_LEN: u16 = 49215;
   129         unimplemented!()
   213 
   130     }
   214     fn to_unwrapped(&self) -> Vec<u8> {
   131 
   215         use self::EngineMessage::*;
   132     fn to_bytes(&self) -> Vec<u8> {
   216         match self {
   133         unimplemented!()
   217             Unknown => unreachable!("you're not supposed to construct such messages"),
   134     }
   218             Empty => unreachable!("you're not supposed to construct such messages"),
   135 }
   219             Synced(SyncedEngineMessage::TimeWrap, _) => vec!['#' as u8, 0xff, 0xff],
       
   220             Synced(msg, timestamp) => {
       
   221                 let mut v = msg.to_bytes();
       
   222                 v.push((*timestamp / 256) as u8);
       
   223                 v.push(*timestamp as u8);
       
   224 
       
   225                 v
       
   226             }
       
   227             Unsynced(msg) => msg.to_bytes(),
       
   228             Unordered(msg) => msg.to_bytes(),
       
   229             Config(msg) => msg.to_bytes(),
       
   230         }
       
   231     }
       
   232 
       
   233     pub fn to_bytes(&self) -> Vec<u8> {
       
   234         let mut unwrapped = self.to_unwrapped();
       
   235         let mut size = unwrapped.len();
       
   236 
       
   237         if size > EngineMessage::MAX_LEN as usize - 2 {
       
   238             size = EngineMessage::MAX_LEN as usize - 2;
       
   239             unwrapped.truncate(size);
       
   240         }
       
   241 
       
   242         if size < 64 {
       
   243             unwrapped.insert(0, size as u8);
       
   244         } else {
       
   245             size -= 64;
       
   246             unwrapped.insert(0, (size / 256 + 64) as u8);
       
   247             unwrapped.insert(1, size as u8);
       
   248         }
       
   249 
       
   250         unwrapped
       
   251     }
       
   252 }
       
   253 
       
   254 #[test]
       
   255 fn message_contruction() {
       
   256     assert_eq!(
       
   257         EngineMessage::Synced(SyncedEngineMessage::TimeWrap, 0).to_bytes(),
       
   258         vec![3, '#' as u8, 255, 255]
       
   259     );
       
   260     assert_eq!(
       
   261         EngineMessage::Synced(SyncedEngineMessage::NextTurn, 258).to_bytes(),
       
   262         vec![3, 'N' as u8, 1, 2]
       
   263     );
       
   264 }