Added Container back

This commit is contained in:
Snowiiii 2024-09-10 09:57:54 +02:00
parent a2fce8479e
commit ada0d82a72
4 changed files with 71 additions and 54 deletions

View File

@ -20,8 +20,11 @@ use std::sync::{Arc, Mutex};
impl Player { impl Player {
pub fn open_container(&self, server: &Arc<Server>, minecraft_menu_id: &str) { pub fn open_container(&self, server: &Arc<Server>, minecraft_menu_id: &str) {
self.inventory.state_id = 0; let inventory = self.inventory.lock().unwrap();
let total_opened_containers = self.inventory.total_opened_containers; 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 container = self.get_open_container(server);
let mut container = container let mut container = container
.as_ref() .as_ref()
@ -38,7 +41,7 @@ impl Player {
let window_title = container let window_title = container
.as_ref() .as_ref()
.map(|container| container.window_name()) .map(|container| container.window_name())
.unwrap_or(self.inventory.window_name()); .unwrap_or(inventory.window_name());
let title = TextComponent::text(window_title); let title = TextComponent::text(window_title);
self.client.send_packet(&COpenScreen::new( self.client.send_packet(&COpenScreen::new(
@ -46,12 +49,15 @@ impl Player {
menu_protocol_id, menu_protocol_id,
title, title,
)); ));
drop(inventory);
self.set_container_content(container.as_deref_mut()); self.set_container_content(container.as_deref_mut());
} }
pub fn set_container_content(&self, container: Option<&mut Box<dyn Container>>) { pub fn set_container_content(&self, container: Option<&mut Box<dyn Container>>) {
let total_opened_containers = self.inventory.total_opened_containers; let mut inventory = self.inventory.lock().unwrap();
let container = OptionallyCombinedContainer::new(&mut self.inventory.lock().unwrap(), container);
let total_opened_containers = inventory.total_opened_containers;
let container = OptionallyCombinedContainer::new(&mut inventory, container);
let slots = container let slots = container
.all_slots_ref() .all_slots_ref()
@ -60,16 +66,19 @@ impl Player {
.collect_vec(); .collect_vec();
let carried_item = { 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() item.into()
} else { } else {
Slot::empty() 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( let packet = CSetContainerContent::new(
total_opened_containers, total_opened_containers,
(self.inventory.state_id as i32).into(), ((i + 1) as i32).into(),
&slots, &slots,
&carried_item, &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 /// 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) { pub fn close_container(&self) {
self.inventory.total_opened_containers += 1; let mut inventory = self.inventory.lock().unwrap();
self.client.send_packet(&CCloseContainer::new( inventory.total_opened_containers += 1;
self.inventory.total_opened_containers, self.client
)) .send_packet(&CCloseContainer::new(inventory.total_opened_containers))
} }
pub fn set_container_property<T: WindowPropertyTrait>( pub fn set_container_property<T: WindowPropertyTrait>(
@ -90,7 +99,7 @@ impl Player {
) { ) {
let (id, value) = window_property.into_tuple(); let (id, value) = window_property.into_tuple();
self.client.send_packet(&CSetContainerProperty::new( self.client.send_packet(&CSetContainerProperty::new(
self.inventory.total_opened_containers, self.inventory.lock().unwrap().total_opened_containers,
id, id,
value, value,
)); ));
@ -107,7 +116,12 @@ impl Player {
.map(|container| container.lock().unwrap()); .map(|container| container.lock().unwrap());
let drag_handler = &server.drag_handler; 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 // This is just checking for regular desync, client hasn't done anything malicious
if state_id != packet.state_id.0 as u32 { if state_id != packet.state_id.0 as u32 {
self.set_container_content(opened_container.as_deref_mut()); self.set_container_content(opened_container.as_deref_mut());
@ -115,7 +129,7 @@ impl Player {
} }
if opened_container.is_some() { 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())); return Err(InventoryError::ClosedContainerInteract(self.entity_id()));
} }
} else if packet.window_id != 0 { } else if packet.window_id != 0 {
@ -177,10 +191,9 @@ impl Player {
drop(opened_container); drop(opened_container);
self.send_whole_container_change(server).await?; self.send_whole_container_change(server).await?;
} else if let container_click::Slot::Normal(slot_index) = click.slot { } else if let container_click::Slot::Normal(slot_index) = click.slot {
let combined_container = OptionallyCombinedContainer::new( let mut inventory = self.inventory.lock().unwrap();
&mut self.inventory.lock().unwrap().lock().unwrap().lock().unwrap(), let combined_container =
Some(&mut opened_container), OptionallyCombinedContainer::new(&mut inventory, Some(&mut opened_container));
);
if let Some(slot) = combined_container.get_slot_excluding_inventory(slot_index) { if let Some(slot) = combined_container.get_slot_excluding_inventory(slot_index) {
let slot = Slot::from(slot); let slot = Slot::from(slot);
drop(opened_container); drop(opened_container);
@ -199,13 +212,14 @@ impl Player {
slot: container_click::Slot, slot: container_click::Slot,
) -> Result<(), InventoryError> { ) -> Result<(), InventoryError> {
let mut inventory = self.inventory.lock().unwrap(); let mut inventory = self.inventory.lock().unwrap();
let mut container = let mut container = OptionallyCombinedContainer::new(&mut inventory, opened_container);
OptionallyCombinedContainer::new(&mut inventory, opened_container);
match slot { match slot {
container_click::Slot::Normal(slot) => { container_click::Slot::Normal(slot) => container.handle_item_change(
container.handle_item_change(&mut self.carried_item.lock().unwrap(), slot, mouse_click) &mut self.carried_item.lock().unwrap(),
} slot,
mouse_click,
),
container_click::Slot::OutsideInventory => Ok(()), container_click::Slot::OutsideInventory => Ok(()),
} }
} }
@ -258,7 +272,7 @@ impl Player {
} }
fn number_button_pressed( fn number_button_pressed(
&mut self, &self,
opened_container: Option<&mut Box<dyn Container>>, opened_container: Option<&mut Box<dyn Container>>,
key_click: KeyClick, key_click: KeyClick,
slot: usize, slot: usize,
@ -267,35 +281,38 @@ impl Player {
KeyClick::Slot(slot) => slot, KeyClick::Slot(slot) => slot,
KeyClick::Offhand => 45, KeyClick::Offhand => 45,
}; };
let mut changing_item_slot = self.inventory.get_slot(changing_slot as usize)?.to_owned(); let mut inventory = self.inventory.lock().unwrap();
let mut container = OptionallyCombinedContainer::new(&mut self.inventory.lock().unwrap(), opened_container); 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)?; 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(()) Ok(())
} }
fn creative_pick_item( fn creative_pick_item(
&mut self, &self,
opened_container: Option<&mut Box<dyn Container>>, opened_container: Option<&mut Box<dyn Container>>,
slot: usize, slot: usize,
) -> Result<(), InventoryError> { ) -> Result<(), InventoryError> {
if self.gamemode != GameMode::Creative { if *self.gamemode.lock().unwrap() != GameMode::Creative {
return Err(InventoryError::PermissionError); 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) { 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(()) Ok(())
} }
fn double_click( fn double_click(
&mut self, &self,
opened_container: Option<&mut Box<dyn Container>>, opened_container: Option<&mut Box<dyn Container>>,
slot: usize, slot: usize,
) -> Result<(), InventoryError> { ) -> 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 mut slots = container.all_slots();
let Some(item) = slots.get_mut(slot) else { 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(()) Ok(())
} }
fn mouse_drag( fn mouse_drag(
&mut self, &self,
drag_handler: &DragHandler, drag_handler: &DragHandler,
opened_container: Option<&mut Box<dyn Container>>, opened_container: Option<&mut Box<dyn Container>>,
mouse_drag_state: MouseDragState, mouse_drag_state: MouseDragState,
@ -340,17 +357,20 @@ impl Player {
.unwrap_or(player_id as u64); .unwrap_or(player_id as u64);
match mouse_drag_state { match mouse_drag_state {
MouseDragState::Start(drag_type) => { 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)? Err(InventoryError::PermissionError)?
} }
drag_handler.new_drag(container_id, player_id, drag_type) drag_handler.new_drag(container_id, player_id, drag_type)
} }
MouseDragState::AddSlot(slot) => drag_handler.add_slot(container_id, player_id, slot), MouseDragState::AddSlot(slot) => drag_handler.add_slot(container_id, player_id, slot),
MouseDragState::End => { MouseDragState::End => {
let mut inventory = self.inventory.lock().unwrap();
let mut container = let mut container =
OptionallyCombinedContainer::new(&mut self.inventory.lock().unwrap(), opened_container); OptionallyCombinedContainer::new(&mut inventory, opened_container);
drag_handler.apply_drag( drag_handler.apply_drag(
&mut self.carried_item, &mut self.carried_item.lock().unwrap(),
&mut container, &mut container,
&container_id, &container_id,
player_id, player_id,
@ -366,7 +386,7 @@ impl Player {
.read() .read()
.expect("open_containers is poisoned"); .expect("open_containers is poisoned");
open_containers open_containers
.get(&self.open_container.unwrap()) .get(&self.open_container.lock().unwrap().unwrap())
.unwrap() .unwrap()
.all_player_ids() .all_player_ids()
.into_iter() .into_iter()
@ -380,8 +400,6 @@ impl Player {
let players = self let players = self
.entity .entity
.lock()
.unwrap()
.world .world
.current_players .current_players
.lock() .lock()
@ -404,17 +422,17 @@ impl Player {
} }
async fn send_container_changes( async fn send_container_changes(
&mut self, &self,
server: &Server, server: &Server,
slot_index: usize, slot_index: usize,
slot: Slot, slot: Slot,
) -> Result<(), InventoryError> { ) -> Result<(), InventoryError> {
for player in self.get_current_players_in_container(server).await { 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 // Returns previous value
let i = player let i = inventory
.inventory
.state_id .state_id
.fetch_add(1, std::sync::atomic::Ordering::Relaxed); .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
let packet = CSetContainerSlot::new( let packet = CSetContainerSlot::new(
@ -440,7 +458,7 @@ impl Player {
} }
pub fn get_open_container(&self, server: &Server) -> Option<Arc<Mutex<Box<dyn Container>>>> { pub fn get_open_container(&self, server: &Server) -> Option<Arc<Mutex<Box<dyn Container>>>> {
if let Some(id) = self.open_container { if let Some(id) = *self.open_container.lock().unwrap() {
server.try_get_container(self.entity_id(), id) server.try_get_container(self.entity_id(), id)
} else { } else {
None None

View File

@ -34,7 +34,7 @@ use thiserror::Error;
pub mod authentication; pub mod authentication;
mod client_packet; mod client_packet;
// mod container; mod container;
pub mod player_packet; pub mod player_packet;
#[derive(Clone)] #[derive(Clone)]

View File

@ -91,7 +91,7 @@ impl Player {
let entity_id = entity.entity_id; let entity_id = entity.entity_id;
let (x, y, z) = (*pos).into(); let (x, y, z) = (*pos).into();
let (lastx, lasty, lastz) = (last_position.x, last_position.y, last_position.z); 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 delta = Vector3::new(x - lastx, y - lasty, z - lastz);
// let velocity = self.velocity; // let velocity = self.velocity;
@ -378,7 +378,7 @@ impl Player {
// TODO: do validation and stuff // TODO: do validation and stuff
let config = &ADVANCED_CONFIG.pvp; let config = &ADVANCED_CONFIG.pvp;
if config.enabled { 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); let attacked_player = world.get_by_entityid(self, entity_id.0 as EntityId);
if let Some(player) = attacked_player { if let Some(player) = attacked_player {
let victem_entity = &player.entity; let victem_entity = &player.entity;

View File

@ -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(()) Ok(())