From 7c2b650bdb391a0d5c6cabb2df7478f60ad11b99 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Fri, 23 Aug 2024 10:32:00 +0200 Subject: [PATCH 01/10] add clientbound packet: CCloseContainer --- .../src/client/play/c_close_container.rs | 16 ++++++++++++++++ pumpkin-protocol/src/client/play/mod.rs | 2 ++ pumpkin/src/client/container.rs | 10 +++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 pumpkin-protocol/src/client/play/c_close_container.rs diff --git a/pumpkin-protocol/src/client/play/c_close_container.rs b/pumpkin-protocol/src/client/play/c_close_container.rs new file mode 100644 index 000000000..56c3bb457 --- /dev/null +++ b/pumpkin-protocol/src/client/play/c_close_container.rs @@ -0,0 +1,16 @@ +use serde::Serialize; +use pumpkin_macros::packet; + +#[derive(Serialize)] +#[packet(0x12)] +pub struct CCloseContainer { + window_id: u8 +} + +impl CCloseContainer { + pub const fn new(window_id: u8) -> Self { + Self { + window_id + } + } +} \ No newline at end of file diff --git a/pumpkin-protocol/src/client/play/mod.rs b/pumpkin-protocol/src/client/play/mod.rs index 2e15aa978..65a5ba8d0 100644 --- a/pumpkin-protocol/src/client/play/mod.rs +++ b/pumpkin-protocol/src/client/play/mod.rs @@ -36,6 +36,7 @@ mod c_update_entity_pos; mod c_update_entity_rot; mod c_worldevent; mod player_action; +mod c_close_container; pub use c_acknowledge_block::*; pub use c_actionbar::*; @@ -75,3 +76,4 @@ pub use c_update_entity_pos::*; pub use c_update_entity_rot::*; pub use c_worldevent::*; pub use player_action::*; +pub use c_close_container::*; \ No newline at end of file diff --git a/pumpkin/src/client/container.rs b/pumpkin/src/client/container.rs index b8a242dbd..ead7eb502 100644 --- a/pumpkin/src/client/container.rs +++ b/pumpkin/src/client/container.rs @@ -1,6 +1,6 @@ use pumpkin_core::text::TextComponent; use pumpkin_inventory::WindowType; -use pumpkin_protocol::client::play::{COpenScreen, CSetContainerContent, CSetContainerSlot}; +use pumpkin_protocol::client::play::{CCloseContainer, COpenScreen, CSetContainerContent, CSetContainerSlot}; use pumpkin_protocol::slot::Slot; use pumpkin_world::item::Item; @@ -82,4 +82,12 @@ impl super::Client { &item.into(), )) } + + /// The official Minecraft client is weird, and will always just close *any* window that is opened when this gets sent + pub fn close_container( + &mut self, + window_type: WindowType + ) { + self.send_packet(&CCloseContainer::new(window_type as u8)) + } } From 85f7ab041ac2decea5f10137d1900ea93322d586 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Fri, 23 Aug 2024 11:51:12 +0200 Subject: [PATCH 02/10] add clientbound packet: CSetContainerProperty --- .../client/play/c_set_container_property.rs | 19 +++++++++++++++++++ pumpkin-protocol/src/client/play/mod.rs | 4 +++- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 pumpkin-protocol/src/client/play/c_set_container_property.rs diff --git a/pumpkin-protocol/src/client/play/c_set_container_property.rs b/pumpkin-protocol/src/client/play/c_set_container_property.rs new file mode 100644 index 000000000..fd54753fe --- /dev/null +++ b/pumpkin-protocol/src/client/play/c_set_container_property.rs @@ -0,0 +1,19 @@ +use serde::Serialize; +use pumpkin_macros::packet; +#[derive(Serialize)] +#[packet(0x14)] +pub struct CSetContainerProperty { + window_id: u8, + property: i16, + value: i16 +} + +impl CSetContainerProperty { + pub const fn new(window_id: u8, property: i16, value:i16) -> Self { + Self { + window_id, + property, + value + } + } +} diff --git a/pumpkin-protocol/src/client/play/mod.rs b/pumpkin-protocol/src/client/play/mod.rs index 65a5ba8d0..838c79272 100644 --- a/pumpkin-protocol/src/client/play/mod.rs +++ b/pumpkin-protocol/src/client/play/mod.rs @@ -37,6 +37,7 @@ mod c_update_entity_rot; mod c_worldevent; mod player_action; mod c_close_container; +mod c_set_container_property; pub use c_acknowledge_block::*; pub use c_actionbar::*; @@ -76,4 +77,5 @@ pub use c_update_entity_pos::*; pub use c_update_entity_rot::*; pub use c_worldevent::*; pub use player_action::*; -pub use c_close_container::*; \ No newline at end of file +pub use c_close_container::*; +pub use c_set_container_property::*; \ No newline at end of file From 1d1dcc6a853349669684f4c32ede8ee6d1983d81 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Fri, 23 Aug 2024 11:51:37 +0200 Subject: [PATCH 03/10] make window property abstractions --- pumpkin-inventory/src/lib.rs | 1 + pumpkin-inventory/src/window_property.rs | 111 +++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 pumpkin-inventory/src/window_property.rs diff --git a/pumpkin-inventory/src/lib.rs b/pumpkin-inventory/src/lib.rs index 044980cc4..0230ac189 100644 --- a/pumpkin-inventory/src/lib.rs +++ b/pumpkin-inventory/src/lib.rs @@ -1,6 +1,7 @@ use num_derive::ToPrimitive; pub mod player; +pub mod window_property; /// https://wiki.vg/Inventory #[derive(Debug, ToPrimitive, Clone)] diff --git a/pumpkin-inventory/src/window_property.rs b/pumpkin-inventory/src/window_property.rs new file mode 100644 index 000000000..64e24d044 --- /dev/null +++ b/pumpkin-inventory/src/window_property.rs @@ -0,0 +1,111 @@ +pub trait WindowPropertyTrait: Sized { + fn to_id(self) -> i16 { + 0 + } +} + +pub struct WindowProperty { + window_property: T, + value: i16 +} + +impl WindowProperty { + pub fn new(window_property: T,value: i16) -> Self { + Self { + window_property, + value + } + } + + pub fn into_packet(self) -> (i16,i16) { + (self.window_property.to_id(), self.value) + } +} + + +pub enum Furnace { + FireIcon, + MaximumFuelBurnTime, + ProgressArrow, + MaximumProgress +} + +impl WindowPropertyTrait for Furnace { + fn to_id(self) -> i16 { + self as i16 + } +} + + + +pub enum EnchantmentTable { + LevelRequirement{ + slot:u8 + }, + EnchantmentSeed, + EnchantmentId{ + slot:u8 + }, + EnchantmentLevel{slot:u8}, +} + +impl WindowPropertyTrait for EnchantmentTable { + fn to_id(self) -> i16 { + use EnchantmentTable::*; + + (match self { + LevelRequirement{slot} => slot, + EnchantmentSeed => 3, + EnchantmentId{slot} => 4+slot, + EnchantmentLevel{slot} => 7+slot, + }) as i16 + } +} + +pub enum Beacon { + PowerLevel, + FirstPotionEffect, + SecondPotionEffect +} + +impl WindowPropertyTrait for Beacon { + fn to_id(self) -> i16 { + self as i16 + } +} + +pub enum Anvil { + RepairCost +} + +impl WindowPropertyTrait for Anvil {} + +pub enum BrewingStand{ + BrewTime, + FuelTime +} + +impl WindowPropertyTrait for BrewingStand { + fn to_id(self) -> i16 { + self as i16 + } +} + +pub enum Stonecutter { + SelectedRecipe +} + +impl WindowPropertyTrait for Stonecutter {} + +pub enum Loom { + SelectedPattern +} + +impl WindowPropertyTrait for Loom {} + +pub enum Lectern { + PageNumber +} + +impl WindowPropertyTrait for Lectern {} + From 4523900de44f66c3d965c2fdf93dda9e18d133d6 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Fri, 23 Aug 2024 11:51:51 +0200 Subject: [PATCH 04/10] add method to set container property --- pumpkin/src/client/container.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pumpkin/src/client/container.rs b/pumpkin/src/client/container.rs index ead7eb502..edec9f39e 100644 --- a/pumpkin/src/client/container.rs +++ b/pumpkin/src/client/container.rs @@ -1,6 +1,7 @@ use pumpkin_core::text::TextComponent; +use pumpkin_inventory::window_property::{WindowProperty, WindowPropertyTrait}; use pumpkin_inventory::WindowType; -use pumpkin_protocol::client::play::{CCloseContainer, COpenScreen, CSetContainerContent, CSetContainerSlot}; +use pumpkin_protocol::client::play::{CCloseContainer, COpenScreen, CSetContainerContent, CSetContainerProperty, CSetContainerSlot}; use pumpkin_protocol::slot::Slot; use pumpkin_world::item::Item; @@ -90,4 +91,9 @@ impl super::Client { ) { self.send_packet(&CCloseContainer::new(window_type as u8)) } + + pub fn set_container_property(&mut self, window_type: WindowType, window_property: WindowProperty) { + let (id,value) = window_property.into_packet(); + self.send_packet(&CSetContainerProperty::new(window_type as u8,id,value)); + } } From 98fcd412c2f86cc2df43a1284d31acaf1b583aca Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Fri, 23 Aug 2024 11:52:21 +0200 Subject: [PATCH 05/10] formatting --- pumpkin-inventory/src/window_property.rs | 46 ++++++++----------- .../src/client/play/c_close_container.rs | 10 ++-- .../client/play/c_set_container_property.rs | 8 ++-- pumpkin-protocol/src/client/play/mod.rs | 8 ++-- pumpkin/src/client/container.rs | 25 +++++----- 5 files changed, 45 insertions(+), 52 deletions(-) diff --git a/pumpkin-inventory/src/window_property.rs b/pumpkin-inventory/src/window_property.rs index 64e24d044..67deb646e 100644 --- a/pumpkin-inventory/src/window_property.rs +++ b/pumpkin-inventory/src/window_property.rs @@ -6,28 +6,27 @@ pub trait WindowPropertyTrait: Sized { pub struct WindowProperty { window_property: T, - value: i16 + value: i16, } impl WindowProperty { - pub fn new(window_property: T,value: i16) -> Self { + pub fn new(window_property: T, value: i16) -> Self { Self { window_property, - value + value, } } - - pub fn into_packet(self) -> (i16,i16) { + + pub fn into_packet(self) -> (i16, i16) { (self.window_property.to_id(), self.value) } } - pub enum Furnace { FireIcon, MaximumFuelBurnTime, ProgressArrow, - MaximumProgress + MaximumProgress, } impl WindowPropertyTrait for Furnace { @@ -36,17 +35,11 @@ impl WindowPropertyTrait for Furnace { } } - - pub enum EnchantmentTable { - LevelRequirement{ - slot:u8 - }, + LevelRequirement { slot: u8 }, EnchantmentSeed, - EnchantmentId{ - slot:u8 - }, - EnchantmentLevel{slot:u8}, + EnchantmentId { slot: u8 }, + EnchantmentLevel { slot: u8 }, } impl WindowPropertyTrait for EnchantmentTable { @@ -54,10 +47,10 @@ impl WindowPropertyTrait for EnchantmentTable { use EnchantmentTable::*; (match self { - LevelRequirement{slot} => slot, + LevelRequirement { slot } => slot, EnchantmentSeed => 3, - EnchantmentId{slot} => 4+slot, - EnchantmentLevel{slot} => 7+slot, + EnchantmentId { slot } => 4 + slot, + EnchantmentLevel { slot } => 7 + slot, }) as i16 } } @@ -65,7 +58,7 @@ impl WindowPropertyTrait for EnchantmentTable { pub enum Beacon { PowerLevel, FirstPotionEffect, - SecondPotionEffect + SecondPotionEffect, } impl WindowPropertyTrait for Beacon { @@ -75,14 +68,14 @@ impl WindowPropertyTrait for Beacon { } pub enum Anvil { - RepairCost + RepairCost, } impl WindowPropertyTrait for Anvil {} -pub enum BrewingStand{ +pub enum BrewingStand { BrewTime, - FuelTime + FuelTime, } impl WindowPropertyTrait for BrewingStand { @@ -92,20 +85,19 @@ impl WindowPropertyTrait for BrewingStand { } pub enum Stonecutter { - SelectedRecipe + SelectedRecipe, } impl WindowPropertyTrait for Stonecutter {} pub enum Loom { - SelectedPattern + SelectedPattern, } impl WindowPropertyTrait for Loom {} pub enum Lectern { - PageNumber + PageNumber, } impl WindowPropertyTrait for Lectern {} - diff --git a/pumpkin-protocol/src/client/play/c_close_container.rs b/pumpkin-protocol/src/client/play/c_close_container.rs index 56c3bb457..b8350265b 100644 --- a/pumpkin-protocol/src/client/play/c_close_container.rs +++ b/pumpkin-protocol/src/client/play/c_close_container.rs @@ -1,16 +1,14 @@ -use serde::Serialize; use pumpkin_macros::packet; +use serde::Serialize; #[derive(Serialize)] #[packet(0x12)] pub struct CCloseContainer { - window_id: u8 + window_id: u8, } impl CCloseContainer { pub const fn new(window_id: u8) -> Self { - Self { - window_id - } + Self { window_id } } -} \ No newline at end of file +} diff --git a/pumpkin-protocol/src/client/play/c_set_container_property.rs b/pumpkin-protocol/src/client/play/c_set_container_property.rs index fd54753fe..1fee26ef5 100644 --- a/pumpkin-protocol/src/client/play/c_set_container_property.rs +++ b/pumpkin-protocol/src/client/play/c_set_container_property.rs @@ -1,19 +1,19 @@ -use serde::Serialize; use pumpkin_macros::packet; +use serde::Serialize; #[derive(Serialize)] #[packet(0x14)] pub struct CSetContainerProperty { window_id: u8, property: i16, - value: i16 + value: i16, } impl CSetContainerProperty { - pub const fn new(window_id: u8, property: i16, value:i16) -> Self { + pub const fn new(window_id: u8, property: i16, value: i16) -> Self { Self { window_id, property, - value + value, } } } diff --git a/pumpkin-protocol/src/client/play/mod.rs b/pumpkin-protocol/src/client/play/mod.rs index 838c79272..8d4a6e84b 100644 --- a/pumpkin-protocol/src/client/play/mod.rs +++ b/pumpkin-protocol/src/client/play/mod.rs @@ -5,6 +5,7 @@ mod c_block_update; mod c_center_chunk; mod c_change_difficulty; mod c_chunk_data; +mod c_close_container; mod c_disguised_chat_message; mod c_entity_animation; mod c_entity_metadata; @@ -23,6 +24,7 @@ mod c_player_info_update; mod c_player_remove; mod c_remove_entities; mod c_set_container_content; +mod c_set_container_property; mod c_set_container_slot; mod c_set_held_item; mod c_set_title; @@ -36,8 +38,6 @@ mod c_update_entity_pos; mod c_update_entity_rot; mod c_worldevent; mod player_action; -mod c_close_container; -mod c_set_container_property; pub use c_acknowledge_block::*; pub use c_actionbar::*; @@ -46,6 +46,7 @@ pub use c_block_update::*; pub use c_center_chunk::*; pub use c_change_difficulty::*; pub use c_chunk_data::*; +pub use c_close_container::*; pub use c_disguised_chat_message::*; pub use c_entity_animation::*; pub use c_entity_metadata::*; @@ -64,6 +65,7 @@ pub use c_player_info_update::*; pub use c_player_remove::*; pub use c_remove_entities::*; pub use c_set_container_content::*; +pub use c_set_container_property::*; pub use c_set_container_slot::*; pub use c_set_held_item::*; pub use c_set_title::*; @@ -77,5 +79,3 @@ pub use c_update_entity_pos::*; pub use c_update_entity_rot::*; pub use c_worldevent::*; pub use player_action::*; -pub use c_close_container::*; -pub use c_set_container_property::*; \ No newline at end of file diff --git a/pumpkin/src/client/container.rs b/pumpkin/src/client/container.rs index edec9f39e..a0c852b53 100644 --- a/pumpkin/src/client/container.rs +++ b/pumpkin/src/client/container.rs @@ -1,7 +1,9 @@ use pumpkin_core::text::TextComponent; use pumpkin_inventory::window_property::{WindowProperty, WindowPropertyTrait}; use pumpkin_inventory::WindowType; -use pumpkin_protocol::client::play::{CCloseContainer, COpenScreen, CSetContainerContent, CSetContainerProperty, CSetContainerSlot}; +use pumpkin_protocol::client::play::{ + CCloseContainer, COpenScreen, CSetContainerContent, CSetContainerProperty, CSetContainerSlot, +}; use pumpkin_protocol::slot::Slot; use pumpkin_world::item::Item; @@ -83,17 +85,18 @@ impl super::Client { &item.into(), )) } - - /// The official Minecraft client is weird, and will always just close *any* window that is opened when this gets sent - pub fn close_container( - &mut self, - window_type: WindowType - ) { + + /// The official Minecraft client is weird, and will always just close *any* window that is opened when this gets sent + pub fn close_container(&mut self, window_type: WindowType) { self.send_packet(&CCloseContainer::new(window_type as u8)) } - - pub fn set_container_property(&mut self, window_type: WindowType, window_property: WindowProperty) { - let (id,value) = window_property.into_packet(); - self.send_packet(&CSetContainerProperty::new(window_type as u8,id,value)); + + pub fn set_container_property( + &mut self, + window_type: WindowType, + window_property: WindowProperty, + ) { + let (id, value) = window_property.into_packet(); + self.send_packet(&CSetContainerProperty::new(window_type as u8, id, value)); } } From e1a7d4e7eed37bba4606d974767f8b0ee91d05cc Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Fri, 23 Aug 2024 11:51:37 +0200 Subject: [PATCH 06/10] add serverbound packet SContainerClose --- pumpkin-inventory/src/lib.rs | 34 +++++++++++++++++++ pumpkin-protocol/src/server/play/mod.rs | 2 ++ .../src/server/play/s_close_container.rs | 8 +++++ pumpkin/src/client/player_packet.rs | 13 +++++++ 4 files changed, 57 insertions(+) create mode 100644 pumpkin-protocol/src/server/play/s_close_container.rs diff --git a/pumpkin-inventory/src/lib.rs b/pumpkin-inventory/src/lib.rs index 0230ac189..3595bd6c2 100644 --- a/pumpkin-inventory/src/lib.rs +++ b/pumpkin-inventory/src/lib.rs @@ -52,3 +52,37 @@ impl WindowType { "WINDOW TITLE" } } +impl TryFrom for WindowType { + type Error = (); + + fn try_from(value: u8) -> Result { + match value { + 0 => Ok(WindowType::Generic9x1), + 1 => Ok(WindowType::Generic9x2), + 2 => Ok(WindowType::Generic9x3), + 3 => Ok(WindowType::Generic9x4), + 4 => Ok(WindowType::Generic9x5), + 5 => Ok(WindowType::Generic9x6), + 6 => Ok(WindowType::Generic3x3), + 7 => Ok(WindowType::Craft3x3), + 8 => Ok(WindowType::Anvil), + 9 => Ok(WindowType::Beacon), + 10 => Ok(WindowType::BlastFurnace), + 11 => Ok(WindowType::BrewingStand), + 12 => Ok(WindowType::CraftingTable), + 13 => Ok(WindowType::EnchantmentTable), + 14 => Ok(WindowType::Furnace), + 15 => Ok(WindowType::Grindstone), + 16 => Ok(WindowType::Hopper), + 17 => Ok(WindowType::Lectern), + 18 => Ok(WindowType::Loom), + 19 => Ok(WindowType::Merchant), + 20 => Ok(WindowType::ShulkerBox), + 21 => Ok(WindowType::SmithingTable), + 22 => Ok(WindowType::Smoker), + 23 => Ok(WindowType::CartographyTable), + 24 => Ok(WindowType::Stonecutter), + _ => Err(()), + } + } +} diff --git a/pumpkin-protocol/src/server/play/mod.rs b/pumpkin-protocol/src/server/play/mod.rs index c29a11775..2cccb9c2e 100644 --- a/pumpkin-protocol/src/server/play/mod.rs +++ b/pumpkin-protocol/src/server/play/mod.rs @@ -1,6 +1,7 @@ mod s_chat_command; mod s_chat_message; mod s_client_information; +mod s_close_container; mod s_confirm_teleport; mod s_interact; mod s_ping_request; @@ -17,6 +18,7 @@ mod s_use_item_on; pub use s_chat_command::*; pub use s_chat_message::*; pub use s_client_information::*; +pub use s_close_container::*; pub use s_confirm_teleport::*; pub use s_interact::*; pub use s_ping_request::*; diff --git a/pumpkin-protocol/src/server/play/s_close_container.rs b/pumpkin-protocol/src/server/play/s_close_container.rs new file mode 100644 index 000000000..5ba6a5698 --- /dev/null +++ b/pumpkin-protocol/src/server/play/s_close_container.rs @@ -0,0 +1,8 @@ +use pumpkin_macros::packet; +use serde::Serialize; + +#[derive(Serialize)] +#[packet(0x0F)] +pub struct SCloseContainer { + pub window_id: u8, +} diff --git a/pumpkin/src/client/player_packet.rs b/pumpkin/src/client/player_packet.rs index 52d1defad..70522718a 100644 --- a/pumpkin/src/client/player_packet.rs +++ b/pumpkin/src/client/player_packet.rs @@ -9,6 +9,8 @@ use crate::{ use num_traits::FromPrimitive; use pumpkin_core::text::TextComponent; use pumpkin_entity::EntityId; +use pumpkin_inventory::WindowType; +use pumpkin_protocol::server::play::SCloseContainer; use pumpkin_protocol::{ client::play::{ Animation, CAcknowledgeBlockChange, CBlockUpdate, CEntityAnimation, CEntityVelocity, @@ -414,4 +416,15 @@ impl Client { inventory.set_slot(packet.slot as usize, packet.clicked_item.to_item(), false); } + + // TODO: + // This function will in the future be used to keep track of if the client is in a valid state. + // But this is not possible yet + pub fn handle_close_container(&mut self, packet: SCloseContainer) { + // window_id 0 represents both 9x1 Generic AND inventory here + let Ok(_window_type) = WindowType::try_from(packet.window_id) else { + self.kick("Invalid window ID"); + return; + }; + } } From ef21b3ae4071b5e61498f4fdb434b316e2198a76 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Fri, 23 Aug 2024 11:51:37 +0200 Subject: [PATCH 07/10] add serverbound packet SContainerClose --- pumpkin-protocol/src/server/play/s_close_container.rs | 4 ++-- pumpkin/src/client/mod.rs | 7 +++++-- pumpkin/src/client/player_packet.rs | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/pumpkin-protocol/src/server/play/s_close_container.rs b/pumpkin-protocol/src/server/play/s_close_container.rs index 5ba6a5698..564151168 100644 --- a/pumpkin-protocol/src/server/play/s_close_container.rs +++ b/pumpkin-protocol/src/server/play/s_close_container.rs @@ -1,7 +1,7 @@ use pumpkin_macros::packet; -use serde::Serialize; +use serde::Deserialize; -#[derive(Serialize)] +#[derive(Deserialize)] #[packet(0x0F)] pub struct SCloseContainer { pub window_id: u8, diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index 8edca66c7..71c49990d 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -28,8 +28,8 @@ use pumpkin_protocol::{ handshake::SHandShake, login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart}, play::{ - SChatCommand, SChatMessage, SClientInformationPlay, SConfirmTeleport, SInteract, - SPlayPingRequest, SPlayerAction, SPlayerCommand, SPlayerPosition, + SChatCommand, SChatMessage, SClientInformationPlay, SCloseContainer, SConfirmTeleport, + SInteract, SPlayPingRequest, SPlayerAction, SPlayerCommand, SPlayerPosition, SPlayerPositionRotation, SPlayerRotation, SSetCreativeSlot, SSetHeldItem, SSwingArm, SUseItemOn, }, @@ -312,6 +312,9 @@ impl Client { SPlayPingRequest::PACKET_ID => { self.handle_play_ping_request(server, SPlayPingRequest::read(bytebuf).unwrap()) } + SCloseContainer::PACKET_ID => { + self.handle_close_container(server, SCloseContainer::read(bytebuf).unwrap()) + } _ => log::error!("Failed to handle player packet id {:#04x}", packet.id.0), } } diff --git a/pumpkin/src/client/player_packet.rs b/pumpkin/src/client/player_packet.rs index 70522718a..27fe5e94c 100644 --- a/pumpkin/src/client/player_packet.rs +++ b/pumpkin/src/client/player_packet.rs @@ -420,7 +420,7 @@ impl Client { // TODO: // This function will in the future be used to keep track of if the client is in a valid state. // But this is not possible yet - pub fn handle_close_container(&mut self, packet: SCloseContainer) { + pub fn handle_close_container(&mut self, _server: &mut Server, packet: SCloseContainer) { // window_id 0 represents both 9x1 Generic AND inventory here let Ok(_window_type) = WindowType::try_from(packet.window_id) else { self.kick("Invalid window ID"); From 52943f66c876bcb7eb1f5422329d297c7d054656 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sat, 24 Aug 2024 18:03:32 +0200 Subject: [PATCH 08/10] Simply abstraction of property trait --- pumpkin-inventory/src/lib.rs | 38 ++------------------ pumpkin-inventory/src/window_property.rs | 46 +++++++++--------------- pumpkin/src/client/player_packet.rs | 2 +- 3 files changed, 19 insertions(+), 67 deletions(-) diff --git a/pumpkin-inventory/src/lib.rs b/pumpkin-inventory/src/lib.rs index 3595bd6c2..dadb10cc6 100644 --- a/pumpkin-inventory/src/lib.rs +++ b/pumpkin-inventory/src/lib.rs @@ -1,10 +1,10 @@ -use num_derive::ToPrimitive; +use num_derive::{FromPrimitive, ToPrimitive}; pub mod player; pub mod window_property; /// https://wiki.vg/Inventory -#[derive(Debug, ToPrimitive, Clone)] +#[derive(Debug, ToPrimitive, FromPrimitive, Clone)] pub enum WindowType { // not used Generic9x1, @@ -52,37 +52,3 @@ impl WindowType { "WINDOW TITLE" } } -impl TryFrom for WindowType { - type Error = (); - - fn try_from(value: u8) -> Result { - match value { - 0 => Ok(WindowType::Generic9x1), - 1 => Ok(WindowType::Generic9x2), - 2 => Ok(WindowType::Generic9x3), - 3 => Ok(WindowType::Generic9x4), - 4 => Ok(WindowType::Generic9x5), - 5 => Ok(WindowType::Generic9x6), - 6 => Ok(WindowType::Generic3x3), - 7 => Ok(WindowType::Craft3x3), - 8 => Ok(WindowType::Anvil), - 9 => Ok(WindowType::Beacon), - 10 => Ok(WindowType::BlastFurnace), - 11 => Ok(WindowType::BrewingStand), - 12 => Ok(WindowType::CraftingTable), - 13 => Ok(WindowType::EnchantmentTable), - 14 => Ok(WindowType::Furnace), - 15 => Ok(WindowType::Grindstone), - 16 => Ok(WindowType::Hopper), - 17 => Ok(WindowType::Lectern), - 18 => Ok(WindowType::Loom), - 19 => Ok(WindowType::Merchant), - 20 => Ok(WindowType::ShulkerBox), - 21 => Ok(WindowType::SmithingTable), - 22 => Ok(WindowType::Smoker), - 23 => Ok(WindowType::CartographyTable), - 24 => Ok(WindowType::Stonecutter), - _ => Err(()), - } - } -} diff --git a/pumpkin-inventory/src/window_property.rs b/pumpkin-inventory/src/window_property.rs index 67deb646e..56f4b2942 100644 --- a/pumpkin-inventory/src/window_property.rs +++ b/pumpkin-inventory/src/window_property.rs @@ -1,6 +1,13 @@ -pub trait WindowPropertyTrait: Sized { +use num_derive::ToPrimitive; +use num_traits::ToPrimitive; + +pub trait WindowPropertyTrait { + fn to_id(self) -> i16; +} + +impl WindowPropertyTrait for T { fn to_id(self) -> i16 { - 0 + self.to_i16().unwrap() } } @@ -21,7 +28,7 @@ impl WindowProperty { (self.window_property.to_id(), self.value) } } - +#[derive(ToPrimitive)] pub enum Furnace { FireIcon, MaximumFuelBurnTime, @@ -29,12 +36,6 @@ pub enum Furnace { MaximumProgress, } -impl WindowPropertyTrait for Furnace { - fn to_id(self) -> i16 { - self as i16 - } -} - pub enum EnchantmentTable { LevelRequirement { slot: u8 }, EnchantmentSeed, @@ -54,50 +55,35 @@ impl WindowPropertyTrait for EnchantmentTable { }) as i16 } } - +#[derive(ToPrimitive)] pub enum Beacon { PowerLevel, FirstPotionEffect, SecondPotionEffect, } -impl WindowPropertyTrait for Beacon { - fn to_id(self) -> i16 { - self as i16 - } -} - +#[derive(ToPrimitive)] pub enum Anvil { RepairCost, } -impl WindowPropertyTrait for Anvil {} - +#[derive(ToPrimitive)] pub enum BrewingStand { BrewTime, FuelTime, } -impl WindowPropertyTrait for BrewingStand { - fn to_id(self) -> i16 { - self as i16 - } -} - +#[derive(ToPrimitive)] pub enum Stonecutter { SelectedRecipe, } -impl WindowPropertyTrait for Stonecutter {} - +#[derive(ToPrimitive)] pub enum Loom { SelectedPattern, } -impl WindowPropertyTrait for Loom {} - +#[derive(ToPrimitive)] pub enum Lectern { PageNumber, } - -impl WindowPropertyTrait for Lectern {} diff --git a/pumpkin/src/client/player_packet.rs b/pumpkin/src/client/player_packet.rs index 27fe5e94c..5f4c0c61c 100644 --- a/pumpkin/src/client/player_packet.rs +++ b/pumpkin/src/client/player_packet.rs @@ -422,7 +422,7 @@ impl Client { // But this is not possible yet pub fn handle_close_container(&mut self, _server: &mut Server, packet: SCloseContainer) { // window_id 0 represents both 9x1 Generic AND inventory here - let Ok(_window_type) = WindowType::try_from(packet.window_id) else { + let Some(_window_type) = WindowType::from_u8(packet.window_id) else { self.kick("Invalid window ID"); return; }; From bae9198980381a7657b05a4fa38c40a12ce0bdbe Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sat, 24 Aug 2024 18:09:13 +0200 Subject: [PATCH 09/10] fix issues --- pumpkin/src/client/container.rs | 6 ++++-- pumpkin/src/client/mod.rs | 1 - pumpkin/src/client/player_packet.rs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pumpkin/src/client/container.rs b/pumpkin/src/client/container.rs index a2edae31c..80616d423 100644 --- a/pumpkin/src/client/container.rs +++ b/pumpkin/src/client/container.rs @@ -88,7 +88,8 @@ impl Player { /// The official Minecraft client is weird, and will always just close *any* window that is opened when this gets sent pub fn close_container(&mut self, window_type: WindowType) { - self.send_packet(&CCloseContainer::new(window_type as u8)) + self.client + .send_packet(&CCloseContainer::new(window_type as u8)) } pub fn set_container_property( @@ -97,6 +98,7 @@ impl Player { window_property: WindowProperty, ) { let (id, value) = window_property.into_packet(); - self.send_packet(&CSetContainerProperty::new(window_type as u8, id, value)); + self.client + .send_packet(&CSetContainerProperty::new(window_type as u8, id, value)); } } diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index ae5b7f650..5146a31f2 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -228,7 +228,6 @@ impl Client { } } - // Reads the connection until our buffer of len 4096 is full, then decode /// Close connection when an error occurs pub async fn poll(&mut self, event: &Event) { diff --git a/pumpkin/src/client/player_packet.rs b/pumpkin/src/client/player_packet.rs index 867b34475..b27af67cd 100644 --- a/pumpkin/src/client/player_packet.rs +++ b/pumpkin/src/client/player_packet.rs @@ -415,7 +415,7 @@ impl Player { pub fn handle_close_container(&mut self, _server: &mut Server, packet: SCloseContainer) { // window_id 0 represents both 9x1 Generic AND inventory here let Some(_window_type) = WindowType::from_u8(packet.window_id) else { - self.kick("Invalid window ID"); + self.kick(TextComponent::text("Invalid window ID")); return; }; } From 3428f03a0f98ef50a3f92f084575fbb2b8a58dbb Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sat, 24 Aug 2024 18:12:51 +0200 Subject: [PATCH 10/10] better name --- pumpkin-inventory/src/window_property.rs | 2 +- pumpkin/src/client/container.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pumpkin-inventory/src/window_property.rs b/pumpkin-inventory/src/window_property.rs index 56f4b2942..136d68312 100644 --- a/pumpkin-inventory/src/window_property.rs +++ b/pumpkin-inventory/src/window_property.rs @@ -24,7 +24,7 @@ impl WindowProperty { } } - pub fn into_packet(self) -> (i16, i16) { + pub fn into_tuple(self) -> (i16, i16) { (self.window_property.to_id(), self.value) } } diff --git a/pumpkin/src/client/container.rs b/pumpkin/src/client/container.rs index 80616d423..fc9cf1059 100644 --- a/pumpkin/src/client/container.rs +++ b/pumpkin/src/client/container.rs @@ -97,7 +97,7 @@ impl Player { window_type: WindowType, window_property: WindowProperty, ) { - let (id, value) = window_property.into_packet(); + let (id, value) = window_property.into_tuple(); self.client .send_packet(&CSetContainerProperty::new(window_type as u8, id, value)); }