- Use logging facilities instead of plain println!
authorunc0rr
Sat, 14 Jan 2017 22:30:09 +0300
changeset 12137 193dfdcb0620
parent 12136 e25a82ce2374
child 12138 e0bf51609062
- Use logging facilities instead of plain println! - Parse malformed messages, parser doesn't get stuck anymore
gameServer2/Cargo.toml
gameServer2/src/main.rs
gameServer2/src/protocol/messages.rs
gameServer2/src/protocol/parser.rs
gameServer2/src/server/client.rs
gameServer2/src/server/server.rs
gameServer2/src/utils.rs
--- a/gameServer2/Cargo.toml	Sat Jan 14 00:46:52 2017 +0300
+++ b/gameServer2/Cargo.toml	Sat Jan 14 22:30:09 2017 +0300
@@ -9,3 +9,5 @@
 slab = "0.3"
 netbuf = "0.3.8"
 nom = "2.0"
+env_logger = "0.3.5"
+log = "0.3.6"
--- a/gameServer2/src/main.rs	Sat Jan 14 00:46:52 2017 +0300
+++ b/gameServer2/src/main.rs	Sat Jan 14 22:30:09 2017 +0300
@@ -4,6 +4,9 @@
 extern crate netbuf;
 #[macro_use]
 extern crate nom;
+#[macro_use]
+extern crate log;
+extern crate env_logger;
 
 //use std::io::*;
 //use rand::Rng;
@@ -16,7 +19,9 @@
 mod protocol;
 
 fn main() {
-    println!("Hedgewars game server, protocol {}", utils::PROTOCOL_VERSION);
+    env_logger::init().unwrap();
+
+    info!("Hedgewars game server, protocol {}", utils::PROTOCOL_VERSION);
 
     let address = "0.0.0.0:46631".parse().unwrap();
     let listener = TcpListener::bind(&address).unwrap();
@@ -43,6 +48,12 @@
                     tok => server.client_writable(&poll, tok).unwrap(),
                 }
             }
+            if event.kind().is_hup() || event.kind().is_error() {
+                match event.token() {
+                    utils::SERVER => unreachable!(),
+                    tok => server.client_error(&poll, tok).unwrap(),
+                }
+            }
         }
     }
 }
--- a/gameServer2/src/protocol/messages.rs	Sat Jan 14 00:46:52 2017 +0300
+++ b/gameServer2/src/protocol/messages.rs	Sat Jan 14 22:30:09 2017 +0300
@@ -67,6 +67,9 @@
     Delete(&'a str),
     SaveRoom(&'a str),
     LoadRoom(&'a str),
+    Connected(u32),
+    Malformed,
+    Empty,
 }
 
 pub fn number<T: From<u8>
@@ -101,6 +104,12 @@
                 => "PING\n\n".to_string(),
             &HWProtocolMessage::Pong
                 => "PONG\n\n".to_string(),
+            &HWProtocolMessage::Connected(protocol_version)
+                => construct_message(&[
+                    "CONNECTED",
+                    "Hedgewars server http://www.hedgewars.org/",
+                    &protocol_version.to_string()
+                ]),
             &HWProtocolMessage::Bye(msg)
                 => construct_message(&["BYE", msg]),
             &HWProtocolMessage::LobbyLeft(msg)
--- a/gameServer2/src/protocol/parser.rs	Sat Jan 14 00:46:52 2017 +0300
+++ b/gameServer2/src/protocol/parser.rs	Sat Jan 14 22:30:09 2017 +0300
@@ -99,13 +99,24 @@
                     (BanNick(n, r, t)))
 ));
 
-named!(message<&[u8], HWProtocolMessage>, terminated!(alt!(
-      basic_message
-    | one_param_message
-    | cmd_message
-    | complex_message
-    ), end_of_message
-));
+named!(malformed_message<&[u8], HWProtocolMessage>,
+    do_parse!(separated_list!(eol, a_line) >> (Malformed)));
+
+named!(empty_message<&[u8], HWProtocolMessage>,
+    do_parse!(alt!(end_of_message | eol) >> (Empty)));
+
+named!(message<&[u8], HWProtocolMessage>, alt!(terminated!(
+    alt!(
+          basic_message
+        | one_param_message
+        | cmd_message
+        | complex_message
+        | malformed_message
+        ), end_of_message
+    )
+    | empty_message
+    )
+);
 
 named!(pub extract_messages<&[u8], Vec<HWProtocolMessage> >, many0!(complete!(message)));
 
