compression_type and more comments

This commit is contained in:
MeexReay 2024-07-16 02:09:05 +03:00
parent 93e392ff22
commit 1651c9828c
2 changed files with 328 additions and 134 deletions

View File

@ -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<T> { fn zigzag(&self) -> T; }
impl Zigzag<u8> for i8 { fn zigzag(&self) -> u8 { ((self << 1) ^ (self >> 7)) as u8 } }
impl Zigzag<i8> for u8 { fn zigzag(&self) -> i8 { ((self >> 1) as i8) ^ (-((self & 1) as i8)) } }
impl Zigzag<u16> for i16 { fn zigzag(&self) -> u16 { ((self << 1) ^ (self >> 15)) as u16 } }
impl Zigzag<i16> for u16 { fn zigzag(&self) -> i16 { ((self >> 1) as i16) ^ (-((self & 1) as i16)) } }
impl Zigzag<u32> for i32 { fn zigzag(&self) -> u32 { ((self << 1) ^ (self >> 31)) as u32 } }
impl Zigzag<i32> for u32 { fn zigzag(&self) -> i32 { ((self >> 1) as i32) ^ (-((self & 1) as i32)) } }
impl Zigzag<u64> for i64 { fn zigzag(&self) -> u64 { ((self << 1) ^ (self >> 63)) as u64 } }
impl Zigzag<i64> for u64 { fn zigzag(&self) -> i64 { ((self >> 1) as i64) ^ (-((self & 1) as i64)) } }
impl Zigzag<u128> for i128 { fn zigzag(&self) -> u128 { ((self << 1) ^ (self >> 127)) as u128 } }
impl Zigzag<i128> for u128 { fn zigzag(&self) -> i128 { ((self >> 1) as i128) ^ (-((self & 1) as i128)) } }
impl Zigzag<usize> for isize { fn zigzag(&self) -> usize { ((self << 1) ^ (self >> std::mem::size_of::<usize>()-1)) as usize } }
impl Zigzag<isize> for usize { fn zigzag(&self) -> isize { ((self >> 1) as isize) ^ (-((self & 1) as isize)) } }
pub trait Zigzag<T> {
fn zigzag(&self) -> T;
}
impl Zigzag<u8> for i8 {
fn zigzag(&self) -> u8 {
((self << 1) ^ (self >> 7)) as u8
}
}
impl Zigzag<i8> for u8 {
fn zigzag(&self) -> i8 {
((self >> 1) as i8) ^ (-((self & 1) as i8))
}
}
impl Zigzag<u16> for i16 {
fn zigzag(&self) -> u16 {
((self << 1) ^ (self >> 15)) as u16
}
}
impl Zigzag<i16> for u16 {
fn zigzag(&self) -> i16 {
((self >> 1) as i16) ^ (-((self & 1) as i16))
}
}
impl Zigzag<u32> for i32 {
fn zigzag(&self) -> u32 {
((self << 1) ^ (self >> 31)) as u32
}
}
impl Zigzag<i32> for u32 {
fn zigzag(&self) -> i32 {
((self >> 1) as i32) ^ (-((self & 1) as i32))
}
}
impl Zigzag<u64> for i64 {
fn zigzag(&self) -> u64 {
((self << 1) ^ (self >> 63)) as u64
}
}
impl Zigzag<i64> for u64 {
fn zigzag(&self) -> i64 {
((self >> 1) as i64) ^ (-((self & 1) as i64))
}
}
impl Zigzag<u128> for i128 {
fn zigzag(&self) -> u128 {
((self << 1) ^ (self >> 127)) as u128
}
}
impl Zigzag<i128> for u128 {
fn zigzag(&self) -> i128 {
((self >> 1) as i128) ^ (-((self & 1) as i128))
}
}
impl Zigzag<usize> for isize {
fn zigzag(&self) -> usize {
((self << 1) ^ (self >> std::mem::size_of::<usize>() - 1)) as usize
}
}
impl Zigzag<isize> 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,7 +171,8 @@ 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))
}
}};
}
@ -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,59 +253,124 @@ 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<usize, ProtocolError> { read_varint!(usize, self) }
fn read_usize_varint(&mut self) -> Result<usize, ProtocolError> {
read_varint!(usize, self)
}
/// Read VarInt as u8
fn read_u8_varint(&mut self) -> Result<u8, ProtocolError> { read_varint!(u8, self) }
fn read_u8_varint(&mut self) -> Result<u8, ProtocolError> {
read_varint!(u8, self)
}
/// Read VarInt as u16
fn read_u16_varint(&mut self) -> Result<u16, ProtocolError> { read_varint!(u16, self) }
fn read_u16_varint(&mut self) -> Result<u16, ProtocolError> {
read_varint!(u16, self)
}
/// Read VarInt as u32
fn read_u32_varint(&mut self) -> Result<u32, ProtocolError> { read_varint!(u32, self) }
fn read_u32_varint(&mut self) -> Result<u32, ProtocolError> {
read_varint!(u32, self)
}
/// Read VarInt as u64
fn read_u64_varint(&mut self) -> Result<u64, ProtocolError> { read_varint!(u64, self) }
fn read_u64_varint(&mut self) -> Result<u64, ProtocolError> {
read_varint!(u64, self)
}
/// Read VarInt as u128
fn read_u128_varint(&mut self) -> Result<u128, ProtocolError> { read_varint!(u128, self) }
fn read_u128_varint(&mut self) -> Result<u128, ProtocolError> {
read_varint!(u128, self)
}
/// Read VarInt as isize
fn read_isize_varint(&mut self) -> Result<isize, ProtocolError> { Ok(self.read_usize_varint()?.zigzag()) }
fn read_isize_varint(&mut self) -> Result<isize, ProtocolError> {
Ok(self.read_usize_varint()?.zigzag())
}
/// Read VarInt as i8
fn read_i8_varint(&mut self) -> Result<i8, ProtocolError> { Ok(self.read_u8_varint()?.zigzag()) }
fn read_i8_varint(&mut self) -> Result<i8, ProtocolError> {
Ok(self.read_u8_varint()?.zigzag())
}
/// Read VarInt as i16
fn read_i16_varint(&mut self) -> Result<i16, ProtocolError> { Ok(self.read_u16_varint()?.zigzag()) }
fn read_i16_varint(&mut self) -> Result<i16, ProtocolError> {
Ok(self.read_u16_varint()?.zigzag())
}
/// Read VarInt as i32
fn read_i32_varint(&mut self) -> Result<i32, ProtocolError> { Ok(self.read_u32_varint()?.zigzag()) }
fn read_i32_varint(&mut self) -> Result<i32, ProtocolError> {
Ok(self.read_u32_varint()?.zigzag())
}
/// Read VarInt as i64
fn read_i64_varint(&mut self) -> Result<i64, ProtocolError> { Ok(self.read_u64_varint()?.zigzag()) }
fn read_i64_varint(&mut self) -> Result<i64, ProtocolError> {
Ok(self.read_u64_varint()?.zigzag())
}
/// Read VarInt as i128
fn read_i128_varint(&mut self) -> Result<i128, ProtocolError> { Ok(self.read_u128_varint()?.zigzag()) }
fn read_i128_varint(&mut self) -> Result<i128, ProtocolError> {
Ok(self.read_u128_varint()?.zigzag())
}
}
/// Packet data writer trait
pub trait DataBufferWriter {
/// Write bytes
@ -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<R: Read> DataBufferReader for R {
@ -367,10 +517,7 @@ impl<W: Write> 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<F>(
id: u8,
builder: F
) -> Result<Packet, ProtocolError>
where F: FnOnce(&mut Packet) -> Result<(), ProtocolError> {
pub fn build<F>(id: u8, builder: F) -> Result<Packet, ProtocolError>
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<T: Read + Write> {
stream: T,
compression: Arc<AtomicUsize>
compression: Arc<AtomicUsize>,
compression_type: u32,
}
impl MinecraftConnection<TcpStream> {
/// Connect to Minecraft Server with TcpStream
pub fn connect(addr: &str) -> Result<MinecraftConnection<TcpStream>, 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<TcpStream> {
/// Try clone MinecraftConnection with compression and stream
pub fn try_clone(&mut self) -> Result<MinecraftConnection<TcpStream>, 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),
}
}
}
@ -537,22 +682,21 @@ impl<T: Read + Write> MinecraftConnection<T> {
pub fn new(stream: T) -> MinecraftConnection<T> {
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<usize>) {
self.compression = Arc::new(AtomicUsize::new(
match threshold {
self.compression = Arc::new(AtomicUsize::new(match threshold {
Some(t) => t,
None => usize::MAX,
}
));
}));
}
/// Get compression threshold
pub fn get_compression(&self) -> Option<usize> {
pub fn compression(&self) -> Option<usize> {
let threshold = self.compression.load(Ordering::Relaxed);
if threshold == usize::MAX {
None
@ -561,6 +705,24 @@ impl<T: Read + Write> MinecraftConnection<T> {
}
}
/// 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
@ -576,7 +738,8 @@ impl<T: Read + Write> MinecraftConnection<T> {
read_packet_atomic(
&mut self.stream,
self.compression.clone(),
Ordering::Relaxed)
Ordering::Relaxed,
)
}
/// Write [`Packet`](Packet) to connection
@ -585,7 +748,9 @@ impl<T: Read + Write> MinecraftConnection<T> {
&mut self.stream,
self.compression.clone(),
Ordering::Relaxed,
packet)
self.compression_type,
packet,
)
}
}
@ -594,13 +759,14 @@ impl<T: Read + Write + Clone> MinecraftConnection<T> {
pub fn clone(&mut self) -> MinecraftConnection<T> {
MinecraftConnection {
stream: self.stream.clone(),
compression: self.compression.clone()
compression: self.compression.clone(),
compression_type: self.compression_type,
}
}
}
fn compress_zlib(bytes: &[u8]) -> Result<Vec<u8>, ProtocolError> {
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
fn compress_zlib(bytes: &[u8], compression: u32) -> Result<Vec<u8>, 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<Vec<u8>, ProtocolError> {
fn decompress_zlib(bytes: &[u8]) -> Result<Vec<u8>, 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<T> = MinecraftConnection<T>;
/// MinecraftConnection\<TcpStream\> shorter alias
pub type MCConnTcp = MinecraftConnection<TcpStream>;
/// Read [`Packet`](Packet) from stream, if compression is usize::MAX, compression is disabled
pub fn read_packet_atomic<T: Read>(stream: &mut T, compression: Arc<AtomicUsize>, ordering: Ordering) -> Result<Packet, ProtocolError> {
/// 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<T: Read>(
stream: &mut T,
compression: Arc<AtomicUsize>,
ordering: Ordering,
) -> Result<Packet, ProtocolError> {
let mut data: Vec<u8>;
let packet_length = stream.read_usize_varint_size()?;
@ -641,8 +818,23 @@ pub fn read_packet_atomic<T: Read>(stream: &mut T, compression: Arc<AtomicUsize>
Ok(Packet::from_data(&data)?)
}
/// Write [`Packet`](Packet) to stream, if compression is usize::MAX, compression is disabled
pub fn write_packet_atomic<T: Write>(stream: &mut T, compression: Arc<AtomicUsize>, 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<T: Write>(
stream: &mut T,
compression: Arc<AtomicUsize>,
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<T: Write>(stream: &mut T, compression: Arc<AtomicUsiz
let mut packet_buf = ByteBuffer::new();
if data_buf.len() >= 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)?;

View File

@ -4,7 +4,9 @@ use std::{net::TcpListener, thread};
#[test]
fn test_compression_server_client() -> Result<(), ProtocolError> {
fn test(first_text: &str) -> Result<bool, ProtocolError> {
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);
@ -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(())
}