# HG changeset patch # User Marcin Mielniczuk # Date 1530286071 -10800 # Node ID 6a818f9192f4ce2972333cf0aacbd5ac080e8e90 # Parent eb91b889101ba351953951d3e94469023993b86a Implement parsing for rnd and add a little documentation diff -r eb91b889101b -r 6a818f9192f4 gameServer2/src/protocol/parser.rs --- a/gameServer2/src/protocol/parser.rs Thu Jun 28 17:29:37 2018 +0200 +++ b/gameServer2/src/protocol/parser.rs Fri Jun 29 18:27:51 2018 +0300 @@ -1,3 +1,12 @@ +/** The parsers for the chat and multiplayer protocol. The main parser is `message`. + * # Protocol + * All messages consist of `\n`-separated strings. The end of a message is + * indicated by a double newline - `\n\n`. + * + * For example, a nullary command like PING will be actually sent as `PING\n\n`. + * A unary command, such as `START_GAME nick` will be actually sent as `START_GAME\nnick\n\n`. + */ + use nom::*; use std::{ @@ -28,6 +37,7 @@ h7: hog_line >> eol >> h8: hog_line >> ([h1, h2, h3, h4, h5, h6, h7, h8]))); +/** Recognizes messages which do not take any parameters */ named!(basic_message<&[u8], HWProtocolMessage>, alt!( do_parse!(tag!("PING") >> (Ping)) | do_parse!(tag!("PONG") >> (Pong)) @@ -42,6 +52,7 @@ | do_parse!(tag!("TOGGLE_REGISTERED_ONLY") >> (ToggleRegisteredOnly)) )); +/** Recognizes messages which take exactly one parameter */ named!(one_param_message<&[u8], HWProtocolMessage>, alt!( do_parse!(tag!("NICK") >> eol >> n: a_line >> (Nick(n))) | do_parse!(tag!("INFO") >> eol >> n: a_line >> (Info(n))) @@ -60,6 +71,7 @@ | do_parse!(tag!("QUIT") >> msg: opt_param >> (Quit(msg))) )); +/** Recognizes messages preceded with CMD */ named!(cmd_message<&[u8], HWProtocolMessage>, preceded!(tag!("CMD\n"), alt!( do_parse!(tag_no_case!("STATS") >> (Stats)) | do_parse!(tag_no_case!("FIX") >> (Fix)) @@ -80,6 +92,10 @@ | do_parse!(tag_no_case!("FORCE") >> eol >> m: a_line >> (ForceVote(m))) | do_parse!(tag_no_case!("INFO") >> eol >> n: a_line >> (Info(n))) | do_parse!(tag_no_case!("MAXTEAMS") >> eol >> n: u8_line >> (MaxTeams(n))) + | do_parse!( + tag_no_case!("RND") >> + v: str_line >> + (Rnd(v.split_whitespace().map(String::from).collect()))) ))); named!(complex_message<&[u8], HWProtocolMessage>, alt!( @@ -222,10 +238,16 @@ assert_eq!(message(b"CMD\nPART\n\n"), IResult::Done(&b""[..], Part(None))); assert_eq!(message(b"CMD\nPART\n_msg_\n\n"), IResult::Done(&b""[..], Part(Some("_msg_".to_string())))); + assert_eq!(message(b"CMD\nRND\n\n"), IResult::Done(&b""[..], Rnd(vec![]))); + assert_eq!( + message(b"CMD\nRND A B\n\n"), + IResult::Done(&b""[..], Rnd(vec![String::from("A"), String::from("B")])) + ); + assert_eq!(extract_messages(b"QUIT\n1\n2\n\n"), IResult::Done(&b""[..], vec![Malformed])); assert_eq!(extract_messages(b"PING\n\nPING\n\nP"), IResult::Done(&b"P"[..], vec![Ping, Ping])); assert_eq!(extract_messages(b"SING\n\nPING\n\n"), IResult::Done(&b""[..], vec![Malformed, Ping])); assert_eq!(extract_messages(b"\n\n\n\nPING\n\n"), IResult::Done(&b""[..], vec![Empty, Empty, Ping])); assert_eq!(extract_messages(b"\n\n\nPING\n\n"), IResult::Done(&b""[..], vec![Empty, Empty, Ping])); -} \ No newline at end of file +}