fix compression mb

This commit is contained in:
MeexReay 2024-05-23 19:15:38 +03:00
parent 9f34891b8a
commit 8058a05876
4 changed files with 119 additions and 134 deletions

View File

@ -7,10 +7,10 @@ license-file = "LICENSE"
readme = "README.md"
keywords = ["minecraft", "protocol", "packets", "lightweight"]
version = "0.1.6"
version = "0.1.7"
edition = "2021"
[dependencies]
flate2 = "1.0.30"
flate2 = { version = "1.0.30", features = ["zlib"]}
bytebuffer = "2.2.0"
uuid = "1.8.0"

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,38 @@
use std::{net::TcpListener, sync::{atomic::AtomicBool, atomic::Ordering}, thread};
use std::sync::mpsc::channel;
use rust_mc_proto::{DataBufferReader, DataBufferWriter, MCConn, MCConnTcp, MinecraftConnection, Packet, ProtocolError};
const LONG_TEXT: &str = "some_long_text_wow_123123123123123123123123";
fn main() {
let (tx, rx) = channel::<()>();
let server_tx = tx.clone();
thread::spawn(move || {
let listener = TcpListener::bind("localhost:44447").unwrap();
server_tx.send(()).unwrap();
for stream in listener.incoming() {
let mut stream = MCConnTcp::new(stream.unwrap());
stream.set_compression(2);
let packet = stream.read_packet().unwrap();
stream.write_packet(&packet).unwrap();
}
});
rx.recv().unwrap();
let mut conn = MCConnTcp::connect("localhost:44447").unwrap();
conn.set_compression(2);
let mut packet = Packet::empty(0x12);
packet.write_string(LONG_TEXT).unwrap();
conn.write_packet(&packet).unwrap();
let mut packet = conn.read_packet().unwrap();
if packet.id == 0x12 && packet.read_string().unwrap() == LONG_TEXT {
println!("success");
}
}

View File

