Split PacketError into 2 Structs

Much nicer now
This commit is contained in:
Snowiiii
2024-11-01 10:26:07 +01:00
parent 9b1e518556
commit 21dd9c194c
7 changed files with 75 additions and 82 deletions

View File

@@ -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

View File

@@ -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),
}

View File

@@ -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,

View File

@@ -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<aes::Aes128>;
@@ -24,17 +23,17 @@ pub struct PacketDecoder {
}
impl PacketDecoder {
pub fn decode(&mut self) -> Result<Option<RawPacket>, PacketError> {
pub fn decode(&mut self) -> Result<Option<RawPacket>, 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,
}

View File

@@ -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<aes::Aes128>;
@@ -25,19 +26,19 @@ pub struct PacketEncoder {
}
impl PacketEncoder {
pub fn append_packet<P: ClientPacket>(&mut self, packet: &P) -> Result<(), PacketError> {
pub fn append_packet<P: ClientPacket>(&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)
}
}

View File

@@ -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),

View File

@@ -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<P: ClientPacket>(&self, packet: &P) -> Result<(), PacketError> {
pub async fn try_send_packet<P: ClientPacket>(
&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