Browse Source

Add RoomListResponse.

wip
Titouan Rigoudy 9 years ago
parent
commit
2925b81d6f
5 changed files with 143 additions and 22 deletions
  1. +47
    -0
      Cargo.lock
  2. +3
    -2
      Cargo.toml
  3. +5
    -2
      src/main.rs
  4. +63
    -2
      src/proto/server.rs
  5. +25
    -16
      src/server.rs

+ 47
- 0
Cargo.lock View File

@ -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"


+ 3
- 2
Cargo.toml View File

@ -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"

+ 5
- 2
src/main.rs View File

@ -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<TcpStream> {
}
fn main() {
env_logger::init().unwrap();
let host = config::SERVER_HOST;
let port = config::SERVER_PORT;
let stream = connect(host, port).unwrap();


+ 63
- 2
src/proto/server.rs View File

@ -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<Self> {
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<Self> {
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<Self> {
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<Vec<(String, u32)>> {
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)
}
}

+ 25
- 16
src/server.rs View File

@ -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<T: Handler>(&self, event_loop: &mut EventLoop<T>) {
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 {


Loading…
Cancel
Save