rust/hedgewars-network-protocol/src/parser.rs
changeset 15810 ee84e417d8d0
parent 15804 747278149393
child 15811 a855f32ab3ca
equal deleted inserted replaced
15809:c3971b38bbfa 15810:ee84e417d8d0
    21     num::ParseIntError,
    21     num::ParseIntError,
    22     str,
    22     str,
    23     str::{FromStr, Utf8Error},
    23     str::{FromStr, Utf8Error},
    24 };
    24 };
    25 
    25 
    26 use crate::messages::{HwProtocolMessage, HwProtocolMessage::*};
    26 use crate::messages::{HwProtocolMessage, HwProtocolMessage::*, HwServerMessage};
    27 use crate::types::{GameCfg, HedgehogInfo, ServerVar, TeamInfo, VoteType};
    27 use crate::types::{GameCfg, HedgehogInfo, ServerVar, TeamInfo, VoteType};
    28 
    28 
    29 #[derive(Debug, PartialEq)]
    29 #[derive(Debug, PartialEq)]
    30 pub struct HwProtocolError {}
    30 pub struct HwProtocolError {}
    31 
    31 
   501             complex_message,
   501             complex_message,
   502         )),
   502         )),
   503         end_of_message,
   503         end_of_message,
   504     )(input)
   504     )(input)
   505 }
   505 }
       
   506 
       
   507 pub fn server_message(input: &[u8]) -> HwResult<HwServerMessage> {
       
   508     use HwServerMessage::*;
       
   509 
       
   510     fn single_arg_message<'a, T, F, G>(
       
   511         name: &'a str,
       
   512         parser: F,
       
   513         constructor: G,
       
   514     ) -> impl FnMut(&'a [u8]) -> HwResult<'a, HwServerMessage>
       
   515     where
       
   516         F: Fn(&[u8]) -> HwResult<T>,
       
   517         G: Fn(T) -> HwServerMessage,
       
   518     {
       
   519         map(
       
   520             preceded(terminated(tag(name), newline), parser),
       
   521             constructor,
       
   522         )
       
   523     }
       
   524 
       
   525     fn list_message<'a, G>(
       
   526         name: &'a str,
       
   527         constructor: G,
       
   528     ) -> impl FnMut(&'a [u8]) -> HwResult<'a, HwServerMessage>
       
   529     where
       
   530         G: Fn(Vec<String>) -> HwServerMessage,
       
   531     {
       
   532         map(
       
   533             preceded(
       
   534                 tag(name),
       
   535                 alt((
       
   536                     map(peek(end_of_message), |_| None),
       
   537                     map(preceded(newline, separated_list0(newline, a_line)), Some),
       
   538                 )),
       
   539             ),
       
   540             move |values| constructor(values.unwrap_or_default()),
       
   541         )
       
   542     }
       
   543 
       
   544     fn string_and_list_message<'a, G>(
       
   545         name: &'a str,
       
   546         constructor: G,
       
   547     ) -> impl FnMut(&'a [u8]) -> HwResult<'a, HwServerMessage>
       
   548     where
       
   549         G: Fn(String, Vec<String>) -> HwServerMessage,
       
   550     {
       
   551         preceded(
       
   552             pair(tag(name), newline),
       
   553             map(
       
   554                 pair(
       
   555                     a_line,
       
   556                     alt((
       
   557                         map(peek(end_of_message), |_| None),
       
   558                         map(preceded(newline, separated_list0(newline, a_line)), Some),
       
   559                     )),
       
   560                 ),
       
   561                 move |(name, values)| constructor(name, values.unwrap_or_default()),
       
   562             ),
       
   563         )
       
   564     }
       
   565 
       
   566     fn message<'a>(
       
   567         name: &'a str,
       
   568         msg: HwServerMessage,
       
   569     ) -> impl Fn(&'a [u8]) -> HwResult<'a, HwServerMessage> {
       
   570         move |i| map(tag(name), |_| msg.clone())(i)
       
   571     }
       
   572 
       
   573     delimited(
       
   574         take_while(|c| c == b'\n'),
       
   575         alt((
       
   576             alt((
       
   577                 message("PING", Ping),
       
   578                 message("PONG", Pong),
       
   579                 message("LOGONPASSED", LogonPassed),
       
   580                 message("KICKED", Kicked),
       
   581                 message("RUN_GAME", RunGame),
       
   582                 message("ROUND_FINISHED", RoundFinished),
       
   583                 message("REPLAY_START", ReplayStart),
       
   584             )),
       
   585             alt((
       
   586                 single_arg_message("REDIRECT", u16_line, Redirect),
       
   587                 single_arg_message("BYE", a_line, Bye),
       
   588                 single_arg_message("NICK", a_line, Nick),
       
   589                 single_arg_message("PROTO", u16_line, Proto),
       
   590                 single_arg_message("ASKPASSWORD", a_line, AskPassword),
       
   591                 single_arg_message("SERVER_AUTH", a_line, ServerAuth),
       
   592                 single_arg_message("ROOM\nDEL", a_line, RoomRemove),
       
   593                 single_arg_message("JOINING", a_line, Joining),
       
   594                 single_arg_message("REMOVE_TEAM", a_line, TeamRemove),
       
   595                 single_arg_message("TEAM_ACCEPTED", a_line, TeamAccepted),
       
   596                 single_arg_message("SERVER_MESSAGE", a_line, ServerMessage),
       
   597                 single_arg_message("NOTICE", a_line, Notice),
       
   598                 single_arg_message("WARNING", a_line, Warning),
       
   599                 single_arg_message("ERROR", a_line, Error),
       
   600             )),
       
   601             alt((
       
   602                 preceded(
       
   603                     pair(tag("LOBBY:LEFT"), newline),
       
   604                     map(pair(terminated(a_line, newline), a_line), |(nick, msg)| {
       
   605                         LobbyLeft(nick, msg)
       
   606                     }),
       
   607                 ),
       
   608                 preceded(
       
   609                     pair(tag("CHAT"), newline),
       
   610                     map(pair(terminated(a_line, newline), a_line), |(nick, msg)| {
       
   611                         ChatMsg { nick, msg }
       
   612                     }),
       
   613                 ),
       
   614                 preceded(
       
   615                     pair(tag("TEAM_COLOR"), newline),
       
   616                     map(
       
   617                         pair(terminated(a_line, newline), u8_line),
       
   618                         |(name, color)| TeamColor(name, color),
       
   619                     ),
       
   620                 ),
       
   621                 preceded(
       
   622                     pair(tag("HH_NUM"), newline),
       
   623                     map(
       
   624                         pair(terminated(a_line, newline), u8_line),
       
   625                         |(name, count)| HedgehogsNumber(name, count),
       
   626                     ),
       
   627                 ),
       
   628                 preceded(
       
   629                     pair(tag("CONNECTED"), newline),
       
   630                     map(
       
   631                         pair(terminated(a_line, newline), u32_line),
       
   632                         |(msg, server_protocol_version)| Connected(msg, server_protocol_version),
       
   633                     ),
       
   634                 ),
       
   635                 preceded(
       
   636                     pair(tag("LEFT"), newline),
       
   637                     map(pair(terminated(a_line, newline), a_line), |(nick, msg)| {
       
   638                         RoomLeft(nick, msg)
       
   639                     }),
       
   640                 ),
       
   641             )),
       
   642             alt((
       
   643                 string_and_list_message("CLIENT_FLAGS", ClientFlags),
       
   644                 string_and_list_message("ROOM\nUPD", RoomUpdated),
       
   645                 string_and_list_message("CFG", ConfigEntry),
       
   646             )),
       
   647             alt((
       
   648                 list_message("LOBBY:JOINED", LobbyJoined),
       
   649                 list_message("ROOMS", Rooms),
       
   650                 list_message("ROOM\nADD", RoomAdd),
       
   651                 list_message("JOINED", RoomJoined),
       
   652                 list_message("ADD_TEAM", TeamAdd),
       
   653                 list_message("EM", ForwardEngineMessage),
       
   654                 list_message("INFO", Info),
       
   655                 list_message("SERVER_VARS", ServerVars),
       
   656             )),
       
   657         )),
       
   658         end_of_message,
       
   659     )(input)
       
   660 }