Start refactoring path from getting message from client to reacting to it
authorunc0rr
Mon, 23 Jan 2017 23:43:29 +0300
changeset 12142 4d7d41be1993
parent 12141 78925eff02c2
child 12143 7e874846afe3
Start refactoring path from getting message from client to reacting to it
gameServer2/src/protocol/messages.rs
gameServer2/src/protocol/parser.rs
gameServer2/src/server/actions.rs
gameServer2/src/server/client.rs
gameServer2/src/server/server.rs
--- a/gameServer2/src/protocol/messages.rs	Wed Jan 18 22:54:02 2017 +0300
+++ b/gameServer2/src/protocol/messages.rs	Mon Jan 23 23:43:29 2017 +0300
@@ -4,85 +4,80 @@
 use std::convert::From;
 
 #[derive(PartialEq, Debug)]
-pub enum HWProtocolMessage<'a> {
+pub enum HWProtocolMessage {
     // core
     Ping,
     Pong,
-    Quit(Option<&'a str>),
-    Bye(&'a str),
-    LobbyLeft(&'a str),
-    //Cmd(&'a str, Vec<&'a str>),
-    Global(&'a str),
-    Watch(&'a str),
+    Quit(Option<String>),
+    //Cmd(String, Vec<String>),
+    Global(String),
+    Watch(String),
     ToggleServerRegisteredOnly,
     SuperPower,
-    Info(&'a str),
+    Info(String),
     // not entered state
-    Nick(&'a str),
+    Nick(String),
     Proto(u32),
-    Password(&'a str, &'a str),
-    Checker(u32, &'a str, &'a str),
+    Password(String, String),
+    Checker(u32, String, String),
     // lobby
     List,
-    Chat(&'a str),
-    CreateRoom(&'a str, Option<&'a str>),
-    Join(&'a str, Option<&'a str>),
-    Follow(&'a str),
-    Rnd(Vec<&'a str>),
-    Kick(&'a str),
-    Ban(&'a str, &'a str, u32),
-    BanIP(&'a str, &'a str, u32),
-    BanNick(&'a str, &'a str, u32),
+    Chat(String),
+    CreateRoom(String, Option<String>),
+    Join(String, Option<String>),
+    Follow(String),
+    Rnd(Vec<String>),
+    Kick(String),
+    Ban(String, String, u32),
+    BanIP(String, String, u32),
+    BanNick(String, String, u32),
     BanList,
-    Unban(&'a str),
+    Unban(String),
     SetServerVar(ServerVar),
     GetServerVar,
     RestartServer,
     Stats,
     // in room
-    Part(Option<&'a str>),
+    Part(Option<String>),
     Cfg(GameCfg),
     AddTeam(TeamInfo),
-    RemoveTeam(&'a str),
-    SetHedgehogsNumber(&'a str, u8),
-    SetTeamColor(&'a str, u8),
+    RemoveTeam(String),
+    SetHedgehogsNumber(String, u8),
+    SetTeamColor(String, u8),
     ToggleReady,
     StartGame,
-    EngineMessage(&'a str),
+    EngineMessage(String),
     RoundFinished,
     ToggleRestrictJoin,
     ToggleRestrictTeams,
     ToggleRegisteredOnly,
-    RoomName(&'a str),
-    Delegate(&'a str),
-    TeamChat(&'a str),
+    RoomName(String),
+    Delegate(String),
+    TeamChat(String),
     MaxTeams(u8),
     Fix,
     Unfix,
-    Greeting(&'a str),
-    CallVote(Option<(&'a str, Option<&'a str>)>),
-    Vote(&'a str),
-    ForceVote(&'a str),
-    Save(&'a str, &'a str),
-    Delete(&'a str),
-    SaveRoom(&'a str),
-    LoadRoom(&'a str),
-    Connected(u32),
+    Greeting(String),
+    CallVote(Option<(String, Option<String>)>),
+    Vote(String),
+    ForceVote(String),
+    Save(String, String),
+    Delete(String),
+    SaveRoom(String),
+    LoadRoom(String),
     Malformed,
     Empty,
 }
 
-pub fn number<T: From<u8>
-                + std::default::Default
-                + std::ops::MulAssign
-                + std::ops::AddAssign>
-    (digits: Vec<u8>) -> T {
-    let mut value: T = T::default();
-    for digit in digits {
-        value *= T::from(10);
-        value += T::from(digit);
-    }
-    value
+pub enum HWServerMessage<'a> {
+    Ping,
+    Pong,
+    Bye(&'a str),
+    Nick(&'a str),
+    LobbyLeft(&'a str),
+
+    Connected(u32),
+    Unreachable,
 }
 
 fn construct_message(msg: & [&str]) -> String {
@@ -97,25 +92,25 @@
     m
 }
 
-impl<'a> HWProtocolMessage<'a> {
+impl<'a> HWServerMessage<'a> {
     pub fn to_raw_protocol(&self) -> String {
         match self {
-            &HWProtocolMessage::Ping
+            &HWServerMessage::Ping
                 => "PING\n\n".to_string(),
-            &HWProtocolMessage::Pong
+            &HWServerMessage::Pong
                 => "PONG\n\n".to_string(),
-            &HWProtocolMessage::Connected(protocol_version)
+            &HWServerMessage::Connected(protocol_version)
                 => construct_message(&[
                     "CONNECTED",
                     "Hedgewars server http://www.hedgewars.org/",
                     &protocol_version.to_string()
                 ]),
-            &HWProtocolMessage::Bye(msg)
-                => construct_message(&["BYE", msg]),
-            &HWProtocolMessage::Nick(nick)
-            => construct_message(&["NICK", nick]),
-            &HWProtocolMessage::LobbyLeft(msg)
-                => construct_message(&["LOBBY_LEFT", msg]),
+            &HWServerMessage::Bye(msg)
+                => construct_message(&["BYE", &msg]),
+            &HWServerMessage::Nick(nick)
+            => construct_message(&["NICK", &nick]),
+            &HWServerMessage::LobbyLeft(msg)
+                => construct_message(&["LOBBY_LEFT", &msg]),
             _ => construct_message(&["ERROR", "UNIMPLEMENTED"]),
         }
     }
--- a/gameServer2/src/protocol/parser.rs	Wed Jan 18 22:54:02 2017 +0300
+++ b/gameServer2/src/protocol/parser.rs	Mon Jan 23 23:43:29 2017 +0300
@@ -6,10 +6,11 @@
 use super::messages::HWProtocolMessage::*;
 
 named!(end_of_message, tag!("\n\n"));
-named!(a_line<&[u8], &str>, map_res!(not_line_ending, str::from_utf8));
-named!( u8_line<&[u8],  u8>, map_res!(a_line, FromStr::from_str));
-named!(u32_line<&[u8], u32>, map_res!(a_line, FromStr::from_str));
-named!(opt_param<&[u8], Option<&str> >, opt!(flat_map!(preceded!(eol, a_line), non_empty)));
+named!(str_line<&[u8],   &str>, map_res!(not_line_ending, str::from_utf8));
+named!(  a_line<&[u8], String>, map!(str_line, String::from));
+named!( u8_line<&[u8],     u8>, map_res!(str_line, FromStr::from_str));
+named!(u32_line<&[u8],    u32>, map_res!(str_line, FromStr::from_str));
+named!(opt_param<&[u8], Option<String> >, opt!(map!(flat_map!(preceded!(eol, str_line), non_empty), String::from)));
 
 named!(basic_message<&[u8], HWProtocolMessage>, alt!(
       do_parse!(tag!("PING") >> (Ping))
@@ -124,12 +125,12 @@
 fn parse_test() {
     assert_eq!(message(b"PING\n\n"),          IResult::Done(&b""[..], Ping));
     assert_eq!(message(b"START_GAME\n\n"),    IResult::Done(&b""[..], StartGame));
-    assert_eq!(message(b"NICK\nit's me\n\n"), IResult::Done(&b""[..], Nick("it's me")));
+    assert_eq!(message(b"NICK\nit's me\n\n"), IResult::Done(&b""[..], Nick("it's me".to_string())));
     assert_eq!(message(b"PROTO\n51\n\n"),     IResult::Done(&b""[..], Proto(51)));
-    assert_eq!(message(b"QUIT\nbye-bye\n\n"), IResult::Done(&b""[..], Quit(Some("bye-bye"))));
+    assert_eq!(message(b"QUIT\nbye-bye\n\n"), IResult::Done(&b""[..], Quit(Some("bye-bye".to_string()))));
     assert_eq!(message(b"QUIT\n\n"),          IResult::Done(&b""[..], Quit(None)));
-    assert_eq!(message(b"CMD\nwatch\ndemo\n\n"), IResult::Done(&b""[..], Watch("demo")));
-    assert_eq!(message(b"BAN\nme\nbad\n77\n\n"), IResult::Done(&b""[..], Ban("me", "bad", 77)));
+    assert_eq!(message(b"CMD\nwatch\ndemo\n\n"), IResult::Done(&b""[..], Watch("demo".to_string())));
+    assert_eq!(message(b"BAN\nme\nbad\n77\n\n"), IResult::Done(&b""[..], Ban("me".to_string(), "bad".to_string(), 77)));
 
     assert_eq!(extract_messages(b"QUIT\n1\n2\n\n"),    IResult::Done(&b""[..], vec![Malformed]));
 
--- a/gameServer2/src/server/actions.rs	Wed Jan 18 22:54:02 2017 +0300
+++ b/gameServer2/src/server/actions.rs	Mon Jan 23 23:43:29 2017 +0300
@@ -4,5 +4,5 @@
     SendMe(String),
     RemoveClient,
     ByeClient(String),
-    SetNick(String),
+    ReactProtocolMessage(HWProtocolMessage),
 }
--- a/gameServer2/src/server/client.rs	Wed Jan 18 22:54:02 2017 +0300
+++ b/gameServer2/src/server/client.rs	Mon Jan 23 23:43:29 2017 +0300
@@ -7,8 +7,7 @@
 
 use utils;
 use protocol::ProtocolDecoder;
-use protocol::messages;
-use protocol::messages::HWProtocolMessage::*;
+use protocol::messages::*;
 use server::actions::Action::*;
 use server::actions::Action;
 use log;
@@ -37,7 +36,7 @@
                       PollOpt::edge())
             .ok().expect("could not register socket with event loop");
 
-        self.send_msg(Connected(utils::PROTOCOL_VERSION));
+        self.send_msg(HWServerMessage::Connected(utils::PROTOCOL_VERSION));
     }
 
     pub fn deregister(&mut self, poll: &Poll) {
@@ -53,7 +52,7 @@
         self.send_raw_msg(&msg.as_bytes());
     }
 
-    pub fn send_msg(&mut self, msg: messages::HWProtocolMessage) {
+    pub fn send_msg(&mut self, msg: HWServerMessage) {
         self.send_string(&msg.to_raw_protocol());
     }
 
@@ -67,11 +66,11 @@
         debug!("Read {} bytes", v);
         let mut response = Vec::new();
         {
-            let msgs = self.decoder.extract_messages();
-            for msg in msgs {
-                match msg {
+            for msg in self.decoder.extract_messages() {
+                response.push(ReactProtocolMessage(msg));
+/*                match msg {
                     Ping => response.push(SendMe(Pong.to_raw_protocol())),
-                    Quit(Some(msg)) => response.push(ByeClient("User quit: ".to_string() + msg)),
+                    Quit(Some(msg)) => response.push(ByeClient("User quit: ".to_string() + &msg)),
                     Quit(None) => response.push(ByeClient("User quit".to_string())),
                     Nick(nick) => if self.nick.len() == 0 {
                         response.push(SetNick(nick.to_string()));
@@ -79,7 +78,7 @@
                     Malformed => warn!("Malformed/unknown message"),
                     Empty => warn!("Empty message"),
                     _ => unimplemented!(),
-                }
+                }*/
             }
         }
         self.decoder.sweep();
--- a/gameServer2/src/server/server.rs	Wed Jan 18 22:54:02 2017 +0300
+++ b/gameServer2/src/server/server.rs	Mon Jan 23 23:43:29 2017 +0300
@@ -9,6 +9,7 @@
 use server::actions::Action;
 use server::actions::Action::*;
 use protocol::messages::HWProtocolMessage::*;
+use protocol::messages::HWServerMessage;
 
 type Slab<T> = slab::Slab<T, Token>;
 
@@ -90,18 +91,26 @@
                 SendMe(msg) => self.send(token, &msg),
                 ByeClient(msg) => {
                     self.react(token, poll, vec![
-                        SendMe(Bye(&msg).to_raw_protocol()),
+                        SendMe(HWServerMessage::Bye(&msg).to_raw_protocol()),
                         RemoveClient,
                     ]);
                 },
-                SetNick(nick) => {
-                    self.send(token, &Nick(&nick).to_raw_protocol());
-                    self.clients[token].nick = nick;
-                }
                 RemoveClient => {
                     self.clients[token].deregister(poll);
                     self.clients.remove(token);
                 },
+                ReactProtocolMessage(msg) => match msg {
+                    Ping => self.react(token, poll, vec![SendMe(HWServerMessage::Pong.to_raw_protocol())]),
+                    Quit(Some(msg)) => self.react(token, poll, vec![ByeClient("User quit: ".to_string() + &msg)]),
+                    Quit(None) => self.react(token, poll, vec![ByeClient("User quit".to_string())]),
+                    Nick(nick) => if self.clients[token].nick.len() == 0 {
+                        self.send(token, &HWServerMessage::Nick(&nick).to_raw_protocol());
+                        self.clients[token].nick = nick;
+                    },
+                    Malformed => warn!("Malformed/unknown message"),
+                    Empty => warn!("Empty message"),
+                    _ => unimplemented!(),
+                }
                 //_ => unimplemented!(),
             }
         }