39 |
39 |
40 const VALID_MESSAGES: &[u8] = |
40 const VALID_MESSAGES: &[u8] = |
41 b"M#+LlRrUuDdZzAaSjJ,NpPwtgfhbc12345\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A"; |
41 b"M#+LlRrUuDdZzAaSjJ,NpPwtgfhbc12345\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A"; |
42 const NON_TIMED_MESSAGES: &[u8] = b"M#hb"; |
42 const NON_TIMED_MESSAGES: &[u8] = b"M#hb"; |
43 |
43 |
|
44 #[cfg(canhazslicepatterns)] |
44 fn is_msg_valid(msg: &[u8], team_indices: &[u8]) -> bool { |
45 fn is_msg_valid(msg: &[u8], team_indices: &[u8]) -> bool { |
45 match msg { |
46 match msg { |
46 [size, typ, body..] => VALID_MESSAGES.contains(typ) |
47 [size, typ, body..] => VALID_MESSAGES.contains(typ) |
47 && match body { |
48 && match body { |
48 [1...8, team, ..] if *typ == b'h' => team_indices.contains(team), |
49 [1...8, team, ..] if *typ == b'h' => team_indices.contains(team), |
50 }, |
51 }, |
51 _ => false |
52 _ => false |
52 } |
53 } |
53 } |
54 } |
54 |
55 |
|
56 fn is_msg_valid(msg: &[u8], team_indices: &[u8]) -> bool { |
|
57 if let Some(typ) = msg.get(1) { |
|
58 VALID_MESSAGES.contains(typ) |
|
59 } else { |
|
60 false |
|
61 } |
|
62 } |
|
63 |
55 fn is_msg_empty(msg: &[u8]) -> bool { |
64 fn is_msg_empty(msg: &[u8]) -> bool { |
56 match msg { |
65 msg.get(1).filter(|t| **t == b'+').is_some() |
57 [_, b'+', ..] => true, |
|
58 _ => false |
|
59 } |
|
60 } |
66 } |
61 |
67 |
62 pub fn handle(server: &mut HWServer, client_id: ClientId, message: HWProtocolMessage) { |
68 pub fn handle(server: &mut HWServer, client_id: ClientId, message: HWProtocolMessage) { |
63 use protocol::messages::HWProtocolMessage::*; |
69 use protocol::messages::HWProtocolMessage::*; |
64 match message { |
70 match message { |
238 if c.teams_in_game > 0 { |
244 if c.teams_in_game > 0 { |
239 let decoding = decode(&em[..]).unwrap(); |
245 let decoding = decode(&em[..]).unwrap(); |
240 let messages = by_msg(&decoding); |
246 let messages = by_msg(&decoding); |
241 let valid = messages.clone().filter(|m| is_msg_valid(m, &c.team_indices)); |
247 let valid = messages.clone().filter(|m| is_msg_valid(m, &c.team_indices)); |
242 let non_empty = messages.filter(|m| !is_msg_empty(m)); |
248 let non_empty = messages.filter(|m| !is_msg_empty(m)); |
243 let last_msg = valid.clone().scan(None, |res, msg| match msg { |
249 let last_msg = None; |
244 [_, b'+', ..] => Some(msg), |
|
245 [_, typ, ..] if NON_TIMED_MESSAGES.contains(typ) => *res, |
|
246 _ => None |
|
247 }).next().map(|s| encode(s)); |
|
248 |
250 |
249 let em_response = encode(&valid.flat_map(|msg| msg).cloned().collect::<Vec<_>>()); |
251 let em_response = encode(&valid.flat_map(|msg| msg).cloned().collect::<Vec<_>>()); |
250 if !em_response.is_empty() { |
252 if !em_response.is_empty() { |
251 actions.push(ForwardEngineMessage(vec![em_response]) |
253 actions.push(ForwardEngineMessage(vec![em_response]) |
252 .send_all().in_room(r.id).but_self().action()); |
254 .send_all().in_room(r.id).but_self().action()); |
253 } |
255 } |
254 let em_log = encode(&non_empty.flat_map(|msg| msg).cloned().collect::<Vec<_>>()); |
256 let em_log = encode(&non_empty.flat_map(|msg| msg).cloned().collect::<Vec<_>>()); |
255 if let Some(ref mut info) = r.game_info { |
257 if let Some(ref mut info) = r.game_info { |
256 if (!em_log.is_empty()) { |
258 if !em_log.is_empty() { |
257 info.msg_log.push(em_log); |
259 info.msg_log.push(em_log); |
258 } |
260 } |
259 if last_msg.is_some() { |
261 if last_msg.is_some() { |
260 info.last_msg = last_msg; |
262 info.last_msg = last_msg; |
261 } |
263 } |