diff --git a/examples/recv_motd.rs b/examples/recv_motd.rs index 14ea850..60c7af8 100755 --- a/examples/recv_motd.rs +++ b/examples/recv_motd.rs @@ -15,10 +15,10 @@ fn send_handshake( next_state: u8 ) -> Result<(), ProtocolError> { conn.write_packet(&Packet::build(0x00, |packet| { - packet.write_u16_varint(protocol_version)?; + packet.write_varint(protocol_version as i32)?; packet.write_string(server_address)?; packet.write_unsigned_short(server_port)?; - packet.write_u8_varint(next_state) + packet.write_varint(next_state as i32) })?) } diff --git a/examples/recv_motd_dirty.rs b/examples/recv_motd_dirty.rs index a32eb4b..111bcca 100755 --- a/examples/recv_motd_dirty.rs +++ b/examples/recv_motd_dirty.rs @@ -4,10 +4,10 @@ fn main() -> Result<(), ProtocolError> { let mut conn = MCConnTcp::connect("localhost:25565")?; // connecting conn.write_packet(&Packet::build(0x00, |packet| { - packet.write_u16_varint(765)?; // protocol_version + packet.write_varint(765)?; // protocol_version packet.write_string("localhost")?; // server_address packet.write_unsigned_short(25565)?; // server_port - packet.write_u8_varint(1) // next_state + packet.write_varint(1) // next_state })?)?; // handshake packet conn.write_packet(&Packet::empty(0x00))?; // status request packet diff --git a/examples/status_server.rs b/examples/status_server.rs index 8e5fce0..c47c577 100755 --- a/examples/status_server.rs +++ b/examples/status_server.rs @@ -63,10 +63,10 @@ impl MinecraftServer { )?)?; } } else if packet.id() == 0x00 { - let protocol_version = packet.read_i32_varint()?; + let protocol_version = packet.read_varint()?; let server_address = packet.read_string()?; let server_port = packet.read_unsigned_short()?; - let next_state = packet.read_u8_varint()?; + let next_state = packet.read_varint()?; if next_state != 1 { break; } diff --git a/src/data/mod.rs b/src/data/mod.rs index fada9ef..9706c1b 100755 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -1,7 +1,6 @@ //! `DataReader` and `DataWriter` traits for reading and writing primitive types in the Minecraft protocol pub mod reader; -pub mod varint; pub mod writer; pub use reader::*; diff --git a/src/data/reader.rs b/src/data/reader.rs index 14330d0..85ad464 100755 --- a/src/data/reader.rs +++ b/src/data/reader.rs @@ -1,7 +1,4 @@ -use crate::{ - data::varint::read_varint, - ProtocolError, -}; +use crate::ProtocolError; use std::io::Read; use uuid::Uuid; @@ -16,12 +13,16 @@ pub trait DataReader { } /// Read String fn read_string(&mut self) -> Result { - let size = self.read_usize_varint()?; + let size = self.read_varint()? as usize; match String::from_utf8(self.read_bytes(size)?) { Ok(i) => Ok(i), Err(_) => Err(ProtocolError::StringParseError), } } + /// Read Signed byte as i8 + fn read_signed_byte(&mut self) -> Result { + Ok(self.read_byte()? as i8) + } /// Read Unsigned Short as u16 fn read_unsigned_short(&mut self) -> Result { self.read_bytes(2) @@ -69,104 +70,56 @@ pub trait DataReader { .map(|o| Uuid::from_bytes(o)) } - /// Read VarInt as usize with size in bytes (varint, size) - fn read_usize_varint_size(&mut self) -> Result<(usize, usize), ProtocolError> { - read_varint!(usize, self) + /// Read VarInt as i32 with size in bytes (varint, size) + fn read_varint_size(&mut self) -> Result<(i32, usize), ProtocolError> { + let mut value: u32 = 0; + let mut position: u32 = 0; + let mut size = 0; + + loop { + let byte = self.read_byte()?; + value |= ((byte & 0x7F) as u32) << position; + + size += 1; + + if (byte & 0x80) == 0 { + break; + } + + position += 7; + } + + Ok((value as i32, size)) } - /// Read VarInt as u8 with size in bytes (varint, size) - fn read_u8_varint_size(&mut self) -> Result<(u8, usize), ProtocolError> { - read_varint!(u8, self) - } - /// Read VarInt as u16 with size in bytes (varint, size) - fn read_u16_varint_size(&mut self) -> Result<(u16, usize), ProtocolError> { - read_varint!(u16, self) - } - /// Read VarInt as u32 with size in bytes (varint, size) - fn read_u32_varint_size(&mut self) -> Result<(u32, usize), ProtocolError> { - read_varint!(u32, self) - } - /// Read VarInt as u64 with size in bytes (varint, size) - fn read_u64_varint_size(&mut self) -> Result<(u64, usize), ProtocolError> { - read_varint!(u64, self) - } - /// Read VarInt as u128 with size in bytes (varint, size) - fn read_u128_varint_size(&mut self) -> Result<(u128, usize), ProtocolError> { - read_varint!(u128, self) + /// Read VarLong as i64 with size in bytes (varint, size) + fn read_varlong_size(&mut self) -> Result<(i64, usize), ProtocolError> { + let mut value: u64 = 0; + let mut position: u32 = 0; + let mut size = 0; + + loop { + let byte = self.read_byte()?; + value |= ((byte & 0x7F) as u64) << position; + + size += 1; + + if (byte & 0x80) == 0 { + break; + } + + position += 7; + } + + Ok((value as i64, size)) } - /// Read VarInt as usize - fn read_usize_varint(&mut self) -> Result { - self.read_usize_varint_size().map(|o| o.0) + /// Read VarInt as i32 + fn read_varint(&mut self) -> Result { + self.read_varint_size().map(|o| o.0) } - /// Read VarInt as u8 - fn read_u8_varint(&mut self) -> Result { - self.read_u8_varint_size().map(|o| o.0) - } - /// Read VarInt as u16 - fn read_u16_varint(&mut self) -> Result { - self.read_u16_varint_size().map(|o| o.0) - } - /// Read VarInt as u32 - fn read_u32_varint(&mut self) -> Result { - self.read_u32_varint_size().map(|o| o.0) - } - /// Read VarInt as u64 - fn read_u64_varint(&mut self) -> Result { - self.read_u64_varint_size().map(|o| o.0) - } - /// Read VarInt as u128 - fn read_u128_varint(&mut self) -> Result { - self.read_u128_varint_size().map(|o| o.0) - } - - /// Read VarInt as usize with zigzag - fn read_isize_varint(&mut self) -> Result { - self.read_usize_varint().map(|o| o as isize) - } - /// Read VarInt as u8 with zigzag - fn read_i8_varint(&mut self) -> Result { - self.read_u8_varint().map(|o| o as i8) - } - /// Read VarInt as u16 with zigzag - fn read_i16_varint(&mut self) -> Result { - self.read_u16_varint().map(|o| o as i16) - } - /// Read VarInt as u32 with zigzag - fn read_i32_varint(&mut self) -> Result { - self.read_u32_varint().map(|o| o as i32) - } - /// Read VarInt as u64 with zigzag - fn read_i64_varint(&mut self) -> Result { - self.read_u64_varint().map(|o| o as i64) - } - /// Read VarInt as u128 with zigzag - fn read_i128_varint(&mut self) -> Result { - self.read_u128_varint().map(|o| o as i128) - } - - /// Read VarInt as usize with zigzag with size in bytes (varint, size) - fn read_isize_varint_size(&mut self) -> Result<(isize, usize), ProtocolError> { - self.read_usize_varint_size().map(|o| (o.0 as isize, o.1)) - } - /// Read VarInt as u8 with zigzag with size in bytes (varint, size) - fn read_i8_varint_size(&mut self) -> Result<(i8, usize), ProtocolError> { - self.read_u8_varint_size().map(|o| (o.0 as i8, o.1)) - } - /// Read VarInt as u16 with zigzag with size in bytes (varint, size) - fn read_i16_varint_size(&mut self) -> Result<(i16, usize), ProtocolError> { - self.read_u16_varint_size().map(|o| (o.0 as i16, o.1)) - } - /// Read VarInt as u32 with zigzag with size in bytes (varint, size) - fn read_i32_varint_size(&mut self) -> Result<(i32, usize), ProtocolError> { - self.read_u32_varint_size().map(|o| (o.0 as i32, o.1)) - } - /// Read VarInt as u64 with zigzag with size in bytes (varint, size) - fn read_i64_varint_size(&mut self) -> Result<(i64, usize), ProtocolError> { - self.read_u64_varint_size().map(|o| (o.0 as i64, o.1)) - } - /// Read VarInt as u128 with zigzag with size in bytes (varint, size) - fn read_i128_varint_size(&mut self) -> Result<(i128, usize), ProtocolError> { - self.read_u128_varint_size().map(|o| (o.0 as i128, o.1)) + /// Read VarLong as i64 + fn read_varlong(&mut self) -> Result { + self.read_varlong_size().map(|o| o.0) } } diff --git a/src/data/varint.rs b/src/data/varint.rs deleted file mode 100755 index fdc2350..0000000 --- a/src/data/varint.rs +++ /dev/null @@ -1,44 +0,0 @@ -macro_rules! read_varint { - ($type:ty, $self:expr) => {{ - let mut shift: $type = 0; - let mut decoded: $type = 0; - let mut size: usize = 0; - - loop { - let next = DataReader::read_byte($self)?; - size += 1; - - if shift >= (std::mem::size_of::<$type>() * 8) as $type { - return Err(ProtocolError::VarIntError); - } - - decoded |= ((next & 0x7F) as $type) << shift; - - if next & 0x80 == 0x80 { - shift += 7; - } else { - return Ok((decoded, size)); - } - } - }}; -} - -macro_rules! write_varint { - ($type:ty, $self:expr, $value:expr) => {{ - let mut value: $type = $value; - - if value == 0 { - DataWriter::write_byte($self, 0) - } else { - while value >= 0x80 { - DataWriter::write_byte($self, ((value & 0x7F) as u8) | 0x80)?; - value >>= 7; - } - - DataWriter::write_byte($self, (value & 0x7F) as u8) - } - }}; -} - -pub(crate) use read_varint; -pub(crate) use write_varint; diff --git a/src/data/writer.rs b/src/data/writer.rs index 54c02a4..a2ddbf0 100755 --- a/src/data/writer.rs +++ b/src/data/writer.rs @@ -1,4 +1,4 @@ -use crate::{data::varint::write_varint, ProtocolError}; +use crate::ProtocolError; use std::io::Write; use uuid::Uuid; @@ -14,13 +14,17 @@ pub trait DataWriter { /// Write String fn write_string(&mut self, val: &str) -> Result<(), ProtocolError> { let bytes = val.as_bytes(); - self.write_usize_varint(bytes.len())?; + self.write_varint(bytes.len() as i32)?; self.write_bytes(bytes) } /// Write UUID fn write_uuid(&mut self, val: &Uuid) -> Result<(), ProtocolError> { self.write_bytes(val.as_bytes()) } + /// Write Signed byte as i8 + fn write_signed_byte(&mut self, val: i8) -> Result<(), ProtocolError> { + self.write_byte(val as u8) + } /// Write Unsigned Short as u16 fn write_unsigned_short(&mut self, val: u16) -> Result<(), ProtocolError> { self.write_bytes(&val.to_be_bytes()) @@ -50,62 +54,44 @@ pub trait DataWriter { self.write_bytes(&val.to_be_bytes()) } - /// 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 as usize) - } - /// Write VarInt as i8 - fn write_i8_varint(&mut self, val: i8) -> Result<(), ProtocolError> { - self.write_u8_varint(val as u8) - } - /// Write VarInt as i16 - fn write_i16_varint(&mut self, val: i16) -> Result<(), ProtocolError> { - self.write_u16_varint(val as u16) - } /// Write VarInt as i32 - fn write_i32_varint(&mut self, val: i32) -> Result<(), ProtocolError> { - self.write_u32_varint(val as u32) + fn write_varint(&mut self, val: i32) -> Result<(), ProtocolError> { + let mut value = val as u32; + + loop { + if value & !0x7F == 0 { + self.write_byte(value as u8)?; + break; + } + + self.write_byte(((value & 0x7F) | 0x80) as u8)?; + + value >>= 7; + } + + Ok(()) } - /// Write VarInt as i64 - fn write_i64_varint(&mut self, val: i64) -> Result<(), ProtocolError> { - self.write_u64_varint(val as u64) - } - /// Write VarInt as i128 - fn write_i128_varint(&mut self, val: i128) -> Result<(), ProtocolError> { - self.write_u128_varint(val as u128) + /// Write VarLong as i64 + fn write_varlong(&mut self, val: i64) -> Result<(), ProtocolError> { + let mut value = val as u64; + + loop { + if value & !0x7F == 0 { + self.write_byte(value as u8)?; + break; + } + + self.write_byte(((value & 0x7F) | 0x80) as u8)?; + + value >>= 7; + } + + Ok(()) } } impl DataWriter for W { fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), ProtocolError> { - match self.write_all(bytes) { - Ok(_) => Ok(()), - Err(_) => Err(ProtocolError::WriteError), - } + self.write_all(bytes).map_err(|_| ProtocolError::WriteError) } } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 722a385..423e201 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -136,7 +136,7 @@ impl MinecraftConnection { impl MinecraftConnection { /// Connect to Minecraft Server with TcpStream - pub fn connect(addr: &str) -> Result, ProtocolError> { + pub fn connect(addr: impl ToSocketAddrs) -> Result, ProtocolError> { let addr = match addr.to_socket_addrs() { Ok(mut i) => match i.next() { Some(i) => i, @@ -209,18 +209,18 @@ pub fn read_packet( ) -> Result { let mut data: Vec; - let packet_length = stream.read_usize_varint_size()?; + let packet_length = stream.read_varint_size()?; if compression.is_some() { - let data_length = stream.read_usize_varint_size()?; + let data_length = stream.read_varint_size()?; - data = stream.read_bytes(packet_length.0 - data_length.1)?; + data = stream.read_bytes(packet_length.0 as usize - data_length.1 as usize)?; if data_length.0 != 0 { data = decompress_zlib(&data)?; } } else { - data = stream.read_bytes(packet_length.0)?; + data = stream.read_bytes(packet_length.0 as usize)?; } Ok(Packet::from_data(&data)?) @@ -245,7 +245,7 @@ pub fn write_packet( let mut buf = Vec::new(); let mut data_buf = Vec::new(); - data_buf.write_u8_varint(packet.id())?; + data_buf.write_varint(packet.id() as i32)?; data_buf.write_bytes(packet.get_bytes())?; if let Some(compression) = compression { @@ -253,19 +253,19 @@ pub fn write_packet( if data_buf.len() >= compression { let compressed_data = compress_zlib(&data_buf, compression_type)?; - packet_buf.write_usize_varint(data_buf.len())?; + packet_buf.write_varint(data_buf.len() as i32)?; packet_buf .write_all(&compressed_data) .or(Err(ProtocolError::WriteError))?; } else { - packet_buf.write_usize_varint(0)?; + packet_buf.write_varint(0)?; packet_buf.write_bytes(&data_buf)?; } - buf.write_usize_varint(packet_buf.len())?; + buf.write_varint(packet_buf.len() as i32)?; buf.write_bytes(&packet_buf)?; } else { - buf.write_usize_varint(data_buf.len())?; + buf.write_varint(data_buf.len() as i32)?; buf.write_bytes(&data_buf)?; } diff --git a/src/packet.rs b/src/packet.rs index b3cae83..b3d6c93 100755 --- a/src/packet.rs +++ b/src/packet.rs @@ -21,12 +21,12 @@ impl Packet { pub fn from_data(data: &[u8]) -> Result { let mut cursor = Cursor::new(data); - let (packet_id, packet_id_size) = cursor.read_u8_varint_size()?; + let (packet_id, packet_id_size) = cursor.read_varint_size()?; let packet_data = DataReader::read_bytes(&mut cursor, data.len() - packet_id_size as usize)?; Ok(Packet { - id: packet_id, + id: packet_id as u8, cursor: Cursor::new(packet_data), }) } @@ -82,7 +82,7 @@ impl Packet { self.len() == 0 } - /// Get cursor remaining bytes + /// Get cursor bytes pub fn get_bytes(&self) -> &[u8] { &self.cursor.get_ref() } diff --git a/src/tests.rs b/src/tests.rs index abc1f34..c12d297 100755 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,60 +1,145 @@ use uuid::Uuid; use super::*; -use std::{io::Cursor, net::TcpListener, thread}; +use std::{io::Cursor, net::TcpListener, thread, time::Duration}; #[test] -fn test_varint() -> Result<(), ProtocolError> { - let mut src = Packet::empty(0x00); +fn test_varints() -> Result<(), ProtocolError> { + /* + + Sample VarInts: - src.write_u8_varint(0)?; // 0x00 - src.write_u8_varint(1)?; // 0x01 - src.write_u8_varint(2)?; // 0x02 - src.write_u8_varint(127)?; // 0x7f - src.write_u8_varint(128)?; // 0x80 0x01 - src.write_u16_varint(255)?; // 0xff 0x01 - src.write_u16_varint(25565)?; // 0xdd 0xc7 0x01 - src.write_u32_varint(2097151)?; // 0xff 0xff 0x7f - src.write_u32_varint(2147483647)?; // 0xff 0xff 0xff 0xff 0x07 - src.write_i8_varint(-1)?; // 0xff 0xff 0xff 0xff 0x0f - src.write_i32_varint(-2147483648)?; // 0x80 0x80 0x80 0x80 0x08 + | Value | Hex bytes | + | ------------ | ---------------------------- | + | 0 | 0x00 | + | 1 | 0x01 | + | 2 | 0x02 | + | 127 | 0x7f | + | 128 | 0x80, 0x01 | + | 255 | 0xff, 0x01 | + | 25565 | 0xdd, 0xc7, 0x01 | + | 2097151 | 0xff, 0xff, 0x7f | + | 2147483647 | 0xff, 0xff, 0xff, 0xff, 0x07 | + | -1 | 0xff, 0xff, 0xff, 0xff, 0x0f | + | -2147483648 | 0x80, 0x80, 0x80, 0x80, 0x08 | - let mut packet = Packet::from_bytes(0x00, src.get_bytes()); - assert_eq!(packet.read_u8_varint()?, 0); - assert_eq!(packet.read_u8_varint()?, 1); - assert_eq!(packet.read_u8_varint()?, 2); - assert_eq!(packet.read_u8_varint()?, 127); - assert_eq!(packet.read_u8_varint()?, 128); - assert_eq!(packet.read_u16_varint()?, 255); - assert_eq!(packet.read_u16_varint()?, 25565); - assert_eq!(packet.read_u32_varint()?, 2097151); - assert_eq!(packet.read_u32_varint()?, 2147483647); - assert_eq!(packet.read_i8_varint()?, -1); - assert_eq!(packet.read_i32_varint()?, -2147483648); + */ - let mut packet = Packet::from_bytes(0x00, src.get_bytes()); - assert_eq!(packet.read_bytes(1)?, vec![0x00]); // 0 - assert_eq!(packet.read_bytes(1)?, vec![0x01]); // 1 - assert_eq!(packet.read_bytes(1)?, vec![0x02]); // 2 - assert_eq!(packet.read_bytes(1)?, vec![0x7f]); // 127 - assert_eq!(packet.read_bytes(2)?, vec![0x80, 0x01]); // 128 - assert_eq!(packet.read_bytes(2)?, vec![0xff, 0x01]); // 255 - assert_eq!(packet.read_bytes(3)?, vec![0xdd, 0xc7, 0x01]); // 25565 - assert_eq!(packet.read_bytes(3)?, vec![0xff, 0xff, 0x7f]); // 2097151 - assert_eq!(packet.read_bytes(5)?, vec![0xff, 0xff, 0xff, 0xff, 0x07]); // 2147483647 - assert_eq!(packet.read_bytes(5)?, vec![0xff, 0xff, 0xff, 0xff, 0x0f]); // -1 - assert_eq!(packet.read_bytes(5)?, vec![0x80, 0x80, 0x80, 0x80, 0x08]); // -2147483648 + let mut packet = Packet::empty(0x00); + + packet.write_varint(0)?; + packet.write_varint(1)?; + packet.write_varint(2)?; + packet.write_varint(127)?; + packet.write_varint(128)?; + packet.write_varint(255)?; + packet.write_varint(25565)?; + packet.write_varint(2097151)?; + packet.write_varint(2147483647)?; + packet.write_varint(-1)?; + packet.write_varint(-2147483648)?; + + packet.get_mut().set_position(0); + + assert_eq!(packet.read_bytes(1)?, &[0x00]); // 0 + assert_eq!(packet.read_bytes(1)?, &[0x01]); // 1 + assert_eq!(packet.read_bytes(1)?, &[0x02]); // 2 + assert_eq!(packet.read_bytes(1)?, &[0x7f]); // 127 + assert_eq!(packet.read_bytes(2)?, &[0x80, 0x01]); // 128 + assert_eq!(packet.read_bytes(2)?, &[0xff, 0x01]); // 255 + assert_eq!(packet.read_bytes(3)?, &[0xdd, 0xc7, 0x01]); // 25565 + assert_eq!(packet.read_bytes(3)?, &[0xff, 0xff, 0x7f]); // 2097151 + assert_eq!(packet.read_bytes(5)?, &[0xff, 0xff, 0xff, 0xff, 0x07]); // 2147483647 + assert_eq!(packet.read_bytes(5)?, &[0xff, 0xff, 0xff, 0xff, 0x0f]); // -1 + assert_eq!(packet.read_bytes(5)?, &[0x80, 0x80, 0x80, 0x80, 0x08]); // -2147483648 + + packet.get_mut().set_position(0); + + assert_eq!(packet.read_varint()?, 0); + assert_eq!(packet.read_varint()?, 1); + assert_eq!(packet.read_varint()?, 2); + assert_eq!(packet.read_varint()?, 127); + assert_eq!(packet.read_varint()?, 128); + assert_eq!(packet.read_varint()?, 255); + assert_eq!(packet.read_varint()?, 25565); + assert_eq!(packet.read_varint()?, 2097151); + assert_eq!(packet.read_varint()?, 2147483647); + assert_eq!(packet.read_varint()?, -1); + assert_eq!(packet.read_varint()?, -2147483648); + + Ok(()) +} + +#[test] +fn test_varlongs() -> Result<(), ProtocolError> { + /* + + Sample VarLongs: + + | Value | Hex bytes | + | --------------------- | ---------------------------------------------------------- | + | 0 | 0x00 | + | 1 | 0x01 | + | 2 | 0x02 | + | 127 | 0x7f | + | 128 | 0x80, 0x01 | + | 255 | 0xff, 0x01 | + | 2147483647 | 0xff, 0xff, 0xff, 0xff, 0x07 | + | 9223372036854775807 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, | + | -1 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01 | + | -2147483648 | 0x80, 0x80, 0x80, 0x80, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01 | + | -9223372036854775808 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01 | + + */ + + let mut packet = Packet::empty(0x00); + + packet.write_varlong(0)?; + packet.write_varlong(1)?; + packet.write_varlong(2)?; + packet.write_varlong(127)?; + packet.write_varlong(128)?; + packet.write_varlong(255)?; + packet.write_varlong(2147483647)?; + packet.write_varlong(9223372036854775807)?; + packet.write_varlong(-1)?; + packet.write_varlong(-2147483648)?; + packet.write_varlong(-9223372036854775808)?; + + packet.get_mut().set_position(0); + + assert_eq!(packet.read_bytes(1)?, &[0x00]); // 0 + assert_eq!(packet.read_bytes(1)?, &[0x01]); // 1 + assert_eq!(packet.read_bytes(1)?, &[0x02]); // 2 + assert_eq!(packet.read_bytes(1)?, &[0x7f]); // 127 + assert_eq!(packet.read_bytes(2)?, &[0x80, 0x01]); // 128 + assert_eq!(packet.read_bytes(2)?, &[0xff, 0x01]); // 255 + assert_eq!(packet.read_bytes(5)?, &[0xff, 0xff, 0xff, 0xff, 0x07]); // 2147483647 + assert_eq!(packet.read_bytes(9)?, &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]); // 9223372036854775807 + assert_eq!(packet.read_bytes(10)?, &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01]); // -1 + assert_eq!(packet.read_bytes(10)?, &[0x80, 0x80, 0x80, 0x80, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01]); // -2147483648 + assert_eq!(packet.read_bytes(10)?, &[0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01]); // -9223372036854775808 + + packet.get_mut().set_position(0); + + assert_eq!(packet.read_varlong()?, 0); + assert_eq!(packet.read_varlong()?, 1); + assert_eq!(packet.read_varlong()?, 2); + assert_eq!(packet.read_varlong()?, 127); + assert_eq!(packet.read_varlong()?, 128); + assert_eq!(packet.read_varlong()?, 255); + assert_eq!(packet.read_varlong()?, 2147483647); + assert_eq!(packet.read_varlong()?, 9223372036854775807); + assert_eq!(packet.read_varlong()?, -1); + assert_eq!(packet.read_varlong()?, -2147483648); + assert_eq!(packet.read_varlong()?, -9223372036854775808); Ok(()) } #[test] fn test_data_transfer() -> Result<(), ProtocolError> { - - thread::spawn(move || -> Result<(), ProtocolError> { - let listener = - TcpListener::bind("localhost:44447").or(Err(ProtocolError::StreamConnectError))?; - + fn server_thread(listener: TcpListener) -> Result<(), ProtocolError> { for stream in listener.incoming() { let mut stream = MCConnTcp::new(stream.or(Err(ProtocolError::StreamConnectError))?); @@ -68,8 +153,8 @@ fn test_data_transfer() -> Result<(), ProtocolError> { pack.write_bytes(&packet.read_bytes(10)?)?; pack.write_double(packet.read_double()?)?; pack.write_float(packet.read_float()?)?; - pack.write_i128_varint(packet.read_i128_varint()?)?; - pack.write_u128_varint(packet.read_u128_varint()?)?; + pack.write_varint(packet.read_varint()?)?; + pack.write_varlong(packet.read_varlong()?)?; pack.write_int(packet.read_int()?)?; pack.write_long(packet.read_long()?)?; pack.write_short(packet.read_short()?)?; @@ -88,8 +173,8 @@ fn test_data_transfer() -> Result<(), ProtocolError> { pack.write_bytes(&packet.read_bytes(10)?)?; pack.write_double(packet.read_double()?)?; pack.write_float(packet.read_float()?)?; - pack.write_i128_varint(packet.read_i128_varint()?)?; - pack.write_u128_varint(packet.read_u128_varint()?)?; + pack.write_varint(packet.read_varint()?)?; + pack.write_varlong(packet.read_varlong()?)?; pack.write_int(packet.read_int()?)?; pack.write_long(packet.read_long()?)?; pack.write_short(packet.read_short()?)?; @@ -100,79 +185,67 @@ fn test_data_transfer() -> Result<(), ProtocolError> { } Ok(()) + } + + fn test_conn(conn: &mut MinecraftConnection) -> Result<(), ProtocolError> { + conn.write_packet(&Packet::build(0xfe, |pack| { + pack.write_boolean(true)?; + pack.write_byte(0x12)?; + pack.write_bytes(&vec![0x01, 0x56, 0x47, 0x48, 0xf5, 0xc2, 0x45, 0x98, 0xde, 0x99])?; + pack.write_double(123456789.123456789f64)?; + pack.write_float(789456.44422f32)?; + pack.write_varint(468927512)?; + pack.write_varlong(99859652365236523)?; + pack.write_int(77861346i32)?; + pack.write_long(789465123545678946i64)?; + pack.write_short(1233i16)?; + pack.write_uuid(&Uuid::try_parse("550e8400-e29b-41d4-a716-446655440000").map_err(|_| ProtocolError::CloneError)?)?; + pack.write_string("&packet.read_string()?")?; + Ok(()) + })?)?; + + let mut packet = conn.read_packet()?; + + assert_eq!(packet.read_boolean()?, true); + assert_eq!(packet.read_byte()?, 0x12); + assert_eq!(packet.read_bytes(10)?, vec![0x01, 0x56, 0x47, 0x48, 0xf5, 0xc2, 0x45, 0x98, 0xde, 0x99]); + assert_eq!(packet.read_double()?, 123456789.123456789f64); + assert_eq!(packet.read_float()?, 789456.44422f32); + assert_eq!(packet.read_varint()?, 468927512); + assert_eq!(packet.read_varlong()?, 99859652365236523); + assert_eq!(packet.read_int()?, 77861346i32); + assert_eq!(packet.read_long()?, 789465123545678946i64); + assert_eq!(packet.read_short()?, 1233i16); + assert_eq!(packet.read_uuid()?, Uuid::try_parse("550e8400-e29b-41d4-a716-446655440000").map_err(|_| ProtocolError::CloneError)?); + assert_eq!(packet.read_string()?, "&packet.read_string()?"); + + Ok(()) + } + + let listener = + TcpListener::bind("127.0.0.1:0").or(Err(ProtocolError::StreamConnectError))?; + + let addr = listener.local_addr().expect("local addr error"); + + thread::spawn(move || { + server_thread(listener).expect("server error") }); - let conn = MCConnTcp::connect("localhost:44447"); - - while let Err(_) = conn {} - - let mut conn = conn?; + let mut conn = loop { + if let Ok(conn) = MCConnTcp::connect(addr) { + break conn; + } else { + thread::sleep(Duration::from_millis(10)); + } + }; conn.set_compression(Some(5)); - conn.write_packet(&Packet::build(0xfe, |pack| { - pack.write_boolean(true)?; - pack.write_byte(0x12)?; - pack.write_bytes(&vec![0x01, 0x56, 0x47, 0x48, 0xf5, 0xc2, 0x45, 0x98, 0xde, 0x99])?; - pack.write_double(123456789.123456789f64)?; - pack.write_float(789456.44422f32)?; - pack.write_i128_varint(468927513325566)?; - pack.write_u128_varint(99859652365236523)?; - pack.write_int(77861346i32)?; - pack.write_long(789465123545678946i64)?; - pack.write_short(1233i16)?; - pack.write_uuid(&Uuid::try_parse("550e8400-e29b-41d4-a716-446655440000").map_err(|_| ProtocolError::CloneError)?)?; - pack.write_string("&packet.read_string()?")?; - Ok(()) - })?)?; - - let mut packet = conn.read_packet()?; - - assert_eq!(packet.read_boolean()?, true); - assert_eq!(packet.read_byte()?, 0x12); - assert_eq!(packet.read_bytes(10)?, vec![0x01, 0x56, 0x47, 0x48, 0xf5, 0xc2, 0x45, 0x98, 0xde, 0x99]); - assert_eq!(packet.read_double()?, 123456789.123456789f64); - assert_eq!(packet.read_float()?, 789456.44422f32); - assert_eq!(packet.read_i128_varint()?, 468927513325566); - assert_eq!(packet.read_u128_varint()?, 99859652365236523); - assert_eq!(packet.read_int()?, 77861346i32); - assert_eq!(packet.read_long()?, 789465123545678946i64); - assert_eq!(packet.read_short()?, 1233i16); - assert_eq!(packet.read_uuid()?, Uuid::try_parse("550e8400-e29b-41d4-a716-446655440000").map_err(|_| ProtocolError::CloneError)?); - assert_eq!(packet.read_string()?, "&packet.read_string()?"); + test_conn(&mut conn)?; conn.set_compression(None); - conn.write_packet(&Packet::build(0xfe, |pack| { - pack.write_boolean(true)?; - pack.write_byte(0x12)?; - pack.write_bytes(&vec![0x01, 0x56, 0x47, 0x48, 0xf5, 0xc2, 0x45, 0x98, 0xde, 0x99])?; - pack.write_double(123456789.123456789f64)?; - pack.write_float(789456.44422f32)?; - pack.write_i128_varint(468927513325566)?; - pack.write_u128_varint(99859652365236523)?; - pack.write_int(77861346i32)?; - pack.write_long(789465123545678946i64)?; - pack.write_short(1233i16)?; - pack.write_uuid(&Uuid::try_parse("550e8400-e29b-41d4-a716-446655440000").map_err(|_| ProtocolError::CloneError)?)?; - pack.write_string("&packet.read_string()?")?; - Ok(()) - })?)?; - - let mut packet = conn.read_packet()?; - - assert_eq!(packet.read_boolean()?, true); - assert_eq!(packet.read_byte()?, 0x12); - assert_eq!(packet.read_bytes(10)?, vec![0x01, 0x56, 0x47, 0x48, 0xf5, 0xc2, 0x45, 0x98, 0xde, 0x99]); - assert_eq!(packet.read_double()?, 123456789.123456789f64); - assert_eq!(packet.read_float()?, 789456.44422f32); - assert_eq!(packet.read_i128_varint()?, 468927513325566); - assert_eq!(packet.read_u128_varint()?, 99859652365236523); - assert_eq!(packet.read_int()?, 77861346i32); - assert_eq!(packet.read_long()?, 789465123545678946i64); - assert_eq!(packet.read_short()?, 1233i16); - assert_eq!(packet.read_uuid()?, Uuid::try_parse("550e8400-e29b-41d4-a716-446655440000").map_err(|_| ProtocolError::CloneError)?); - assert_eq!(packet.read_string()?, "&packet.read_string()?"); + test_conn(&mut conn)?; Ok(()) }