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 } |