From 4ccb6487c8987a9481370070ad205f08a25f99ca Mon Sep 17 00:00:00 2001 From: MeexReay Date: Sun, 10 Nov 2024 03:31:21 +0300 Subject: [PATCH] is alive state --- Cargo.toml | 4 +-- README.md | 2 +- src/lib.rs | 96 +++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 77 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bc57d73..0c64d52 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,5 +16,5 @@ bytebuffer = "2.3.0" uuid = "1.11.0" [features] -default = [] -atomic_compression = [] \ No newline at end of file +default = ["atomic_clone"] +atomic_clone = [] \ No newline at end of file diff --git a/README.md b/README.md index 72c3058..bb9317b 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ rust_mc_proto = { git = "https://github.com/MeexReay/rust_mc_proto" } # unstable ``` Features: -- `atomic_compression` +- `atomic_clone` ## How to use diff --git a/src/lib.rs b/src/lib.rs index b251e41..9e76d04 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,14 +13,10 @@ pub use crate::{ use bytebuffer::ByteBuffer; use flate2::{read::ZlibDecoder, write::ZlibEncoder, Compression}; use std::{ - error::Error, - fmt, - io::{Read, Write}, - net::{TcpStream, ToSocketAddrs}, - usize, + error::Error, fmt, io::{Read, Write}, net::{TcpStream, ToSocketAddrs}, sync::atomic::AtomicBool, usize }; -#[cfg(feature = "atomic_compression")] +#[cfg(feature = "atomic_clone")] use std::sync::{ atomic::{AtomicUsize, Ordering}, Arc, @@ -39,6 +35,7 @@ pub enum ProtocolError { ZlibError, UnsignedShortError, CloneError, + ConnectionClosedError } impl fmt::Display for ProtocolError { @@ -52,11 +49,15 @@ impl Error for ProtocolError {} /// Minecraft connection, wrapper for stream with compression pub struct MinecraftConnection { stream: T, - #[cfg(feature = "atomic_compression")] + #[cfg(feature = "atomic_clone")] compression: Arc, - #[cfg(not(feature = "atomic_compression"))] + #[cfg(not(feature = "atomic_clone"))] compression: Option, compression_type: u32, + #[cfg(feature = "atomic_clone")] + is_alive: Arc, + #[cfg(not(feature = "atomic_clone"))] + is_alive: bool, } impl MinecraftConnection { @@ -77,10 +78,14 @@ impl MinecraftConnection { Ok(MinecraftConnection { stream, - #[cfg(feature = "atomic_compression")] + #[cfg(feature = "atomic_clone")] compression: Arc::new(AtomicUsize::new(usize::MAX)), - #[cfg(not(feature = "atomic_compression"))] + #[cfg(not(feature = "atomic_clone"))] compression: None, + #[cfg(feature = "atomic_clone")] + is_alive: Arc::new(AtomicBool::new(true)), + #[cfg(not(feature = "atomic_clone"))] + is_alive: true, compression_type: 1, }) } @@ -90,8 +95,17 @@ impl MinecraftConnection { } /// Close TcpStream + #[cfg(not(feature = "atomic_clone"))] + pub fn close(&mut self) { + let _ = self.stream.shutdown(std::net::Shutdown::Both); + self.is_alive = false; + } + + /// Close TcpStream + #[cfg(feature = "atomic_clone")] pub fn close(&self) { let _ = self.stream.shutdown(std::net::Shutdown::Both); + self.is_alive.store(false, Ordering::Relaxed); } /// Try clone MinecraftConnection with compression and stream @@ -99,6 +113,7 @@ impl MinecraftConnection { match self.stream.try_clone() { Ok(stream) => Ok(MinecraftConnection { stream, + is_alive: self.is_alive.clone(), compression: self.compression.clone(), compression_type: self.compression_type, }), @@ -131,17 +146,45 @@ impl MinecraftConnection { pub fn new(stream: T) -> MinecraftConnection { MinecraftConnection { stream, - #[cfg(feature = "atomic_compression")] + #[cfg(feature = "atomic_clone")] compression: Arc::new(AtomicUsize::new(usize::MAX)), - #[cfg(not(feature = "atomic_compression"))] + #[cfg(not(feature = "atomic_clone"))] compression: None, + #[cfg(feature = "atomic_clone")] + is_alive: Arc::new(AtomicBool::new(true)), + #[cfg(not(feature = "atomic_clone"))] + is_alive: true, compression_type: 1, } } + /// Set alive state + #[cfg(not(feature = "atomic_clone"))] + pub fn set_alive(&mut self, state: bool) { + self.is_alive = state; + } + + /// Set alive state + #[cfg(feature = "atomic_clone")] + pub fn set_alive(&self, state: bool) { + self.is_alive.store(state, Ordering::Relaxed); + } + + /// Is connection alive + #[cfg(not(feature = "atomic_clone"))] + pub fn set_alive(&self) -> bool { + self.is_alive + } + + /// Is connection alive + #[cfg(feature = "atomic_clone")] + pub fn is_alive(&self) -> bool { + self.is_alive.load(Ordering::Relaxed) + } + /// Set compression threshold pub fn set_compression(&mut self, threshold: Option) { - #[cfg(feature = "atomic_compression")] + #[cfg(feature = "atomic_clone")] self.compression.store( match threshold { Some(t) => t, @@ -149,7 +192,7 @@ impl MinecraftConnection { }, Ordering::Relaxed, ); - #[cfg(not(feature = "atomic_compression"))] + #[cfg(not(feature = "atomic_clone"))] { self.compression = threshold; } @@ -157,7 +200,7 @@ impl MinecraftConnection { /// Get compression threshold pub fn compression(&self) -> Option { - #[cfg(feature = "atomic_compression")] + #[cfg(feature = "atomic_clone")] { let threshold = self.compression.load(Ordering::Relaxed); if threshold == usize::MAX { @@ -166,7 +209,7 @@ impl MinecraftConnection { return Some(threshold) } } - #[cfg(not(feature = "atomic_compression"))] + #[cfg(not(feature = "atomic_clone"))] { self.compression } @@ -202,7 +245,11 @@ impl MinecraftConnection { /// Read [`Packet`](Packet) from connection pub fn read_packet(&mut self) -> Result { - #[cfg(feature = "atomic_compression")] + if !self.is_alive() { + return Err(ProtocolError::ConnectionClosedError); + } + + #[cfg(feature = "atomic_clone")] { return read_packet_atomic( &mut self.stream, @@ -211,13 +258,17 @@ impl MinecraftConnection { ) } - #[cfg(not(feature = "atomic_compression"))] + #[cfg(not(feature = "atomic_clone"))] read_packet(&mut self.stream, self.compression) } /// Write [`Packet`](Packet) to connection pub fn write_packet(&mut self, packet: &Packet) -> Result<(), ProtocolError> { - #[cfg(feature = "atomic_compression")] + if !self.is_alive() { + return Err(ProtocolError::ConnectionClosedError); + } + + #[cfg(feature = "atomic_clone")] { return write_packet_atomic( &mut self.stream, @@ -228,7 +279,7 @@ impl MinecraftConnection { ) } - #[cfg(not(feature = "atomic_compression"))] + #[cfg(not(feature = "atomic_clone"))] { write_packet(&mut self.stream, self.compression, self.compression_type, packet) } @@ -241,6 +292,7 @@ impl MinecraftConnection { MinecraftConnection { stream: self.stream.clone(), compression: self.compression.clone(), + is_alive: self.is_alive.clone(), compression_type: self.compression_type, } } @@ -351,7 +403,7 @@ pub fn write_packet( /// usize::MAX means that compression is disabled /// /// `ordering` is order how to load atomic -#[cfg(feature = "atomic_compression")] +#[cfg(feature = "atomic_clone")] pub fn read_packet_atomic( stream: &mut T, compression: Arc, @@ -373,7 +425,7 @@ pub fn read_packet_atomic( /// `compression_type` is integer from 0 (none) to 9 (longest) /// 1 is fast compression /// 6 is normal compression -#[cfg(feature = "atomic_compression")] +#[cfg(feature = "atomic_clone")] pub fn write_packet_atomic( stream: &mut T, compression: Arc,