Remove unwarp when reading packets

This commit is contained in:
Snowiiii 2024-08-25 11:02:40 +02:00
parent cb32cd3eca
commit 020c71a973
2 changed files with 139 additions and 77 deletions

View File

@ -1,5 +1,4 @@
use std::{ use std::{
collections::VecDeque,
io::{self, Write}, io::{self, Write},
net::SocketAddr, net::SocketAddr,
rc::Rc, rc::Rc,
@ -14,7 +13,7 @@ use authentication::GameProfile;
use mio::{event::Event, net::TcpStream, Token}; use mio::{event::Event, net::TcpStream, Token};
use pumpkin_core::text::TextComponent; use pumpkin_core::text::TextComponent;
use pumpkin_protocol::{ use pumpkin_protocol::{
bytebuf::packet_id::Packet, bytebuf::{packet_id::Packet, DeserializerError},
client::{config::CConfigDisconnect, login::CLoginDisconnect, play::CPlayDisconnect}, client::{config::CConfigDisconnect, login::CLoginDisconnect, play::CPlayDisconnect},
packet_decoder::PacketDecoder, packet_decoder::PacketDecoder,
packet_encoder::PacketEncoder, packet_encoder::PacketEncoder,
@ -76,7 +75,7 @@ pub struct Client {
pub address: SocketAddr, pub address: SocketAddr,
enc: PacketEncoder, enc: PacketEncoder,
dec: PacketDecoder, dec: PacketDecoder,
pub client_packets_queue: VecDeque<RawPacket>, pub client_packets_queue: Vec<RawPacket>,
pub make_player: bool, pub make_player: bool,
} }
@ -96,14 +95,14 @@ impl Client {
dec: PacketDecoder::default(), dec: PacketDecoder::default(),
encryption: true, encryption: true,
closed: false, closed: false,
client_packets_queue: VecDeque::new(), client_packets_queue: Vec::new(),
make_player: false, make_player: false,
} }
} }
/// adds a Incoming packet to the queue /// adds a Incoming packet to the queue
pub fn add_packet(&mut self, packet: RawPacket) { pub fn add_packet(&mut self, packet: RawPacket) {
self.client_packets_queue.push_back(packet); self.client_packets_queue.push(packet);
} }
/// enables encryption /// enables encryption
@ -146,86 +145,121 @@ impl Client {
} }
pub async fn process_packets(&mut self, server: &mut Server) { pub async fn process_packets(&mut self, server: &mut Server) {
let mut i = 0; while let Some(mut packet) = self.client_packets_queue.pop() {
while i < self.client_packets_queue.len() { match self.handle_packet(server, &mut packet).await {
let mut packet = self.client_packets_queue.remove(i).unwrap(); Ok(_) => {}
self.handle_packet(server, &mut packet).await; Err(e) => {
i += 1; let text = format!("Error while reading incoming packet {}", e);
log::error!("{}", text);
self.kick(&text)
}
};
} }
} }
/// Handles an incoming decoded not Play state Packet /// Handles an incoming decoded not Play state Packet
pub async fn handle_packet(&mut self, server: &mut Server, packet: &mut RawPacket) { pub async fn handle_packet(
&mut self,
server: &mut Server,
packet: &mut RawPacket,
) -> Result<(), DeserializerError> {
// TODO: handle each packet's Error instead of calling .unwrap() // TODO: handle each packet's Error instead of calling .unwrap()
let bytebuf = &mut packet.bytebuf; let bytebuf = &mut packet.bytebuf;
match self.connection_state { match self.connection_state {
pumpkin_protocol::ConnectionState::HandShake => match packet.id.0 { pumpkin_protocol::ConnectionState::HandShake => match packet.id.0 {
SHandShake::PACKET_ID => { SHandShake::PACKET_ID => {
self.handle_handshake(server, SHandShake::read(bytebuf).unwrap()) self.handle_handshake(server, SHandShake::read(bytebuf)?);
Ok(())
} }
_ => log::error!( _ => {
log::error!(
"Failed to handle packet id {} while in Handshake state", "Failed to handle packet id {} while in Handshake state",
packet.id.0 packet.id.0
), );
Ok(())
}
}, },
pumpkin_protocol::ConnectionState::Status => match packet.id.0 { pumpkin_protocol::ConnectionState::Status => match packet.id.0 {
SStatusRequest::PACKET_ID => { SStatusRequest::PACKET_ID => {
self.handle_status_request(server, SStatusRequest::read(bytebuf).unwrap()) self.handle_status_request(server, SStatusRequest::read(bytebuf)?);
Ok(())
} }
SStatusPingRequest::PACKET_ID => { SStatusPingRequest::PACKET_ID => {
self.handle_ping_request(server, SStatusPingRequest::read(bytebuf).unwrap()) self.handle_ping_request(server, SStatusPingRequest::read(bytebuf)?);
Ok(())
} }
_ => log::error!( _ => {
log::error!(
"Failed to handle packet id {} while in Status state", "Failed to handle packet id {} while in Status state",
packet.id.0 packet.id.0
), );
Ok(())
}
}, },
// TODO: Check config if transfer is enabled // TODO: Check config if transfer is enabled
pumpkin_protocol::ConnectionState::Login pumpkin_protocol::ConnectionState::Login
| pumpkin_protocol::ConnectionState::Transfer => match packet.id.0 { | pumpkin_protocol::ConnectionState::Transfer => match packet.id.0 {
SLoginStart::PACKET_ID => { SLoginStart::PACKET_ID => {
self.handle_login_start(server, SLoginStart::read(bytebuf).unwrap()) self.handle_login_start(server, SLoginStart::read(bytebuf)?);
Ok(())
} }
SEncryptionResponse::PACKET_ID => { SEncryptionResponse::PACKET_ID => {
self.handle_encryption_response( self.handle_encryption_response(server, SEncryptionResponse::read(bytebuf)?)
server, .await;
SEncryptionResponse::read(bytebuf).unwrap(), Ok(())
)
.await
} }
SLoginPluginResponse::PACKET_ID => self SLoginPluginResponse::PACKET_ID => {
.handle_plugin_response(server, SLoginPluginResponse::read(bytebuf).unwrap()), self.handle_plugin_response(server, SLoginPluginResponse::read(bytebuf)?);
SLoginAcknowledged::PACKET_ID => self Ok(())
.handle_login_acknowledged(server, SLoginAcknowledged::read(bytebuf).unwrap()), }
_ => log::error!( SLoginAcknowledged::PACKET_ID => {
self.handle_login_acknowledged(server, SLoginAcknowledged::read(bytebuf)?);
Ok(())
}
_ => {
log::error!(
"Failed to handle packet id {} while in Login state", "Failed to handle packet id {} while in Login state",
packet.id.0 packet.id.0
), );
Ok(())
}
}, },
pumpkin_protocol::ConnectionState::Config => match packet.id.0 { pumpkin_protocol::ConnectionState::Config => match packet.id.0 {
SClientInformationConfig::PACKET_ID => self.handle_client_information_config( SClientInformationConfig::PACKET_ID => {
self.handle_client_information_config(
server, server,
SClientInformationConfig::read(bytebuf).unwrap(), SClientInformationConfig::read(bytebuf)?,
), );
Ok(())
}
SPluginMessage::PACKET_ID => { SPluginMessage::PACKET_ID => {
self.handle_plugin_message(server, SPluginMessage::read(bytebuf).unwrap()) self.handle_plugin_message(server, SPluginMessage::read(bytebuf)?);
Ok(())
} }
SAcknowledgeFinishConfig::PACKET_ID => { SAcknowledgeFinishConfig::PACKET_ID => {
self.handle_config_acknowledged( self.handle_config_acknowledged(
server, server,
SAcknowledgeFinishConfig::read(bytebuf).unwrap(), SAcknowledgeFinishConfig::read(bytebuf)?,
) )
.await .await;
Ok(())
} }
SKnownPacks::PACKET_ID => { SKnownPacks::PACKET_ID => {
self.handle_known_packs(server, SKnownPacks::read(bytebuf).unwrap()) self.handle_known_packs(server, SKnownPacks::read(bytebuf)?);
Ok(())
} }
_ => log::error!( _ => {
log::error!(
"Failed to handle packet id {} while in Config state", "Failed to handle packet id {} while in Config state",
packet.id.0 packet.id.0
), );
Ok(())
}
}, },
_ => log::error!("Invalid Connection state {:?}", self.connection_state), _ => {
log::error!("Invalid Connection state {:?}", self.connection_state);
Ok(())
}
} }
} }
@ -279,7 +313,7 @@ impl Client {
match self.connection_state { match self.connection_state {
ConnectionState::Login => { ConnectionState::Login => {
self.try_send_packet(&CLoginDisconnect::new( self.try_send_packet(&CLoginDisconnect::new(
&serde_json::to_string_pretty(&reason).unwrap(), &serde_json::to_string_pretty(&reason).unwrap_or("".into()),
)) ))
.unwrap_or_else(|_| self.close()); .unwrap_or_else(|_| self.close());
} }

View File

@ -6,7 +6,7 @@ use pumpkin_core::text::TextComponent;
use pumpkin_entity::{entity_type::EntityType, Entity, EntityId}; use pumpkin_entity::{entity_type::EntityType, Entity, EntityId};
use pumpkin_inventory::player::PlayerInventory; use pumpkin_inventory::player::PlayerInventory;
use pumpkin_protocol::{ use pumpkin_protocol::{
bytebuf::packet_id::Packet, bytebuf::{packet_id::Packet, DeserializerError},
client::play::{CGameEvent, CPlayDisconnect, CSyncPlayerPosition, CSystemChatMessage}, client::play::{CGameEvent, CPlayDisconnect, CSyncPlayerPosition, CSystemChatMessage},
server::play::{ server::play::{
SChatCommand, SChatMessage, SClientInformationPlay, SConfirmTeleport, SInteract, SChatCommand, SChatMessage, SClientInformationPlay, SConfirmTeleport, SInteract,
@ -153,61 +153,89 @@ impl Player {
impl Player { impl Player {
pub fn process_packets(&mut self, server: &mut Server) { pub fn process_packets(&mut self, server: &mut Server) {
let mut i = 0; while let Some(mut packet) = self.client.client_packets_queue.pop() {
while i < self.client.client_packets_queue.len() { match self.handle_play_packet(server, &mut packet) {
let mut packet = self.client.client_packets_queue.remove(i).unwrap(); Ok(_) => {}
self.handle_play_packet(server, &mut packet); Err(e) => {
i += 1; let text = format!("Error while reading incoming packet {}", e);
log::error!("{}", text);
self.kick(TextComponent::text(&text))
}
};
} }
} }
pub fn handle_play_packet(&mut self, server: &mut Server, packet: &mut RawPacket) { pub fn handle_play_packet(
&mut self,
server: &mut Server,
packet: &mut RawPacket,
) -> Result<(), DeserializerError> {
let bytebuf = &mut packet.bytebuf; let bytebuf = &mut packet.bytebuf;
match packet.id.0 { match packet.id.0 {
SConfirmTeleport::PACKET_ID => { SConfirmTeleport::PACKET_ID => {
self.handle_confirm_teleport(server, SConfirmTeleport::read(bytebuf).unwrap()) self.handle_confirm_teleport(server, SConfirmTeleport::read(bytebuf)?);
Ok(())
} }
SChatCommand::PACKET_ID => { SChatCommand::PACKET_ID => {
self.handle_chat_command(server, SChatCommand::read(bytebuf).unwrap()) self.handle_chat_command(server, SChatCommand::read(bytebuf)?);
Ok(())
} }
SPlayerPosition::PACKET_ID => { SPlayerPosition::PACKET_ID => {
self.handle_position(server, SPlayerPosition::read(bytebuf).unwrap()) self.handle_position(server, SPlayerPosition::read(bytebuf)?);
Ok(())
}
SPlayerPositionRotation::PACKET_ID => {
self.handle_position_rotation(server, SPlayerPositionRotation::read(bytebuf)?);
Ok(())
} }
SPlayerPositionRotation::PACKET_ID => self
.handle_position_rotation(server, SPlayerPositionRotation::read(bytebuf).unwrap()),
SPlayerRotation::PACKET_ID => { SPlayerRotation::PACKET_ID => {
self.handle_rotation(server, SPlayerRotation::read(bytebuf).unwrap()) self.handle_rotation(server, SPlayerRotation::read(bytebuf)?);
Ok(())
} }
SPlayerCommand::PACKET_ID => { SPlayerCommand::PACKET_ID => {
self.handle_player_command(server, SPlayerCommand::read(bytebuf).unwrap()) self.handle_player_command(server, SPlayerCommand::read(bytebuf)?);
Ok(())
} }
SSwingArm::PACKET_ID => { SSwingArm::PACKET_ID => {
self.handle_swing_arm(server, SSwingArm::read(bytebuf).unwrap()) self.handle_swing_arm(server, SSwingArm::read(bytebuf)?);
Ok(())
} }
SChatMessage::PACKET_ID => { SChatMessage::PACKET_ID => {
self.handle_chat_message(server, SChatMessage::read(bytebuf).unwrap()) self.handle_chat_message(server, SChatMessage::read(bytebuf)?);
Ok(())
}
SClientInformationPlay::PACKET_ID => {
self.handle_client_information_play(server, SClientInformationPlay::read(bytebuf)?);
Ok(())
}
SInteract::PACKET_ID => {
self.handle_interact(server, SInteract::read(bytebuf)?);
Ok(())
} }
SClientInformationPlay::PACKET_ID => self.handle_client_information_play(
server,
SClientInformationPlay::read(bytebuf).unwrap(),
),
SInteract::PACKET_ID => self.handle_interact(server, SInteract::read(bytebuf).unwrap()),
SPlayerAction::PACKET_ID => { SPlayerAction::PACKET_ID => {
self.handle_player_action(server, SPlayerAction::read(bytebuf).unwrap()) self.handle_player_action(server, SPlayerAction::read(bytebuf)?);
Ok(())
} }
SUseItemOn::PACKET_ID => { SUseItemOn::PACKET_ID => {
self.handle_use_item_on(server, SUseItemOn::read(bytebuf).unwrap()) self.handle_use_item_on(server, SUseItemOn::read(bytebuf)?);
Ok(())
} }
SSetHeldItem::PACKET_ID => { SSetHeldItem::PACKET_ID => {
self.handle_set_held_item(server, SSetHeldItem::read(bytebuf).unwrap()) self.handle_set_held_item(server, SSetHeldItem::read(bytebuf)?);
Ok(())
} }
SSetCreativeSlot::PACKET_ID => { SSetCreativeSlot::PACKET_ID => {
self.handle_set_creative_slot(server, SSetCreativeSlot::read(bytebuf).unwrap()) self.handle_set_creative_slot(server, SSetCreativeSlot::read(bytebuf)?);
Ok(())
} }
SPlayPingRequest::PACKET_ID => { SPlayPingRequest::PACKET_ID => {
self.handle_play_ping_request(server, SPlayPingRequest::read(bytebuf).unwrap()) self.handle_play_ping_request(server, SPlayPingRequest::read(bytebuf)?);
Ok(())
}
_ => {
log::error!("Failed to handle player packet id {:#04x}", packet.id.0);
Ok(())
} }
_ => log::error!("Failed to handle player packet id {:#04x}", packet.id.0),
} }
} }
} }