@ -1,7 +1,8 @@
use std::io::{Write, Read};
use std::net::{TcpStream, ToSocketAddrs};
use flate2::bufread::ZlibDecoder;
use flate2::read::ZlibDecoder;
use flate2::write::ZlibEncoder;
use flate2::{Compress, Compression, Decompress, FlushCompress, Status, FlushDecompress};
use bytebuffer::ByteBuffer;
use uuid::Uuid;
@ -116,6 +117,15 @@ macro_rules! write_varint {
};
}
macro_rules! return_error {
($ex: expr, $error: expr) => {
match $ex {
Ok(i) => i,
Err(_) => { return Err($error) },
}
};
}
pub trait DataBufferReader {
fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, ProtocolError>;
fn read_byte(&mut self) -> Result<u8, ProtocolError>;
@ -265,14 +275,8 @@ pub trait DataBufferWriter {
impl<R: Read> DataBufferReader for R {
fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, ProtocolError> {
let mut buf = vec![0; size];
match self.read(&mut buf) {
Ok(i) => {
if i < size {
Err(ProtocolError::ReadError)
} else {
Ok(buf)
}
},
match self.read_exact(&mut buf) {
Ok(_) => Ok(buf),
Err(_) => Err(ProtocolError::ReadError),
}
}
@ -391,14 +395,8 @@ impl MinecraftConnection<TcpStream> {
impl<T: Read + Write> DataBufferReader for MinecraftConnection<T> {
fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, ProtocolError> {
let mut buf = vec![0; size];
match self.stream.read(&mut buf) {
Ok(i) => {
if i < size {
Err(ProtocolError::ReadError)
} else {
Ok(buf)
}
},
match self.stream.read_exact(&mut buf) {
Ok(_) => Ok(buf),
Err(_) => Err(ProtocolError::ReadError),
}
}
@ -436,155 +434,81 @@ impl<T: Read + Write> MinecraftConnection<T> {
self.compress = true;
self.compress_threashold = threashold;
}
pub fn read_packet(&mut self) -> Result<Packet, ProtocolError> {
if !self.compress {
let length = self.read_usize_varint()?;
let packet_id = self.read_u8_varint()?;
let mut data: Vec<u8> = vec![0; length - 1];
match self.stream.read_exact(&mut data) {
Ok(i) => i,
Err(_) => { return Err(ProtocolError::ReadError) },
};
let data = self.read_bytes(length - 1)?;
return Ok(Packet::from_bytes(packet_id, &data))
}
let packet_length = self.read_usize_varint_size()?;
let data_length = self.read_usize_varint_size()?;
if data_length.0 == 0 {
let packet_length = self.read_usize_varint()?;
let data_length = self.read_usize_varint()?;
if data_length == 0 {
let packet_id = self.read_u8_varint()?;
let mut data: Vec<u8> = vec![0; packet_length.0 - 2];
match self.stream.read_exact(&mut data) {
Ok(i) => i,
Err(_) => { return Err(ProtocolError::ReadError) },
};
let data = self.read_bytes(packet_length - 2)?;
return Ok(Packet::from_bytes(packet_id, &data))
}
let mut data: Vec<u8> = vec![0; packet_length.0 - packet_length.1 - data_length.1];
match self.stream.read_exact(&mut data) {
Ok(i) => i,
Err(_) => { return Err(ProtocolError::ReadError) },
};
let data = self.read_bytes(packet_length - 2)?;
let mut data_buf = ByteBuffer::from_vec(decompress_zlib(&data, packet_length)?);
let mut data_buf = ByteBuffer::from_vec(decompress_zlib(&data, packet_length.0 - packet_length.1 - data_length.1)?);
let packet_id = return_error!(data_buf.read_u8_varint(), ProtocolError::VarIntError);
let mut packet_data = vec![0; data_length - 1];
return_error!(data_buf.read_exact(&mut packet_data), ProtocolError::ReadError);
let packet_id = match data_buf.read_u8_varint() {
Ok(i) => i,
Err(_) => { return Err(ProtocolError::VarIntError) },
};
let mut data: Vec<u8> = vec![0; packet_length.0 - packet_length.1 - data_length.1 - 1];
match data_buf.read_exact(&mut data) {
Ok(i) => i,
Err(_) => { return Err(ProtocolError::ReadError) },
};
Ok(Packet::from_bytes(packet_id, &data))
Ok(Packet::from_bytes(packet_id, &packet_data))
}
pub fn write_packet(&mut self, packet: &Packet) -> Result<(), ProtocolError> {
pub fn write_packet(&mut self, pack: &Packet) -> Result<(), ProtocolError> {
let mut buf = ByteBuffer::new();
if !self.compress {
match buf.write_usize_varint(packet.buffer.len() + 1) {
Ok(_) => {},
Err(_) => { return Err(ProtocolError::WriteError) },
};
match buf.write_u8_varint(packet.id) {
Ok(_) => {},
Err(_) => { return Err(ProtocolError::WriteError) },
};
match buf.write_all(packet.buffer.as_bytes()) {
Ok(_) => {},
Err(_) => { return Err(ProtocolError::WriteError) },
};
return_error!(buf.write_usize_varint(pack.buffer.len() + 1), ProtocolError::WriteError);
return_error!(buf.write_u8_varint(pack.id), ProtocolError::WriteError);
return_error!(buf.write_all(pack.buffer.as_bytes()), ProtocolError::WriteError);
} else {
let mut pack = ByteBuffer::new();
let mut packet = ByteBuffer::new();
if packet.buffer.len() < self.compress_threashold {
match pack.write_usize_varint(0) {
Ok(_) => {},
Err(_) => { return Err(ProtocolError::WriteError) },
};
match pack.write_u8_varint(packet.id) {
Ok(_) => {},
Err(_) => { return Err(ProtocolError::WriteError) },
};
match pack.write_all(packet.buffer.as_bytes()) {
Ok(_) => {},
Err(_) => { return Err(ProtocolError::WriteError) },
};
} else {
let mut data = ByteBuffer::new();
return_error!(data.write_u8_varint(pack.id), ProtocolError::WriteError);
return_error!(data.write_all(pack.buffer.as_bytes()), ProtocolError::WriteError);
match data.write_u8_varint(packet.id) {
Ok(_) => {},
Err(_) => { return Err(ProtocolError::WriteError) },
};
match data.write_all(packet.buffer.as_bytes()) {
Ok(_) => {},
Err(_) => { return Err(ProtocolError::WriteError) },
};
let data = compress_zlib(data.as_bytes())?;
match pack.write_usize_varint(packet.buffer.len() + 1) {
Ok(_) => {},
Err(_) => { return Err(ProtocolError::WriteError) },
};
match pack.write_all(&data) {
Ok(_) => {},
Err(_) => { return Err(ProtocolError::WriteError) },
};
if pack.buffer.len() < self.compress_threashold {
return_error!(packet.write_usize_varint(0), ProtocolError::WriteError); // data length
return_error!(packet.write_all(data.as_bytes()), ProtocolError::WriteError);
} else {
return_error!(packet.write_usize_varint(data.len()), ProtocolError::WriteError); // data length
return_error!(packet.write_all(&compress_zlib(data.as_bytes())?), ProtocolError::WriteError);
}
match buf.write_usize_varint(pack.len()) {
Ok(_) => {},
Err(_) => { return Err(ProtocolError::WriteError) },
};
match buf.write_all(pack.as_bytes()) {
Ok(_) => {},
Err(_) => { return Err(ProtocolError::WriteError) },
};
return_error!(buf.write_usize_varint(packet.len()), ProtocolError::WriteError); // packet length
return_error!(buf.write_all(packet.as_bytes()), ProtocolError::WriteError);
}
match self.stream.write_all(buf.as_bytes()) {
Ok(_) => {},
Err(_) => { return Err(ProtocolError::WriteError) },
};
return_error!(self.write_bytes(buf.as_bytes()), ProtocolError::WriteError);
Ok(())
}
}
fn compress_zlib(bytes: &[u8]) -> Result<Vec<u8>, ProtocolError> {
let mut compresser = Compress::new(Compression::best(), true);
let mut output: Vec<u8> = Vec::new();
match compresser.compress_vec(&bytes, &mut output, FlushCompress::Finish) {
Ok(i) => {
match i {
Status::Ok => Ok(output),
_ => Err(ProtocolError::ZlibError),
}
},
Err(_) => Err(ProtocolError::ZlibError)
}
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::fast());
return_error!(encoder.write_all(bytes), ProtocolError::ZlibError);
let output = return_error!(encoder.finish(), ProtocolError::ZlibError);
Ok(output)
}
fn decompress_zlib(bytes: &[u8], packet_length: usize) -> Result<Vec<u8>, ProtocolError> {
let mut compresser = Decompress::new(true);
let mut output: Vec<u8> = Vec::with_capacity(packet_length);
match compresser.decompress_vec(&bytes, &mut output, FlushDecompress::Sync) {
Ok(i) => {
match i {
Status::Ok => Ok(output),
_ => Err(ProtocolError::ZlibError),
}
},
Err(_) => Err(ProtocolError::ZlibError)
}
let mut decoder = ZlibDecoder::new(bytes);
let mut output = Vec::new();
return_error!(decoder.read_to_end(&mut output), ProtocolError::ZlibError);
Ok(output)
}