gameServer2/src/protocol/parser.rs
author unc0rr
Wed, 18 Jan 2017 22:23:41 +0300
changeset 12140 7e259e47eb0d
parent 12137 193dfdcb0620
child 12142 4d7d41be1993
permissions -rw-r--r--
Fix malformed messages parsing
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
12133
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
     1
use nom::*;
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
     2
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
     3
use std::str;
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
     4
use std::str::FromStr;
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
     5
use super::messages::HWProtocolMessage;
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
     6
use super::messages::HWProtocolMessage::*;
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
     7
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
     8
named!(end_of_message, tag!("\n\n"));
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
     9
named!(a_line<&[u8], &str>, map_res!(not_line_ending, str::from_utf8));
12135
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    10
named!( u8_line<&[u8],  u8>, map_res!(a_line, FromStr::from_str));
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    11
named!(u32_line<&[u8], u32>, map_res!(a_line, FromStr::from_str));
12134
109e6765b1fc Optional parameters parsing function
unc0rr
parents: 12133
diff changeset
    12
named!(opt_param<&[u8], Option<&str> >, opt!(flat_map!(preceded!(eol, a_line), non_empty)));
109e6765b1fc Optional parameters parsing function
unc0rr
parents: 12133
diff changeset
    13
12133
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
    14
named!(basic_message<&[u8], HWProtocolMessage>, alt!(
12135
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    15
      do_parse!(tag!("PING") >> (Ping))
12133
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
    16
    | do_parse!(tag!("PONG") >> (Pong))
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
    17
    | do_parse!(tag!("LIST") >> (List))
12135
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    18
    | do_parse!(tag!("BANLIST")        >> (BanList))
12133
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
    19
    | do_parse!(tag!("GET_SERVER_VAR") >> (GetServerVar))
12135
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    20
    | do_parse!(tag!("TOGGLE_READY")   >> (ToggleReady))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    21
    | do_parse!(tag!("START_GAME")     >> (StartGame))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    22
    | do_parse!(tag!("ROUNDFINISHED")  >> (RoundFinished))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    23
    | do_parse!(tag!("TOGGLE_RESTRICT_JOINS")  >> (ToggleRestrictJoin))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    24
    | do_parse!(tag!("TOGGLE_RESTRICT_TEAMS")  >> (ToggleRestrictTeams))
12133
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
    25
    | do_parse!(tag!("TOGGLE_REGISTERED_ONLY") >> (ToggleRegisteredOnly))
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
    26
));
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
    27
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
    28
