aboutsummaryrefslogtreecommitdiff
path: root/azalea/src
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2025-06-09 13:14:20 -1100
committermat <git@matdoes.dev>2025-06-09 13:14:20 -1100
commit086f979a2895e7f15ec61e5704869a0cfc94d16f (patch)
treed5218a1b7df4524d913ba6605f40f5966dc3149b /azalea/src
parent40bcb62a777fca73a5b887af4d9a3fce01ee9053 (diff)
downloadazalea-drasl-086f979a2895e7f15ec61e5704869a0cfc94d16f.tar.xz
replace Client::get_open_container and view_container_or_inventory with get_inventory
Diffstat (limited to 'azalea/src')
-rw-r--r--azalea/src/container.rs172
1 files changed, 63 insertions, 109 deletions
diff --git a/azalea/src/container.rs b/azalea/src/container.rs
index 6c4e86cc..f452b1be 100644
--- a/azalea/src/container.rs
+++ b/azalea/src/container.rs
@@ -14,6 +14,7 @@ use azalea_physics::collision::BlockWithShape;
use azalea_protocol::packets::game::ClientboundGamePacket;
use bevy_app::{App, Plugin, Update};
use bevy_ecs::{component::Component, prelude::EventReader, system::Commands};
+use derive_more::Deref;
use futures_lite::Future;
use crate::bot::BotClientExt;
@@ -26,17 +27,6 @@ impl Plugin for ContainerPlugin {
}
pub trait ContainerClientExt {
- fn open_container_at(
- &self,
- pos: BlockPos,
- ) -> impl Future<Output = Option<ContainerHandle>> + Send;
- fn open_inventory(&self) -> Option<ContainerHandle>;
- fn get_held_item(&self) -> ItemStack;
- fn get_open_container(&self) -> Option<ContainerHandleRef>;
- fn view_container_or_inventory(&self) -> Menu;
-}
-
-impl ContainerClientExt for Client {
/// Open a container in the world, like a chest. Use
/// [`Client::open_inventory`] to open your own inventory.
///
@@ -54,6 +44,39 @@ impl ContainerClientExt for Client {
/// let container = bot.open_container_at(target_pos).await;
/// # }
/// ```
+ fn open_container_at(
+ &self,
+ pos: BlockPos,
+ ) -> impl Future<Output = Option<ContainerHandle>> + Send;
+ /// Open the player's inventory. This will return None if another
+ /// container is open.
+ ///
+ /// Note that this will send a packet to the server once it's dropped. Also,
+ /// due to how it's implemented, you could call this function multiple times
+ /// while another inventory handle already exists (but you shouldn't).
+ ///
+ /// If you just want to get the items in the player's inventory without
+ /// sending any packets, use [`Client::menu`], [`Menu::player_slots_range`],
+ /// and [`Menu::slots`].
+ fn open_inventory(&self) -> Option<ContainerHandle>;
+ /// Returns a [`ContainerHandleRef`] to the client's currently open
+ /// container, or their inventory.
+ ///
+ /// This will not send a packet to close the container when it's dropped,
+ /// which may cause anticheat compatibility issues if you modify your
+ /// inventory without closing it afterwards.
+ ///
+ /// To simulate opening your own inventory (like pressing 'e') in a way that
+ /// won't trigger anticheats, use [`Client::open_inventory`].
+ ///
+ /// To open a container in the world, use [`Client::open_container_at`].
+ fn get_inventory(&self) -> ContainerHandleRef;
+ /// Get the item in the bot's hotbar that is currently being held in its
+ /// main hand.
+ fn get_held_item(&self) -> ItemStack;
+}
+
+impl ContainerClientExt for Client {
async fn open_container_at(&self, pos: BlockPos) -> Option<ContainerHandle> {
let mut ticks = self.get_tick_broadcaster();
// wait until it's not air (up to 10 ticks)
@@ -92,20 +115,9 @@ impl ContainerClientExt for Client {
}
}
- /// Open the player's inventory. This will return None if another
- /// container is open.
- ///
- /// Note that this will send a packet to the server once it's dropped. Also,
- /// due to how it's implemented, you could call this function multiple times
- /// while another inventory handle already exists (but you shouldn't).
- ///
- /// If you just want to get the items in the player's inventory without
- /// sending any packets, use [`Client::menu`], [`Menu::player_slots_range`],
- /// and [`Menu::slots`].
fn open_inventory(&self) -> Option<ContainerHandle> {
let ecs = self.ecs.lock();
let inventory = ecs.get::<Inventory>(self.entity).expect("no inventory");
-
if inventory.id == 0 {
Some(ContainerHandle::new(0, self.clone()))
} else {
@@ -113,45 +125,15 @@ impl ContainerClientExt for Client {
}
}
- /// Get the item in the bot's hotbar that is currently being held in its
- /// main hand.
- fn get_held_item(&self) -> ItemStack {
- self.map_get_component::<Inventory, _>(|inventory| inventory.held_item())
- .expect("no inventory")
- }
-
- /// Get a handle to the open container. This will return None if no
- /// container is open. This will not close the container when it's dropped.
- ///
- /// See [`Client::open_inventory`] or [`Client::menu`] if you want to open
- /// your own inventory.
- fn get_open_container(&self) -> Option<ContainerHandleRef> {
+ fn get_inventory(&self) -> ContainerHandleRef {
let ecs = self.ecs.lock();
let inventory = ecs.get::<Inventory>(self.entity).expect("no inventory");
-
- if inventory.id == 0 {
- None
- } else {
- Some(ContainerHandleRef {
- id: inventory.id,
- client: self.clone(),
- })
- }
+ ContainerHandleRef::new(inventory.id, self.clone())
}
- /// Returns the player's currently open container menu, or their inventory
- /// if no container is open.
- ///
- /// This tries to access the client's [`Inventory::container_menu`] and
- /// falls back to [`Inventory::inventory_menu`].
- fn view_container_or_inventory(&self) -> Menu {
- self.map_get_component::<Inventory, _>(|inventory| {
- inventory
- .container_menu
- .clone()
- .unwrap_or(inventory.inventory_menu.clone())
- })
- .expect("no inventory")
+ fn get_held_item(&self) -> ItemStack {
+ self.map_get_component::<Inventory, _>(|inventory| inventory.held_item())
+ .expect("no inventory")
}
}
@@ -169,6 +151,10 @@ impl Debug for ContainerHandleRef {
}
}
impl ContainerHandleRef {
+ pub fn new(id: i32, client: Client) -> Self {
+ Self { id, client }
+ }
+
pub fn close(&self) {
self.client.ecs.lock().send_event(CloseContainerEvent {
entity: self.client.entity,
@@ -219,6 +205,25 @@ impl ContainerHandleRef {
self.menu().map(|menu| menu.slots())
}
+ /// A shortcut for [`Self::click`] with `PickupClick::Left`.
+ pub fn left_click(&self, slot: impl Into<usize>) {
+ self.click(PickupClick::Left {
+ slot: Some(slot.into() as u16),
+ });
+ }
+ /// A shortcut for [`Self::click`] with `QuickMoveClick::Left`.
+ pub fn shift_click(&self, slot: impl Into<usize>) {
+ self.click(QuickMoveClick::Left {
+ slot: slot.into() as u16,
+ });
+ }
+ /// A shortcut for [`Self::click`] with `PickupClick::Right`.
+ pub fn right_click(&self, slot: impl Into<usize>) {
+ self.click(PickupClick::Right {
+ slot: Some(slot.into() as u16),
+ });
+ }
+
pub fn click(&self, operation: impl Into<ClickOperation>) {
let operation = operation.into();
self.client.ecs.lock().send_event(ContainerClickEvent {
@@ -231,6 +236,7 @@ impl ContainerHandleRef {
/// A handle to the open container. The container will be closed once this is
/// dropped.
+#[derive(Deref)]
pub struct ContainerHandle(ContainerHandleRef);
impl Drop for ContainerHandle {
@@ -250,62 +256,10 @@ impl ContainerHandle {
Self(ContainerHandleRef { id, client })
}
- /// Get the id of the container. If this is 0, that means it's the player's
- /// inventory. Otherwise, the number isn't really meaningful since only one
- /// container can be open at a time.
- pub fn id(&self) -> i32 {
- self.0.id()
- }
-
- /// Returns the menu of the container. If the container is closed, this
- /// will return `None`.
- ///
- /// Note that any modifications you make to the `Menu` you're given will not
- /// actually cause any packets to be sent. If you're trying to modify your
- /// inventory, use [`ContainerHandle::click`] instead
- pub fn menu(&self) -> Option<Menu> {
- self.0.menu()
- }
-
- /// Returns the item slots in the container, not including the player's
- /// inventory. If the container is closed, this will return `None`.
- pub fn contents(&self) -> Option<Vec<ItemStack>> {
- self.0.contents()
- }
-
- /// Return the contents of the menu, including the player's inventory. If
- /// the container is closed, this will return `None`.
- pub fn slots(&self) -> Option<Vec<ItemStack>> {
- self.0.slots()
- }
-
/// Closes the inventory by dropping the handle.
pub fn close(self) {
// implicitly calls drop
}
-
- pub fn click(&self, operation: impl Into<ClickOperation>) {
- self.0.click(operation);
- }
-
- /// A shortcut for [`Self::click`] with `PickupClick::Left`.
- pub fn left_click(&self, slot: impl Into<usize>) {
- self.click(PickupClick::Left {
- slot: Some(slot.into() as u16),
- });
- }
- /// A shortcut for [`Self::click`] with `QuickMoveClick::Left`.
- pub fn shift_click(&self, slot: impl Into<usize>) {
- self.click(QuickMoveClick::Left {
- slot: slot.into() as u16,
- });
- }
- /// A shortcut for [`Self::click`] with `PickupClick::Right`.
- pub fn right_click(&self, slot: impl Into<usize>) {
- self.click(PickupClick::Right {
- slot: Some(slot.into() as u16),
- });
- }
}
#[derive(Component, Debug)]