fix compression mb
This commit is contained in:
parent
9f34891b8a
commit
8058a05876
@ -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
38
examples/test_compression.rs
Normal file
38
examples/test_compression.rs
Normal 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");
|
||||
}
|
||||
}
|
182
src/lib.rs
182
src/lib.rs
@ -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) },
|
||||
};
|
||||
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);
|
||||
|
||||
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 {
|
||||
let mut data = ByteBuffer::new();
|
||||
|
||||
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) },
|
||||
};
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user