named!(one_param_message<&[u8], HWProtocolMessage>, alt!(
12135
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    29
      do_parse!(tag!("NICK")    >> eol >> n: a_line >> (Nick(n)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    30
    | do_parse!(tag!("INFO")    >> eol >> n: a_line >> (Info(n)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    31
    | do_parse!(tag!("CHAT")    >> eol >> m: a_line >> (Chat(m)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    32
    | do_parse!(tag!("FOLLOW")  >> eol >> n: a_line >> (Follow(n)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    33
    | do_parse!(tag!("KICK")    >> eol >> n: a_line >> (Kick(n)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    34
    | do_parse!(tag!("UNBAN")   >> eol >> n: a_line >> (Unban(n)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    35
    | do_parse!(tag!("EM")      >> eol >> m: a_line >> (EngineMessage(m)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    36
    | do_parse!(tag!("TEAMCHAT")    >> eol >> m: a_line >> (TeamChat(m)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    37
    | do_parse!(tag!("ROOM_NAME")   >> eol >> n: a_line >> (RoomName(n)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    38
    | do_parse!(tag!("REMOVE_TEAM") >> eol >> n: a_line >> (RemoveTeam(n)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    39
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    40
    | do_parse!(tag!("PROTO")   >> eol >> d: u32_line >> (Proto(d)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    41
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    42
    | do_parse!(tag!("QUIT")   >> msg: opt_param >> (Quit(msg)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    43
));
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    44
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    45
named!(cmd_message<&[u8], HWProtocolMessage>, preceded!(tag!("CMD\n"), alt!(
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    46
      do_parse!(tag_no_case!("STATS") >> (Stats))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    47
    | do_parse!(tag_no_case!("FIX")   >> (Fix))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    48
    | do_parse!(tag_no_case!("UNFIX") >> (Unfix))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    49
    | do_parse!(tag_no_case!("RESTART_SERVER") >> eol >> tag!("YES") >> (RestartServer))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    50
    | do_parse!(tag_no_case!("REGISTERED_ONLY") >> (ToggleServerRegisteredOnly))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    51
    | do_parse!(tag_no_case!("SUPER_POWER")     >> (SuperPower))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    52
    | do_parse!(tag_no_case!("PART")     >> eol >> m: opt_param >> (Quit(m)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    53
    | do_parse!(tag_no_case!("QUIT")     >> eol >> m: opt_param >> (Part(m)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    54
    | do_parse!(tag_no_case!("DELEGATE") >> eol >> n: a_line  >> (Delegate(n)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    55
    | do_parse!(tag_no_case!("SAVEROOM") >> eol >> r: a_line  >> (SaveRoom(r)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    56
    | do_parse!(tag_no_case!("LOADROOM") >> eol >> r: a_line  >> (LoadRoom(r)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    57
    | do_parse!(tag_no_case!("DELETE")   >> eol >> r: a_line  >> (Delete(r)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    58
    | do_parse!(tag_no_case!("GLOBAL")   >> eol >> m: a_line  >> (Global(m)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    59
    | do_parse!(tag_no_case!("WATCH")    >> eol >> i: a_line  >> (Watch(i)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    60
    | do_parse!(tag_no_case!("GREETING") >> eol >> m: a_line  >> (Greeting(m)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    61
    | do_parse!(tag_no_case!("VOTE")     >> eol >> m: a_line  >> (Vote(m)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    62
    | do_parse!(tag_no_case!("FORCE")    >> eol >> m: a_line  >> (ForceVote(m)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    63
    | do_parse!(tag_no_case!("INFO")     >> eol >> n: a_line  >> (Info(n)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    64
    | do_parse!(tag_no_case!("MAXTEAMS") >> eol >> n: u8_line >> (MaxTeams(n)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    65
)));
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    66
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    67
named!(complex_message<&[u8], HWProtocolMessage>, alt!(
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    68
      do_parse!(tag!("PASSWORD")  >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    69
                    p: a_line     >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    70
                    s: a_line     >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    71
                    (Password(p, s)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    72
    | do_parse!(tag!("CHECKER")   >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    73
                    i: u32_line   >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    74
                    n: a_line     >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    75
                    p: a_line     >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    76
                    (Checker(i, n, p)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    77
    | do_parse!(tag!("CREATE_ROOM") >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    78
                    n: a_line       >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    79
                    p: opt_param    >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    80
                    (CreateRoom(n, p)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    81
    | do_parse!(tag!("JOIN")        >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    82
                    n: a_line       >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    83
                    p: opt_param    >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    84
                    (Join(n, p)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    85
    | do_parse!(tag!("BAN")    >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    86
                    n: a_line     >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    87
                    r: a_line     >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    88
                    t: u32_line   >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    89
                    (Ban(n, r, t)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    90
    | do_parse!(tag!("BAN_IP")    >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    91
                    n: a_line     >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    92
                    r: a_line     >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    93
                    t: u32_line   >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    94
                    (BanIP(n, r, t)))
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    95
    | do_parse!(tag!("BAN_NICK")    >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    96
                    n: a_line     >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    97
                    r: a_line     >> eol >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    98
                    t: u32_line   >>
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
    99
                    (BanNick(n, r, t)))
12133
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
   100
));
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
   101
12137
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   102
named!(malformed_message<&[u8], HWProtocolMessage>,
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   103
    do_parse!(separated_list!(eol, a_line) >> (Malformed)));
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   104
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   105
named!(empty_message<&[u8], HWProtocolMessage>,
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   106
    do_parse!(alt!(end_of_message | eol) >> (Empty)));
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   107
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   108
named!(message<&[u8], HWProtocolMessage>, alt!(terminated!(
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   109
    alt!(
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   110
          basic_message
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   111
        | one_param_message
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   112
        | cmd_message
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   113
        | complex_message
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   114
        ), end_of_message
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   115
    )
12140
7e259e47eb0d Fix malformed messages parsing
unc0rr
parents: 12137
diff changeset
   116
    | terminated!(malformed_message, end_of_message)
12137
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   117
    | empty_message
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   118
    )
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   119
);
12133
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
   120
12136
e25a82ce2374 - Render messages to string
unc0rr
parents: 12135
diff changeset
   121
named!(pub extract_messages<&[u8], Vec<HWProtocolMessage> >, many0!(complete!(message)));
12133
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
   122
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
   123
#[test]
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
   124
fn parse_test() {
12134
109e6765b1fc Optional parameters parsing function
unc0rr
parents: 12133
diff changeset
   125
    assert_eq!(message(b"PING\n\n"),          IResult::Done(&b""[..], Ping));
109e6765b1fc Optional parameters parsing function
unc0rr
parents: 12133
diff changeset
   126
    assert_eq!(message(b"START_GAME\n\n"),    IResult::Done(&b""[..], StartGame));
12133
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
   127
    assert_eq!(message(b"NICK\nit's me\n\n"), IResult::Done(&b""[..], Nick("it's me")));
12134
109e6765b1fc Optional parameters parsing function
unc0rr
parents: 12133
diff changeset
   128
    assert_eq!(message(b"PROTO\n51\n\n"),     IResult::Done(&b""[..], Proto(51)));
109e6765b1fc Optional parameters parsing function
unc0rr
parents: 12133
diff changeset
   129
    assert_eq!(message(b"QUIT\nbye-bye\n\n"), IResult::Done(&b""[..], Quit(Some("bye-bye"))));
109e6765b1fc Optional parameters parsing function
unc0rr
parents: 12133
diff changeset
   130
    assert_eq!(message(b"QUIT\n\n"),          IResult::Done(&b""[..], Quit(None)));
12135
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
   131
    assert_eq!(message(b"CMD\nwatch\ndemo\n\n"), IResult::Done(&b""[..], Watch("demo")));
23ee939ba66a Add more messages to the parser
unc0rr
parents: 12134
diff changeset
   132
    assert_eq!(message(b"BAN\nme\nbad\n77\n\n"), IResult::Done(&b""[..], Ban("me", "bad", 77)));
12136
e25a82ce2374 - Render messages to string
unc0rr
parents: 12135
diff changeset
   133
12140
7e259e47eb0d Fix malformed messages parsing
unc0rr
parents: 12137
diff changeset
   134
    assert_eq!(extract_messages(b"QUIT\n1\n2\n\n"),    IResult::Done(&b""[..], vec![Malformed]));
7e259e47eb0d Fix malformed messages parsing
unc0rr
parents: 12137
diff changeset
   135
12137
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   136
    assert_eq!(extract_messages(b"PING\n\nPING\n\nP"), IResult::Done(&b"P"[..], vec![Ping, Ping]));
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   137
    assert_eq!(extract_messages(b"SING\n\nPING\n\n"),  IResult::Done(&b""[..],  vec![Malformed, Ping]));
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   138
    assert_eq!(extract_messages(b"\n\n\n\nPING\n\n"),  IResult::Done(&b""[..],  vec![Empty, Empty, Ping]));
193dfdcb0620 - Use logging facilities instead of plain println!
unc0rr
parents: 12136
diff changeset
   139
    assert_eq!(extract_messages(b"\n\n\nPING\n\n"),    IResult::Done(&b""[..],  vec![Empty, Empty, Ping]));
12133
81df2e1f9ae9 Some parsing using nom
unc0rr
parents:
diff changeset
   140
}