rust/hedgewars-server/src/protocol/parser.rs
changeset 15119 901751d3cd80
parent 15118 0e59abde6766
child 15122 4f31954a0b81
equal deleted inserted replaced
15118:0e59abde6766 15119:901751d3cd80
   175         ),
   175         ),
   176         map(
   176         map(
   177             preceded(pair(tag_no_case("HEDGEHOGS"), spaces), u8_line),
   177             preceded(pair(tag_no_case("HEDGEHOGS"), spaces), u8_line),
   178             VoteType::HedgehogsPerTeam,
   178             VoteType::HedgehogsPerTeam,
   179         ),
   179         ),
   180         map(
   180         map(preceded(tag_no_case("MAP"), opt_space_arg), VoteType::Map),
   181             preceded(tag_no_case("MAP"), opt_space_arg),
       
   182             VoteType::Map,
       
   183         ),
       
   184     ))(input)
   181     ))(input)
   185 }
   182 }
   186 
   183 
   187 fn no_arg_message(input: &[u8]) -> HwResult<HwProtocolMessage> {
   184 fn no_arg_message(input: &[u8]) -> HwResult<HwProtocolMessage> {
   188     fn messagec<'a>(
   185     fn message<'a>(
   189         input: &'a [u8],
       
   190         name: &'a str,
   186         name: &'a str,
   191         msg: HwProtocolMessage,
   187         msg: HwProtocolMessage,
   192     ) -> HwResult<'a, HwProtocolMessage> {
   188     ) -> impl Fn(&'a [u8]) -> HwResult<'a, HwProtocolMessage> {
   193         map(tag(name), |_| msg.clone())(input)
   189         move |i| map(tag(name), |_| msg.clone())(i)
   194     }
   190     }
   195 
   191 
   196     alt((
   192     alt((
   197         |i| messagec(i, "PING", Ping),
   193         message("PING", Ping),
   198         |i| messagec(i, "PONG", Pong),
   194         message("PONG", Pong),
   199         |i| messagec(i, "LIST", List),
   195         message("LIST", List),
   200         |i| messagec(i, "BANLIST", BanList),
   196         message("BANLIST", BanList),
   201         |i| messagec(i, "GET_SERVER_VAR", GetServerVar),
   197         message("GET_SERVER_VAR", GetServerVar),
   202         |i| messagec(i, "TOGGLE_READY", ToggleReady),
   198         message("TOGGLE_READY", ToggleReady),
   203         |i| messagec(i, "START_GAME", StartGame),
   199         message("START_GAME", StartGame),
   204         |i| messagec(i, "TOGGLE_RESTRICT_JOINS", ToggleRestrictJoin),
   200         message("TOGGLE_RESTRICT_JOINS", ToggleRestrictJoin),
   205         |i| messagec(i, "TOGGLE_RESTRICT_TEAMS", ToggleRestrictTeams),
   201         message("TOGGLE_RESTRICT_TEAMS", ToggleRestrictTeams),
   206         |i| messagec(i, "TOGGLE_REGISTERED_ONLY", ToggleRegisteredOnly),
   202         message("TOGGLE_REGISTERED_ONLY", ToggleRegisteredOnly),
   207     ))(input)
   203     ))(input)
   208 }
   204 }
   209 
   205 
   210 fn single_arg_message(input: &[u8]) -> HwResult<HwProtocolMessage> {
   206 fn single_arg_message(input: &[u8]) -> HwResult<HwProtocolMessage> {
   211     fn messagec<'a, T, F, G>(
   207     fn message<'a, T, F, G>(
   212         input: &'a [u8],
       
   213         name: &'a str,
   208         name: &'a str,
   214         parser: F,
   209         parser: F,
   215         constructor: G,
   210         constructor: G,
   216     ) -> HwResult<'a, HwProtocolMessage>
   211     ) -> impl Fn(&'a [u8]) -> HwResult<'a, HwProtocolMessage>
   217     where
   212     where
   218         F: Fn(&[u8]) -> HwResult<T>,
   213         F: Fn(&[u8]) -> HwResult<T>,
   219         G: Fn(T) -> HwProtocolMessage,
   214         G: Fn(T) -> HwProtocolMessage,
   220     {
   215     {
   221         map(preceded(tag(name), parser), constructor)(input)
   216         map(preceded(tag(name), parser), constructor)
   222     }
   217     }
   223 
   218 
   224     alt((
   219     alt((
   225         |i| messagec(i, "NICK\n", a_line, Nick),
   220         message("NICK\n", a_line, Nick),
   226         |i| messagec(i, "INFO\n", a_line, Info),
   221         message("INFO\n", a_line, Info),
   227         |i| messagec(i, "CHAT\n", a_line, Chat),
   222         message("CHAT\n", a_line, Chat),
   228         |i| messagec(i, "PART", opt_arg, Part),
   223         message("PART", opt_arg, Part),
   229         |i| messagec(i, "FOLLOW\n", a_line, Follow),
   224         message("FOLLOW\n", a_line, Follow),
   230         |i| messagec(i, "KICK\n", a_line, Kick),
   225         message("KICK\n", a_line, Kick),
   231         |i| messagec(i, "UNBAN\n", a_line, Unban),
   226         message("UNBAN\n", a_line, Unban),
   232         |i| messagec(i, "EM\n", a_line, EngineMessage),
   227         message("EM\n", a_line, EngineMessage),
   233         |i| messagec(i, "TEAMCHAT\n", a_line, TeamChat),
   228         message("TEAMCHAT\n", a_line, TeamChat),
   234         |i| messagec(i, "ROOM_NAME\n", a_line, RoomName),
   229         message("ROOM_NAME\n", a_line, RoomName),
   235         |i| messagec(i, "REMOVE_TEAM\n", a_line, RemoveTeam),
   230         message("REMOVE_TEAM\n", a_line, RemoveTeam),
   236         |i| messagec(i, "ROUNDFINISHED", opt_arg, |_| RoundFinished),
   231         message("ROUNDFINISHED", opt_arg, |_| RoundFinished),
   237         |i| messagec(i, "PROTO\n", u16_line, Proto),
   232         message("PROTO\n", u16_line, Proto),
   238         |i| messagec(i, "QUIT", opt_arg, Quit),
   233         message("QUIT", opt_arg, Quit),
   239     ))(input)
   234     ))(input)
   240 }
   235 }
   241 
   236 
   242 fn cmd_message<'a>(input: &'a [u8]) -> HwResult<'a, HwProtocolMessage> {
   237 fn cmd_message<'a>(input: &'a [u8]) -> HwResult<'a, HwProtocolMessage> {
   243     fn cmdc_no_arg<'a>(
   238     fn cmd_no_arg<'a>(
   244         input: &'a [u8],
       
   245         name: &'a str,
   239         name: &'a str,
   246         msg: HwProtocolMessage,
   240         msg: HwProtocolMessage,
   247     ) -> HwResult<'a, HwProtocolMessage> {
   241     ) -> impl Fn(&'a [u8]) -> HwResult<'a, HwProtocolMessage> {
   248         map(tag_no_case(name), |_| msg.clone())(input)
   242         move |i| map(tag_no_case(name), |_| msg.clone())(i)
   249     }
   243     }
   250 
   244 
   251     fn cmdc_single_arg<'a, T, F, G>(
   245     fn cmd_single_arg<'a, T, F, G>(
   252         input: &'a [u8],
       
   253         name: &'a str,
   246         name: &'a str,
   254         parser: F,
   247         parser: F,
   255         constructor: G,
   248         constructor: G,
   256     ) -> HwResult<'a, HwProtocolMessage>
   249     ) -> impl Fn(&'a [u8]) -> HwResult<'a, HwProtocolMessage>
   257     where
   250     where
   258         F: Fn(&'a [u8]) -> HwResult<'a, T>,
   251         F: Fn(&'a [u8]) -> HwResult<'a, T>,
   259         G: Fn(T) -> HwProtocolMessage,
   252         G: Fn(T) -> HwProtocolMessage,
   260     {
   253     {
   261         map(
   254         map(
   262             preceded(pair(tag_no_case(name), spaces), parser),
   255             preceded(pair(tag_no_case(name), spaces), parser),
   263             constructor,
   256             constructor,
   264         )(input)
   257         )
   265     }
   258     }
   266 
   259 
   267     fn cmd_no_arg_message(input: &[u8]) -> HwResult<HwProtocolMessage> {
   260     fn cmd_no_arg_message(input: &[u8]) -> HwResult<HwProtocolMessage> {
   268         alt((
   261         alt((
   269             |i| cmdc_no_arg(i, "STATS", Stats),
   262             cmd_no_arg("STATS", Stats),
   270             |i| cmdc_no_arg(i, "FIX", Fix),
   263             cmd_no_arg("FIX", Fix),
   271             |i| cmdc_no_arg(i, "UNFIX", Unfix),
   264             cmd_no_arg("UNFIX", Unfix),
   272             |i| cmdc_no_arg(i, "REGISTERED_ONLY", ToggleServerRegisteredOnly),
   265             cmd_no_arg("REGISTERED_ONLY", ToggleServerRegisteredOnly),
   273             |i| cmdc_no_arg(i, "SUPER_POWER", SuperPower),
   266             cmd_no_arg("SUPER_POWER", SuperPower),
   274         ))(input)
   267         ))(input)
   275     }
   268     }
   276 
   269 
   277     fn cmd_single_arg_message(input: &[u8]) -> HwResult<HwProtocolMessage> {
   270     fn cmd_single_arg_message(input: &[u8]) -> HwResult<HwProtocolMessage> {
   278         alt((
   271         alt((
   279             |i| cmdc_single_arg(i, "RESTART_SERVER", |i| tag("YES")(i), |_| RestartServer),
   272             cmd_single_arg("RESTART_SERVER", |i| tag("YES")(i), |_| RestartServer),
   280             |i| cmdc_single_arg(i, "DELEGATE", a_line, Delegate),
   273             cmd_single_arg("DELEGATE", a_line, Delegate),
   281             |i| cmdc_single_arg(i, "DELETE", a_line, Delete),
   274             cmd_single_arg("DELETE", a_line, Delete),
   282             |i| cmdc_single_arg(i, "SAVEROOM", a_line, SaveRoom),
   275             cmd_single_arg("SAVEROOM", a_line, SaveRoom),
   283             |i| cmdc_single_arg(i, "LOADROOM", a_line, LoadRoom),
   276             cmd_single_arg("LOADROOM", a_line, LoadRoom),
   284             |i| cmdc_single_arg(i, "GLOBAL", a_line, Global),
   277             cmd_single_arg("GLOBAL", a_line, Global),
   285             |i| cmdc_single_arg(i, "WATCH", u32_line, Watch),
   278             cmd_single_arg("WATCH", u32_line, Watch),
   286             |i| cmdc_single_arg(i, "VOTE", yes_no_line, Vote),
   279             cmd_single_arg("VOTE", yes_no_line, Vote),
   287             |i| cmdc_single_arg(i, "FORCE", yes_no_line, ForceVote),
   280             cmd_single_arg("FORCE", yes_no_line, ForceVote),
   288             |i| cmdc_single_arg(i, "INFO", a_line, Info),
   281             cmd_single_arg("INFO", a_line, Info),
   289             |i| cmdc_single_arg(i, "MAXTEAMS", u8_line, MaxTeams),
   282             cmd_single_arg("MAXTEAMS", u8_line, MaxTeams),
   290             |i| cmdc_single_arg(i, "CALLVOTE", voting, |v| CallVote(Some(v))),
   283             cmd_single_arg("CALLVOTE", voting, |v| CallVote(Some(v))),
   291         ))(input)
   284         ))(input)
   292     }
   285     }
   293 
   286 
   294     preceded(
   287     preceded(
   295         tag("CMD\n"),
   288         tag("CMD\n"),
   296         alt((
   289         alt((
   297             cmd_no_arg_message,
   290             cmd_no_arg_message,
   298             cmd_single_arg_message,
   291             cmd_single_arg_message,
   299             map(tag_no_case("CALLVOTE"), |_| CallVote(None)),
   292             map(tag_no_case("CALLVOTE"), |_| CallVote(None)),
   300             map(
   293             map(preceded(tag_no_case("GREETING"), opt_space_arg), Greeting),
   301                 preceded(tag_no_case("GREETING"), opt_space_arg),
       
   302                 Greeting,
       
   303             ),
       
   304             map(preceded(tag_no_case("PART"), opt_space_arg), Part),
   294             map(preceded(tag_no_case("PART"), opt_space_arg), Part),
   305             map(preceded(tag_no_case("QUIT"), opt_space_arg), Quit),
   295             map(preceded(tag_no_case("QUIT"), opt_space_arg), Quit),
   306             map(
   296             map(
   307                 preceded(
   297                 preceded(
   308                     tag_no_case("SAVE"),
   298                     tag_no_case("SAVE"),
   323         )),
   313         )),
   324     )(input)
   314     )(input)
   325 }
   315 }
   326 
   316 
   327 fn config_message<'a>(input: &'a [u8]) -> HwResult<'a, HwProtocolMessage> {
   317 fn config_message<'a>(input: &'a [u8]) -> HwResult<'a, HwProtocolMessage> {
   328     fn cfgc_single_arg<'a, T, F, G>(
   318     fn cfg_single_arg<'a, T, F, G>(
   329         input: &'a [u8],
       
   330         name: &'a str,
   319         name: &'a str,
   331         parser: F,
   320         parser: F,
   332         constructor: G,
   321         constructor: G,
   333     ) -> HwResult<'a, GameCfg>
   322     ) -> impl Fn(&'a [u8]) -> HwResult<'a, GameCfg>
   334     where
   323     where
   335         F: Fn(&[u8]) -> HwResult<T>,
   324         F: Fn(&[u8]) -> HwResult<T>,
   336         G: Fn(T) -> GameCfg,
   325         G: Fn(T) -> GameCfg,
   337     {
   326     {
   338         map(preceded(pair(tag(name), newline), parser), constructor)(input)
   327         map(preceded(pair(tag(name), newline), parser), constructor)
   339     }
   328     }
   340 
   329 
   341     let (i, cfg) = preceded(
   330     let (i, cfg) = preceded(
   342         tag("CFG\n"),
   331         tag("CFG\n"),
   343         alt((
   332         alt((
   344             |i| cfgc_single_arg(i, "THEME", a_line, GameCfg::Theme),
   333             cfg_single_arg("THEME", a_line, GameCfg::Theme),
   345             |i| cfgc_single_arg(i, "SCRIPT", a_line, GameCfg::Script),
   334             cfg_single_arg("SCRIPT", a_line, GameCfg::Script),
   346             |i| cfgc_single_arg(i, "MAP", a_line, GameCfg::MapType),
   335             cfg_single_arg("MAP", a_line, GameCfg::MapType),
   347             |i| cfgc_single_arg(i, "MAPGEN", u32_line, GameCfg::MapGenerator),
   336             cfg_single_arg("MAPGEN", u32_line, GameCfg::MapGenerator),
   348             |i| cfgc_single_arg(i, "MAZE_SIZE", u32_line, GameCfg::MazeSize),
   337             cfg_single_arg("MAZE_SIZE", u32_line, GameCfg::MazeSize),
   349             |i| cfgc_single_arg(i, "TEMPLATE", u32_line, GameCfg::Template),
   338             cfg_single_arg("TEMPLATE", u32_line, GameCfg::Template),
   350             |i| cfgc_single_arg(i, "FEATURE_SIZE", u32_line, GameCfg::FeatureSize),
   339             cfg_single_arg("FEATURE_SIZE", u32_line, GameCfg::FeatureSize),
   351             |i| cfgc_single_arg(i, "SEED", a_line, GameCfg::Seed),
   340             cfg_single_arg("SEED", a_line, GameCfg::Seed),
   352             |i| cfgc_single_arg(i, "DRAWNMAP", a_line, GameCfg::DrawnMap),
   341             cfg_single_arg("DRAWNMAP", a_line, GameCfg::DrawnMap),
   353             preceded(pair(tag("AMMO"), newline), |i| {
   342             preceded(pair(tag("AMMO"), newline), |i| {
   354                 let (i, name) = a_line(i)?;
   343                 let (i, name) = a_line(i)?;
   355                 let (i, value) = opt_arg(i)?;
   344                 let (i, value) = opt_arg(i)?;
   356                 Ok((i, GameCfg::Ammo(name, value)))
   345                 Ok((i, GameCfg::Ammo(name, value)))
   357             }),
   346             }),