diff --git a/src/data_buffer/mod.rs b/src/data_buffer/mod.rs new file mode 100644 index 0000000..2f67125 --- /dev/null +++ b/src/data_buffer/mod.rs @@ -0,0 +1,6 @@ +pub mod reader; +pub mod varint; +pub mod writer; + +pub use reader::*; +pub use writer::*; diff --git a/src/data_buffer/reader.rs b/src/data_buffer/reader.rs new file mode 100644 index 0000000..924a46d --- /dev/null +++ b/src/data_buffer/reader.rs @@ -0,0 +1,212 @@ +use crate::{ + data_buffer::varint::{read_varint, size_varint}, + zigzag::Zigzag, + ProtocolError, +}; +use bytebuffer::ByteBuffer; +use std::io::Read; +use uuid::Uuid; + +/// Packet data reader trait +pub trait DataBufferReader { + /// Read bytes + fn read_bytes(&mut self, size: usize) -> Result, ProtocolError>; + + /// Read byte + fn read_byte(&mut self) -> Result { + Ok(self.read_bytes(1)?[0]) + } + /// Read [`ByteBuffer`](ByteBuffer) + fn read_buffer(&mut self, size: usize) -> Result { + Ok(ByteBuffer::from_vec(self.read_bytes(size)?)) + } + /// Read String + 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), + } + } + /// Read Unsigned Short as u16 + 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), + } + } + /// Read Boolean + fn read_boolean(&mut self) -> Result { + Ok(self.read_byte()? == 0x01) + } + /// Read Short as i16 + 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), + } + } + /// Read Long as i64 + 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), + } + } + /// Read Float as f32 + 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), + } + } + /// Read Double as f64 + 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), + } + } + /// Read Int as i32 + 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), + } + } + /// Read UUID + fn read_uuid(&mut self) -> Result { + match self.read_bytes(16)?.try_into() { + Ok(i) => Ok(Uuid::from_bytes(i)), + Err(_) => Err(ProtocolError::ReadError), + } + } + + /// Read VarInt as usize with size in bytes (varint, size) + fn read_usize_varint_size(&mut self) -> Result<(usize, usize), ProtocolError> { + size_varint!(usize, self) + } + /// Read VarInt as u8 with size in bytes (varint, size) + fn read_u8_varint_size(&mut self) -> Result<(u8, u8), ProtocolError> { + size_varint!(u8, self) + } + /// Read VarInt as u16 with size in bytes (varint, size) + fn read_u16_varint_size(&mut self) -> Result<(u16, u16), ProtocolError> { + size_varint!(u16, self) + } + /// Read VarInt as u32 with size in bytes (varint, size) + fn read_u32_varint_size(&mut self) -> Result<(u32, u32), ProtocolError> { + size_varint!(u32, self) + } + /// Read VarInt as u64 with size in bytes (varint, size) + fn read_u64_varint_size(&mut self) -> Result<(u64, u64), ProtocolError> { + size_varint!(u64, self) + } + /// Read VarInt as u128 with size in bytes (varint, size) + fn read_u128_varint_size(&mut self) -> Result<(u128, u128), ProtocolError> { + size_varint!(u128, self) + } + + /// Read VarInt as isize with size in bytes (varint, size) + fn read_isize_varint_size(&mut self) -> Result<(isize, isize), ProtocolError> { + Ok({ + let i = self.read_usize_varint_size()?; + (i.0.zigzag(), i.1.zigzag()) + }) + } + /// Read VarInt as i8 with size in bytes (varint, size) + fn read_i8_varint_size(&mut self) -> Result<(i8, i8), ProtocolError> { + Ok({ + let i = self.read_u8_varint_size()?; + (i.0.zigzag(), i.1.zigzag()) + }) + } + /// Read VarInt as i16 with size in bytes (varint, size) + fn read_i16_varint_size(&mut self) -> Result<(i16, i16), ProtocolError> { + Ok({ + let i = self.read_u16_varint_size()?; + (i.0.zigzag(), i.1.zigzag()) + }) + } + /// Read VarInt as i32 with size in bytes (varint, size) + fn read_i32_varint_size(&mut self) -> Result<(i32, i32), ProtocolError> { + Ok({ + let i = self.read_u32_varint_size()?; + (i.0.zigzag(), i.1.zigzag()) + }) + } + /// Read VarInt as i64 with size in bytes (varint, size) + fn read_i64_varint_size(&mut self) -> Result<(i64, i64), ProtocolError> { + Ok({ + let i = self.read_u64_varint_size()?; + (i.0.zigzag(), i.1.zigzag()) + }) + } + /// Read VarInt as i128 with size in bytes (varint, size) + fn read_i128_varint_size(&mut self) -> Result<(i128, i128), ProtocolError> { + Ok({ + let i = self.read_u128_varint_size()?; + (i.0.zigzag(), i.1.zigzag()) + }) + } + + /// Read VarInt as usize + fn read_usize_varint(&mut self) -> Result { + read_varint!(usize, self) + } + /// Read VarInt as u8 + fn read_u8_varint(&mut self) -> Result { + read_varint!(u8, self) + } + /// Read VarInt as u16 + fn read_u16_varint(&mut self) -> Result { + read_varint!(u16, self) + } + /// Read VarInt as u32 + fn read_u32_varint(&mut self) -> Result { + read_varint!(u32, self) + } + /// Read VarInt as u64 + fn read_u64_varint(&mut self) -> Result { + read_varint!(u64, self) + } + /// Read VarInt as u128 + fn read_u128_varint(&mut self) -> Result { + read_varint!(u128, self) + } + + /// Read VarInt as isize + fn read_isize_varint(&mut self) -> Result { + Ok(self.read_usize_varint()?.zigzag()) + } + /// Read VarInt as i8 + fn read_i8_varint(&mut self) -> Result { + Ok(self.read_u8_varint()?.zigzag()) + } + /// Read VarInt as i16 + fn read_i16_varint(&mut self) -> Result { + Ok(self.read_u16_varint()?.zigzag()) + } + /// Read VarInt as i32 + fn read_i32_varint(&mut self) -> Result { + Ok(self.read_u32_varint()?.zigzag()) + } + /// Read VarInt as i64 + fn read_i64_varint(&mut self) -> Result { + Ok(self.read_u64_varint()?.zigzag()) + } + /// Read VarInt as i128 + fn read_i128_varint(&mut self) -> Result { + Ok(self.read_u128_varint()?.zigzag()) + } +} + +impl DataBufferReader for R { + fn read_bytes(&mut self, size: usize) -> Result, ProtocolError> { + let mut buf = vec![0; size]; + match self.read_exact(&mut buf) { + Ok(_) => Ok(buf), + Err(_) => Err(ProtocolError::ReadError), + } + } +} diff --git a/src/data_buffer/varint.rs b/src/data_buffer/varint.rs new file mode 100644 index 0000000..1eb15ec --- /dev/null +++ b/src/data_buffer/varint.rs @@ -0,0 +1,71 @@ +macro_rules! size_varint { + ($type:ty, $self:expr) => {{ + let mut shift: $type = 0; + let mut decoded: $type = 0; + let mut size: $type = 0; + + loop { + let next = DataBufferReader::read_byte($self).or(Err(ProtocolError::VarIntError))?; + size += 1; + + if shift >= (std::mem::size_of::<$type>() * 8) as $type { + return Err(ProtocolError::VarIntError); + } + + decoded |= ((next & 0b01111111) as $type) << shift; + + if next & 0b10000000 == 0b10000000 { + shift += 7; + } else { + return Ok((decoded, size)); + } + } + }}; +} + +macro_rules! read_varint { + ($type:ty, $self:expr) => {{ + let mut shift: $type = 0; + let mut decoded: $type = 0; + + loop { + let next = DataBufferReader::read_byte($self).or(Err(ProtocolError::VarIntError))?; + + if shift >= (std::mem::size_of::<$type>() * 8) as $type { + return Err(ProtocolError::VarIntError); + } + + 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).or(Err(ProtocolError::VarIntError)) + } else { + while value >= 0b10000000 { + let next: u8 = ((value & 0b01111111) as u8) | 0b10000000; + value >>= 7; + + DataBufferWriter::write_byte($self, next).or(Err(ProtocolError::VarIntError))?; + } + + DataBufferWriter::write_byte($self, (value & 0b01111111) as u8) + .or(Err(ProtocolError::VarIntError)) + } + }}; +} + +pub(crate) use read_varint; +pub(crate) use size_varint; +pub(crate) use write_varint; diff --git a/src/data_buffer/writer.rs b/src/data_buffer/writer.rs new file mode 100644 index 0000000..0425ad7 --- /dev/null +++ b/src/data_buffer/writer.rs @@ -0,0 +1,137 @@ +use crate::{data_buffer::varint::write_varint, zigzag::Zigzag, ProtocolError}; +use bytebuffer::ByteBuffer; +use std::io::Write; +use uuid::Uuid; + +/// Packet data writer trait +pub trait DataBufferWriter { + /// Write bytes + fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), ProtocolError>; + + /// Write byte + fn write_byte(&mut self, byte: u8) -> Result<(), ProtocolError> { + self.write_bytes(&[byte]) + } + /// Write [`ByteBuffer`](ByteBuffer) + fn write_buffer(&mut self, buffer: &ByteBuffer) -> Result<(), ProtocolError> { + self.write_bytes(buffer.as_bytes()) + } + /// Write String + fn write_string(&mut self, val: &str) -> Result<(), ProtocolError> { + let bytes = val.as_bytes(); + self.write_usize_varint(bytes.len())?; + self.write_bytes(bytes) + } + /// Write UUID + fn write_uuid(&mut self, val: &Uuid) -> Result<(), ProtocolError> { + self.write_bytes(val.as_bytes()) + } + /// Write Unsigned Short as u16 + fn write_unsigned_short(&mut self, val: u16) -> Result<(), ProtocolError> { + match self.write_bytes(&val.to_be_bytes()) { + Ok(_) => Ok(()), + Err(_) => Err(ProtocolError::UnsignedShortError), + } + } + /// Write Boolean + fn write_boolean(&mut self, val: bool) -> Result<(), ProtocolError> { + match self.write_byte(if val { 0x01 } else { 0x00 }) { + Ok(_) => Ok(()), + Err(_) => Err(ProtocolError::UnsignedShortError), + } + } + /// Write Short as i16 + fn write_short(&mut self, val: i16) -> Result<(), ProtocolError> { + match self.write_bytes(&val.to_be_bytes()) { + Ok(_) => Ok(()), + Err(_) => Err(ProtocolError::UnsignedShortError), + } + } + /// Write Long as i64 + fn write_long(&mut self, val: i64) -> Result<(), ProtocolError> { + match self.write_bytes(&val.to_be_bytes()) { + Ok(_) => Ok(()), + Err(_) => Err(ProtocolError::UnsignedShortError), + } + } + /// Write Float as f32 + fn write_float(&mut self, val: f32) -> Result<(), ProtocolError> { + match self.write_bytes(&val.to_be_bytes()) { + Ok(_) => Ok(()), + Err(_) => Err(ProtocolError::UnsignedShortError), + } + } + /// Write Double as f64 + fn write_double(&mut self, val: f64) -> Result<(), ProtocolError> { + match self.write_bytes(&val.to_be_bytes()) { + Ok(_) => Ok(()), + Err(_) => Err(ProtocolError::UnsignedShortError), + } + } + /// Write Int as i32 + fn write_int(&mut self, val: i32) -> Result<(), ProtocolError> { + match self.write_bytes(&val.to_be_bytes()) { + Ok(_) => Ok(()), + Err(_) => Err(ProtocolError::UnsignedShortError), + } + } + + /// Write VarInt as usize + fn write_usize_varint(&mut self, val: usize) -> Result<(), ProtocolError> { + write_varint!(usize, self, val) + } + /// Write VarInt as u8 + fn write_u8_varint(&mut self, val: u8) -> Result<(), ProtocolError> { + write_varint!(u8, self, val) + } + /// Write VarInt as u16 + fn write_u16_varint(&mut self, val: u16) -> Result<(), ProtocolError> { + write_varint!(u16, self, val) + } + /// Write VarInt as u32 + fn write_u32_varint(&mut self, val: u32) -> Result<(), ProtocolError> { + write_varint!(u32, self, val) + } + /// Write VarInt as u64 + fn write_u64_varint(&mut self, val: u64) -> Result<(), ProtocolError> { + write_varint!(u64, self, val) + } + /// Write VarInt as u128 + fn write_u128_varint(&mut self, val: u128) -> Result<(), ProtocolError> { + write_varint!(u128, self, val) + } + + /// Write VarInt as isize + fn write_isize_varint(&mut self, val: isize) -> Result<(), ProtocolError> { + self.write_usize_varint(val.zigzag()) + } + /// Write VarInt as i8 + fn write_i8_varint(&mut self, val: i8) -> Result<(), ProtocolError> { + self.write_u8_varint(val.zigzag()) + } + /// Write VarInt as i16 + fn write_i16_varint(&mut self, val: i16) -> Result<(), ProtocolError> { + self.write_u16_varint(val.zigzag()) + } + /// Write VarInt as i32 + fn write_i32_varint(&mut self, val: i32) -> Result<(), ProtocolError> { + self.write_u32_varint(val.zigzag()) + } + /// Write VarInt as i64 + fn write_i64_varint(&mut self, val: i64) -> Result<(), ProtocolError> { + self.write_u64_varint(val.zigzag()) + } + /// Write VarInt as i128 + fn write_i128_varint(&mut self, val: i128) -> Result<(), ProtocolError> { + self.write_u128_varint(val.zigzag()) + } +} + +impl DataBufferWriter for W { + fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), ProtocolError> { + match self.write_all(bytes) { + Ok(_) => Ok(()), + Err(_) => Err(ProtocolError::WriteError), + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 100eb7d..3d667f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,15 @@ +#[cfg(test)] +mod tests; + +pub mod data_buffer; +pub mod packet; +pub mod zigzag; + +pub use crate::{ + data_buffer::{DataBufferReader, DataBufferWriter}, + packet::Packet, +}; + use bytebuffer::ByteBuffer; use flate2::{read::ZlibDecoder, write::ZlibEncoder, Compression}; use std::{ @@ -10,74 +22,6 @@ use std::{ Arc, }, }; -use uuid::Uuid; - -#[cfg(test)] -mod tests; - -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)) - } -} /// Minecraft protocol error #[derive(Debug)] @@ -102,514 +46,6 @@ impl fmt::Display for ProtocolError { impl Error for ProtocolError {} -/// Minecraft packet -#[derive(Debug, Clone)] -pub struct Packet { - id: u8, - buffer: ByteBuffer, -} - -macro_rules! size_varint { - ($type:ty, $self:expr) => {{ - let mut shift: $type = 0; - let mut decoded: $type = 0; - let mut size: $type = 0; - - loop { - let next = DataBufferReader::read_byte($self).or(Err(ProtocolError::VarIntError))?; - size += 1; - - if shift >= (std::mem::size_of::<$type>() * 8) as $type { - return Err(ProtocolError::VarIntError); - } - - decoded |= ((next & 0b01111111) as $type) << shift; - - if next & 0b10000000 == 0b10000000 { - shift += 7; - } else { - return Ok((decoded, size)); - } - } - }}; -} - -macro_rules! read_varint { - ($type:ty, $self:expr) => {{ - let mut shift: $type = 0; - let mut decoded: $type = 0; - - loop { - let next = DataBufferReader::read_byte($self).or(Err(ProtocolError::VarIntError))?; - - if shift >= (std::mem::size_of::<$type>() * 8) as $type { - return Err(ProtocolError::VarIntError); - } - - 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).or(Err(ProtocolError::VarIntError)) - } else { - while value >= 0b10000000 { - let next: u8 = ((value & 0b01111111) as u8) | 0b10000000; - value >>= 7; - - DataBufferWriter::write_byte($self, next).or(Err(ProtocolError::VarIntError))?; - } - - DataBufferWriter::write_byte($self, (value & 0b01111111) as u8) - .or(Err(ProtocolError::VarIntError)) - } - }}; -} - -/// Packet data reader trait -pub trait DataBufferReader { - /// Read bytes - fn read_bytes(&mut self, size: usize) -> Result, ProtocolError>; - - /// Read byte - fn read_byte(&mut self) -> Result { - Ok(self.read_bytes(1)?[0]) - } - /// Read [`ByteBuffer`](ByteBuffer) - fn read_buffer(&mut self, size: usize) -> Result { - Ok(ByteBuffer::from_vec(self.read_bytes(size)?)) - } - /// Read String - 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), - } - } - /// Read Unsigned Short as u16 - 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), - } - } - /// Read Boolean - fn read_boolean(&mut self) -> Result { - Ok(self.read_byte()? == 0x01) - } - /// Read Short as i16 - 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), - } - } - /// Read Long as i64 - 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), - } - } - /// Read Float as f32 - 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), - } - } - /// Read Double as f64 - 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), - } - } - /// Read Int as i32 - 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), - } - } - /// Read UUID - fn read_uuid(&mut self) -> Result { - match self.read_bytes(16)?.try_into() { - Ok(i) => Ok(Uuid::from_bytes(i)), - Err(_) => Err(ProtocolError::ReadError), - } - } - - /// Read VarInt as usize with size in bytes (varint, size) - fn read_usize_varint_size(&mut self) -> Result<(usize, usize), ProtocolError> { - size_varint!(usize, self) - } - /// Read VarInt as u8 with size in bytes (varint, size) - fn read_u8_varint_size(&mut self) -> Result<(u8, u8), ProtocolError> { - size_varint!(u8, self) - } - /// Read VarInt as u16 with size in bytes (varint, size) - fn read_u16_varint_size(&mut self) -> Result<(u16, u16), ProtocolError> { - size_varint!(u16, self) - } - /// Read VarInt as u32 with size in bytes (varint, size) - fn read_u32_varint_size(&mut self) -> Result<(u32, u32), ProtocolError> { - size_varint!(u32, self) - } - /// Read VarInt as u64 with size in bytes (varint, size) - fn read_u64_varint_size(&mut self) -> Result<(u64, u64), ProtocolError> { - size_varint!(u64, self) - } - /// Read VarInt as u128 with size in bytes (varint, size) - fn read_u128_varint_size(&mut self) -> Result<(u128, u128), ProtocolError> { - size_varint!(u128, self) - } - - /// Read VarInt as isize with size in bytes (varint, size) - fn read_isize_varint_size(&mut self) -> Result<(isize, isize), ProtocolError> { - Ok({ - let i = self.read_usize_varint_size()?; - (i.0.zigzag(), i.1.zigzag()) - }) - } - /// Read VarInt as i8 with size in bytes (varint, size) - fn read_i8_varint_size(&mut self) -> Result<(i8, i8), ProtocolError> { - Ok({ - let i = self.read_u8_varint_size()?; - (i.0.zigzag(), i.1.zigzag()) - }) - } - /// Read VarInt as i16 with size in bytes (varint, size) - fn read_i16_varint_size(&mut self) -> Result<(i16, i16), ProtocolError> { - Ok({ - let i = self.read_u16_varint_size()?; - (i.0.zigzag(), i.1.zigzag()) - }) - } - /// Read VarInt as i32 with size in bytes (varint, size) - fn read_i32_varint_size(&mut self) -> Result<(i32, i32), ProtocolError> { - Ok({ - let i = self.read_u32_varint_size()?; - (i.0.zigzag(), i.1.zigzag()) - }) - } - /// Read VarInt as i64 with size in bytes (varint, size) - fn read_i64_varint_size(&mut self) -> Result<(i64, i64), ProtocolError> { - Ok({ - let i = self.read_u64_varint_size()?; - (i.0.zigzag(), i.1.zigzag()) - }) - } - /// Read VarInt as i128 with size in bytes (varint, size) - fn read_i128_varint_size(&mut self) -> Result<(i128, i128), ProtocolError> { - Ok({ - let i = self.read_u128_varint_size()?; - (i.0.zigzag(), i.1.zigzag()) - }) - } - - /// Read VarInt as usize - fn read_usize_varint(&mut self) -> Result { - read_varint!(usize, self) - } - /// Read VarInt as u8 - fn read_u8_varint(&mut self) -> Result { - read_varint!(u8, self) - } - /// Read VarInt as u16 - fn read_u16_varint(&mut self) -> Result { - read_varint!(u16, self) - } - /// Read VarInt as u32 - fn read_u32_varint(&mut self) -> Result { - read_varint!(u32, self) - } - /// Read VarInt as u64 - fn read_u64_varint(&mut self) -> Result { - read_varint!(u64, self) - } - /// Read VarInt as u128 - fn read_u128_varint(&mut self) -> Result { - read_varint!(u128, self) - } - - /// Read VarInt as isize - fn read_isize_varint(&mut self) -> Result { - Ok(self.read_usize_varint()?.zigzag()) - } - /// Read VarInt as i8 - fn read_i8_varint(&mut self) -> Result { - Ok(self.read_u8_varint()?.zigzag()) - } - /// Read VarInt as i16 - fn read_i16_varint(&mut self) -> Result { - Ok(self.read_u16_varint()?.zigzag()) - } - /// Read VarInt as i32 - fn read_i32_varint(&mut self) -> Result { - Ok(self.read_u32_varint()?.zigzag()) - } - /// Read VarInt as i64 - fn read_i64_varint(&mut self) -> Result { - Ok(self.read_u64_varint()?.zigzag()) - } - /// Read VarInt as i128 - fn read_i128_varint(&mut self) -> Result { - Ok(self.read_u128_varint()?.zigzag()) - } -} - -/// Packet data writer trait -pub trait DataBufferWriter { - /// Write bytes - fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), ProtocolError>; - - /// Write byte - fn write_byte(&mut self, byte: u8) -> Result<(), ProtocolError> { - self.write_bytes(&[byte]) - } - /// Write [`ByteBuffer`](ByteBuffer) - fn write_buffer(&mut self, buffer: &ByteBuffer) -> Result<(), ProtocolError> { - self.write_bytes(buffer.as_bytes()) - } - /// Write String - fn write_string(&mut self, val: &str) -> Result<(), ProtocolError> { - let bytes = val.as_bytes(); - self.write_usize_varint(bytes.len())?; - self.write_bytes(bytes) - } - /// Write UUID - fn write_uuid(&mut self, val: &Uuid) -> Result<(), ProtocolError> { - self.write_bytes(val.as_bytes()) - } - /// Write Unsigned Short as u16 - fn write_unsigned_short(&mut self, val: u16) -> Result<(), ProtocolError> { - match self.write_bytes(&val.to_be_bytes()) { - Ok(_) => Ok(()), - Err(_) => Err(ProtocolError::UnsignedShortError), - } - } - /// Write Boolean - fn write_boolean(&mut self, val: bool) -> Result<(), ProtocolError> { - match self.write_byte(if val { 0x01 } else { 0x00 }) { - Ok(_) => Ok(()), - Err(_) => Err(ProtocolError::UnsignedShortError), - } - } - /// Write Short as i16 - fn write_short(&mut self, val: i16) -> Result<(), ProtocolError> { - match self.write_bytes(&val.to_be_bytes()) { - Ok(_) => Ok(()), - Err(_) => Err(ProtocolError::UnsignedShortError), - } - } - /// Write Long as i64 - fn write_long(&mut self, val: i64) -> Result<(), ProtocolError> { - match self.write_bytes(&val.to_be_bytes()) { - Ok(_) => Ok(()), - Err(_) => Err(ProtocolError::UnsignedShortError), - } - } - /// Write Float as f32 - fn write_float(&mut self, val: f32) -> Result<(), ProtocolError> { - match self.write_bytes(&val.to_be_bytes()) { - Ok(_) => Ok(()), - Err(_) => Err(ProtocolError::UnsignedShortError), - } - } - /// Write Double as f64 - fn write_double(&mut self, val: f64) -> Result<(), ProtocolError> { - match self.write_bytes(&val.to_be_bytes()) { - Ok(_) => Ok(()), - Err(_) => Err(ProtocolError::UnsignedShortError), - } - } - /// Write Int as i32 - fn write_int(&mut self, val: i32) -> Result<(), ProtocolError> { - match self.write_bytes(&val.to_be_bytes()) { - Ok(_) => Ok(()), - Err(_) => Err(ProtocolError::UnsignedShortError), - } - } - - /// Write VarInt as usize - fn write_usize_varint(&mut self, val: usize) -> Result<(), ProtocolError> { - write_varint!(usize, self, val) - } - /// Write VarInt as u8 - fn write_u8_varint(&mut self, val: u8) -> Result<(), ProtocolError> { - write_varint!(u8, self, val) - } - /// Write VarInt as u16 - fn write_u16_varint(&mut self, val: u16) -> Result<(), ProtocolError> { - write_varint!(u16, self, val) - } - /// Write VarInt as u32 - fn write_u32_varint(&mut self, val: u32) -> Result<(), ProtocolError> { - write_varint!(u32, self, val) - } - /// Write VarInt as u64 - fn write_u64_varint(&mut self, val: u64) -> Result<(), ProtocolError> { - write_varint!(u64, self, val) - } - /// Write VarInt as u128 - fn write_u128_varint(&mut self, val: u128) -> Result<(), ProtocolError> { - write_varint!(u128, self, val) - } - - /// Write VarInt as isize - fn write_isize_varint(&mut self, val: isize) -> Result<(), ProtocolError> { - self.write_usize_varint(val.zigzag()) - } - /// Write VarInt as i8 - fn write_i8_varint(&mut self, val: i8) -> Result<(), ProtocolError> { - self.write_u8_varint(val.zigzag()) - } - /// Write VarInt as i16 - fn write_i16_varint(&mut self, val: i16) -> Result<(), ProtocolError> { - self.write_u16_varint(val.zigzag()) - } - /// Write VarInt as i32 - fn write_i32_varint(&mut self, val: i32) -> Result<(), ProtocolError> { - self.write_u32_varint(val.zigzag()) - } - /// Write VarInt as i64 - fn write_i64_varint(&mut self, val: i64) -> Result<(), ProtocolError> { - self.write_u64_varint(val.zigzag()) - } - /// Write VarInt as i128 - 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_exact(&mut buf) { - Ok(_) => Ok(buf), - Err(_) => Err(ProtocolError::ReadError), - } - } -} - -impl DataBufferWriter for W { - fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), ProtocolError> { - match self.write_all(bytes) { - Ok(_) => Ok(()), - Err(_) => Err(ProtocolError::WriteError), - } - } -} - -impl Packet { - /// Create new packet from id and buffer - pub fn new(id: u8, buffer: ByteBuffer) -> Packet { - Packet { id, buffer } - } - - /// Create new packet from packet data - pub fn from_data(data: &[u8]) -> Result { - let mut buf = ByteBuffer::from_bytes(data); - - let (packet_id, packet_id_size) = buf.read_u8_varint_size()?; - let packet_data = - DataBufferReader::read_bytes(&mut buf, data.len() - packet_id_size as usize)?; - - Ok(Packet { - id: packet_id, - buffer: ByteBuffer::from_bytes(&packet_data), - }) - } - - /// Create new packet from id and bytes in buffer - pub fn from_bytes(id: u8, data: &[u8]) -> Packet { - Packet { - id, - buffer: ByteBuffer::from_bytes(data), - } - } - - /// Create new packet with id and empty buffer - pub fn empty(id: u8) -> Packet { - Packet { - id, - buffer: ByteBuffer::new(), - } - } - - /// Build packet with lambda - pub fn build(id: u8, builder: F) -> Result - where - F: FnOnce(&mut Packet) -> Result<(), ProtocolError>, - { - let mut packet = Self::empty(id); - builder(&mut packet)?; - Ok(packet) - } - - /// Get packet id - pub fn id(&self) -> u8 { - self.id - } - - /// Set packet id - pub fn set_id(&mut self, id: u8) { - self.id = id; - } - - /// Get mutable reference of buffer - pub fn buffer(&mut self) -> &mut ByteBuffer { - &mut self.buffer - } - - /// Set packet buffer - pub fn set_buffer(&mut self, buffer: ByteBuffer) { - self.buffer = buffer; - } - - /// Get buffer length - pub fn len(&self) -> usize { - self.buffer.len() - } - - /// Get buffer bytes - pub fn get_bytes(&self) -> Vec { - self.buffer.as_bytes().to_vec() - } -} - -impl DataBufferReader for Packet { - fn read_bytes(&mut self, size: usize) -> Result, ProtocolError> { - let mut buf = vec![0; size]; - match self.buffer.read_exact(&mut buf) { - Ok(_) => Ok(buf), - Err(_) => Err(ProtocolError::ReadError), - } - } -} - -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), - } - } -} - /// Minecraft connection, wrapper for stream with compression pub struct MinecraftConnection { stream: T, @@ -841,8 +277,8 @@ pub fn write_packet_atomic( let mut buf = ByteBuffer::new(); let mut data_buf = ByteBuffer::new(); - data_buf.write_u8_varint(packet.id)?; - data_buf.write_buffer(&packet.buffer)?; + data_buf.write_u8_varint(packet.id())?; + data_buf.write_buffer(packet.buffer_ref())?; let compress_threshold = compression.load(ordering); diff --git a/src/packet.rs b/src/packet.rs new file mode 100644 index 0000000..7b50ed4 --- /dev/null +++ b/src/packet.rs @@ -0,0 +1,117 @@ +use crate::data_buffer::{DataBufferReader, DataBufferWriter}; +use crate::ProtocolError; +use bytebuffer::ByteBuffer; +use std::io::{Read, Write}; + +/// Minecraft packet +#[derive(Debug, Clone)] +pub struct Packet { + id: u8, + buffer: ByteBuffer, +} + +impl Packet { + /// Create new packet from id and buffer + pub fn new(id: u8, buffer: ByteBuffer) -> Packet { + Packet { id, buffer } + } + + /// Create new packet from packet data + pub fn from_data(data: &[u8]) -> Result { + let mut buf = ByteBuffer::from_bytes(data); + + let (packet_id, packet_id_size) = buf.read_u8_varint_size()?; + let packet_data = + DataBufferReader::read_bytes(&mut buf, data.len() - packet_id_size as usize)?; + + Ok(Packet { + id: packet_id, + buffer: ByteBuffer::from_bytes(&packet_data), + }) + } + + /// Create new packet from id and bytes in buffer + pub fn from_bytes(id: u8, data: &[u8]) -> Packet { + Packet { + id, + buffer: ByteBuffer::from_bytes(data), + } + } + + /// Create new packet with id and empty buffer + pub fn empty(id: u8) -> Packet { + Packet { + id, + buffer: ByteBuffer::new(), + } + } + + /// Build packet with lambda + pub fn build(id: u8, builder: F) -> Result + where + F: FnOnce(&mut Packet) -> Result<(), ProtocolError>, + { + let mut packet = Self::empty(id); + builder(&mut packet)?; + Ok(packet) + } + + /// Get packet id + pub fn id(&self) -> u8 { + self.id + } + + /// Set packet id + pub fn set_id(&mut self, id: u8) { + self.id = id; + } + + /// Get mutable reference of buffer + pub fn buffer(&mut self) -> &mut ByteBuffer { + &mut self.buffer + } + + /// Get immutable reference of buffer + pub fn buffer_ref(&self) -> &ByteBuffer { + &self.buffer + } + + /// Set packet buffer + pub fn set_buffer(&mut self, buffer: ByteBuffer) { + self.buffer = buffer; + } + + /// Get buffer length + pub fn len(&self) -> usize { + self.buffer.len() + } + + /// Is buffer empty + pub fn is_empty(&self) -> bool { + self.buffer.len() == 0 + } + + /// Get buffer bytes + pub fn get_bytes(&self) -> Vec { + self.buffer.as_bytes().to_vec() + } +} + +impl DataBufferReader for Packet { + fn read_bytes(&mut self, size: usize) -> Result, ProtocolError> { + let mut buf = vec![0; size]; + match self.buffer.read_exact(&mut buf) { + Ok(_) => Ok(buf), + Err(_) => Err(ProtocolError::ReadError), + } + } +} + +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), + } + } +} diff --git a/src/zigzag.rs b/src/zigzag.rs new file mode 100644 index 0000000..2783066 --- /dev/null +++ b/src/zigzag.rs @@ -0,0 +1,63 @@ +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)) + } +}