stevenarella/src/protocol/mod.rs

967 lines
28 KiB
Rust
Raw Normal View History

2016-03-16 14:25:35 -04:00
// Copyright 2016 Matthew Collins
2015-09-17 11:21:56 -04:00
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2015-09-07 16:11:00 -04:00
#![allow(dead_code)]
2015-09-17 11:04:25 -04:00
use openssl;
use serde_json;
use hyper;
2015-09-07 16:11:00 -04:00
2015-09-10 06:49:41 -04:00
pub mod mojang;
2015-09-12 15:31:26 -04:00
use nbt;
2015-09-10 06:49:41 -04:00
use format;
2015-09-12 15:31:26 -04:00
use std::fmt;
2015-09-08 07:57:24 -04:00
use std::default;
2015-09-07 16:11:00 -04:00
use std::net::TcpStream;
use std::io;
use std::io::{Write, Read};
use std::convert;
2015-09-17 11:04:25 -04:00
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
use flate2::read::{ZlibDecoder, ZlibEncoder};
use flate2;
2015-09-25 09:00:49 -04:00
use time;
2016-03-25 16:56:45 -04:00
pub const SUPPORTED_PROTOCOL: i32 = 107;
2015-09-07 16:11:00 -04:00
2015-09-07 16:11:00 -04:00
/// Helper macro for defining packets
#[macro_export]
macro_rules! state_packets {
($($state:ident $stateName:ident {
$($dir:ident $dirName:ident {
2015-09-12 15:31:26 -04:00
$(
$name:ident {
2015-09-10 06:49:41 -04:00
$($field:ident: $field_type:ty = $(when ($cond:expr))*, )+
})*
2015-09-07 16:11:00 -04:00
})+
})+) => {
use protocol::*;
use std::io;
2015-09-12 15:31:26 -04:00
#[derive(Debug)]
2015-09-07 16:11:00 -04:00
pub enum Packet {
$(
$(
$(
$name($state::$dir::$name),
)*
)+
)+
}
$(
pub mod $state {
2015-09-07 16:11:00 -04:00
$(
pub mod $dir {
2015-09-10 06:49:41 -04:00
#![allow(unused_imports)]
2015-09-07 16:11:00 -04:00
use protocol::*;
use std::io;
2015-09-10 06:49:41 -04:00
use format;
2015-09-12 15:31:26 -04:00
use nbt;
use types;
use item;
2015-09-07 16:11:00 -04:00
pub mod internal_ids {
create_ids!(i32, $($name),*);
}
2015-09-07 16:11:00 -04:00
$(
2015-09-12 15:31:26 -04:00
#[derive(Default, Debug)]
2015-09-07 16:11:00 -04:00
pub struct $name {
$(pub $field: $field_type),+,
}
impl PacketType for $name {
fn packet_id(&self) -> i32 { internal_ids::$name }
2015-09-07 16:11:00 -04:00
2015-09-12 15:31:26 -04:00
fn write(self, buf: &mut io::Write) -> Result<(), io::Error> {
2015-09-07 16:11:00 -04:00
$(
2015-09-10 06:49:41 -04:00
if true $(&& ($cond(&self)))* {
try!(self.$field.write_to(buf));
}
2015-09-07 16:11:00 -04:00
)+
Result::Ok(())
}
}
)*
}
)+
}
)+
/// Returns the packet for the given state, direction and id after parsing the fields
/// from the buffer.
2015-09-12 15:31:26 -04:00
pub fn packet_by_id(state: State, dir: Direction, id: i32, mut buf: &mut io::Read) -> Result<Option<Packet>, io::Error> {
2015-09-07 16:11:00 -04:00
match state {
$(
State::$stateName => {
match dir {
$(
Direction::$dirName => {
match id {
$(
self::$state::$dir::internal_ids::$name => {
2015-09-10 06:49:41 -04:00
use self::$state::$dir::$name;
let mut packet : $name = $name::default();
2015-09-08 07:57:24 -04:00
$(
2015-09-10 06:49:41 -04:00
if true $(&& ($cond(&packet)))* {
packet.$field = try!(Serializable::read_from(&mut buf));
}
2015-09-08 07:57:24 -04:00
)+
Result::Ok(Option::Some(Packet::$name(packet)))
},
2015-09-07 16:11:00 -04:00
)*
2015-09-08 07:57:24 -04:00
_ => Result::Ok(Option::None)
2015-09-07 16:11:00 -04:00
}
}
)+
}
}
)+
}
}
}
}
pub mod packet;
2015-09-25 09:00:49 -04:00
pub trait Serializable: Sized {
2015-09-08 07:57:24 -04:00
fn read_from(buf: &mut io::Read) -> Result<Self, io::Error>;
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error>;
}
2015-09-12 15:31:26 -04:00
impl Serializable for Vec<u8> {
2015-10-07 14:36:59 -04:00
fn read_from(buf: &mut io::Read) -> Result<Vec<u8>, io::Error> {
2015-09-12 15:31:26 -04:00
let mut v = Vec::new();
try!(buf.read_to_end(&mut v));
Ok(v)
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
buf.write_all(&self[..])
}
}
impl Serializable for Option<nbt::NamedTag>{
fn read_from(buf: &mut io::Read) -> Result<Option<nbt::NamedTag>, io::Error> {
let ty = try!(buf.read_u8());
if ty == 0 {
Result::Ok(None)
} else {
let name = try!(nbt::read_string(buf));
let tag = try!(nbt::Tag::read_from(buf));
Result::Ok(Some(nbt::NamedTag(name, tag)))
}
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
match *self {
Some(ref val) => {
try!(buf.write_u8(10));
try!(nbt::write_string(buf, &val.0));
try!(val.1.write_to(buf));
}
None => try!(buf.write_u8(0)),
}
Result::Ok(())
}
}
2015-09-10 06:49:41 -04:00
impl <T> Serializable for Option<T> where T : Serializable {
fn read_from(buf: &mut io::Read) -> Result<Option<T>, io::Error> {
Result::Ok(Some(try!(T::read_from(buf))))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
if self.is_some() {
try!(self.as_ref().unwrap().write_to(buf));
}
Result::Ok(())
}
}
2015-09-08 07:57:24 -04:00
impl Serializable for String {
fn read_from(buf: &mut io::Read) -> Result<String, io::Error> {
let len = try!(VarInt::read_from(buf)).0;
let mut ret = String::new();
try!(buf.take(len as u64).read_to_string(&mut ret));
Result::Ok(ret)
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
let bytes = self.as_bytes();
try!(VarInt(bytes.len() as i32).write_to(buf));
try!(buf.write_all(bytes));
Result::Ok(())
}
}
2015-09-10 06:49:41 -04:00
impl Serializable for format::Component {
fn read_from(buf: &mut io::Read) -> Result<Self, io::Error> {
let len = try!(VarInt::read_from(buf)).0;
let mut ret = String::new();
try!(buf.take(len as u64).read_to_string(&mut ret));
2015-10-07 14:36:59 -04:00
let val: serde_json::Value = serde_json::from_str(&ret[..]).unwrap();
2015-09-10 06:49:41 -04:00
Result::Ok(Self::from_value(&val))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
let val = serde_json::to_string(&self.to_value()).unwrap();
let bytes = val.as_bytes();
try!(VarInt(bytes.len() as i32).write_to(buf));
try!(buf.write_all(bytes));
Result::Ok(())
}
}
impl Serializable for () {
fn read_from(_: &mut io::Read) -> Result<(), io::Error> {
Result::Ok(())
}
fn write_to(&self, _: &mut io::Write) -> Result<(), io::Error> {
Result::Ok(())
}
}
impl Serializable for bool {
fn read_from(buf: &mut io::Read) -> Result<bool, io::Error> {
Result::Ok(try!(buf.read_u8()) != 0)
2015-09-08 07:57:24 -04:00
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
2015-10-07 14:36:59 -04:00
try!(buf.write_u8(if *self {
1
} else {
0
}));
2015-09-08 07:57:24 -04:00
Result::Ok(())
}
}
2015-09-12 15:31:26 -04:00
impl Serializable for i8 {
fn read_from(buf: &mut io::Read) -> Result<i8, io::Error> {
Result::Ok(try!(buf.read_i8()))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_i8(*self));
Result::Ok(())
}
}
2015-09-10 06:49:41 -04:00
impl Serializable for i16 {
fn read_from(buf: &mut io::Read) -> Result<i16, io::Error> {
Result::Ok(try!(buf.read_i16::<BigEndian>()))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_i16::<BigEndian>(*self));
Result::Ok(())
}
2015-09-08 07:57:24 -04:00
}
impl Serializable for i32 {
fn read_from(buf: &mut io::Read) -> Result<i32, io::Error> {
Result::Ok(try!(buf.read_i32::<BigEndian>()))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_i32::<BigEndian>(*self));
Result::Ok(())
}
}
impl Serializable for i64 {
fn read_from(buf: &mut io::Read) -> Result<i64, io::Error> {
Result::Ok(try!(buf.read_i64::<BigEndian>()))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_i64::<BigEndian>(*self));
Result::Ok(())
}
}
2015-09-10 06:49:41 -04:00
impl Serializable for u8 {
fn read_from(buf: &mut io::Read) -> Result<u8, io::Error> {
Result::Ok(try!(buf.read_u8()))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_u8(*self));
Result::Ok(())
}
}
2015-09-08 07:57:24 -04:00
impl Serializable for u16 {
fn read_from(buf: &mut io::Read) -> Result<u16, io::Error> {
Result::Ok(try!(buf.read_u16::<BigEndian>()))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_u16::<BigEndian>(*self));
Result::Ok(())
}
}
2016-03-21 10:05:13 -04:00
impl Serializable for u64 {
fn read_from(buf: &mut io::Read) -> Result<u64, io::Error> {
Result::Ok(try!(buf.read_u64::<BigEndian>()))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_u64::<BigEndian>(*self));
Result::Ok(())
}
}
2015-09-12 15:31:26 -04:00
impl Serializable for f32 {
fn read_from(buf: &mut io::Read) -> Result<f32, io::Error> {
Result::Ok(try!(buf.read_f32::<BigEndian>()))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_f32::<BigEndian>(*self));
Result::Ok(())
}
}
impl Serializable for f64 {
fn read_from(buf: &mut io::Read) -> Result<f64, io::Error> {
Result::Ok(try!(buf.read_f64::<BigEndian>()))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_f64::<BigEndian>(*self));
Result::Ok(())
}
}
#[derive(Debug)]
pub struct UUID(u64, u64);
impl Default for UUID {
2015-10-07 14:36:59 -04:00
fn default() -> Self {
UUID(0, 0)
}
2015-09-12 15:31:26 -04:00
}
impl Serializable for UUID {
fn read_from(buf: &mut io::Read) -> Result<UUID, io::Error> {
2015-10-07 14:36:59 -04:00
Result::Ok(UUID(try!(buf.read_u64::<BigEndian>()),
try!(buf.read_u64::<BigEndian>())))
2015-09-12 15:31:26 -04:00
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_u64::<BigEndian>(self.0));
try!(buf.write_u64::<BigEndian>(self.1));
Result::Ok(())
}
}
pub trait Lengthable : Serializable + Copy + Default {
fn into(self) -> usize;
fn from(usize) -> Self;
}
2015-09-10 06:49:41 -04:00
pub struct LenPrefixed<L: Lengthable, V> {
len: L,
2015-10-07 14:36:59 -04:00
pub data: Vec<V>,
2015-09-10 06:49:41 -04:00
}
impl <L: Lengthable, V: Default> LenPrefixed<L, V> {
2016-03-21 06:55:31 -04:00
pub fn new(data: Vec<V>) -> LenPrefixed<L, V> {
2015-09-29 15:09:36 -04:00
LenPrefixed {
2015-09-10 06:49:41 -04:00
len: Default::default(),
data: data,
}
}
}
impl <L: Lengthable, V: Serializable> Serializable for LenPrefixed<L, V> {
fn read_from(buf: &mut io::Read) -> Result<LenPrefixed<L, V>, io::Error> {
2015-10-07 14:36:59 -04:00
let len_data: L = try!(Serializable::read_from(buf));
let len: usize = len_data.into();
let mut data: Vec<V> = Vec::with_capacity(len);
for _ in 0..len {
2015-09-10 06:49:41 -04:00
data.push(try!(Serializable::read_from(buf)));
}
2015-10-07 14:36:59 -04:00
Result::Ok(LenPrefixed {
len: len_data,
data: data,
})
2015-09-10 06:49:41 -04:00
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
2015-10-07 14:36:59 -04:00
let len_data: L = L::from(self.data.len());
2015-09-10 06:49:41 -04:00
try!(len_data.write_to(buf));
2015-09-29 15:09:36 -04:00
let data = &self.data;
2015-09-10 06:49:41 -04:00
for val in data {
try!(val.write_to(buf));
}
Result::Ok(())
}
}
2015-09-12 15:31:26 -04:00
2015-09-10 06:49:41 -04:00
impl <L: Lengthable, V: Default> Default for LenPrefixed<L, V> {
fn default() -> Self {
LenPrefixed {
len: default::Default::default(),
2015-10-07 14:36:59 -04:00
data: default::Default::default(),
2015-09-10 06:49:41 -04:00
}
}
}
2015-09-12 15:31:26 -04:00
impl <L: Lengthable, V: fmt::Debug> fmt::Debug for LenPrefixed<L, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.data.fmt(f)
}
}
// Optimization
pub struct LenPrefixedBytes<L: Lengthable> {
len: L,
2015-10-07 14:36:59 -04:00
pub data: Vec<u8>,
2015-09-12 15:31:26 -04:00
}
impl <L: Lengthable> LenPrefixedBytes<L> {
2016-03-21 06:55:31 -04:00
pub fn new(data: Vec<u8>) -> LenPrefixedBytes<L> {
2015-09-29 15:09:36 -04:00
LenPrefixedBytes {
2015-09-12 15:31:26 -04:00
len: Default::default(),
data: data,
}
}
}
impl <L: Lengthable> Serializable for LenPrefixedBytes<L> {
fn read_from(buf: &mut io::Read) -> Result<LenPrefixedBytes<L>, io::Error> {
2015-10-07 14:36:59 -04:00
let len_data: L = try!(Serializable::read_from(buf));
let len: usize = len_data.into();
let mut data: Vec<u8> = Vec::with_capacity(len);
2015-09-12 15:31:26 -04:00
try!(buf.take(len as u64).read_to_end(&mut data));
2015-10-07 14:36:59 -04:00
Result::Ok(LenPrefixedBytes {
len: len_data,
data: data,
})
2015-09-12 15:31:26 -04:00
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
2015-10-07 14:36:59 -04:00
let len_data: L = L::from(self.data.len());
2015-09-12 15:31:26 -04:00
try!(len_data.write_to(buf));
try!(buf.write_all(&self.data[..]));
Result::Ok(())
}
}
impl <L: Lengthable> Default for LenPrefixedBytes<L> {
fn default() -> Self {
LenPrefixedBytes {
len: default::Default::default(),
2015-10-07 14:36:59 -04:00
data: default::Default::default(),
2015-09-12 15:31:26 -04:00
}
}
}
impl <L: Lengthable> fmt::Debug for LenPrefixedBytes<L> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.data.fmt(f)
}
}
impl Lengthable for i16 {
fn into(self) -> usize {
self as usize
}
fn from(u: usize) -> i16 {
u as i16
}
}
impl Lengthable for i32 {
fn into(self) -> usize {
self as usize
}
fn from(u: usize) -> i32 {
u as i32
}
}
2015-09-07 16:11:00 -04:00
/// VarInt have a variable size (between 1 and 5 bytes) when encoded based
/// on the size of the number
2015-09-10 06:49:41 -04:00
#[derive(Clone, Copy)]
2015-09-12 15:31:26 -04:00
pub struct VarInt(pub i32);
2015-09-08 07:57:24 -04:00
2015-09-12 15:31:26 -04:00
impl Lengthable for VarInt {
fn into(self) -> usize {
self.0 as usize
}
fn from(u: usize) -> VarInt {
VarInt(u as i32)
}
}
2015-09-10 06:49:41 -04:00
2015-09-08 07:57:24 -04:00
impl Serializable for VarInt {
/// Decodes a VarInt from the Reader
fn read_from(buf: &mut io::Read) -> Result<VarInt, io::Error> {
const PART : u32 = 0x7F;
let mut size = 0;
let mut val = 0u32;
loop {
let b = try!(buf.read_u8()) as u32;
val |= (b & PART) << (size * 7);
2015-10-07 14:36:59 -04:00
size += 1;
2015-09-08 07:57:24 -04:00
if size > 5 {
2015-10-07 14:36:59 -04:00
return Result::Err(io::Error::new(io::ErrorKind::InvalidInput,
Error::Err("VarInt too big".to_owned())))
2015-09-08 07:57:24 -04:00
}
if (b & 0x80) == 0 {
break
}
2015-09-07 16:11:00 -04:00
}
2015-09-08 07:57:24 -04:00
Result::Ok(VarInt(val as i32))
2015-09-07 16:11:00 -04:00
}
2015-09-08 07:57:24 -04:00
/// Encodes a VarInt into the Writer
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
const PART : u32 = 0x7F;
let mut val = self.0 as u32;
loop {
if (val & !PART) == 0 {
try!(buf.write_u8(val as u8));
return Result::Ok(());
}
try!(buf.write_u8(((val & PART) | 0x80) as u8));
val >>= 7;
2015-09-07 16:11:00 -04:00
}
}
2015-09-08 07:57:24 -04:00
}
2015-09-07 16:11:00 -04:00
2015-09-08 07:57:24 -04:00
impl default::Default for VarInt {
2015-10-07 14:36:59 -04:00
fn default() -> VarInt {
VarInt(0)
}
2015-09-07 16:11:00 -04:00
}
2015-09-12 15:31:26 -04:00
impl fmt::Debug for VarInt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
/// VarLong have a variable size (between 1 and 10 bytes) when encoded based
/// on the size of the number
#[derive(Clone, Copy)]
pub struct VarLong(pub i64);
impl Lengthable for VarLong {
2015-09-10 06:49:41 -04:00
fn into(self) -> usize {
self.0 as usize
}
2015-09-12 15:31:26 -04:00
fn from(u: usize) -> VarLong {
VarLong(u as i64)
}
2015-09-10 06:49:41 -04:00
}
2015-09-12 15:31:26 -04:00
impl Serializable for VarLong {
/// Decodes a VarLong from the Reader
fn read_from(buf: &mut io::Read) -> Result<VarLong, io::Error> {
const PART : u64 = 0x7F;
let mut size = 0;
let mut val = 0u64;
loop {
let b = try!(buf.read_u8()) as u64;
val |= (b & PART) << (size * 7);
2015-10-07 14:36:59 -04:00
size += 1;
2015-09-12 15:31:26 -04:00
if size > 10 {
2015-10-07 14:36:59 -04:00
return Result::Err(io::Error::new(io::ErrorKind::InvalidInput,
Error::Err("VarLong too big".to_owned())))
2015-09-12 15:31:26 -04:00
}
if (b & 0x80) == 0 {
break
}
}
Result::Ok(VarLong(val as i64))
}
/// Encodes a VarLong into the Writer
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
const PART : u64 = 0x7F;
let mut val = self.0 as u64;
loop {
if (val & !PART) == 0 {
try!(buf.write_u8(val as u8));
return Result::Ok(());
}
try!(buf.write_u8(((val & PART) | 0x80) as u8));
val >>= 7;
}
}
}
impl default::Default for VarLong {
2015-10-07 14:36:59 -04:00
fn default() -> VarLong {
VarLong(0)
}
2015-09-12 15:31:26 -04:00
}
impl fmt::Debug for VarLong {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
2015-09-10 06:49:41 -04:00
}
}
2015-09-07 16:11:00 -04:00
/// Direction is used to define whether packets are going to the
/// server or the client.
2015-09-10 06:49:41 -04:00
#[derive(Clone, Copy)]
2015-09-07 16:11:00 -04:00
pub enum Direction {
Serverbound,
2015-10-07 14:36:59 -04:00
Clientbound,
2015-09-07 16:11:00 -04:00
}
/// The protocol has multiple 'sub-protocols' or states which control which
/// packet an id points to.
#[derive(Clone, Copy)]
pub enum State {
Handshaking,
Play,
Status,
2015-10-07 14:36:59 -04:00
Login,
2015-09-07 16:11:00 -04:00
}
/// Return for any protocol related error.
#[derive(Debug)]
pub enum Error {
Err(String),
2016-03-20 08:04:02 -04:00
Disconnect(format::Component),
2015-09-07 16:11:00 -04:00
IOError(io::Error),
Json(serde_json::Error),
Hyper(hyper::Error),
2015-09-07 16:11:00 -04:00
}
impl convert::From<io::Error> for Error {
2015-10-07 14:36:59 -04:00
fn from(e: io::Error) -> Error {
2015-09-07 16:11:00 -04:00
Error::IOError(e)
}
}
impl convert::From<serde_json::Error> for Error {
fn from(e: serde_json::Error) -> Error {
Error::Json(e)
}
}
impl convert::From<hyper::Error> for Error {
fn from(e: hyper::Error) -> Error {
Error::Hyper(e)
}
}
2015-09-07 16:11:00 -04:00
impl ::std::error::Error for Error {
fn description(&self) -> &str {
2015-09-29 15:09:36 -04:00
match *self {
Error::Err(ref val) => &val[..],
2016-03-20 08:04:02 -04:00
Error::Disconnect(_) => "Disconnect",
2015-09-29 15:09:36 -04:00
Error::IOError(ref e) => e.description(),
Error::Json(ref e) => e.description(),
Error::Hyper(ref e) => e.description(),
2015-09-07 16:11:00 -04:00
}
}
}
impl ::std::fmt::Display for Error {
2015-10-07 14:36:59 -04:00
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
2015-09-29 15:09:36 -04:00
match *self {
Error::Err(ref val) => write!(f, "protocol error: {}", val),
2016-03-20 08:04:02 -04:00
Error::Disconnect(ref val) => write!(f, "{}", val),
2015-10-07 14:36:59 -04:00
Error::IOError(ref e) => e.fmt(f),
Error::Json(ref e) => e.fmt(f),
Error::Hyper(ref e) => e.fmt(f),
2015-09-07 16:11:00 -04:00
}
}
}
pub struct Conn {
stream: TcpStream,
2016-03-20 08:04:02 -04:00
pub host: String,
pub port: u16,
2015-09-07 16:11:00 -04:00
direction: Direction,
2016-03-20 08:04:02 -04:00
pub state: State,
2015-09-10 06:49:41 -04:00
cipher: Option<openssl::EVPCipher>,
compression_threshold: i32,
2015-10-07 14:36:59 -04:00
compression_read: Option<ZlibDecoder<io::Cursor<Vec<u8>>>>,
2015-09-10 06:49:41 -04:00
compression_write: Option<ZlibEncoder<io::Cursor<Vec<u8>>>>,
2015-09-07 16:11:00 -04:00
}
impl Conn {
2015-10-07 14:36:59 -04:00
pub fn new(target: &str) -> Result<Conn, Error> {
2015-09-07 16:11:00 -04:00
// TODO SRV record support
2015-09-25 09:00:49 -04:00
let mut parts = target.split(":").collect::<Vec<&str>>();
let address = if parts.len() == 1 {
parts.push("25565");
format!("{}:25565", parts[0])
} else {
format!("{}:{}", parts[0], parts[1])
2015-09-07 16:11:00 -04:00
};
2015-09-25 09:00:49 -04:00
let stream = try!(TcpStream::connect(&*address));
2015-09-07 16:11:00 -04:00
Result::Ok(Conn {
stream: stream,
host: parts[0].to_owned(),
port: parts[1].parse().unwrap(),
direction: Direction::Serverbound,
state: State::Handshaking,
2015-09-10 06:49:41 -04:00
cipher: Option::None,
compression_threshold: -1,
compression_read: Option::None,
compression_write: Option::None,
2015-09-07 16:11:00 -04:00
})
}
pub fn write_packet<T: PacketType>(&mut self, packet: T) -> Result<(), Error> {
let mut buf = Vec::new();
2015-09-08 07:57:24 -04:00
try!(VarInt(packet.packet_id()).write_to(&mut buf));
2015-09-07 16:11:00 -04:00
try!(packet.write(&mut buf));
2015-09-10 06:49:41 -04:00
2015-10-07 14:36:59 -04:00
let mut extra = if self.compression_threshold >= 0 {
1
} else {
0
};
2015-09-10 06:49:41 -04:00
if self.compression_threshold >= 0 && buf.len() as i32 > self.compression_threshold {
extra = 0;
let uncompressed_size = buf.len();
let mut new = Vec::new();
try!(VarInt(uncompressed_size as i32).write_to(&mut new));
let mut write = self.compression_write.as_mut().unwrap();
write.reset(io::Cursor::new(buf));
try!(write.read_to_end(&mut new));
buf = new;
}
try!(VarInt(buf.len() as i32 + extra).write_to(self));
if self.compression_threshold >= 0 && extra == 1 {
try!(VarInt(0).write_to(self));
}
2016-03-26 06:19:16 -04:00
try!(self.write_all(&buf));
2015-09-07 16:11:00 -04:00
Result::Ok(())
}
pub fn read_packet(&mut self) -> Result<packet::Packet, Error> {
2015-09-10 06:49:41 -04:00
let len = try!(VarInt::read_from(self)).0 as usize;
let mut ibuf = vec![0; len];
try!(self.read_exact(&mut ibuf));
2015-09-07 16:11:00 -04:00
let mut buf = io::Cursor::new(ibuf);
2015-09-10 06:49:41 -04:00
if self.compression_threshold >= 0 {
let uncompressed_size = try!(VarInt::read_from(&mut buf)).0;
if uncompressed_size != 0 {
let mut new = Vec::with_capacity(uncompressed_size as usize);
{
let mut reader = self.compression_read.as_mut().unwrap();
reader.reset(buf);
try!(reader.read_to_end(&mut new));
}
buf = io::Cursor::new(new);
}
}
2015-09-08 07:57:24 -04:00
let id = try!(VarInt::read_from(&mut buf)).0;
2015-09-07 16:11:00 -04:00
let dir = match self.direction {
Direction::Clientbound => Direction::Serverbound,
Direction::Serverbound => Direction::Clientbound,
};
2015-09-08 07:57:24 -04:00
let packet = try!(packet::packet_by_id(self.state, dir, id, &mut buf));
2015-09-07 16:11:00 -04:00
match packet {
Some(val) => {
let pos = buf.position() as usize;
let ibuf = buf.into_inner();
2015-09-12 15:31:26 -04:00
if ibuf.len() != pos {
2015-10-07 14:36:59 -04:00
return Result::Err(Error::Err(format!("Failed to read all of packet 0x{:X}, \
had {} bytes left",
id,
ibuf.len() - pos)))
2015-09-07 16:11:00 -04:00
}
Result::Ok(val)
2015-10-07 14:36:59 -04:00
}
None => Result::Err(Error::Err("missing packet".to_owned())),
2015-09-10 06:49:41 -04:00
}
}
2016-03-26 10:24:26 -04:00
pub fn enable_encyption(&mut self, key: &[u8], decrypt: bool) {
2015-09-10 06:49:41 -04:00
self.cipher = Option::Some(openssl::EVPCipher::new(key, key, decrypt));
}
pub fn set_compresssion(&mut self, threshold: i32, read: bool) {
self.compression_threshold = threshold;
2016-03-26 10:24:26 -04:00
if read {
2015-09-10 06:49:41 -04:00
self.compression_read = Some(ZlibDecoder::new(io::Cursor::new(Vec::new())));
2016-03-26 10:24:26 -04:00
} else {
self.compression_write = Some(ZlibEncoder::new(io::Cursor::new(Vec::new()), flate2::Compression::Default));
2015-09-10 06:49:41 -04:00
}
}
2015-09-25 09:00:49 -04:00
2015-10-07 14:36:59 -04:00
pub fn do_status(mut self) -> Result<(Status, time::Duration), Error> {
2015-09-25 09:00:49 -04:00
use serde_json::Value;
use self::packet::status::serverbound::*;
use self::packet::handshake::serverbound::Handshake;
2015-09-25 09:00:49 -04:00
use self::packet::Packet;
let host = self.host.clone();
let port = self.port;
2015-10-07 14:36:59 -04:00
try!(self.write_packet(Handshake {
2015-09-25 09:00:49 -04:00
protocol_version: VarInt(SUPPORTED_PROTOCOL),
host: host,
port: port,
next: VarInt(1),
}));
self.state = State::Status;
2015-10-07 14:36:59 -04:00
try!(self.write_packet(StatusRequest { empty: () }));
2015-09-25 09:00:49 -04:00
let status = if let Packet::StatusResponse(res) = try!(self.read_packet()) {
res.status
} else {
return Err(Error::Err("Wrong packet".to_owned()));
};
let start = time::now();
2015-10-07 14:36:59 -04:00
try!(self.write_packet(StatusPing { ping: 42 }));
2015-09-25 09:00:49 -04:00
if let Packet::StatusPong(_) = try!(self.read_packet()) {
} else {
return Err(Error::Err("Wrong packet".to_owned()));
};
let ping = time::now() - start;
let val: Value = match serde_json::from_str(&status) {
Ok(val) => val,
Err(_) => return Err(Error::Err("Json parse error".to_owned())),
};
let invalid_status = || Error::Err("Invalid status".to_owned());
let version = try!(val.find("version").ok_or(invalid_status()));
let players = try!(val.find("players").ok_or(invalid_status()));
Ok((Status {
version: StatusVersion {
2015-10-07 14:36:59 -04:00
name: try!(version.find("name").and_then(Value::as_string).ok_or(invalid_status()))
.to_owned(),
protocol: try!(version.find("protocol")
.and_then(Value::as_i64)
.ok_or(invalid_status())) as i32,
2015-09-25 09:00:49 -04:00
},
players: StatusPlayers {
2015-10-07 14:36:59 -04:00
max: try!(players.find("max")
.and_then(Value::as_i64)
.ok_or(invalid_status())) as i32,
online: try!(players.find("online")
.and_then(Value::as_i64)
.ok_or(invalid_status())) as i32,
sample: Vec::new(), /* TODO */
2015-09-25 09:00:49 -04:00
},
2015-10-07 14:36:59 -04:00
description: format::Component::from_value(try!(val.find("description")
.ok_or(invalid_status()))),
2015-09-25 09:00:49 -04:00
favicon: val.find("favicon").and_then(Value::as_string).map(|v| v.to_owned()),
2015-10-07 14:36:59 -04:00
},
ping))
2015-09-25 09:00:49 -04:00
}
}
#[derive(Debug)]
pub struct Status {
pub version: StatusVersion,
pub players: StatusPlayers,
pub description: format::Component,
pub favicon: Option<String>,
}
#[derive(Debug)]
pub struct StatusVersion {
pub name: String,
pub protocol: i32,
}
#[derive(Debug)]
pub struct StatusPlayers {
pub max: i32,
pub online: i32,
pub sample: Vec<StatusPlayer>,
}
#[derive(Debug)]
pub struct StatusPlayer {
name: String,
id: String,
2015-09-10 06:49:41 -04:00
}
impl Read for Conn {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match self.cipher.as_mut() {
Option::None => self.stream.read(buf),
Option::Some(cipher) => {
let ret = try!(self.stream.read(buf));
let data = cipher.decrypt(&buf[..ret]);
2015-10-07 14:36:59 -04:00
for i in 0..ret {
2015-09-10 06:49:41 -04:00
buf[i] = data[i];
}
Ok(ret)
2015-10-07 14:36:59 -04:00
}
2015-09-10 06:49:41 -04:00
}
}
}
impl Write for Conn {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
match self.cipher.as_mut() {
Option::None => self.stream.write(buf),
Option::Some(cipher) => {
let data = cipher.encrypt(buf);
try!(self.stream.write_all(&data[..]));
Ok(buf.len())
2015-10-07 14:36:59 -04:00
}
2015-09-10 06:49:41 -04:00
}
}
fn flush(&mut self) -> io::Result<()> {
self.stream.flush()
}
}
impl Clone for Conn {
fn clone(&self) -> Self {
Conn {
stream: self.stream.try_clone().unwrap(),
host: self.host.clone(),
port: self.port,
direction: self.direction,
state: self.state,
cipher: Option::None,
compression_threshold: self.compression_threshold,
compression_read: Option::None,
compression_write: Option::None,
2015-09-07 16:11:00 -04:00
}
}
}
2015-09-27 14:38:58 -04:00
pub trait PacketType: Sized {
2015-09-07 16:11:00 -04:00
fn packet_id(&self) -> i32;
2015-09-12 15:31:26 -04:00
fn write(self, buf: &mut io::Write) -> Result<(), io::Error>;
2015-09-07 16:11:00 -04:00
}