atomic_compression feature
This commit is contained in:
parent
666b38b8f8
commit
7a78fccd7d
@ -11,6 +11,10 @@ version = "0.1.15"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
flate2 = "1.0.30"
|
flate2 = "1.0.32"
|
||||||
bytebuffer = "2.2.0"
|
bytebuffer = "2.3.0"
|
||||||
uuid = "1.10.0"
|
uuid = "1.10.0"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
# default = [ "atomic_compression" ]
|
||||||
|
atomic_compression = []
|
17
README.md
17
README.md
@ -5,6 +5,23 @@ all types of packets you can find on [wiki.vg](https://wiki.vg/) \
|
|||||||
[crates](https://crates.io/crates/rust_mc_proto)
|
[crates](https://crates.io/crates/rust_mc_proto)
|
||||||
[github](https://github.com/MeexReay/rust_mc_proto)
|
[github](https://github.com/MeexReay/rust_mc_proto)
|
||||||
|
|
||||||
|
## setup
|
||||||
|
|
||||||
|
stable
|
||||||
|
|
||||||
|
```toml
|
||||||
|
rust_mc_proto = "0.1.15"
|
||||||
|
```
|
||||||
|
|
||||||
|
unstable
|
||||||
|
|
||||||
|
```toml
|
||||||
|
rust_mc_proto = { git = "https://github.com/MeexReay/rust_mc_proto" }
|
||||||
|
```
|
||||||
|
|
||||||
|
features:
|
||||||
|
- atomic_compression (default)
|
||||||
|
|
||||||
## how to use it
|
## how to use it
|
||||||
|
|
||||||
for reference:
|
for reference:
|
||||||
|
147
src/lib.rs
147
src/lib.rs
@ -17,10 +17,13 @@ use std::{
|
|||||||
fmt,
|
fmt,
|
||||||
io::{Read, Write},
|
io::{Read, Write},
|
||||||
net::{TcpStream, ToSocketAddrs},
|
net::{TcpStream, ToSocketAddrs},
|
||||||
sync::{
|
usize,
|
||||||
atomic::{AtomicUsize, Ordering},
|
};
|
||||||
Arc,
|
|
||||||
},
|
#[cfg(feature = "atomic_compression")]
|
||||||
|
use sync::{
|
||||||
|
atomic::{AtomicUsize, Ordering},
|
||||||
|
Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Minecraft protocol error
|
/// Minecraft protocol error
|
||||||
@ -49,7 +52,10 @@ impl Error for ProtocolError {}
|
|||||||
/// Minecraft connection, wrapper for stream with compression
|
/// Minecraft connection, wrapper for stream with compression
|
||||||
pub struct MinecraftConnection<T: Read + Write> {
|
pub struct MinecraftConnection<T: Read + Write> {
|
||||||
stream: T,
|
stream: T,
|
||||||
|
#[cfg(feature = "atomic_compression")]
|
||||||
compression: Arc<AtomicUsize>,
|
compression: Arc<AtomicUsize>,
|
||||||
|
#[cfg(not(feature = "atomic_compression"))]
|
||||||
|
compression: Option<usize>,
|
||||||
compression_type: u32,
|
compression_type: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +77,10 @@ impl MinecraftConnection<TcpStream> {
|
|||||||
|
|
||||||
Ok(MinecraftConnection {
|
Ok(MinecraftConnection {
|
||||||
stream,
|
stream,
|
||||||
|
#[cfg(feature = "atomic_compression")]
|
||||||
compression: Arc::new(AtomicUsize::new(usize::MAX)),
|
compression: Arc::new(AtomicUsize::new(usize::MAX)),
|
||||||
|
#[cfg(not(feature = "atomic_compression"))]
|
||||||
|
compression: None,
|
||||||
compression_type: 1,
|
compression_type: 1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -87,7 +96,7 @@ impl MinecraftConnection<TcpStream> {
|
|||||||
Ok(stream) => Ok(MinecraftConnection {
|
Ok(stream) => Ok(MinecraftConnection {
|
||||||
stream,
|
stream,
|
||||||
compression: self.compression.clone(),
|
compression: self.compression.clone(),
|
||||||
compression_type: 1,
|
compression_type: self.compression_type,
|
||||||
}),
|
}),
|
||||||
_ => Err(ProtocolError::CloneError),
|
_ => Err(ProtocolError::CloneError),
|
||||||
}
|
}
|
||||||
@ -118,13 +127,17 @@ impl<T: Read + Write> MinecraftConnection<T> {
|
|||||||
pub fn new(stream: T) -> MinecraftConnection<T> {
|
pub fn new(stream: T) -> MinecraftConnection<T> {
|
||||||
MinecraftConnection {
|
MinecraftConnection {
|
||||||
stream,
|
stream,
|
||||||
|
#[cfg(feature = "atomic_compression")]
|
||||||
compression: Arc::new(AtomicUsize::new(usize::MAX)),
|
compression: Arc::new(AtomicUsize::new(usize::MAX)),
|
||||||
|
#[cfg(not(feature = "atomic_compression"))]
|
||||||
|
compression: None,
|
||||||
compression_type: 1,
|
compression_type: 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set compression threshold
|
/// Set compression threshold
|
||||||
pub fn set_compression(&mut self, threshold: Option<usize>) {
|
pub fn set_compression(&mut self, threshold: Option<usize>) {
|
||||||
|
#[cfg(feature = "atomic_compression")]
|
||||||
self.compression.store(
|
self.compression.store(
|
||||||
match threshold {
|
match threshold {
|
||||||
Some(t) => t,
|
Some(t) => t,
|
||||||
@ -132,15 +145,26 @@ impl<T: Read + Write> MinecraftConnection<T> {
|
|||||||
},
|
},
|
||||||
Ordering::Relaxed,
|
Ordering::Relaxed,
|
||||||
);
|
);
|
||||||
|
#[cfg(not(feature = "atomic_compression"))]
|
||||||
|
{
|
||||||
|
self.compression = threshold;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get compression threshold
|
/// Get compression threshold
|
||||||
pub fn compression(&self) -> Option<usize> {
|
pub fn compression(&self) -> Option<usize> {
|
||||||
let threshold = self.compression.load(Ordering::Relaxed);
|
#[cfg(feature = "atomic_compression")]
|
||||||
if threshold == usize::MAX {
|
{
|
||||||
None
|
let threshold = self.compression.load(Ordering::Relaxed);
|
||||||
} else {
|
if threshold == usize::MAX {
|
||||||
Some(threshold)
|
return None
|
||||||
|
} else {
|
||||||
|
return Some(threshold)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "atomic_compression"))]
|
||||||
|
{
|
||||||
|
self.compression
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,22 +198,36 @@ impl<T: Read + Write> MinecraftConnection<T> {
|
|||||||
|
|
||||||
/// Read [`Packet`](Packet) from connection
|
/// Read [`Packet`](Packet) from connection
|
||||||
pub fn read_packet(&mut self) -> Result<Packet, ProtocolError> {
|
pub fn read_packet(&mut self) -> Result<Packet, ProtocolError> {
|
||||||
read_packet_atomic(
|
#[cfg(feature = "atomic_compression")]
|
||||||
&mut self.stream,
|
{
|
||||||
self.compression.clone(),
|
return read_packet_atomic(
|
||||||
Ordering::Relaxed,
|
&mut self.stream,
|
||||||
)
|
self.compression.clone(),
|
||||||
|
Ordering::Relaxed,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "atomic_compression"))]
|
||||||
|
read_packet(&mut self.stream, self.compression)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write [`Packet`](Packet) to connection
|
/// Write [`Packet`](Packet) to connection
|
||||||
pub fn write_packet(&mut self, packet: &Packet) -> Result<(), ProtocolError> {
|
pub fn write_packet(&mut self, packet: &Packet) -> Result<(), ProtocolError> {
|
||||||
write_packet_atomic(
|
#[cfg(feature = "atomic_compression")]
|
||||||
&mut self.stream,
|
{
|
||||||
self.compression.clone(),
|
return write_packet_atomic(
|
||||||
Ordering::Relaxed,
|
&mut self.stream,
|
||||||
self.compression_type,
|
self.compression.clone(),
|
||||||
packet,
|
Ordering::Relaxed,
|
||||||
)
|
self.compression_type,
|
||||||
|
packet,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "atomic_compression"))]
|
||||||
|
{
|
||||||
|
write_packet(&mut self.stream, self.compression, self.compression_type, packet)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,24 +263,22 @@ pub type MCConn<T> = MinecraftConnection<T>;
|
|||||||
/// MinecraftConnection\<TcpStream\> shorter alias
|
/// MinecraftConnection\<TcpStream\> shorter alias
|
||||||
pub type MCConnTcp = MinecraftConnection<TcpStream>;
|
pub type MCConnTcp = MinecraftConnection<TcpStream>;
|
||||||
|
|
||||||
|
|
||||||
/// Read [`Packet`](Packet) from stream
|
/// Read [`Packet`](Packet) from stream
|
||||||
///
|
///
|
||||||
/// `compression` here is atomic usize
|
/// `compression` here is atomic usize
|
||||||
/// usize::MAX means that compression is disabled
|
/// usize::MAX means that compression is disabled
|
||||||
///
|
///
|
||||||
/// `ordering` is order how to load atomic
|
/// `ordering` is order how to load atomic
|
||||||
pub fn read_packet_atomic<T: Read>(
|
pub fn read_packet<T: Read>(
|
||||||
stream: &mut T,
|
stream: &mut T,
|
||||||
compression: Arc<AtomicUsize>,
|
compression: Option<usize>
|
||||||
ordering: Ordering,
|
|
||||||
) -> Result<Packet, ProtocolError> {
|
) -> Result<Packet, ProtocolError> {
|
||||||
let mut data: Vec<u8>;
|
let mut data: Vec<u8>;
|
||||||
|
|
||||||
let packet_length = stream.read_usize_varint_size()?;
|
let packet_length = stream.read_usize_varint_size()?;
|
||||||
|
|
||||||
let compress_threashold = compression.load(ordering);
|
if compression.is_some() {
|
||||||
|
|
||||||
if compress_threashold != usize::MAX {
|
|
||||||
let data_length = stream.read_usize_varint_size()?;
|
let data_length = stream.read_usize_varint_size()?;
|
||||||
|
|
||||||
data = stream.read_bytes(packet_length.0 - data_length.1)?;
|
data = stream.read_bytes(packet_length.0 - data_length.1)?;
|
||||||
@ -259,7 +295,7 @@ pub fn read_packet_atomic<T: Read>(
|
|||||||
|
|
||||||
/// Write [`Packet`](Packet) to stream
|
/// Write [`Packet`](Packet) to stream
|
||||||
///
|
///
|
||||||
/// `compression` here is atomic usize
|
/// `compression` here is usize
|
||||||
/// usize::MAX means that compression is disabled
|
/// usize::MAX means that compression is disabled
|
||||||
///
|
///
|
||||||
/// `ordering` is order how to load atomic
|
/// `ordering` is order how to load atomic
|
||||||
@ -267,10 +303,9 @@ pub fn read_packet_atomic<T: Read>(
|
|||||||
/// `compression_type` is integer from 0 (none) to 9 (longest)
|
/// `compression_type` is integer from 0 (none) to 9 (longest)
|
||||||
/// 1 is fast compression
|
/// 1 is fast compression
|
||||||
/// 6 is normal compression
|
/// 6 is normal compression
|
||||||
pub fn write_packet_atomic<T: Write>(
|
pub fn write_packet<T: Write>(
|
||||||
stream: &mut T,
|
stream: &mut T,
|
||||||
compression: Arc<AtomicUsize>,
|
compression: Option<usize>,
|
||||||
ordering: Ordering,
|
|
||||||
compression_type: u32,
|
compression_type: u32,
|
||||||
packet: &Packet,
|
packet: &Packet,
|
||||||
) -> Result<(), ProtocolError> {
|
) -> Result<(), ProtocolError> {
|
||||||
@ -280,12 +315,10 @@ pub fn write_packet_atomic<T: Write>(
|
|||||||
data_buf.write_u8_varint(packet.id())?;
|
data_buf.write_u8_varint(packet.id())?;
|
||||||
data_buf.write_buffer(packet.buffer())?;
|
data_buf.write_buffer(packet.buffer())?;
|
||||||
|
|
||||||
let compress_threshold = compression.load(ordering);
|
if let Some(compression) = compression {
|
||||||
|
|
||||||
if compress_threshold != usize::MAX {
|
|
||||||
let mut packet_buf = ByteBuffer::new();
|
let mut packet_buf = ByteBuffer::new();
|
||||||
|
|
||||||
if data_buf.len() >= compress_threshold {
|
if data_buf.len() >= compression {
|
||||||
let compressed_data = compress_zlib(data_buf.as_bytes(), compression_type)?;
|
let compressed_data = compress_zlib(data_buf.as_bytes(), compression_type)?;
|
||||||
packet_buf.write_usize_varint(data_buf.len())?;
|
packet_buf.write_usize_varint(data_buf.len())?;
|
||||||
packet_buf
|
packet_buf
|
||||||
@ -307,3 +340,45 @@ pub fn write_packet_atomic<T: Write>(
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read [`Packet`](Packet) from stream
|
||||||
|
///
|
||||||
|
/// `compression` here is atomic usize
|
||||||
|
/// usize::MAX means that compression is disabled
|
||||||
|
///
|
||||||
|
/// `ordering` is order how to load atomic
|
||||||
|
#[cfg(feature = "atomic_compression")]
|
||||||
|
pub fn read_packet_atomic<T: Read>(
|
||||||
|
stream: &mut T,
|
||||||
|
compression: Arc<AtomicUsize>,
|
||||||
|
ordering: Ordering,
|
||||||
|
) -> Result<Packet, ProtocolError> {
|
||||||
|
read_packet(stream, match compression.load(ordering) {
|
||||||
|
usize::MAX => None,
|
||||||
|
i => Some(i),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
#[cfg(feature = "atomic_compression")]
|
||||||
|
pub fn write_packet_atomic<T: Write>(
|
||||||
|
stream: &mut T,
|
||||||
|
compression: Arc<AtomicUsize>,
|
||||||
|
ordering: Ordering,
|
||||||
|
compression_type: u32,
|
||||||
|
packet: &Packet,
|
||||||
|
) -> Result<(), ProtocolError> {
|
||||||
|
write_packet(stream, match compression.load(ordering) {
|
||||||
|
usize::MAX => None,
|
||||||
|
i => Some(i),
|
||||||
|
}, compression_type, packet)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user