diff --git a/pumpkin/src/client/container.rs b/pumpkin/src/client/container.rs index c11ccb381..86769642e 100644 --- a/pumpkin/src/client/container.rs +++ b/pumpkin/src/client/container.rs @@ -20,8 +20,11 @@ use std::sync::{Arc, Mutex}; impl Player { pub fn open_container(&self, server: &Arc, minecraft_menu_id: &str) { - self.inventory.state_id = 0; - let total_opened_containers = self.inventory.total_opened_containers; + let inventory = self.inventory.lock().unwrap(); + inventory + .state_id + .store(0, std::sync::atomic::Ordering::Relaxed); + let total_opened_containers = inventory.total_opened_containers; let container = self.get_open_container(server); let mut container = container .as_ref() @@ -38,7 +41,7 @@ impl Player { let window_title = container .as_ref() .map(|container| container.window_name()) - .unwrap_or(self.inventory.window_name()); + .unwrap_or(inventory.window_name()); let title = TextComponent::text(window_title); self.client.send_packet(&COpenScreen::new( @@ -46,12 +49,15 @@ impl Player { menu_protocol_id, title, )); + drop(inventory); self.set_container_content(container.as_deref_mut()); } pub fn set_container_content(&self, container: Option<&mut Box>) { - let total_opened_containers = self.inventory.total_opened_containers; - let container = OptionallyCombinedContainer::new(&mut self.inventory.lock().unwrap(), container); + let mut inventory = self.inventory.lock().unwrap(); + + let total_opened_containers = inventory.total_opened_containers; + let container = OptionallyCombinedContainer::new(&mut inventory, container); let slots = container .all_slots_ref() @@ -60,16 +66,19 @@ impl Player { .collect_vec(); let carried_item = { - if let Some(item) = self.carried_item.as_ref() { + if let Some(item) = self.carried_item.lock().unwrap().as_ref() { item.into() } else { Slot::empty() } }; - self.inventory.state_id += 1; + // Gets the previous value + let i = inventory + .state_id + .fetch_add(1, std::sync::atomic::Ordering::Relaxed); let packet = CSetContainerContent::new( total_opened_containers, - (self.inventory.state_id as i32).into(), + ((i + 1) as i32).into(), &slots, &carried_item, ); @@ -78,10 +87,10 @@ 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(&self) { - self.inventory.total_opened_containers += 1; - self.client.send_packet(&CCloseContainer::new( - self.inventory.total_opened_containers, - )) + let mut inventory = self.inventory.lock().unwrap(); + inventory.total_opened_containers += 1; + self.client + .send_packet(&CCloseContainer::new(inventory.total_opened_containers)) } pub fn set_container_property( @@ -90,7 +99,7 @@ impl Player { ) { let (id, value) = window_property.into_tuple(); self.client.send_packet(&CSetContainerProperty::new( - self.inventory.total_opened_containers, + self.inventory.lock().unwrap().total_opened_containers, id, value, )); @@ -107,7 +116,12 @@ impl Player { .map(|container| container.lock().unwrap()); let drag_handler = &server.drag_handler; - let state_id = self.inventory.state_id; + let state_id = self + .inventory + .lock() + .unwrap() + .state_id + .load(std::sync::atomic::Ordering::Relaxed); // This is just checking for regular desync, client hasn't done anything malicious if state_id != packet.state_id.0 as u32 { self.set_container_content(opened_container.as_deref_mut()); @@ -115,7 +129,7 @@ impl Player { } if opened_container.is_some() { - if packet.window_id != self.inventory.total_opened_containers { + if packet.window_id != self.inventory.lock().unwrap().total_opened_containers { return Err(InventoryError::ClosedContainerInteract(self.entity_id())); } } else if packet.window_id != 0 { @@ -177,10 +191,9 @@ impl Player { drop(opened_container); self.send_whole_container_change(server).await?; } else if let container_click::Slot::Normal(slot_index) = click.slot { - let combined_container = OptionallyCombinedContainer::new( - &mut self.inventory.lock().unwrap().lock().unwrap().lock().unwrap(), - Some(&mut opened_container), - ); + let mut inventory = self.inventory.lock().unwrap(); + let combined_container = + OptionallyCombinedContainer::new(&mut inventory, Some(&mut opened_container)); if let Some(slot) = combined_container.get_slot_excluding_inventory(slot_index) { let slot = Slot::from(slot); drop(opened_container); @@ -199,13 +212,14 @@ impl Player { slot: container_click::Slot, ) -> Result<(), InventoryError> { let mut inventory = self.inventory.lock().unwrap(); - let mut container = - OptionallyCombinedContainer::new(&mut inventory, opened_container); - + let mut container = OptionallyCombinedContainer::new(&mut inventory, opened_container); + match slot { - container_click::Slot::Normal(slot) => { - container.handle_item_change(&mut self.carried_item.lock().unwrap(), slot, mouse_click) - } + container_click::Slot::Normal(slot) => container.handle_item_change( + &mut self.carried_item.lock().unwrap(), + slot, + mouse_click, + ), container_click::Slot::OutsideInventory => Ok(()), } } @@ -215,7 +229,7 @@ impl Player { opened_container: Option<&mut Box>, slot: container_click::Slot, ) -> Result<(), InventoryError> { - let mut inventory = self.inventory.lock().unwrap(); + let mut inventory = self.inventory.lock().unwrap(); let mut container = OptionallyCombinedContainer::new(&mut inventory, opened_container); match slot { @@ -258,7 +272,7 @@ impl Player { } fn number_button_pressed( - &mut self, + &self, opened_container: Option<&mut Box>, key_click: KeyClick, slot: usize, @@ -267,35 +281,38 @@ impl Player { KeyClick::Slot(slot) => slot, KeyClick::Offhand => 45, }; - let mut changing_item_slot = self.inventory.get_slot(changing_slot as usize)?.to_owned(); - let mut container = OptionallyCombinedContainer::new(&mut self.inventory.lock().unwrap(), opened_container); + let mut inventory = self.inventory.lock().unwrap(); + let mut changing_item_slot = inventory.get_slot(changing_slot as usize)?.to_owned(); + let mut container = OptionallyCombinedContainer::new(&mut inventory, opened_container); container.handle_item_change(&mut changing_item_slot, slot, MouseClick::Left)?; - *self.inventory.get_slot(changing_slot as usize)? = changing_item_slot; + *inventory.get_slot(changing_slot as usize)? = changing_item_slot; Ok(()) } fn creative_pick_item( - &mut self, + &self, opened_container: Option<&mut Box>, slot: usize, ) -> Result<(), InventoryError> { - if self.gamemode != GameMode::Creative { + if *self.gamemode.lock().unwrap() != GameMode::Creative { return Err(InventoryError::PermissionError); } - let mut container = OptionallyCombinedContainer::new(&mut self.inventory.lock().unwrap(), opened_container); + let mut inventory = self.inventory.lock().unwrap(); + let mut container = OptionallyCombinedContainer::new(&mut inventory, opened_container); if let Some(Some(item)) = container.all_slots().get_mut(slot) { - self.carried_item = Some(item.to_owned()) + *self.carried_item.lock().unwrap() = Some(item.to_owned()) } Ok(()) } fn double_click( - &mut self, + &self, opened_container: Option<&mut Box>, slot: usize, ) -> Result<(), InventoryError> { - let mut container = OptionallyCombinedContainer::new(&mut self.inventory.lock().unwrap(), opened_container); + let mut inventory = self.inventory.lock().unwrap(); + let mut container = OptionallyCombinedContainer::new(&mut inventory, opened_container); let mut slots = container.all_slots(); let Some(item) = slots.get_mut(slot) else { @@ -323,12 +340,12 @@ impl Player { } } } - self.carried_item = Some(carried_item); + *self.carried_item.lock().unwrap() = Some(carried_item); Ok(()) } fn mouse_drag( - &mut self, + &self, drag_handler: &DragHandler, opened_container: Option<&mut Box>, mouse_drag_state: MouseDragState, @@ -340,17 +357,20 @@ impl Player { .unwrap_or(player_id as u64); match mouse_drag_state { MouseDragState::Start(drag_type) => { - if drag_type == MouseDragType::Middle && self.gamemode != GameMode::Creative { + if drag_type == MouseDragType::Middle + && *self.gamemode.lock().unwrap() != GameMode::Creative + { Err(InventoryError::PermissionError)? } drag_handler.new_drag(container_id, player_id, drag_type) } MouseDragState::AddSlot(slot) => drag_handler.add_slot(container_id, player_id, slot), MouseDragState::End => { + let mut inventory = self.inventory.lock().unwrap(); let mut container = - OptionallyCombinedContainer::new(&mut self.inventory.lock().unwrap(), opened_container); + OptionallyCombinedContainer::new(&mut inventory, opened_container); drag_handler.apply_drag( - &mut self.carried_item, + &mut self.carried_item.lock().unwrap(), &mut container, &container_id, player_id, @@ -366,7 +386,7 @@ impl Player { .read() .expect("open_containers is poisoned"); open_containers - .get(&self.open_container.unwrap()) + .get(&self.open_container.lock().unwrap().unwrap()) .unwrap() .all_player_ids() .into_iter() @@ -380,8 +400,6 @@ impl Player { let players = self .entity - .lock() - .unwrap() .world .current_players .lock() @@ -404,17 +422,17 @@ impl Player { } async fn send_container_changes( - &mut self, + &self, server: &Server, slot_index: usize, slot: Slot, ) -> Result<(), InventoryError> { for player in self.get_current_players_in_container(server).await { - let total_opened_containers = player.inventory.total_opened_containers; + let inventory = player.inventory.lock().unwrap(); + let total_opened_containers = inventory.total_opened_containers; // Returns previous value - let i = player - .inventory + let i = inventory .state_id .fetch_add(1, std::sync::atomic::Ordering::Relaxed); let packet = CSetContainerSlot::new( @@ -440,7 +458,7 @@ impl Player { } pub fn get_open_container(&self, server: &Server) -> Option>>> { - if let Some(id) = self.open_container { + if let Some(id) = *self.open_container.lock().unwrap() { server.try_get_container(self.entity_id(), id) } else { None diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index 19a89fc1f..f4e89a450 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -34,7 +34,7 @@ use thiserror::Error; pub mod authentication; mod client_packet; -// mod container; +mod container; pub mod player_packet; #[derive(Clone)] diff --git a/pumpkin/src/client/player_packet.rs b/pumpkin/src/client/player_packet.rs index d2c2a2716..7f342d872 100644 --- a/pumpkin/src/client/player_packet.rs +++ b/pumpkin/src/client/player_packet.rs @@ -91,7 +91,7 @@ impl Player { let entity_id = entity.entity_id; let (x, y, z) = (*pos).into(); let (lastx, lasty, lastz) = (last_position.x, last_position.y, last_position.z); - let world = entity.world.clone(); + let world = &entity.world; // let delta = Vector3::new(x - lastx, y - lasty, z - lastz); // let velocity = self.velocity; @@ -378,7 +378,7 @@ impl Player { // TODO: do validation and stuff let config = &ADVANCED_CONFIG.pvp; if config.enabled { - let world = entity.world.clone(); + let world = &entity.world; let attacked_player = world.get_by_entityid(self, entity_id.0 as EntityId); if let Some(player) = attacked_player { let victem_entity = &player.entity; diff --git a/pumpkin/src/commands/cmd_echest.rs b/pumpkin/src/commands/cmd_echest.rs index fbf7bdd69..fe55c9608 100644 --- a/pumpkin/src/commands/cmd_echest.rs +++ b/pumpkin/src/commands/cmd_echest.rs @@ -27,8 +27,7 @@ pub(crate) fn init_command_tree<'a>() -> CommandTree<'a> { } } } - // TODO - // player.open_container(server, "minecraft:generic_9x3"); + player.open_container(server, "minecraft:generic_9x3"); } Ok(())