use std::io::{Write, Read}; use std::net::{TcpStream, ToSocketAddrs}; use flate2::bufread::ZlibDecoder; use flate2::{Compress, Compression, Decompress, FlushCompress, Status, FlushDecompress}; use bytebuffer::ByteBuffer; pub trait Zigzag { fn zigzag(&self) -> T; } impl Zigzag for i8 { fn zigzag(&self) -> u8 { ((self << 1) ^ (self >> 7)) as u8 } } impl Zigzag for u8 { fn zigzag(&self) -> i8 { ((self >> 1) as i8) ^ (-((self & 1) as i8)) } } impl Zigzag for i16 { fn zigzag(&self) -> u16 { ((self << 1) ^ (self >> 15)) as u16 } } impl Zigzag for u16 { fn zigzag(&self) -> i16 { ((self >> 1) as i16) ^ (-((self & 1) as i16)) } } impl Zigzag for i32 { fn zigzag(&self) -> u32 { ((self << 1) ^ (self >> 31)) as u32 } } impl Zigzag for u32 { fn zigzag(&self) -> i32 { ((self >> 1) as i32) ^ (-((self & 1) as i32)) } } impl Zigzag for i64 { fn zigzag(&self) -> u64 { ((self << 1) ^ (self >> 63)) as u64 } } impl Zigzag for u64 { fn zigzag(&self) -> i64 { ((self >> 1) as i64) ^ (-((self & 1) as i64)) } } impl Zigzag for i128 { fn zigzag(&self) -> u128 { ((self << 1) ^ (self >> 127)) as u128 } } impl Zigzag for u128 { fn zigzag(&self) -> i128 { ((self >> 1) as i128) ^ (-((self & 1) as i128)) } } impl Zigzag for isize { fn zigzag(&self) -> usize { ((self << 1) ^ (self >> std::mem::size_of::()-1)) as usize } } impl Zigzag for usize { fn zigzag(&self) -> isize { ((self >> 1) as isize) ^ (-((self & 1) as isize)) } } #[derive(Debug)] pub enum ProtocolError { AddressParseError, DataRanOutError, StringParseError, StreamConnectError, VarIntError, ReadError, WriteError, ZlibError, UnsignedShortError } #[derive(Debug)] pub struct Packet { pub id: u8, pub buffer: ByteBuffer } // copied from varint-rs (im sorry T-T) macro_rules! size_varint { ($type: ty, $self: expr) => { { let mut shift: $type = 0; let mut decoded: $type = 0; let mut next: u8 = 0; loop { match DataBufferReader::read_byte($self) { Ok(value) => next = value, Err(error) => Err(error)? } decoded |= ((next & 0b01111111) as $type) << shift; if next & 0b10000000 == 0b10000000 { shift += 7; } else { return Ok((decoded, shift / 7)) } } } }; } macro_rules! read_varint { ($type: ty, $self: expr) => { { let mut shift: $type = 0; let mut decoded: $type = 0; let mut next: u8 = 0; loop { match DataBufferReader::read_byte($self) { Ok(value) => next = value, Err(error) => Err(error)? } decoded |= ((next & 0b01111111) as $type) << shift; if next & 0b10000000 == 0b10000000 { shift += 7; } else { return Ok(decoded) } } } }; } macro_rules! write_varint { ($type: ty, $self: expr, $value: expr) => { { let mut value: $type = $value; if value == 0 { DataBufferWriter::write_byte($self, 0) } else { while value >= 0b10000000 { let next: u8 = ((value & 0b01111111) as u8) | 0b10000000; value >>= 7; match DataBufferWriter::write_byte($self, next) { Err(error) => Err(error)?, Ok(_) => () } } DataBufferWriter::write_byte($self, (value & 0b01111111) as u8) } } }; } pub trait DataBufferReader { fn read_bytes(&mut self, size: usize) -> Result, ProtocolError>; fn read_byte(&mut self) -> Result; fn read_string(&mut self) -> Result { let size = self.read_usize_varint()?; match String::from_utf8(self.read_bytes(size)?) { Ok(i) => Ok(i), Err(_) => Err(ProtocolError::StringParseError) } } fn read_unsigned_short(&mut self) -> Result { match self.read_bytes(2)?.try_into() { Ok(i) => Ok(u16::from_be_bytes(i)), Err(_) => Err(ProtocolError::ReadError), } } fn read_boolean(&mut self) -> Result { Ok(self.read_byte()? == 0x01) } fn read_short(&mut self) -> Result { match self.read_bytes(2)?.try_into() { Ok(i) => Ok(i16::from_be_bytes(i)), Err(_) => Err(ProtocolError::ReadError), } } fn read_long(&mut self) -> Result { match self.read_bytes(8)?.try_into() { Ok(i) => Ok(i64::from_be_bytes(i)), Err(_) => Err(ProtocolError::ReadError), } } fn read_float(&mut self) -> Result { match self.read_bytes(4)?.try_into() { Ok(i) => Ok(f32::from_be_bytes(i)), Err(_) => Err(ProtocolError::ReadError), } } fn read_double(&mut self) -> Result { match self.read_bytes(8)?.try_into() { Ok(i) => Ok(f64::from_be_bytes(i)), Err(_) => Err(ProtocolError::ReadError), } } fn read_int(&mut self) -> Result { match self.read_bytes(4)?.try_into() { Ok(i) => Ok(i32::from_be_bytes(i)), Err(_) => Err(ProtocolError::ReadError), } } fn read_usize_varint_size(&mut self) -> Result<(usize, usize), ProtocolError> { size_varint!(usize, self) } fn read_usize_varint(&mut self) -> Result { read_varint!(usize, self) } fn read_u8_varint(&mut self) -> Result { read_varint!(u8, self) } fn read_u16_varint(&mut self) -> Result { read_varint!(u16, self) } fn read_u32_varint(&mut self) -> Result { read_varint!(u32, self) } fn read_u64_varint(&mut self) -> Result { read_varint!(u64, self) } fn read_u128_varint(&mut self) -> Result { read_varint!(u128, self) } fn read_isize_varint(&mut self) -> Result { Ok(self.read_usize_varint()?.zigzag()) } fn read_i8_varint(&mut self) -> Result { Ok(self.read_u8_varint()?.zigzag()) } fn read_i16_varint(&mut self) -> Result { Ok(self.read_u16_varint()?.zigzag()) } fn read_i32_varint(&mut self) -> Result { Ok(self.read_u32_varint()?.zigzag()) } fn read_i64_varint(&mut self) -> Result { Ok(self.read_u64_varint()?.zigzag()) } fn read_i128_varint(&mut self) -> Result { Ok(self.read_u128_varint()?.zigzag()) } } pub trait DataBufferWriter { fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), ProtocolError>; fn write_byte(&mut self, byte: u8) -> Result<(), ProtocolError>; fn write_string(&mut self, val: &str) -> Result<(), ProtocolError> { let bytes = val.as_bytes(); self.write_usize_varint(bytes.len())?; self.write_bytes(bytes) } fn write_unsigned_short(&mut self, val: u16) -> Result<(), ProtocolError> { match self.write_bytes(&val.to_be_bytes()) { Ok(_) => Ok(()), Err(_) => Err(ProtocolError::UnsignedShortError), } } fn write_boolean(&mut self, val: bool) -> Result<(), ProtocolError> { match self.write_byte(if val { 0x01 } else { 0x00 }) { Ok(_) => Ok(()), Err(_) => Err(ProtocolError::UnsignedShortError), } } fn write_short(&mut self, val: i16) -> Result<(), ProtocolError> { match self.write_bytes(&val.to_be_bytes()) { Ok(_) => Ok(()), Err(_) => Err(ProtocolError::UnsignedShortError), } } fn write_long(&mut self, val: i64) -> Result<(), ProtocolError> { match self.write_bytes(&val.to_be_bytes()) { Ok(_) => Ok(()), Err(_) => Err(ProtocolError::UnsignedShortError), } } fn write_float(&mut self, val: f32) -> Result<(), ProtocolError> { match self.write_bytes(&val.to_be_bytes()) { Ok(_) => Ok(()), Err(_) => Err(ProtocolError::UnsignedShortError), } } fn write_double(&mut self, val: f64) -> Result<(), ProtocolError> { match self.write_bytes(&val.to_be_bytes()) { Ok(_) => Ok(()), Err(_) => Err(ProtocolError::UnsignedShortError), } } fn write_int(&mut self, val: i32) -> Result<(), ProtocolError> { match self.write_bytes(&val.to_be_bytes()) { Ok(_) => Ok(()), Err(_) => Err(ProtocolError::UnsignedShortError), } } fn write_usize_varint(&mut self, val: usize) -> Result<(), ProtocolError> { write_varint!(usize, self, val) } fn write_u8_varint(&mut self, val: u8) -> Result<(), ProtocolError> { write_varint!(u8, self, val) } fn write_u16_varint(&mut self, val: u16) -> Result<(), ProtocolError> { write_varint!(u16, self, val) } fn write_u32_varint(&mut self, val: u32) -> Result<(), ProtocolError> { write_varint!(u32, self, val) } fn write_u64_varint(&mut self, val: u64) -> Result<(), ProtocolError> { write_varint!(u64, self, val) } fn write_u128_varint(&mut self, val: u128) -> Result<(), ProtocolError> { write_varint!(u128, self, val) } fn write_isize_varint(&mut self, val: isize) -> Result<(), ProtocolError> { self.write_usize_varint(val.zigzag()) } fn write_i8_varint(&mut self, val: i8) -> Result<(), ProtocolError> { self.write_u8_varint(val.zigzag()) } fn write_i16_varint(&mut self, val: i16) -> Result<(), ProtocolError> { self.write_u16_varint(val.zigzag()) } fn write_i32_varint(&mut self, val: i32) -> Result<(), ProtocolError> { self.write_u32_varint(val.zigzag()) } fn write_i64_varint(&mut self, val: i64) -> Result<(), ProtocolError> { self.write_u64_varint(val.zigzag()) } fn write_i128_varint(&mut self, val: i128) -> Result<(), ProtocolError> { self.write_u128_varint(val.zigzag()) } } impl DataBufferReader for R { fn read_bytes(&mut self, size: usize) -> Result, ProtocolError> { let mut buf = vec![0; size]; match self.read(&mut buf) { Ok(i) => { if i < size { Err(ProtocolError::ReadError) } else { Ok(buf) } }, Err(_) => Err(ProtocolError::ReadError), } } fn read_byte(&mut self) -> Result { match self.read_bytes(1) { Ok(i) => Ok(i[0]), Err(i) => Err(i), } } } impl DataBufferWriter for W { fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), ProtocolError> { match self.write_all(bytes) { Ok(_) => Ok(()), Err(_) => Err(ProtocolError::WriteError), } } fn write_byte(&mut self, byte: u8) -> Result<(), ProtocolError> { self.write_bytes(&[byte]) } } impl Packet { pub fn new(id: u8, buffer: ByteBuffer) -> Packet { Packet { id, buffer } } pub fn from_bytes(id: u8, data: &[u8]) -> Packet { Packet { id, buffer: ByteBuffer::from_bytes(data) } } pub fn empty(id: u8) -> Packet { Packet { id, buffer: ByteBuffer::new() } } } impl DataBufferReader for Packet { fn read_bytes(&mut self, size: usize) -> Result, ProtocolError> { let mut buf = vec![0; size]; match self.buffer.read(&mut buf) { Ok(i) => { if i < size { Err(ProtocolError::ReadError) } else { Ok(buf) } }, Err(_) => Err(ProtocolError::ReadError), } } fn read_byte(&mut self) -> Result { match self.read_bytes(1) { Ok(i) => Ok(i[0]), Err(i) => Err(i), } } } impl DataBufferWriter for Packet { fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), ProtocolError> { match self.buffer.write_all(bytes) { Ok(_) => Ok(()), Err(_) => Err(ProtocolError::WriteError), } } fn write_byte(&mut self, byte: u8) -> Result<(), ProtocolError> { self.write_bytes(&[byte]) } } pub struct MinecraftConnection { pub stream: T, compress: bool, compress_threashold: usize } impl MinecraftConnection { pub fn connect(addr: &str) -> Result, ProtocolError> { let addr = match addr.to_socket_addrs() { Ok(mut i) => { match i.next() { Some(i) => { i }, None => { return Err(ProtocolError::AddressParseError) }, } }, Err(_) => { return Err(ProtocolError::AddressParseError) }, }; let stream: TcpStream = match TcpStream::connect(&addr) { Ok(i) => i, Err(_) => { return Err(ProtocolError::StreamConnectError) }, }; Ok(MinecraftConnection { stream, compress: false, compress_threashold: 0 }) } pub fn close(&mut self) { let _ = self.stream.shutdown(std::net::Shutdown::Both); } } impl DataBufferReader for MinecraftConnection { fn read_bytes(&mut self, size: usize) -> Result, ProtocolError> { let mut buf = vec![0; size]; match self.stream.read(&mut buf) { Ok(i) => { if i < size { Err(ProtocolError::ReadError) } else { Ok(buf) } }, Err(_) => Err(ProtocolError::ReadError), } } fn read_byte(&mut self) -> Result { match self.read_bytes(1) { Ok(i) => Ok(i[0]), Err(i) => Err(i), } } } impl DataBufferWriter for MinecraftConnection { fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), ProtocolError> { match self.stream.write_all(bytes) { Ok(_) => Ok(()), Err(_) => Err(ProtocolError::WriteError), } } fn write_byte(&mut self, byte: u8) -> Result<(), ProtocolError> { self.write_bytes(&[byte]) } } impl MinecraftConnection { pub fn new(stream: T) -> MinecraftConnection { MinecraftConnection { stream, compress: false, compress_threashold: 0 } } pub fn set_compression(&mut self, threashold: usize) { self.compress = true; self.compress_threashold = threashold; } pub fn read_packet(&mut self) -> Result { if !self.compress { let length = self.read_usize_varint()?; let packet_id = self.read_u8_varint()?; let mut data: Vec = vec![0; length - 1]; match self.stream.read_exact(&mut data) { Ok(i) => i, Err(_) => { return Err(ProtocolError::ReadError) }, }; return Ok(Packet::from_bytes(packet_id, &data)) } let packet_length = self.read_usize_varint_size()?; let data_length = self.read_usize_varint_size()?; if data_length.0 == 0 { let packet_id = self.read_u8_varint()?; let mut data: Vec = vec![0; packet_length.0 - 2]; match self.stream.read_exact(&mut data) { Ok(i) => i, Err(_) => { return Err(ProtocolError::ReadError) }, }; return Ok(Packet::from_bytes(packet_id, &data)) } let mut data: Vec = vec![0; packet_length.0 - packet_length.1 - data_length.1]; match self.stream.read_exact(&mut data) { Ok(i) => i, Err(_) => { return Err(ProtocolError::ReadError) }, }; let mut data_buf = ByteBuffer::from_vec(decompress_zlib(&data, packet_length.0 - packet_length.1 - data_length.1)?); let packet_id = match data_buf.read_u8_varint() { Ok(i) => i, Err(_) => { return Err(ProtocolError::VarIntError) }, }; let mut data: Vec = vec![0; packet_length.0 - packet_length.1 - data_length.1 - 1]; match data_buf.read_exact(&mut data) { Ok(i) => i, Err(_) => { return Err(ProtocolError::ReadError) }, }; Ok(Packet::from_bytes(packet_id, &data)) } pub fn write_packet(&mut self, packet: &Packet) -> Result<(), ProtocolError> { let mut buf = ByteBuffer::new(); if !self.compress { match buf.write_usize_varint(packet.buffer.len() + 1) { Ok(_) => {}, Err(_) => { return Err(ProtocolError::WriteError) }, }; match buf.write_u8_varint(packet.id) { Ok(_) => {}, Err(_) => { return Err(ProtocolError::WriteError) }, }; match buf.write_all(packet.buffer.as_bytes()) { Ok(_) => {}, Err(_) => { return Err(ProtocolError::WriteError) }, }; } else { let mut pack = ByteBuffer::new(); if packet.buffer.len() < self.compress_threashold { match pack.write_usize_varint(0) { Ok(_) => {}, Err(_) => { return Err(ProtocolError::WriteError) }, }; match pack.write_u8_varint(packet.id) { Ok(_) => {}, Err(_) => { return Err(ProtocolError::WriteError) }, }; match pack.write_all(packet.buffer.as_bytes()) { Ok(_) => {}, Err(_) => { return Err(ProtocolError::WriteError) }, }; } else { let mut data = ByteBuffer::new(); match data.write_u8_varint(packet.id) { Ok(_) => {}, Err(_) => { return Err(ProtocolError::WriteError) }, }; match data.write_all(packet.buffer.as_bytes()) { Ok(_) => {}, Err(_) => { return Err(ProtocolError::WriteError) }, }; let data = compress_zlib(data.as_bytes())?; match pack.write_usize_varint(packet.buffer.len() + 1) { Ok(_) => {}, Err(_) => { return Err(ProtocolError::WriteError) }, }; match pack.write_all(&data) { Ok(_) => {}, Err(_) => { return Err(ProtocolError::WriteError) }, }; } match buf.write_usize_varint(pack.len()) { Ok(_) => {}, Err(_) => { return Err(ProtocolError::WriteError) }, }; match buf.write_all(pack.as_bytes()) { Ok(_) => {}, Err(_) => { return Err(ProtocolError::WriteError) }, }; } match self.stream.write_all(buf.as_bytes()) { Ok(_) => {}, Err(_) => { return Err(ProtocolError::WriteError) }, }; Ok(()) } } fn compress_zlib(bytes: &[u8]) -> Result, ProtocolError> { let mut compresser = Compress::new(Compression::best(), true); let mut output: Vec = Vec::new(); match compresser.compress_vec(&bytes, &mut output, FlushCompress::Finish) { Ok(i) => { match i { Status::Ok => Ok(output), _ => Err(ProtocolError::ZlibError), } }, Err(_) => Err(ProtocolError::ZlibError) } } fn decompress_zlib(bytes: &[u8], packet_length: usize) -> Result, ProtocolError> { let mut compresser = Decompress::new(true); let mut output: Vec = Vec::with_capacity(packet_length); match compresser.decompress_vec(&bytes, &mut output, FlushDecompress::Sync) { Ok(i) => { match i { Status::Ok => Ok(output), _ => Err(ProtocolError::ZlibError), } }, Err(_) => Err(ProtocolError::ZlibError) } } pub type MCConn = MinecraftConnection; pub type MCConnTcp = MinecraftConnection;