From 1651c9828cbe3398a10431e5e03c3a6ca5d7123d Mon Sep 17 00:00:00 2001 From: MeexReay Date: Tue, 16 Jul 2024 02:09:05 +0300 Subject: [PATCH] compression_type and more comments --- src/lib.rs | 428 +++++++++++++++++++++++++++++++++++++-------------- src/tests.rs | 34 ++-- 2 files changed, 328 insertions(+), 134 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 14ae155..feec248 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,25 +1,85 @@ -use std::{error::Error, fmt, io::{Read, Write}, net::{TcpStream, ToSocketAddrs}, sync::{Arc, atomic::{AtomicUsize, Ordering}}}; -use flate2::{read::ZlibDecoder, write::ZlibEncoder, Compression}; use bytebuffer::ByteBuffer; +use flate2::{read::ZlibDecoder, write::ZlibEncoder, Compression}; +use std::{ + error::Error, + fmt, + io::{Read, Write}, + net::{TcpStream, ToSocketAddrs}, + sync::{ + atomic::{AtomicUsize, Ordering}, + 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)) } } +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)] pub enum ProtocolError { AddressParseError, @@ -31,7 +91,7 @@ pub enum ProtocolError { WriteError, ZlibError, UnsignedShortError, - CloneError + CloneError, } impl fmt::Display for ProtocolError { @@ -46,7 +106,7 @@ impl Error for ProtocolError {} #[derive(Debug, Clone)] pub struct Packet { id: u8, - buffer: ByteBuffer + buffer: ByteBuffer, } macro_rules! size_varint { @@ -111,12 +171,13 @@ macro_rules! write_varint { DataBufferWriter::write_byte($self, next).or(Err(ProtocolError::VarIntError))?; } - DataBufferWriter::write_byte($self, (value & 0b01111111) as u8).or(Err(ProtocolError::VarIntError)) + DataBufferWriter::write_byte($self, (value & 0b01111111) as u8) + .or(Err(ProtocolError::VarIntError)) } }}; } -/// Packet data reader trait +/// Packet data reader trait pub trait DataBufferReader { /// Read bytes fn read_bytes(&mut self, size: usize) -> Result, ProtocolError>; @@ -134,7 +195,7 @@ pub trait DataBufferReader { let size = self.read_usize_varint()?; match String::from_utf8(self.read_bytes(size)?) { Ok(i) => Ok(i), - Err(_) => Err(ProtocolError::StringParseError) + Err(_) => Err(ProtocolError::StringParseError), } } /// Read Unsigned Short as u16 @@ -192,60 +253,125 @@ pub trait DataBufferReader { } /// 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) } + 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) } + 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) } + 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) } + 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) } + 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) } + 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())}) } + 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())}) } + 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())}) } + 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())}) } + 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())}) } + 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())}) } + 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) } + 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) } + 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) } + 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) } + 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) } + 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) } + 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()) } + 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()) } + 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()) } + 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()) } + 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()) } + 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()) } + fn read_i128_varint(&mut self) -> Result { + Ok(self.read_u128_varint()?.zigzag()) + } } - -/// Packet data writer trait +/// Packet data writer trait pub trait DataBufferWriter { /// Write bytes fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), ProtocolError>; @@ -319,30 +445,54 @@ pub trait DataBufferWriter { } /// Write VarInt as usize - fn write_usize_varint(&mut self, val: usize) -> Result<(), ProtocolError> { write_varint!(usize, self, val) } + 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) } + 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) } + 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) } + 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) } + 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) } + 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()) } + 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()) } + 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()) } + 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()) } + 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()) } + 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()) } + fn write_i128_varint(&mut self, val: i128) -> Result<(), ProtocolError> { + self.write_u128_varint(val.zigzag()) + } } impl DataBufferReader for R { @@ -367,10 +517,7 @@ impl DataBufferWriter for W { impl Packet { /// Create new packet from id and buffer pub fn new(id: u8, buffer: ByteBuffer) -> Packet { - Packet { - id, - buffer - } + Packet { id, buffer } } /// Create new packet from packet data @@ -378,12 +525,12 @@ impl Packet { 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)?; + 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) + buffer: ByteBuffer::from_bytes(&packet_data), }) } @@ -391,7 +538,7 @@ impl Packet { pub fn from_bytes(id: u8, data: &[u8]) -> Packet { Packet { id, - buffer: ByteBuffer::from_bytes(data) + buffer: ByteBuffer::from_bytes(data), } } @@ -399,16 +546,15 @@ impl Packet { pub fn empty(id: u8) -> Packet { Packet { id, - buffer: ByteBuffer::new() + buffer: ByteBuffer::new(), } } /// Build packet with lambda - pub fn build( - id: u8, - builder: F - ) -> Result - where F: FnOnce(&mut Packet) -> Result<(), ProtocolError> { + 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) @@ -464,30 +610,33 @@ impl DataBufferWriter for Packet { } } +/// Minecraft connection, wrapper for stream with compression pub struct MinecraftConnection { stream: T, - compression: Arc + compression: Arc, + compression_type: u32, } impl MinecraftConnection { /// Connect to Minecraft Server with TcpStream 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) }, + 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) }, + Err(_) => return Err(ProtocolError::StreamConnectError), }; - + Ok(MinecraftConnection { stream, - compression: Arc::new(AtomicUsize::new(usize::MAX)) + compression: Arc::new(AtomicUsize::new(usize::MAX)), + compression_type: 1, }) } @@ -499,17 +648,13 @@ impl MinecraftConnection { /// Try clone MinecraftConnection with compression and stream pub fn try_clone(&mut self) -> Result, ProtocolError> { match self.stream.try_clone() { - Ok(stream) => { - Ok(MinecraftConnection { - stream: stream, - compression: self.compression.clone() - }) - }, - _ => { - Err(ProtocolError::CloneError) - }, + Ok(stream) => Ok(MinecraftConnection { + stream, + compression: self.compression.clone(), + compression_type: 1, + }), + _ => Err(ProtocolError::CloneError), } - } } @@ -535,24 +680,23 @@ impl DataBufferWriter for MinecraftConnection { impl MinecraftConnection { /// Create new MinecraftConnection from stream pub fn new(stream: T) -> MinecraftConnection { - MinecraftConnection { + MinecraftConnection { stream, - compression: Arc::new(AtomicUsize::new(usize::MAX)) + compression: Arc::new(AtomicUsize::new(usize::MAX)), + compression_type: 1, } } /// Set compression threshold pub fn set_compression(&mut self, threshold: Option) { - self.compression = Arc::new(AtomicUsize::new( - match threshold { - Some(t) => t, - None => usize::MAX, - } - )); + self.compression = Arc::new(AtomicUsize::new(match threshold { + Some(t) => t, + None => usize::MAX, + })); } /// Get compression threshold - pub fn get_compression(&self) -> Option { + pub fn compression(&self) -> Option { let threshold = self.compression.load(Ordering::Relaxed); if threshold == usize::MAX { None @@ -561,6 +705,24 @@ impl MinecraftConnection { } } + /// Set compression type + /// + /// `compression_type` is integer from 0 (none) to 9 (longest) + /// 1 is fast compression + /// 6 is normal compression + pub fn set_compression_type(&mut self, compression_type: u32) { + self.compression_type = compression_type; + } + + /// Get compression type + /// + /// `compression_type` is integer from 0 (none) to 9 (longest) + /// 1 is fast compression + /// 6 is normal compression + pub fn compression_type(&self) -> u32 { + self.compression_type + } + /// Get mutable reference of stream pub fn get_mut(&mut self) -> &mut T { &mut self.stream @@ -574,18 +736,21 @@ impl MinecraftConnection { /// Read [`Packet`](Packet) from connection pub fn read_packet(&mut self) -> Result { read_packet_atomic( - &mut self.stream, + &mut self.stream, self.compression.clone(), - Ordering::Relaxed) + Ordering::Relaxed, + ) } /// Write [`Packet`](Packet) to connection pub fn write_packet(&mut self, packet: &Packet) -> Result<(), ProtocolError> { write_packet_atomic( - &mut self.stream, - self.compression.clone(), + &mut self.stream, + self.compression.clone(), Ordering::Relaxed, - packet) + self.compression_type, + packet, + ) } } @@ -594,13 +759,14 @@ impl MinecraftConnection { pub fn clone(&mut self) -> MinecraftConnection { MinecraftConnection { stream: self.stream.clone(), - compression: self.compression.clone() + compression: self.compression.clone(), + compression_type: self.compression_type, } } } -fn compress_zlib(bytes: &[u8]) -> Result, ProtocolError> { - let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default()); +fn compress_zlib(bytes: &[u8], compression: u32) -> Result, ProtocolError> { + let mut encoder = ZlibEncoder::new(Vec::new(), Compression::new(compression)); encoder.write_all(bytes).or(Err(ProtocolError::ZlibError))?; encoder.finish().or(Err(ProtocolError::ZlibError)) } @@ -608,7 +774,9 @@ fn compress_zlib(bytes: &[u8]) -> Result, ProtocolError> { fn decompress_zlib(bytes: &[u8]) -> Result, ProtocolError> { let mut decoder = ZlibDecoder::new(bytes); let mut output = Vec::new(); - decoder.read_to_end(&mut output).or(Err(ProtocolError::ZlibError))?; + decoder + .read_to_end(&mut output) + .or(Err(ProtocolError::ZlibError))?; Ok(output) } @@ -618,8 +786,17 @@ pub type MCConn = MinecraftConnection; /// MinecraftConnection\ shorter alias pub type MCConnTcp = MinecraftConnection; -/// Read [`Packet`](Packet) from stream, if compression is usize::MAX, compression is disabled -pub fn read_packet_atomic(stream: &mut T, compression: Arc, ordering: Ordering) -> Result { +/// Read [`Packet`](Packet) from stream +/// +/// `compression` here is atomic usize +/// usize::MAX means that compression is disabled +/// +/// `ordering` is order how to load atomic +pub fn read_packet_atomic( + stream: &mut T, + compression: Arc, + ordering: Ordering, +) -> Result { let mut data: Vec; let packet_length = stream.read_usize_varint_size()?; @@ -641,8 +818,23 @@ pub fn read_packet_atomic(stream: &mut T, compression: Arc Ok(Packet::from_data(&data)?) } -/// Write [`Packet`](Packet) to stream, if compression is usize::MAX, compression is disabled -pub fn write_packet_atomic(stream: &mut T, compression: Arc, ordering: Ordering, packet: &Packet) -> Result<(), ProtocolError> { +/// Write [`Packet`](Packet) to stream +/// +/// `compression` here is atomic usize +/// usize::MAX means that compression is disabled +/// +/// `ordering` is order how to load atomic +/// +/// `compression_type` is integer from 0 (none) to 9 (longest) +/// 1 is fast compression +/// 6 is normal compression +pub fn write_packet_atomic( + stream: &mut T, + compression: Arc, + ordering: Ordering, + compression_type: u32, + packet: &Packet, +) -> Result<(), ProtocolError> { let mut buf = ByteBuffer::new(); let mut data_buf = ByteBuffer::new(); @@ -655,9 +847,11 @@ pub fn write_packet_atomic(stream: &mut T, compression: Arc= compress_threshold { - let compressed_data = compress_zlib(data_buf.as_bytes())?; + let compressed_data = compress_zlib(data_buf.as_bytes(), compression_type)?; packet_buf.write_usize_varint(data_buf.len())?; - packet_buf.write_all(&compressed_data).or(Err(ProtocolError::WriteError))?; + packet_buf + .write_all(&compressed_data) + .or(Err(ProtocolError::WriteError))?; } else { packet_buf.write_usize_varint(0)?; packet_buf.write_buffer(&data_buf)?; @@ -673,4 +867,4 @@ pub fn write_packet_atomic(stream: &mut T, compression: Arc Result<(), ProtocolError> { fn test(first_text: &str) -> Result { - let Ok(mut conn) = MCConnTcp::connect("localhost:44447") else { return test(first_text) }; + let Ok(mut conn) = MCConnTcp::connect("localhost:44447") else { + return test(first_text); + }; conn.set_compression(Some(5)); - + let mut packet = Packet::empty(0x12); packet.write_string(first_text)?; conn.write_packet(&packet)?; @@ -22,7 +24,8 @@ fn test_compression_server_client() -> Result<(), ProtocolError> { } thread::spawn(move || -> Result<(), ProtocolError> { - let listener = TcpListener::bind("localhost:44447").or(Err(ProtocolError::StreamConnectError))?; + let listener = + TcpListener::bind("localhost:44447").or(Err(ProtocolError::StreamConnectError))?; for stream in listener.incoming() { let mut stream = MCConnTcp::new(stream.or(Err(ProtocolError::StreamConnectError))?); @@ -45,22 +48,19 @@ fn test_compression_server_client() -> Result<(), ProtocolError> { #[test] fn test_compression_atomic_bytebuffer() -> Result<(), ProtocolError> { - let packet_1 = Packet::build(0x12, |p| { - p.write_bytes(b"1234567890qwertyuiopasdfghjklzxcvbnm") - })?; + let mut conn = MCConn::new(ByteBuffer::new()); + conn.set_compression(Some(5)); - let compression = Arc::new(AtomicUsize::new(5)); + let mut packet_1 = Packet::empty(0x12); + packet_1.write_bytes(b"1234567890qwertyuiopasdfghjklzxcvbnm")?; + conn.write_packet(&packet_1)?; - let mut buffer = ByteBuffer::new(); + let mut packet_2 = conn.read_packet()?; - write_packet_atomic(&mut buffer, compression.clone(), Ordering::Acquire, &packet_1)?; - - buffer.set_rpos(0); - buffer.set_wpos(0); - - let mut packet_2 = read_packet_atomic(&mut buffer, compression.clone(), Ordering::Acquire)?; - - assert_eq!(packet_2.read_bytes(36)?, b"1234567890qwertyuiopasdfghjklzxcvbnm"); + assert_eq!( + packet_2.read_bytes(36)?, + b"1234567890qwertyuiopasdfghjklzxcvbnm" + ); Ok(()) -} \ No newline at end of file +}