diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index f90b97b7f..43a10ff0c 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -1,5 +1,4 @@ use std::{ - collections::VecDeque, io::{self, Write}, net::SocketAddr, rc::Rc, @@ -14,7 +13,7 @@ use authentication::GameProfile; use mio::{event::Event, net::TcpStream, Token}; use pumpkin_core::text::TextComponent; use pumpkin_protocol::{ - bytebuf::packet_id::Packet, + bytebuf::{packet_id::Packet, DeserializerError}, client::{config::CConfigDisconnect, login::CLoginDisconnect, play::CPlayDisconnect}, packet_decoder::PacketDecoder, packet_encoder::PacketEncoder, @@ -76,7 +75,7 @@ pub struct Client { pub address: SocketAddr, enc: PacketEncoder, dec: PacketDecoder, - pub client_packets_queue: VecDeque, + pub client_packets_queue: Vec, pub make_player: bool, } @@ -96,14 +95,14 @@ impl Client { dec: PacketDecoder::default(), encryption: true, closed: false, - client_packets_queue: VecDeque::new(), + client_packets_queue: Vec::new(), make_player: false, } } /// adds a Incoming packet to the queue pub fn add_packet(&mut self, packet: RawPacket) { - self.client_packets_queue.push_back(packet); + self.client_packets_queue.push(packet); } /// enables encryption @@ -146,86 +145,121 @@ impl Client { } pub async fn process_packets(&mut self, server: &mut Server) { - let mut i = 0; - while i < self.client_packets_queue.len() { - let mut packet = self.client_packets_queue.remove(i).unwrap(); - self.handle_packet(server, &mut packet).await; - i += 1; + while let Some(mut packet) = self.client_packets_queue.pop() { + match self.handle_packet(server, &mut packet).await { + Ok(_) => {} + Err(e) => { + let text = format!("Error while reading incoming packet {}", e); + log::error!("{}", text); + self.kick(&text) + } + }; } } /// 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() let bytebuf = &mut packet.bytebuf; match self.connection_state { pumpkin_protocol::ConnectionState::HandShake => match packet.id.0 { SHandShake::PACKET_ID => { - self.handle_handshake(server, SHandShake::read(bytebuf).unwrap()) + self.handle_handshake(server, SHandShake::read(bytebuf)?); + Ok(()) + } + _ => { + log::error!( + "Failed to handle packet id {} while in Handshake state", + packet.id.0 + ); + Ok(()) } - _ => log::error!( - "Failed to handle packet id {} while in Handshake state", - packet.id.0 - ), }, pumpkin_protocol::ConnectionState::Status => match packet.id.0 { SStatusRequest::PACKET_ID => { - self.handle_status_request(server, SStatusRequest::read(bytebuf).unwrap()) + self.handle_status_request(server, SStatusRequest::read(bytebuf)?); + Ok(()) } SStatusPingRequest::PACKET_ID => { - self.handle_ping_request(server, SStatusPingRequest::read(bytebuf).unwrap()) + self.handle_ping_request(server, SStatusPingRequest::read(bytebuf)?); + Ok(()) + } + _ => { + log::error!( + "Failed to handle packet id {} while in Status state", + packet.id.0 + ); + Ok(()) } - _ => log::error!( - "Failed to handle packet id {} while in Status state", - packet.id.0 - ), }, // TODO: Check config if transfer is enabled pumpkin_protocol::ConnectionState::Login | pumpkin_protocol::ConnectionState::Transfer => match packet.id.0 { SLoginStart::PACKET_ID => { - self.handle_login_start(server, SLoginStart::read(bytebuf).unwrap()) + self.handle_login_start(server, SLoginStart::read(bytebuf)?); + Ok(()) } SEncryptionResponse::PACKET_ID => { - self.handle_encryption_response( - server, - SEncryptionResponse::read(bytebuf).unwrap(), - ) - .await + self.handle_encryption_response(server, SEncryptionResponse::read(bytebuf)?) + .await; + Ok(()) + } + SLoginPluginResponse::PACKET_ID => { + self.handle_plugin_response(server, SLoginPluginResponse::read(bytebuf)?); + Ok(()) + } + SLoginAcknowledged::PACKET_ID => { + self.handle_login_acknowledged(server, SLoginAcknowledged::read(bytebuf)?); + Ok(()) + } + _ => { + log::error!( + "Failed to handle packet id {} while in Login state", + packet.id.0 + ); + Ok(()) } - SLoginPluginResponse::PACKET_ID => self - .handle_plugin_response(server, SLoginPluginResponse::read(bytebuf).unwrap()), - SLoginAcknowledged::PACKET_ID => self - .handle_login_acknowledged(server, SLoginAcknowledged::read(bytebuf).unwrap()), - _ => log::error!( - "Failed to handle packet id {} while in Login state", - packet.id.0 - ), }, pumpkin_protocol::ConnectionState::Config => match packet.id.0 { - SClientInformationConfig::PACKET_ID => self.handle_client_information_config( - server, - SClientInformationConfig::read(bytebuf).unwrap(), - ), + SClientInformationConfig::PACKET_ID => { + self.handle_client_information_config( + server, + SClientInformationConfig::read(bytebuf)?, + ); + Ok(()) + } SPluginMessage::PACKET_ID => { - self.handle_plugin_message(server, SPluginMessage::read(bytebuf).unwrap()) + self.handle_plugin_message(server, SPluginMessage::read(bytebuf)?); + Ok(()) } SAcknowledgeFinishConfig::PACKET_ID => { self.handle_config_acknowledged( server, - SAcknowledgeFinishConfig::read(bytebuf).unwrap(), + SAcknowledgeFinishConfig::read(bytebuf)?, ) - .await + .await; + Ok(()) } SKnownPacks::PACKET_ID => { - self.handle_known_packs(server, SKnownPacks::read(bytebuf).unwrap()) + self.handle_known_packs(server, SKnownPacks::read(bytebuf)?); + Ok(()) + } + _ => { + log::error!( + "Failed to handle packet id {} while in Config state", + packet.id.0 + ); + Ok(()) } - _ => log::error!( - "Failed to handle packet id {} while in Config state", - packet.id.0 - ), }, - _ => 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 { ConnectionState::Login => { 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()); } diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index 64f46e585..8a8d3471d 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -6,7 +6,7 @@ use pumpkin_core::text::TextComponent; use pumpkin_entity::{entity_type::EntityType, Entity, EntityId}; use pumpkin_inventory::player::PlayerInventory; use pumpkin_protocol::{ - bytebuf::packet_id::Packet, + bytebuf::{packet_id::Packet, DeserializerError}, client::play::{CGameEvent, CPlayDisconnect, CSyncPlayerPosition, CSystemChatMessage}, server::play::{ SChatCommand, SChatMessage, SClientInformationPlay, SConfirmTeleport, SInteract, @@ -153,61 +153,89 @@ impl Player { impl Player { pub fn process_packets(&mut self, server: &mut Server) { - let mut i = 0; - while i < self.client.client_packets_queue.len() { - let mut packet = self.client.client_packets_queue.remove(i).unwrap(); - self.handle_play_packet(server, &mut packet); - i += 1; + while let Some(mut packet) = self.client.client_packets_queue.pop() { + match self.handle_play_packet(server, &mut packet) { + Ok(_) => {} + Err(e) => { + 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; match packet.id.0 { SConfirmTeleport::PACKET_ID => { - self.handle_confirm_teleport(server, SConfirmTeleport::read(bytebuf).unwrap()) + self.handle_confirm_teleport(server, SConfirmTeleport::read(bytebuf)?); + Ok(()) } SChatCommand::PACKET_ID => { - self.handle_chat_command(server, SChatCommand::read(bytebuf).unwrap()) + self.handle_chat_command(server, SChatCommand::read(bytebuf)?); + Ok(()) } 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 => { - self.handle_rotation(server, SPlayerRotation::read(bytebuf).unwrap()) + self.handle_rotation(server, SPlayerRotation::read(bytebuf)?); + Ok(()) } SPlayerCommand::PACKET_ID => { - self.handle_player_command(server, SPlayerCommand::read(bytebuf).unwrap()) + self.handle_player_command(server, SPlayerCommand::read(bytebuf)?); + Ok(()) } SSwingArm::PACKET_ID => { - self.handle_swing_arm(server, SSwingArm::read(bytebuf).unwrap()) + self.handle_swing_arm(server, SSwingArm::read(bytebuf)?); + Ok(()) } 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 => { - self.handle_player_action(server, SPlayerAction::read(bytebuf).unwrap()) + self.handle_player_action(server, SPlayerAction::read(bytebuf)?); + Ok(()) } 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 => { - self.handle_set_held_item(server, SSetHeldItem::read(bytebuf).unwrap()) + self.handle_set_held_item(server, SSetHeldItem::read(bytebuf)?); + Ok(()) } 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 => { - 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), } } }