Skip to content

Commit

Permalink
Added Container back
Browse files Browse the repository at this point in the history
  • Loading branch information
Snowiiii committed Sep 10, 2024
1 parent a2fce84 commit ada0d82
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 54 deletions.
116 changes: 67 additions & 49 deletions pumpkin/src/client/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ use std::sync::{Arc, Mutex};

impl Player {
pub fn open_container(&self, server: &Arc<Server>, 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()
Expand All @@ -38,20 +41,23 @@ 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(
total_opened_containers.into(),
menu_protocol_id,
title,
));
drop(inventory);
self.set_container_content(container.as_deref_mut());
}

pub fn set_container_content(&self, container: Option<&mut Box<dyn Container>>) {
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()
Expand All @@ -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,
);
Expand All @@ -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<T: WindowPropertyTrait>(
Expand All @@ -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,
));
Expand All @@ -107,15 +116,20 @@ 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());
return Ok(());
}

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 {
Expand Down Expand Up @@ -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);
Expand All @@ -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(()),
}
}
Expand All @@ -215,7 +229,7 @@ impl Player {
opened_container: Option<&mut Box<dyn Container>>,
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 {
Expand Down Expand Up @@ -258,7 +272,7 @@ impl Player {
}

fn number_button_pressed(
&mut self,
&self,
opened_container: Option<&mut Box<dyn Container>>,
key_click: KeyClick,
slot: usize,
Expand All @@ -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<dyn Container>>,
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<dyn Container>>,
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 {
Expand Down Expand Up @@ -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<dyn Container>>,
mouse_drag_state: MouseDragState,
Expand All @@ -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,
Expand All @@ -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()
Expand All @@ -380,8 +400,6 @@ impl Player {

let players = self
.entity
.lock()
.unwrap()
.world
.current_players
.lock()
Expand All @@ -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(
Expand All @@ -440,7 +458,7 @@ impl Player {
}

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)
} else {
None
Expand Down
2 changes: 1 addition & 1 deletion pumpkin/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use thiserror::Error;

pub mod authentication;
mod client_packet;
// mod container;
mod container;
pub mod player_packet;

#[derive(Clone)]
Expand Down
4 changes: 2 additions & 2 deletions pumpkin/src/client/player_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 1 addition & 2 deletions pumpkin/src/commands/cmd_echest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
Expand Down

0 comments on commit ada0d82

Please sign in to comment.