From 99116190d972965f1ccca93bce32bf8d35343e51 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 21 Aug 2024 13:00:49 +0200 Subject: [PATCH 1/8] first steps towards making containers openable --- pumpkin-inventory/src/lib.rs | 10 +++- pumpkin-inventory/src/player.rs | 9 ++++ .../client/play/c_set_container_content.rs | 27 +++++++++++ pumpkin-protocol/src/client/play/mod.rs | 2 + pumpkin-protocol/src/slot.rs | 32 ++++++++++--- pumpkin/src/client/mod.rs | 48 ++++++++++++++++++- 6 files changed, 118 insertions(+), 10 deletions(-) create mode 100644 pumpkin-protocol/src/client/play/c_set_container_content.rs diff --git a/pumpkin-inventory/src/lib.rs b/pumpkin-inventory/src/lib.rs index 1ab7cba1c..2b5730afb 100644 --- a/pumpkin-inventory/src/lib.rs +++ b/pumpkin-inventory/src/lib.rs @@ -3,7 +3,7 @@ use num_derive::ToPrimitive; pub mod player; /// https://wiki.vg/Inventory -#[derive(Debug, ToPrimitive)] +#[derive(Debug, ToPrimitive, Clone)] pub enum WindowType { // not used Generic9x1, @@ -41,3 +41,11 @@ pub enum WindowType { CartographyTable, Stonecutter, } + +impl WindowType { + pub const fn default_title(&self) -> &'static str { + match self { + _ => "WINDOW TITLE" + } + } +} \ No newline at end of file diff --git a/pumpkin-inventory/src/player.rs b/pumpkin-inventory/src/player.rs index f7147f181..fe01acc98 100644 --- a/pumpkin-inventory/src/player.rs +++ b/pumpkin-inventory/src/player.rs @@ -95,4 +95,13 @@ impl PlayerInventory { debug_assert!((0..9).contains(&self.selected)); self.items[self.selected + 36 - 9].as_ref() } + + pub fn slots(&self) -> Vec> { + let mut slots = vec![self.crafting_output.as_ref()]; + slots.extend(self.crafting.iter().map(|c|c.as_ref())); + slots.extend(self.armor.iter().map(|c|c.as_ref())); + slots.extend(self.items.iter().map(|c|c.as_ref())); + slots.push(self.offhand.as_ref()); + slots + } } diff --git a/pumpkin-protocol/src/client/play/c_set_container_content.rs b/pumpkin-protocol/src/client/play/c_set_container_content.rs new file mode 100644 index 000000000..39a298d47 --- /dev/null +++ b/pumpkin-protocol/src/client/play/c_set_container_content.rs @@ -0,0 +1,27 @@ +use pumpkin_macros::packet; +use serde::Serialize; +use crate::slot::Slot; +use crate::VarInt; + +#[derive(Serialize)] +#[packet(0x13)] +pub struct CSetContainerContent<'a> { + window_id: u8, + state_id: VarInt, + count: VarInt, + slot_data: &'a [Slot], + carried_item: Slot +} + + +impl<'a> CSetContainerContent<'a> { + pub fn new(window_id: u8,state_id: VarInt, slots: &'a [Slot], carried_item: Slot) -> Self { + Self { + window_id, + state_id, + count: slots.len().try_into().unwrap(), + slot_data: slots, + carried_item + } + } +} diff --git a/pumpkin-protocol/src/client/play/mod.rs b/pumpkin-protocol/src/client/play/mod.rs index 2ff20e4c0..6437e23a5 100644 --- a/pumpkin-protocol/src/client/play/mod.rs +++ b/pumpkin-protocol/src/client/play/mod.rs @@ -33,6 +33,7 @@ mod c_update_entity_pos; mod c_update_entity_rot; mod c_worldevent; mod player_action; +mod c_set_container_content; pub use c_acknowledge_block::*; pub use c_actionbar::*; @@ -69,3 +70,4 @@ pub use c_update_entity_pos::*; pub use c_update_entity_rot::*; pub use c_worldevent::*; pub use player_action::*; +pub use c_set_container_content::*; \ No newline at end of file diff --git a/pumpkin-protocol/src/slot.rs b/pumpkin-protocol/src/slot.rs index 22223f3b4..84ffd662d 100644 --- a/pumpkin-protocol/src/slot.rs +++ b/pumpkin-protocol/src/slot.rs @@ -3,9 +3,10 @@ use pumpkin_world::item::Item; use serde::{ de::{self, SeqAccess, Visitor}, Deserialize, + Serialize }; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize)] #[allow(dead_code)] pub struct Slot { item_count: VarInt, @@ -83,12 +84,29 @@ impl Slot { item_count: self.item_count.0.try_into().unwrap(), }) } -} -impl From for Item { - fn from(slot: Slot) -> Self { - Item { - item_count: slot.item_count.0.try_into().unwrap(), - item_id: slot.item_id.unwrap().0.try_into().unwrap(), + + pub const fn empty() -> Self { + Slot { + item_count: VarInt(0), + item_id: None, + num_components_to_add: None, + num_components_to_remove: None, + components_to_add: None, + components_to_remove: None, } } } + +impl From<&Item> for Slot { + fn from(item: &Item) -> Self { + Slot { + item_count: item.item_count.into(), + item_id: Some(item.item_id.into()), + // TODO: add these + num_components_to_add: None, + num_components_to_remove: None, + components_to_add: None, + components_to_remove: None, + } + } +} \ No newline at end of file diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index 837976873..59e38e0f0 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -18,7 +18,7 @@ use pumpkin_protocol::{ client::{ config::CConfigDisconnect, login::CLoginDisconnect, - play::{CGameEvent, CPlayDisconnect, CSyncPlayerPostion, CSystemChatMessge}, + play::{CGameEvent, CPlayDisconnect, CSyncPlayerPostion, CSystemChatMessge, CSetContainerContent}, }, packet_decoder::PacketDecoder, packet_encoder::PacketEncoder, @@ -40,6 +40,10 @@ use pumpkin_text::TextComponent; use std::io::Read; use thiserror::Error; +use pumpkin_inventory::WindowType; +use pumpkin_protocol::client::play::COpenScreen; +use pumpkin_protocol::slot::Slot; +use pumpkin_world::item::Item; pub mod authentication; mod client_packet; @@ -174,6 +178,46 @@ impl Client { player.gamemode = gamemode; self.send_packet(&CGameEvent::new(3, gamemode.to_f32().unwrap())); } + + pub fn open_container(&mut self, window_type: WindowType, minecraft_menu_id: &str,window_title: Option<&str>) { + let menu_protocol_id = (*pumpkin_world::global_registry::REGISTRY.get("minecraft:menu").unwrap().entries.get(minecraft_menu_id).expect("Should be a valid menu id").get("protocol_id").unwrap()).into(); + let title = TextComponent::text(window_title.unwrap_or(window_type.default_title())); + self.send_packet(&COpenScreen::new((window_type.clone() as u8 +1).into(),menu_protocol_id, title)); + let temp_item = Item { + item_id: 91, // Diamond block + item_count: 64 + }; + self.set_container_content(window_type, Some([Some(&temp_item);27].to_vec()), None); + } + + pub fn set_container_content<'a>(&mut self, window_type: WindowType, items: Option>>, carried_item: Option<&'a Item>) { + let player = self.player.as_ref().unwrap(); + + let slots: Vec = {if let Some(mut items) = items { + items.extend(player.inventory.slots() + ); + items + } else { + player.inventory.slots() + }.into_iter() + .map(|item|{ + if let Some(item) = item { + Slot::from(item) + } else { + Slot::empty() + } + }).collect()}; + + let carried_item = { + if let Some(item) = carried_item { + item.into() + } else { + Slot::empty() + } + }; + + self.send_packet(&CSetContainerContent::new(window_type as u8, 10.into(), &slots, carried_item)) + } pub async fn process_packets(&mut self, server: &mut Server) { let mut i = 0; @@ -359,7 +403,7 @@ impl Client { } } } - + pub fn send_system_message(&mut self, text: TextComponent) { self.send_packet(&CSystemChatMessge::new(text, false)); } From 53f7b3b573da0f7f53017b6e4bcde08883a7952c Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 21 Aug 2024 13:00:54 +0200 Subject: [PATCH 2/8] testing command --- pumpkin/src/commands/cmd_chest.rs | 14 ++++++++++++++ pumpkin/src/commands/mod.rs | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 pumpkin/src/commands/cmd_chest.rs diff --git a/pumpkin/src/commands/cmd_chest.rs b/pumpkin/src/commands/cmd_chest.rs new file mode 100644 index 000000000..0e7957932 --- /dev/null +++ b/pumpkin/src/commands/cmd_chest.rs @@ -0,0 +1,14 @@ +use pumpkin_inventory::WindowType; + +use crate::commands::tree::CommandTree; + +pub(crate) const NAME: &str = "chest"; + +const DESCRIPTION: &str = "Open a chest containing lots of diamond blocks"; + +pub(crate) fn init_command_tree<'a>() -> CommandTree<'a> { + CommandTree::new(DESCRIPTION).execute(&|sender, _| { + sender.as_mut_player().unwrap().open_container(WindowType::Generic3x3,"minecraft:generic_9x3",None); + Ok(()) + }) +} diff --git a/pumpkin/src/commands/mod.rs b/pumpkin/src/commands/mod.rs index c622691d6..c1b2d9f6c 100644 --- a/pumpkin/src/commands/mod.rs +++ b/pumpkin/src/commands/mod.rs @@ -12,6 +12,7 @@ mod cmd_stop; mod dispatcher; mod tree; mod tree_builder; +mod cmd_chest; pub enum CommandSender<'a> { Rcon(&'a mut Vec), @@ -77,7 +78,7 @@ fn dispatcher_init<'a>() -> CommandDispatcher<'a> { map.insert(cmd_stop::NAME, cmd_stop::init_command_tree()); map.insert(cmd_help::NAME, cmd_help::init_command_tree()); map.insert(cmd_help::ALIAS, cmd_help::init_command_tree()); - + map.insert(cmd_chest::NAME,cmd_chest::init_command_tree()); CommandDispatcher { commands: map } } From 9003ee3dcc4518135bb9f7712d36423475475102 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 21 Aug 2024 19:27:58 +0200 Subject: [PATCH 3/8] add CSetContainerContent --- .../client/play/c_set_container_content.rs | 4 +- pumpkin-protocol/src/slot.rs | 65 +++++++++++++++++-- pumpkin/src/client/mod.rs | 15 ++--- 3 files changed, 65 insertions(+), 19 deletions(-) diff --git a/pumpkin-protocol/src/client/play/c_set_container_content.rs b/pumpkin-protocol/src/client/play/c_set_container_content.rs index 39a298d47..666039a7f 100644 --- a/pumpkin-protocol/src/client/play/c_set_container_content.rs +++ b/pumpkin-protocol/src/client/play/c_set_container_content.rs @@ -10,12 +10,12 @@ pub struct CSetContainerContent<'a> { state_id: VarInt, count: VarInt, slot_data: &'a [Slot], - carried_item: Slot + carried_item: &'a Slot } impl<'a> CSetContainerContent<'a> { - pub fn new(window_id: u8,state_id: VarInt, slots: &'a [Slot], carried_item: Slot) -> Self { + pub fn new(window_id: u8,state_id: VarInt, slots: &'a [Slot], carried_item: &'a Slot) -> Self { Self { window_id, state_id, diff --git a/pumpkin-protocol/src/slot.rs b/pumpkin-protocol/src/slot.rs index 84ffd662d..51521a960 100644 --- a/pumpkin-protocol/src/slot.rs +++ b/pumpkin-protocol/src/slot.rs @@ -1,12 +1,9 @@ use crate::VarInt; use pumpkin_world::item::Item; -use serde::{ - de::{self, SeqAccess, Visitor}, - Deserialize, - Serialize -}; +use serde::{de::{self, SeqAccess, Visitor}, Deserialize, Serialize, Serializer}; +use serde::ser::SerializeSeq; -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone)] #[allow(dead_code)] pub struct Slot { item_count: VarInt, @@ -76,6 +73,60 @@ impl<'de> Deserialize<'de> for Slot { deserializer.deserialize_seq(VarIntVisitor) } } + +impl Serialize for Slot { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + if self.item_count == 0.into() { + let mut s = serializer.serialize_seq(Some(1))?; + s.serialize_element(&self.item_count)?; + s.end() + } else { + match (&self.num_components_to_add,&self.num_components_to_remove) { + (Some(to_add),Some(to_remove)) => { + let mut s = serializer.serialize_seq(Some(6))?; + s.serialize_element(&self.item_count)?; + s.serialize_element(self.item_id.as_ref().unwrap())?; + s.serialize_element(to_add)?; + s.serialize_element(to_remove)?; + s.serialize_element(self.components_to_add.as_ref().unwrap())?; + s.serialize_element(self.components_to_remove.as_ref().unwrap())?; + s.end() + } + (None, Some(to_remove)) => { + let mut s = serializer.serialize_seq(Some(5))?; + s.serialize_element(&self.item_count)?; + s.serialize_element(self.item_id.as_ref().unwrap())?; + s.serialize_element(&VarInt(0))?; + s.serialize_element(to_remove)?; + s.serialize_element(self.components_to_remove.as_ref().unwrap())?; + s.end() + } + (Some(to_add),None) => { + let mut s = serializer.serialize_seq(Some(5))?; + s.serialize_element(&self.item_count)?; + s.serialize_element(self.item_id.as_ref().unwrap())?; + s.serialize_element(to_add)?; + s.serialize_element(&VarInt(0))?; + s.serialize_element(self.components_to_add.as_ref().unwrap())?; + s.end() + } + (None,None) => { + let mut s = serializer.serialize_seq(Some(4))?; + s.serialize_element(&self.item_count)?; + s.serialize_element(&self.item_id.as_ref().unwrap())?; + s.serialize_element(&VarInt(0))?; + s.serialize_element(&VarInt(0))?; + s.end() + } + } + + } + } +} + impl Slot { pub fn to_item(self) -> Option { let item_id = self.item_id?.0.try_into().unwrap(); @@ -103,7 +154,7 @@ impl From<&Item> for Slot { item_count: item.item_count.into(), item_id: Some(item.item_id.into()), // TODO: add these - num_components_to_add: None, + num_components_to_add:None, num_components_to_remove: None, components_to_add: None, components_to_remove: None, diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index 59e38e0f0..bc7d598ff 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -41,6 +41,7 @@ use pumpkin_text::TextComponent; use std::io::Read; use thiserror::Error; use pumpkin_inventory::WindowType; +use pumpkin_protocol::bytebuf::ByteBuffer; use pumpkin_protocol::client::play::COpenScreen; use pumpkin_protocol::slot::Slot; use pumpkin_world::item::Item; @@ -179,23 +180,18 @@ impl Client { self.send_packet(&CGameEvent::new(3, gamemode.to_f32().unwrap())); } - pub fn open_container(&mut self, window_type: WindowType, minecraft_menu_id: &str,window_title: Option<&str>) { + pub fn open_container(&mut self, window_type: WindowType, minecraft_menu_id: &str,window_title: Option<&str>, items: Option>>, carried_item: Option<&Item>) { let menu_protocol_id = (*pumpkin_world::global_registry::REGISTRY.get("minecraft:menu").unwrap().entries.get(minecraft_menu_id).expect("Should be a valid menu id").get("protocol_id").unwrap()).into(); let title = TextComponent::text(window_title.unwrap_or(window_type.default_title())); self.send_packet(&COpenScreen::new((window_type.clone() as u8 +1).into(),menu_protocol_id, title)); - let temp_item = Item { - item_id: 91, // Diamond block - item_count: 64 - }; - self.set_container_content(window_type, Some([Some(&temp_item);27].to_vec()), None); + self.set_container_content(window_type, items, carried_item); } pub fn set_container_content<'a>(&mut self, window_type: WindowType, items: Option>>, carried_item: Option<&'a Item>) { let player = self.player.as_ref().unwrap(); let slots: Vec = {if let Some(mut items) = items { - items.extend(player.inventory.slots() - ); + items.extend(player.inventory.slots()); items } else { player.inventory.slots() @@ -215,8 +211,7 @@ impl Client { Slot::empty() } }; - - self.send_packet(&CSetContainerContent::new(window_type as u8, 10.into(), &slots, carried_item)) + self.send_packet(&CSetContainerContent::new(window_type as u8+1, 0.into(), &slots, &carried_item)); } pub async fn process_packets(&mut self, server: &mut Server) { From 2e00110d5dd02644a0436ce987c3afbfafdeacaf Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 21 Aug 2024 19:28:27 +0200 Subject: [PATCH 4/8] remove debug thing --- pumpkin/src/commands/cmd_chest.rs | 14 -------------- pumpkin/src/commands/mod.rs | 2 -- 2 files changed, 16 deletions(-) delete mode 100644 pumpkin/src/commands/cmd_chest.rs diff --git a/pumpkin/src/commands/cmd_chest.rs b/pumpkin/src/commands/cmd_chest.rs deleted file mode 100644 index 0e7957932..000000000 --- a/pumpkin/src/commands/cmd_chest.rs +++ /dev/null @@ -1,14 +0,0 @@ -use pumpkin_inventory::WindowType; - -use crate::commands::tree::CommandTree; - -pub(crate) const NAME: &str = "chest"; - -const DESCRIPTION: &str = "Open a chest containing lots of diamond blocks"; - -pub(crate) fn init_command_tree<'a>() -> CommandTree<'a> { - CommandTree::new(DESCRIPTION).execute(&|sender, _| { - sender.as_mut_player().unwrap().open_container(WindowType::Generic3x3,"minecraft:generic_9x3",None); - Ok(()) - }) -} diff --git a/pumpkin/src/commands/mod.rs b/pumpkin/src/commands/mod.rs index c1b2d9f6c..c977bb0f9 100644 --- a/pumpkin/src/commands/mod.rs +++ b/pumpkin/src/commands/mod.rs @@ -12,7 +12,6 @@ mod cmd_stop; mod dispatcher; mod tree; mod tree_builder; -mod cmd_chest; pub enum CommandSender<'a> { Rcon(&'a mut Vec), @@ -78,7 +77,6 @@ fn dispatcher_init<'a>() -> CommandDispatcher<'a> { map.insert(cmd_stop::NAME, cmd_stop::init_command_tree()); map.insert(cmd_help::NAME, cmd_help::init_command_tree()); map.insert(cmd_help::ALIAS, cmd_help::init_command_tree()); - map.insert(cmd_chest::NAME,cmd_chest::init_command_tree()); CommandDispatcher { commands: map } } From 816215c698b060903bb0a3d2158e697f69716ebe Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 21 Aug 2024 19:28:48 +0200 Subject: [PATCH 5/8] format --- pumpkin-inventory/src/lib.rs | 4 +- pumpkin-inventory/src/player.rs | 6 +- .../client/play/c_set_container_content.rs | 11 ++- pumpkin-protocol/src/client/play/mod.rs | 4 +- pumpkin-protocol/src/slot.rs | 18 +++-- pumpkin/src/client/mod.rs | 76 ++++++++++++++----- 6 files changed, 78 insertions(+), 41 deletions(-) diff --git a/pumpkin-inventory/src/lib.rs b/pumpkin-inventory/src/lib.rs index 2b5730afb..691c69370 100644 --- a/pumpkin-inventory/src/lib.rs +++ b/pumpkin-inventory/src/lib.rs @@ -45,7 +45,7 @@ pub enum WindowType { impl WindowType { pub const fn default_title(&self) -> &'static str { match self { - _ => "WINDOW TITLE" + _ => "WINDOW TITLE", } } -} \ No newline at end of file +} diff --git a/pumpkin-inventory/src/player.rs b/pumpkin-inventory/src/player.rs index fe01acc98..b67af9c6b 100644 --- a/pumpkin-inventory/src/player.rs +++ b/pumpkin-inventory/src/player.rs @@ -98,9 +98,9 @@ impl PlayerInventory { pub fn slots(&self) -> Vec> { let mut slots = vec![self.crafting_output.as_ref()]; - slots.extend(self.crafting.iter().map(|c|c.as_ref())); - slots.extend(self.armor.iter().map(|c|c.as_ref())); - slots.extend(self.items.iter().map(|c|c.as_ref())); + slots.extend(self.crafting.iter().map(|c| c.as_ref())); + slots.extend(self.armor.iter().map(|c| c.as_ref())); + slots.extend(self.items.iter().map(|c| c.as_ref())); slots.push(self.offhand.as_ref()); slots } diff --git a/pumpkin-protocol/src/client/play/c_set_container_content.rs b/pumpkin-protocol/src/client/play/c_set_container_content.rs index 666039a7f..919bc44d3 100644 --- a/pumpkin-protocol/src/client/play/c_set_container_content.rs +++ b/pumpkin-protocol/src/client/play/c_set_container_content.rs @@ -1,7 +1,7 @@ -use pumpkin_macros::packet; -use serde::Serialize; use crate::slot::Slot; use crate::VarInt; +use pumpkin_macros::packet; +use serde::Serialize; #[derive(Serialize)] #[packet(0x13)] @@ -10,18 +10,17 @@ pub struct CSetContainerContent<'a> { state_id: VarInt, count: VarInt, slot_data: &'a [Slot], - carried_item: &'a Slot + carried_item: &'a Slot, } - impl<'a> CSetContainerContent<'a> { - pub fn new(window_id: u8,state_id: VarInt, slots: &'a [Slot], carried_item: &'a Slot) -> Self { + pub fn new(window_id: u8, state_id: VarInt, slots: &'a [Slot], carried_item: &'a Slot) -> Self { Self { window_id, state_id, count: slots.len().try_into().unwrap(), slot_data: slots, - carried_item + carried_item, } } } diff --git a/pumpkin-protocol/src/client/play/mod.rs b/pumpkin-protocol/src/client/play/mod.rs index 6437e23a5..df63734c9 100644 --- a/pumpkin-protocol/src/client/play/mod.rs +++ b/pumpkin-protocol/src/client/play/mod.rs @@ -22,6 +22,7 @@ mod c_player_chat_message; mod c_player_info_update; mod c_player_remove; mod c_remove_entities; +mod c_set_container_content; mod c_set_held_item; mod c_set_title; mod c_spawn_player; @@ -33,7 +34,6 @@ mod c_update_entity_pos; mod c_update_entity_rot; mod c_worldevent; mod player_action; -mod c_set_container_content; pub use c_acknowledge_block::*; pub use c_actionbar::*; @@ -59,6 +59,7 @@ pub use c_player_chat_message::*; 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_held_item::*; pub use c_set_title::*; pub use c_spawn_player::*; @@ -70,4 +71,3 @@ pub use c_update_entity_pos::*; pub use c_update_entity_rot::*; pub use c_worldevent::*; pub use player_action::*; -pub use c_set_container_content::*; \ No newline at end of file diff --git a/pumpkin-protocol/src/slot.rs b/pumpkin-protocol/src/slot.rs index 51521a960..4f18a23da 100644 --- a/pumpkin-protocol/src/slot.rs +++ b/pumpkin-protocol/src/slot.rs @@ -1,7 +1,10 @@ use crate::VarInt; use pumpkin_world::item::Item; -use serde::{de::{self, SeqAccess, Visitor}, Deserialize, Serialize, Serializer}; use serde::ser::SerializeSeq; +use serde::{ + de::{self, SeqAccess, Visitor}, + Deserialize, Serialize, Serializer, +}; #[derive(Debug, Clone)] #[allow(dead_code)] @@ -84,8 +87,8 @@ impl Serialize for Slot { s.serialize_element(&self.item_count)?; s.end() } else { - match (&self.num_components_to_add,&self.num_components_to_remove) { - (Some(to_add),Some(to_remove)) => { + match (&self.num_components_to_add, &self.num_components_to_remove) { + (Some(to_add), Some(to_remove)) => { let mut s = serializer.serialize_seq(Some(6))?; s.serialize_element(&self.item_count)?; s.serialize_element(self.item_id.as_ref().unwrap())?; @@ -104,7 +107,7 @@ impl Serialize for Slot { s.serialize_element(self.components_to_remove.as_ref().unwrap())?; s.end() } - (Some(to_add),None) => { + (Some(to_add), None) => { let mut s = serializer.serialize_seq(Some(5))?; s.serialize_element(&self.item_count)?; s.serialize_element(self.item_id.as_ref().unwrap())?; @@ -113,7 +116,7 @@ impl Serialize for Slot { s.serialize_element(self.components_to_add.as_ref().unwrap())?; s.end() } - (None,None) => { + (None, None) => { let mut s = serializer.serialize_seq(Some(4))?; s.serialize_element(&self.item_count)?; s.serialize_element(&self.item_id.as_ref().unwrap())?; @@ -122,7 +125,6 @@ impl Serialize for Slot { s.end() } } - } } } @@ -154,10 +156,10 @@ impl From<&Item> for Slot { item_count: item.item_count.into(), item_id: Some(item.item_id.into()), // TODO: add these - num_components_to_add:None, + num_components_to_add: None, num_components_to_remove: None, components_to_add: None, components_to_remove: None, } } -} \ No newline at end of file +} diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index bc7d598ff..4497f1128 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -18,7 +18,10 @@ use pumpkin_protocol::{ client::{ config::CConfigDisconnect, login::CLoginDisconnect, - play::{CGameEvent, CPlayDisconnect, CSyncPlayerPostion, CSystemChatMessge, CSetContainerContent}, + play::{ + CGameEvent, CPlayDisconnect, CSetContainerContent, CSyncPlayerPostion, + CSystemChatMessge, + }, }, packet_decoder::PacketDecoder, packet_encoder::PacketEncoder, @@ -38,13 +41,13 @@ use pumpkin_protocol::{ }; use pumpkin_text::TextComponent; -use std::io::Read; -use thiserror::Error; use pumpkin_inventory::WindowType; use pumpkin_protocol::bytebuf::ByteBuffer; use pumpkin_protocol::client::play::COpenScreen; use pumpkin_protocol::slot::Slot; use pumpkin_world::item::Item; +use std::io::Read; +use thiserror::Error; pub mod authentication; mod client_packet; @@ -179,30 +182,58 @@ impl Client { player.gamemode = gamemode; self.send_packet(&CGameEvent::new(3, gamemode.to_f32().unwrap())); } - - pub fn open_container(&mut self, window_type: WindowType, minecraft_menu_id: &str,window_title: Option<&str>, items: Option>>, carried_item: Option<&Item>) { - let menu_protocol_id = (*pumpkin_world::global_registry::REGISTRY.get("minecraft:menu").unwrap().entries.get(minecraft_menu_id).expect("Should be a valid menu id").get("protocol_id").unwrap()).into(); + + pub fn open_container( + &mut self, + window_type: WindowType, + minecraft_menu_id: &str, + window_title: Option<&str>, + items: Option>>, + carried_item: Option<&Item>, + ) { + let menu_protocol_id = (*pumpkin_world::global_registry::REGISTRY + .get("minecraft:menu") + .unwrap() + .entries + .get(minecraft_menu_id) + .expect("Should be a valid menu id") + .get("protocol_id") + .unwrap()) + .into(); let title = TextComponent::text(window_title.unwrap_or(window_type.default_title())); - self.send_packet(&COpenScreen::new((window_type.clone() as u8 +1).into(),menu_protocol_id, title)); + self.send_packet(&COpenScreen::new( + (window_type.clone() as u8 + 1).into(), + menu_protocol_id, + title, + )); self.set_container_content(window_type, items, carried_item); } - - pub fn set_container_content<'a>(&mut self, window_type: WindowType, items: Option>>, carried_item: Option<&'a Item>) { + + pub fn set_container_content<'a>( + &mut self, + window_type: WindowType, + items: Option>>, + carried_item: Option<&'a Item>, + ) { let player = self.player.as_ref().unwrap(); - - let slots: Vec = {if let Some(mut items) = items { - items.extend(player.inventory.slots()); - items - } else { - player.inventory.slots() - }.into_iter() - .map(|item|{ + + let slots: Vec = { + if let Some(mut items) = items { + items.extend(player.inventory.slots()); + items + } else { + player.inventory.slots() + } + .into_iter() + .map(|item| { if let Some(item) = item { Slot::from(item) } else { Slot::empty() } - }).collect()}; + }) + .collect() + }; let carried_item = { if let Some(item) = carried_item { @@ -211,7 +242,12 @@ impl Client { Slot::empty() } }; - self.send_packet(&CSetContainerContent::new(window_type as u8+1, 0.into(), &slots, &carried_item)); + self.send_packet(&CSetContainerContent::new( + window_type as u8 + 1, + 0.into(), + &slots, + &carried_item, + )); } pub async fn process_packets(&mut self, server: &mut Server) { @@ -398,7 +434,7 @@ impl Client { } } } - + pub fn send_system_message(&mut self, text: TextComponent) { self.send_packet(&CSystemChatMessge::new(text, false)); } From 7818f83ea2af73b0aeef52e45f4acd26b5a9032c Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 21 Aug 2024 19:38:19 +0200 Subject: [PATCH 6/8] fix lints --- pumpkin-inventory/src/lib.rs | 6 ++++-- pumpkin-protocol/src/client/play/c_set_container_content.rs | 2 +- pumpkin-protocol/src/slot.rs | 3 +-- pumpkin/src/client/mod.rs | 1 - 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pumpkin-inventory/src/lib.rs b/pumpkin-inventory/src/lib.rs index 691c69370..044980cc4 100644 --- a/pumpkin-inventory/src/lib.rs +++ b/pumpkin-inventory/src/lib.rs @@ -44,8 +44,10 @@ pub enum WindowType { impl WindowType { pub const fn default_title(&self) -> &'static str { - match self { + // TODO: Add titles here: + /*match self { _ => "WINDOW TITLE", - } + }*/ + "WINDOW TITLE" } } diff --git a/pumpkin-protocol/src/client/play/c_set_container_content.rs b/pumpkin-protocol/src/client/play/c_set_container_content.rs index 919bc44d3..791ee1db5 100644 --- a/pumpkin-protocol/src/client/play/c_set_container_content.rs +++ b/pumpkin-protocol/src/client/play/c_set_container_content.rs @@ -18,7 +18,7 @@ impl<'a> CSetContainerContent<'a> { Self { window_id, state_id, - count: slots.len().try_into().unwrap(), + count: slots.len().into(), slot_data: slots, carried_item, } diff --git a/pumpkin-protocol/src/slot.rs b/pumpkin-protocol/src/slot.rs index 114e1e77a..053813fc7 100644 --- a/pumpkin-protocol/src/slot.rs +++ b/pumpkin-protocol/src/slot.rs @@ -2,7 +2,7 @@ use crate::VarInt; use pumpkin_world::item::Item; use serde::ser::SerializeSeq; use serde::{ - de::{self, SeqAccess, Visitor}, + de::{self, SeqAccess}, Deserialize, Serialize, Serializer, }; @@ -129,7 +129,6 @@ impl Serialize for Slot { } } - impl Slot { pub fn to_item(self) -> Option { let item_id = self.item_id?.0.try_into().unwrap(); diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index a8b9ade7c..0e1083a3e 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -42,7 +42,6 @@ use pumpkin_protocol::{ }; use pumpkin_inventory::WindowType; -use pumpkin_protocol::bytebuf::ByteBuffer; use pumpkin_protocol::client::play::COpenScreen; use pumpkin_protocol::slot::Slot; use pumpkin_world::item::Item; From 1fd3595ecce654a9d2b13c2c95081cc6d19d8ce9 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 21 Aug 2024 19:41:33 +0200 Subject: [PATCH 7/8] whoops --- pumpkin/src/commands/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pumpkin/src/commands/mod.rs b/pumpkin/src/commands/mod.rs index 6e34b4eb0..d784122c1 100644 --- a/pumpkin/src/commands/mod.rs +++ b/pumpkin/src/commands/mod.rs @@ -79,6 +79,8 @@ fn dispatcher_init<'a>() -> CommandDispatcher<'a> { dispatcher.register(cmd_gamemode::init_command_tree()); dispatcher.register(cmd_stop::init_command_tree()); dispatcher.register(cmd_help::init_command_tree()); + + dispatcher } pub fn handle_command(sender: &mut CommandSender, cmd: &str) { From d80bbb725665b681ddaca749fa936a48514adb9c Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 21 Aug 2024 19:41:48 +0200 Subject: [PATCH 8/8] fmt --- pumpkin/src/commands/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pumpkin/src/commands/mod.rs b/pumpkin/src/commands/mod.rs index d784122c1..d6b2f4bde 100644 --- a/pumpkin/src/commands/mod.rs +++ b/pumpkin/src/commands/mod.rs @@ -79,7 +79,7 @@ fn dispatcher_init<'a>() -> CommandDispatcher<'a> { dispatcher.register(cmd_gamemode::init_command_tree()); dispatcher.register(cmd_stop::init_command_tree()); dispatcher.register(cmd_help::init_command_tree()); - + dispatcher }