From 21dd9c194cb1d38922701b66b6e95fb23cea6eb2 Mon Sep 17 00:00:00 2001 From: Snowiiii Date: Fri, 1 Nov 2024 10:26:07 +0100 Subject: [PATCH] Split PacketError into 2 Structs Much nicer now --- README.md | 3 +- pumpkin-protocol/src/bytebuf/deserializer.rs | 2 +- pumpkin-protocol/src/lib.rs | 41 ----------------- pumpkin-protocol/src/packet_decoder.rs | 39 ++++++++++++----- pumpkin-protocol/src/packet_encoder.rs | 46 +++++++++++++++----- pumpkin/src/client/authentication.rs | 2 +- pumpkin/src/client/mod.rs | 24 ++++------ 7 files changed, 75 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index 53921141d..b18888dc6 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ and customizable experience. It prioritizes performance and player enjoyment whi - [x] Entity Spawning - [x] Chunk Loading - [x] Chunk Generation + - [ ] World Time - [x] Scoreboard - [x] World Borders - [ ] World Saving @@ -61,7 +62,7 @@ and customizable experience. It prioritizes performance and player enjoyment whi - [x] Player Inventory - [x] Player Combat - Server - - [x] Plugins + - [ ] Plugins - [ ] Query - [x] RCON - [x] Inventories diff --git a/pumpkin-protocol/src/bytebuf/deserializer.rs b/pumpkin-protocol/src/bytebuf/deserializer.rs index e8d92267d..462087364 100644 --- a/pumpkin-protocol/src/bytebuf/deserializer.rs +++ b/pumpkin-protocol/src/bytebuf/deserializer.rs @@ -15,7 +15,7 @@ pub enum DeserializerError { UnknownPacket, #[error("serializer error {0}")] Message(String), - #[error("Stdio error")] + #[error("Stdio error {0}")] Stdio(std::io::Error), } diff --git a/pumpkin-protocol/src/lib.rs b/pumpkin-protocol/src/lib.rs index 0ef2bc252..5def3df30 100644 --- a/pumpkin-protocol/src/lib.rs +++ b/pumpkin-protocol/src/lib.rs @@ -1,7 +1,6 @@ use bytebuf::{packet_id::ClientPacketID, ByteBuffer, DeserializerError}; use pumpkin_core::text::{style::Style, TextComponent}; use serde::{Deserialize, Serialize}; -use thiserror::Error; pub mod bytebuf; pub mod client; @@ -30,46 +29,6 @@ pub type FixedBitSet = bytes::Bytes; pub struct BitSet<'a>(pub VarInt, pub &'a [i64]); -#[derive(Error, Debug)] -pub enum PacketError { - #[error("failed to decode packet ID")] - DecodeID, - #[error("failed to encode packet ID")] - EncodeID, - #[error("failed to encode packet Length")] - EncodeLength, - #[error("failed to encode packet data")] - EncodeData, - #[error("failed to write encoded packet")] - EncodeFailedWrite, - #[error("failed to write into decoder: {0}")] - FailedWrite(String), - #[error("failed to flush decoder")] - FailedFinish, - #[error("failed to write encoded packet to connection")] - ConnectionWrite, - #[error("packet exceeds maximum length")] - TooLong, - #[error("packet length is out of bounds")] - OutOfBounds, - #[error("malformed packet length VarInt")] - MalformedLength, -} - -impl PacketError { - pub fn kickable(&self) -> bool { - // We no longer have a connection, so dont try to kick the player, just close - !matches!( - self, - Self::EncodeData - | Self::EncodeFailedWrite - | Self::FailedWrite(_) - | Self::FailedFinish - | Self::ConnectionWrite - ) - } -} - #[derive(Debug, PartialEq, Clone, Copy)] pub enum ConnectionState { HandShake, diff --git a/pumpkin-protocol/src/packet_decoder.rs b/pumpkin-protocol/src/packet_decoder.rs index a30c0f870..4d9ad6ecd 100644 --- a/pumpkin-protocol/src/packet_decoder.rs +++ b/pumpkin-protocol/src/packet_decoder.rs @@ -1,14 +1,13 @@ use aes::cipher::{generic_array::GenericArray, BlockDecryptMut, BlockSizeUser, KeyIvInit}; use bytes::{Buf, BytesMut}; +use thiserror::Error; use std::io::Write; use bytes::BufMut; use flate2::write::ZlibDecoder; -use crate::{ - bytebuf::ByteBuffer, PacketError, RawPacket, VarInt, VarIntDecodeError, MAX_PACKET_SIZE, -}; +use crate::{bytebuf::ByteBuffer, RawPacket, VarInt, VarIntDecodeError, MAX_PACKET_SIZE}; type Cipher = cfb8::Decryptor; @@ -24,17 +23,17 @@ pub struct PacketDecoder { } impl PacketDecoder { - pub fn decode(&mut self) -> Result, PacketError> { + pub fn decode(&mut self) -> Result, PacketDecodeError> { let mut r = &self.buf[..]; let packet_len = match VarInt::decode_partial(&mut r) { Ok(len) => len, Err(VarIntDecodeError::Incomplete) => return Ok(None), - Err(VarIntDecodeError::TooLarge) => Err(PacketError::MalformedLength)?, + Err(VarIntDecodeError::TooLarge) => Err(PacketDecodeError::MalformedLength)?, }; if !(0..=MAX_PACKET_SIZE).contains(&packet_len) { - Err(PacketError::OutOfBounds)? + Err(PacketDecodeError::OutOfBounds)? } if r.len() < packet_len as usize { @@ -48,10 +47,12 @@ impl PacketDecoder { if self.compression { r = &r[..packet_len as usize]; - let data_len = VarInt::decode(&mut r).map_err(|_| PacketError::TooLong)?.0; + let data_len = VarInt::decode(&mut r) + .map_err(|_| PacketDecodeError::TooLong)? + .0; if !(0..=MAX_PACKET_SIZE).contains(&data_len) { - Err(PacketError::OutOfBounds)? + Err(PacketDecodeError::OutOfBounds)? } // Is this packet compressed? @@ -64,8 +65,8 @@ impl PacketDecoder { let mut z = ZlibDecoder::new(&mut self.decompress_buf[..]); z.write_all(r) - .map_err(|e| PacketError::FailedWrite(e.to_string()))?; - z.finish().map_err(|_| PacketError::FailedFinish)?; + .map_err(|e| PacketDecodeError::FailedWrite(e.to_string()))?; + z.finish().map_err(|_| PacketDecodeError::FailedFinish)?; let total_packet_len = VarInt(packet_len).written_size() + packet_len as usize; @@ -88,7 +89,7 @@ impl PacketDecoder { } r = &data[..]; - let packet_id = VarInt::decode(&mut r).map_err(|_| PacketError::DecodeID)?; + let packet_id = VarInt::decode(&mut r).map_err(|_| PacketDecodeError::DecodeID)?; data.advance(data.len() - r.len()); Ok(Some(RawPacket { @@ -158,3 +159,19 @@ impl PacketDecoder { self.buf.reserve(additional); } } + +#[derive(Error, Debug)] +pub enum PacketDecodeError { + #[error("failed to decode packet ID")] + DecodeID, + #[error("failed to write into decoder: {0}")] + FailedWrite(String), + #[error("failed to flush decoder")] + FailedFinish, + #[error("packet exceeds maximum length")] + TooLong, + #[error("packet length is out of bounds")] + OutOfBounds, + #[error("malformed packet length VarInt")] + MalformedLength, +} diff --git a/pumpkin-protocol/src/packet_encoder.rs b/pumpkin-protocol/src/packet_encoder.rs index 947fdf81e..acc1b285d 100644 --- a/pumpkin-protocol/src/packet_encoder.rs +++ b/pumpkin-protocol/src/packet_encoder.rs @@ -3,13 +3,14 @@ use std::io::Write; use aes::cipher::{generic_array::GenericArray, BlockEncryptMut, BlockSizeUser, KeyIvInit}; use bytes::{BufMut, BytesMut}; use pumpkin_config::compression::CompressionInfo; +use thiserror::Error; use std::io::Read; use flate2::bufread::ZlibEncoder; use flate2::Compression; -use crate::{bytebuf::ByteBuffer, ClientPacket, PacketError, VarInt, MAX_PACKET_SIZE}; +use crate::{bytebuf::ByteBuffer, ClientPacket, VarInt, MAX_PACKET_SIZE}; type Cipher = cfb8::Encryptor; @@ -25,19 +26,19 @@ pub struct PacketEncoder { } impl PacketEncoder { - pub fn append_packet(&mut self, packet: &P) -> Result<(), PacketError> { + pub fn append_packet(&mut self, packet: &P) -> Result<(), PacketEncodeError> { let start_len = self.buf.len(); let mut writer = (&mut self.buf).writer(); let mut packet_buf = ByteBuffer::empty(); VarInt(P::PACKET_ID) .encode(&mut writer) - .map_err(|_| PacketError::EncodeID)?; + .map_err(|_| PacketEncodeError::EncodeID)?; packet.write(&mut packet_buf); writer .write(packet_buf.buf()) - .map_err(|_| PacketError::EncodeFailedWrite)?; + .map_err(|_| PacketEncodeError::EncodeFailedWrite)?; let data_len = self.buf.len() - start_len; @@ -53,7 +54,7 @@ impl PacketEncoder { let packet_len = data_len_size + z.read_to_end(&mut self.compress_buf).unwrap(); if packet_len >= MAX_PACKET_SIZE as usize { - Err(PacketError::TooLong)? + Err(PacketEncodeError::TooLong)? } drop(z); @@ -64,17 +65,17 @@ impl PacketEncoder { VarInt(packet_len as i32) .encode(&mut writer) - .map_err(|_| PacketError::EncodeLength)?; + .map_err(|_| PacketEncodeError::EncodeLength)?; VarInt(data_len as i32) .encode(&mut writer) - .map_err(|_| PacketError::EncodeData)?; + .map_err(|_| PacketEncodeError::EncodeData)?; self.buf.extend_from_slice(&self.compress_buf); } else { let data_len_size = 1; let packet_len = data_len_size + data_len; if packet_len >= MAX_PACKET_SIZE as usize { - Err(PacketError::TooLong)? + Err(PacketEncodeError::TooLong)? } let packet_len_size = VarInt(packet_len as i32).written_size(); @@ -89,11 +90,11 @@ impl PacketEncoder { VarInt(packet_len as i32) .encode(&mut front) - .map_err(|_| PacketError::EncodeLength)?; + .map_err(|_| PacketEncodeError::EncodeLength)?; // Zero for no compression on this packet. VarInt(0) .encode(front) - .map_err(|_| PacketError::EncodeData)?; + .map_err(|_| PacketEncodeError::EncodeData)?; } return Ok(()); @@ -102,7 +103,7 @@ impl PacketEncoder { let packet_len = data_len; if packet_len >= MAX_PACKET_SIZE as usize { - Err(PacketError::TooLong)? + Err(PacketEncodeError::TooLong)? } let packet_len_size = VarInt(packet_len as i32).written_size(); @@ -114,7 +115,7 @@ impl PacketEncoder { let front = &mut self.buf[start_len..]; VarInt(packet_len as i32) .encode(front) - .map_err(|_| PacketError::EncodeID)?; + .map_err(|_| PacketEncodeError::EncodeID)?; Ok(()) } @@ -146,3 +147,24 @@ impl PacketEncoder { self.buf.split() } } + +#[derive(Error, Debug)] +pub enum PacketEncodeError { + #[error("failed to encode packet ID")] + EncodeID, + #[error("failed to encode packet Length")] + EncodeLength, + #[error("failed to encode packet data")] + EncodeData, + #[error("failed to write encoded packet")] + EncodeFailedWrite, + #[error("packet exceeds maximum length")] + TooLong, +} + +impl PacketEncodeError { + pub fn kickable(&self) -> bool { + // We no longer have a connection, so dont try to kick the player, just close + !matches!(self, Self::EncodeData | Self::EncodeFailedWrite) + } +} diff --git a/pumpkin/src/client/authentication.rs b/pumpkin/src/client/authentication.rs index e2fc8ab1a..9b105b0f3 100644 --- a/pumpkin/src/client/authentication.rs +++ b/pumpkin/src/client/authentication.rs @@ -147,7 +147,7 @@ pub enum AuthError { #[derive(Error, Debug)] pub enum TextureError { - #[error("Invalid URL")] + #[error("Invalid URL {0}")] InvalidURL(String), #[error("Invalid URL scheme for player texture: {0}")] DisallowedUrlScheme(String), diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index b4c5c2164..503a6ea16 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -21,7 +21,7 @@ use pumpkin_protocol::{ bytebuf::DeserializerError, client::{config::CConfigDisconnect, login::CLoginDisconnect, play::CPlayDisconnect}, packet_decoder::PacketDecoder, - packet_encoder::PacketEncoder, + packet_encoder::{PacketEncodeError, PacketEncoder}, server::{ config::{ SAcknowledgeFinishConfig, SClientInformationConfig, SKnownPacks, SPluginMessage, @@ -34,7 +34,7 @@ use pumpkin_protocol::{ }, status::{SStatusPingRequest, SStatusRequest, ServerboundStatusPackets}, }, - ClientPacket, ConnectionState, PacketError, RawPacket, ServerPacket, + ClientPacket, ConnectionState, RawPacket, ServerPacket, }; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::sync::Mutex; @@ -231,14 +231,8 @@ impl Client { } let mut writer = self.connection_writer.lock().await; - if let Err(error) = writer - .write_all(&enc.take()) - .await - .map_err(|_| PacketError::ConnectionWrite) - { - if error.kickable() { - self.kick(&error.to_string()).await; - } + if let Err(error) = writer.write_all(&enc.take()).await { + log::debug!("{}", error.to_string()); } /* @@ -265,7 +259,10 @@ impl Client { /// # Errors /// /// Returns an `PacketError` if the could not be Send. - pub async fn try_send_packet(&self, packet: &P) -> Result<(), PacketError> { + pub async fn try_send_packet( + &self, + packet: &P, + ) -> Result<(), PacketEncodeError> { // assert!(!self.closed); /* log::debug!( @@ -279,10 +276,7 @@ impl Client { enc.append_packet(packet)?; let mut writer = self.connection_writer.lock().await; - writer - .write_all(&enc.take()) - .await - .map_err(|_| PacketError::ConnectionWrite)?; + let _ = writer.write_all(&enc.take()).await; /* writer