From 2925b81d6fedf68530a41b84d0fe89d8b11a0948 Mon Sep 17 00:00:00 2001 From: Titouan Rigoudy Date: Fri, 19 Feb 2016 14:36:18 +0100 Subject: [PATCH] Add RoomListResponse. --- Cargo.lock | 47 ++++++++++++++++++++++++++++++++ Cargo.toml | 5 ++-- src/main.rs | 7 +++-- src/proto/server.rs | 65 +++++++++++++++++++++++++++++++++++++++++++-- src/server.rs | 41 +++++++++++++++++----------- 5 files changed, 143 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ed4f92..cbf60bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,6 +3,7 @@ name = "solstice" version = "0.1.0" dependencies = [ "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", @@ -17,6 +18,14 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "aho-corasick" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bitflags" version = "0.3.3" @@ -37,6 +46,15 @@ name = "cfg-if" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "env_logger" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "gcc" version = "0.3.22" @@ -73,6 +91,14 @@ dependencies = [ "libc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "memchr" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mio" version = "0.5.0" @@ -132,6 +158,22 @@ dependencies = [ "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "regex" +version = "0.1.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rust-crypto" version = "0.2.34" @@ -164,6 +206,11 @@ dependencies = [ "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "utf8-ranges" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "winapi" version = "0.2.5" diff --git a/Cargo.toml b/Cargo.toml index 993320b..2be306a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,8 @@ version = "0.1.0" authors = ["letitz"] [dependencies] -mio = "^0.5" -log = "^0.3.5" byteorder = "^0.4.2" +env_logger = "^0.3.2" +log = "^0.3.5" +mio = "^0.5" rust-crypto = "^0.2.34" diff --git a/src/main.rs b/src/main.rs index c8f277f..b1d9ca1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,10 +2,11 @@ mod server; mod proto; mod config; -#[macro_use] extern crate log; -extern crate mio; extern crate byteorder; extern crate crypto; +#[macro_use] extern crate log; +extern crate env_logger; +extern crate mio; use std::io; use std::net::ToSocketAddrs; @@ -27,6 +28,8 @@ fn connect(hostname: &str, port: u16) -> io::Result { } fn main() { + env_logger::init().unwrap(); + let host = config::SERVER_HOST; let port = config::SERVER_PORT; let stream = connect(host, port).unwrap(); diff --git a/src/proto/server.rs b/src/proto/server.rs index 81043c2..87f33cd 100644 --- a/src/proto/server.rs +++ b/src/proto/server.rs @@ -37,6 +37,8 @@ impl ServerRequest { pub enum ServerResponse { LoginResponse(LoginResponse), + RoomListResponse(RoomListResponse), + UnknownResponse(u32, Packet), } @@ -44,7 +46,12 @@ impl ServerResponse { pub fn from_packet(mut packet: Packet) -> io::Result { let resp = match try!(packet.read_uint()) { CODE_LOGIN => ServerResponse::LoginResponse( - try!(LoginResponse::from_packet(packet))), + try!(LoginResponse::from_packet(packet)) + ), + + CODE_ROOM_LIST => ServerResponse::RoomListResponse( + try!(RoomListResponse::from_packet(packet)) + ), code => ServerResponse::UnknownResponse(code, packet), }; @@ -115,7 +122,7 @@ impl LoginResponse { pub fn from_packet(mut packet: Packet) -> io::Result { let ok = try!(packet.read_bool()); let resp = if ok { - let motd = try!(packet.read_str()).to_string(); + let motd = try!(packet.read_str()); let ip = net::Ipv4Addr::from(try!(packet.read_uint())); LoginResponse::LoginOk { motd: motd, @@ -148,3 +155,57 @@ impl WriteToPacket for RoomListRequest { Ok(()) } } + +pub struct RoomListResponse { + pub rooms: Vec<(String, u32)>, + pub owned_private_rooms: Vec<(String, u32)>, + pub other_private_rooms: Vec<(String, u32)>, +} + +impl RoomListResponse { + fn from_packet(mut packet: Packet) -> io::Result { + let rooms = try!(Self::read_rooms(&mut packet)); + + let (owned_private_rooms, other_private_rooms) = + match Self::read_rooms(&mut packet) { + + Err(e) => (Vec::new(), Vec::new()), + + Ok(owned_private_rooms) => match Self::read_rooms(&mut packet) { + Err(e) => (owned_private_rooms, Vec::new()), + + Ok(other_private_rooms) => + (owned_private_rooms, other_private_rooms) + }, + }; + + Ok(RoomListResponse { + rooms: rooms, + owned_private_rooms: owned_private_rooms, + other_private_rooms: other_private_rooms, + }) + } + + fn read_rooms(packet: &mut Packet) -> io::Result> { + let mut rooms = Vec::new(); + + let num_rooms = try!(packet.read_uint()) as usize; + for i in 0..num_rooms { + let room_name = try!(packet.read_str()); + rooms.push((room_name, 0)); + } + + let num_user_counts = try!(packet.read_uint()) as usize; + for i in 0..num_user_counts { + let user_count = try!(packet.read_uint()); + rooms[i].1 = user_count; + } + + if num_rooms != num_user_counts { + warn!("Numbers of rooms and user counts do not match: {} != {}", + num_rooms, num_user_counts); + } + + Ok(rooms) + } +} diff --git a/src/server.rs b/src/server.rs index b8cc454..5adc230 100644 --- a/src/server.rs +++ b/src/server.rs @@ -7,12 +7,7 @@ use mio::tcp::TcpStream; use config; use proto::{Packet, PacketStream}; -use proto::server::{ - LoginRequest, - LoginResponse, - ServerRequest, - ServerResponse, -}; +use proto::server::*; #[derive(Debug, Clone, Copy)] enum State { @@ -66,14 +61,8 @@ impl ServerConnection { pub fn server_readable(&mut self) { match self.server_stream.try_read() { Ok(Some(packet)) => { - match ServerResponse::from_packet(packet).unwrap() { - ServerResponse::LoginResponse(login) => { - self.handle_login(login); - }, - ServerResponse::UnknownResponse(code, packet) => { - println!("Unknown packet code {}", code); - }, - } + let response = ServerResponse::from_packet(packet).unwrap(); + self.handle_server_response(response) }, Ok(None) => (), @@ -82,12 +71,25 @@ impl ServerConnection { } } + fn handle_server_response(&mut self, response: ServerResponse) { + match response { + ServerResponse::LoginResponse(login_response) => + self.handle_login_response(login_response), + + ServerResponse::RoomListResponse(room_list_response) => + self.handle_room_list_response(room_list_response), + + ServerResponse::UnknownResponse(code, packet) => + println!("Unknown packet code {}", code), + } + } + pub fn register_all(&self, event_loop: &mut EventLoop) { self.server_stream.register(event_loop, self.server_token, self.server_interest, PollOpt::edge()); } - fn handle_login(&mut self, login: LoginResponse) -> io::Result<()> { + fn handle_login_response(&mut self, login: LoginResponse) { match self.state { State::LoggingIn => { match login { @@ -117,12 +119,19 @@ impl ServerConnection { println!("Reason: {}", reason); } } - Ok(()) }, _ => unimplemented!(), } } + + fn handle_room_list_response(&mut self, + room_list_response: RoomListResponse) { + info!("Received room list"); + for (ref room_name, num_members) in room_list_response.rooms { + info!("Room \"{}\" has {} members", room_name, num_members); + } + } } impl Handler for ServerConnection {