@@ -120,5 +131,8 @@
     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!(extract_messages(b"PING\n\nPING\n\nP"),   IResult::Done(&b"P"[..], vec![Ping, Ping]));
+    assert_eq!(extract_messages(b"PING\n\nPING\n\nP"), IResult::Done(&b"P"[..], vec![Ping, Ping]));
+    assert_eq!(extract_messages(b"SING\n\nPING\n\n"),  IResult::Done(&b""[..],  vec![Malformed, Ping]));
+    assert_eq!(extract_messages(b"\n\n\n\nPING\n\n"),  IResult::Done(&b""[..],  vec![Empty, Empty, Ping]));
+    assert_eq!(extract_messages(b"\n\n\nPING\n\n"),    IResult::Done(&b""[..],  vec![Empty, Empty, Ping]));
 }
--- a/gameServer2/src/server/client.rs	Sat Jan 14 00:46:52 2017 +0300
+++ b/gameServer2/src/server/client.rs	Sat Jan 14 22:30:09 2017 +0300
@@ -9,6 +9,7 @@
 use protocol::ProtocolDecoder;
 use protocol::messages;
 use protocol::messages::HWProtocolMessage::*;
+use log;
 
 pub struct HWClient {
     sock: TcpStream,
@@ -26,13 +27,11 @@
     }
 
     pub fn register(&mut self, poll: &Poll, token: Token) {
-        poll.register(&self.sock, token, Ready::readable(),
+        poll.register(&self.sock, token, Ready::all(),
                       PollOpt::edge())
             .ok().expect("could not register socket with event loop");
 
-        self.send_raw_msg(
-            format!("CONNECTED\nHedgewars server http://www.hedgewars.org/\n{}\n\n"
-                    , utils::PROTOCOL_VERSION).as_bytes());
+        self.send_msg(Connected(utils::PROTOCOL_VERSION));
     }
 
     fn send_raw_msg(&mut self, msg: &[u8]) {
@@ -51,14 +50,16 @@
 
     pub fn readable(&mut self, poll: &Poll) -> io::Result<()> {
         let v = self.decoder.read_from(&mut self.sock)?;
-        println!("Read {} bytes", v);
+        debug!("Read {} bytes", v);
         let mut response = Vec::new();
         {
             let msgs = self.decoder.extract_messages();
             for msg in msgs {
                 match msg {
                     Ping => response.push(Pong),
-                    _ => println!("Unknown message")
+                    Malformed => warn!("Malformed/unknown message"),
+                    Empty => warn!("Empty message"),
+                    _ => unimplemented!(),
                 }
             }
         }
@@ -73,4 +74,9 @@
         self.buf_out.write_to(&mut self.sock)?;
         Ok(())
     }
+
+    pub fn error(&mut self, poll: &Poll) -> io::Result<()> {
+        debug!("Client error");
+        Ok(())
+    }
 }
--- a/gameServer2/src/server/server.rs	Sat Jan 14 00:46:52 2017 +0300
+++ b/gameServer2/src/server/server.rs	Sat Jan 14 22:30:09 2017 +0300
@@ -31,7 +31,7 @@
 
     pub fn accept(&mut self, poll: &Poll) -> io::Result<()> {
         let (sock, addr) = self.listener.accept()?;
-        println!("Connected: {}", addr);
+        info!("Connected: {}", addr);
 
         let client = HWClient::new(sock);
         let token = self.clients.insert(client)
@@ -51,6 +51,11 @@
                            token: Token) -> io::Result<()> {
         self.clients[token].writable(poll)
     }
+
+    pub fn client_error(&mut self, poll: &Poll,
+                           token: Token) -> io::Result<()> {
+        self.clients[token].error(poll)
+    }
 }
 
 
--- a/gameServer2/src/utils.rs	Sat Jan 14 00:46:52 2017 +0300
+++ b/gameServer2/src/utils.rs	Sat Jan 14 22:30:09 2017 +0300
@@ -1,4 +1,4 @@
 use mio;
 
-pub const PROTOCOL_VERSION : i32 = 3;
+pub const PROTOCOL_VERSION : u32 = 3;
 pub const SERVER: mio::Token = mio::Token(1000000000 + 0);