|
|
@ -13,78 +13,81 @@ const MAX_MESSAGE_SIZE: usize = MAX_PACKET_SIZE - U32_SIZE; |
|
|
|
|
|
|
|
|
const CODE_LOGIN: u32 = 1;
|
|
|
const CODE_LOGIN: u32 = 1;
|
|
|
|
|
|
|
|
|
/*=========*
|
|
|
|
|
|
* MESSAGE *
|
|
|
|
|
|
*=========*/
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
|
|
|
pub enum MessageCode {
|
|
|
|
|
|
Login,
|
|
|
|
|
|
Unknown(u32),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl MessageCode {
|
|
|
|
|
|
fn to_u32(&self) -> u32 {
|
|
|
|
|
|
match *self {
|
|
|
|
|
|
MessageCode::Login => CODE_LOGIN,
|
|
|
|
|
|
MessageCode::Unknown(code) => code,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn from_u32(code: u32) -> MessageCode {
|
|
|
|
|
|
match code {
|
|
|
|
|
|
CODE_LOGIN => MessageCode::Login,
|
|
|
|
|
|
_ => MessageCode::Unknown(code),
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
#[derive(Debug)]
|
|
|
pub struct Message {
|
|
|
|
|
|
code: MessageCode,
|
|
|
|
|
|
|
|
|
pub struct Packet {
|
|
|
|
|
|
cursor: usize,
|
|
|
bytes: Vec<u8>,
|
|
|
bytes: Vec<u8>,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
impl Message {
|
|
|
|
|
|
pub fn new(code: MessageCode) -> Message {
|
|
|
|
|
|
|
|
|
impl Packet {
|
|
|
|
|
|
pub fn new(code: u32) -> Self {
|
|
|
let mut bytes = Vec::new();
|
|
|
let mut bytes = Vec::new();
|
|
|
bytes.write_u32::<LittleEndian>(0).unwrap();
|
|
|
bytes.write_u32::<LittleEndian>(0).unwrap();
|
|
|
bytes.write_u32::<LittleEndian>(code.to_u32()).unwrap();
|
|
|
|
|
|
Message {
|
|
|
|
|
|
code: code,
|
|
|
|
|
|
|
|
|
bytes.write_u32::<LittleEndian>(code).unwrap();
|
|
|
|
|
|
Packet {
|
|
|
|
|
|
cursor: 2*U32_SIZE,
|
|
|
bytes: bytes,
|
|
|
bytes: bytes,
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
fn from_raw_parts(bytes: Vec<u8>) -> Message {
|
|
|
|
|
|
let code_u32 = LittleEndian::read_u32(&bytes[U32_SIZE..2*U32_SIZE]);
|
|
|
|
|
|
Message {
|
|
|
|
|
|
code: MessageCode::from_u32(code_u32),
|
|
|
|
|
|
|
|
|
fn from_raw_parts(bytes: Vec<u8>) -> Self {
|
|
|
|
|
|
let size = LittleEndian::read_u32(&bytes[..U32_SIZE]) as usize;
|
|
|
|
|
|
assert!(size + U32_SIZE == bytes.len());
|
|
|
|
|
|
Packet {
|
|
|
|
|
|
cursor: U32_SIZE,
|
|
|
bytes: bytes,
|
|
|
bytes: bytes,
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
pub fn code(&self) -> MessageCode {
|
|
|
|
|
|
self.code
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
// Writing convenience
|
|
|
|
|
|
|
|
|
pub fn write_str(&mut self, string: &str) -> io::Result<usize> {
|
|
|
pub fn write_str(&mut self, string: &str) -> io::Result<usize> {
|
|
|
try!(self.write_u32(string.len() as u32));
|
|
|
|
|
|
let n = try!(self.bytes.write(string.as_bytes()));
|
|
|
|
|
|
|
|
|
try!(self.write_uint(string.len() as u32));
|
|
|
|
|
|
let n = try!(self.write(string.as_bytes()));
|
|
|
Ok(n + U32_SIZE)
|
|
|
Ok(n + U32_SIZE)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
pub fn write_u32(&mut self, n: u32) -> io::Result<usize> {
|
|
|
|
|
|
match self.bytes.write_u32::<LittleEndian>(n) {
|
|
|
|
|
|
|
|
|
pub fn write_uint(&mut self, n: u32) -> io::Result<usize> {
|
|
|
|
|
|
match self.write_u32::<LittleEndian>(n) {
|
|
|
Ok(()) => Ok(U32_SIZE),
|
|
|
Ok(()) => Ok(U32_SIZE),
|
|
|
Err(e) => Err(io::Error::from(e))
|
|
|
Err(e) => Err(io::Error::from(e))
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
pub fn write_bool(&mut self, b: bool) -> io::Result<usize> {
|
|
|
pub fn write_bool(&mut self, b: bool) -> io::Result<usize> {
|
|
|
self.bytes.write(&[b as u8])
|
|
|
|
|
|
|
|
|
self.write(&[b as u8])
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Reading convenience
|
|
|
|
|
|
|
|
|
|
|
|
pub fn read_uint(&mut self) -> io::Result<u32> {
|
|
|
|
|
|
self.read_u32::<LittleEndian>().map_err(io::Error::from)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn read_str(&mut self) -> io::Result<String> {
|
|
|
|
|
|
let len = try!(self.read_uint()) as usize;
|
|
|
|
|
|
let mut buffer = vec![0; len];
|
|
|
|
|
|
try!(self.read(&mut buffer));
|
|
|
|
|
|
let result = String::from_utf8(buffer);
|
|
|
|
|
|
match result {
|
|
|
|
|
|
Ok(string) => Ok(string),
|
|
|
|
|
|
Err(e) => Err(io::Error::new(io::ErrorKind::Other, e.to_string())),
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn read_bool(&mut self) -> io::Result<bool> {
|
|
|
|
|
|
let mut buffer = vec![0; 1];
|
|
|
|
|
|
try!(self.read(&mut buffer));
|
|
|
|
|
|
match buffer[0] {
|
|
|
|
|
|
0 => Ok(false),
|
|
|
|
|
|
1 => Ok(true),
|
|
|
|
|
|
n => Err(io::Error::new(io::ErrorKind::InvalidInput,
|
|
|
|
|
|
format!("{} is not a boolean", n)))
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn finalize(mut self) -> Vec<u8> {
|
|
|
pub fn finalize(mut self) -> Vec<u8> {
|
|
|
let bytes_len = (self.bytes.len() - U32_SIZE) as u32;
|
|
|
let bytes_len = (self.bytes.len() - U32_SIZE) as u32;
|
|
|
{
|
|
|
{
|
|
|
@ -95,7 +98,7 @@ impl Message { |
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
impl io::Write for Message {
|
|
|
|
|
|
|
|
|
impl io::Write for Packet {
|
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
|
|
self.bytes.write(buf)
|
|
|
self.bytes.write(buf)
|
|
|
}
|
|
|
}
|
|
|
@ -105,19 +108,32 @@ impl io::Write for Message { |
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl io::Read for Packet {
|
|
|
|
|
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
|
|
|
|
|
let mut slice = &self.bytes[self.cursor..];
|
|
|
|
|
|
let result = slice.read(buf);
|
|
|
|
|
|
match result {
|
|
|
|
|
|
Ok(num_bytes_read) => self.cursor += num_bytes_read,
|
|
|
|
|
|
Err(_) => ()
|
|
|
|
|
|
}
|
|
|
|
|
|
result
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*======*
|
|
|
/*======*
|
|
|
* PEER *
|
|
|
* PEER *
|
|
|
*======*/
|
|
|
*======*/
|
|
|
|
|
|
|
|
|
pub trait Peer {
|
|
|
pub trait Peer {
|
|
|
fn read_message(&mut self) -> Option<Message>;
|
|
|
|
|
|
fn write_message(&mut self, message: Message);
|
|
|
|
|
|
|
|
|
fn read_packet(&mut self) -> Option<Packet>;
|
|
|
|
|
|
fn write_packet(&mut self, packet: Packet);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
enum State {
|
|
|
enum State {
|
|
|
ReadingLength,
|
|
|
ReadingLength,
|
|
|
ReadingMessage,
|
|
|
|
|
|
|
|
|
ReadingPacket,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
#[derive(Debug)]
|
|
|
@ -161,25 +177,25 @@ impl<T: Peer> Connection<T> { |
|
|
if message_len > MAX_MESSAGE_SIZE {
|
|
|
if message_len > MAX_MESSAGE_SIZE {
|
|
|
unimplemented!();
|
|
|
unimplemented!();
|
|
|
};
|
|
|
};
|
|
|
self.state = State::ReadingMessage;
|
|
|
|
|
|
|
|
|
self.state = State::ReadingPacket;
|
|
|
self.num_bytes_left = message_len;
|
|
|
self.num_bytes_left = message_len;
|
|
|
self.buffer.extend(repeat(0).take(message_len));
|
|
|
self.buffer.extend(repeat(0).take(message_len));
|
|
|
},
|
|
|
},
|
|
|
|
|
|
|
|
|
State::ReadingMessage => {
|
|
|
|
|
|
|
|
|
State::ReadingPacket => {
|
|
|
self.state = State::ReadingLength;
|
|
|
self.state = State::ReadingLength;
|
|
|
self.num_bytes_left = U32_SIZE;
|
|
|
self.num_bytes_left = U32_SIZE;
|
|
|
let new_buffer = vec![0;U32_SIZE];
|
|
|
let new_buffer = vec![0;U32_SIZE];
|
|
|
let old_buffer = mem::replace(&mut self.buffer, new_buffer);
|
|
|
let old_buffer = mem::replace(&mut self.buffer, new_buffer);
|
|
|
self.peer.write_message(Message::from_raw_parts(old_buffer));
|
|
|
|
|
|
|
|
|
self.peer.write_packet(Packet::from_raw_parts(old_buffer));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
pub fn ready_to_write(&mut self, stream: &mut TcpStream) {
|
|
|
pub fn ready_to_write(&mut self, stream: &mut TcpStream) {
|
|
|
match self.peer.read_message() {
|
|
|
|
|
|
Some(message) => {
|
|
|
|
|
|
stream.write(&message.finalize()).unwrap();
|
|
|
|
|
|
|
|
|
match self.peer.read_packet() {
|
|
|
|
|
|
Some(packet) => {
|
|
|
|
|
|
stream.write(&packet.finalize()).unwrap();
|
|
|
()
|
|
|
()
|
|
|
},
|
|
|
},
|
|
|
None => (),
|
|
|
None => (),
|