From 1bd6eef2a4d22e70cee047a14f298798b7bcd5f1 Mon Sep 17 00:00:00 2001 From: Greened <108997309+GreenedDev@users.noreply.github.com> Date: Sat, 6 Jun 2026 18:10:51 +0400 Subject: [PATCH] feat: Implement TakeItemActor for bedrock (#2239) * fix: only send TakeItem packet to tracking players. implement TakeItemActor packet for bedrock * fix: clippy warnings * feat: introduce macros for VarLong and VarULong * chore: change source --------- Co-authored-by: Alexander Medvedev --- pumpkin-protocol/src/bedrock/client/mod.rs | 1 + .../src/bedrock/client/take_item_actor.rs | 19 ++++++++ pumpkin-protocol/src/codec/var_long.rs | 27 +++++------ pumpkin-protocol/src/codec/var_ulong.rs | 45 ++++++++++--------- pumpkin/src/entity/living.rs | 17 ++++--- 5 files changed, 67 insertions(+), 42 deletions(-) create mode 100644 pumpkin-protocol/src/bedrock/client/take_item_actor.rs diff --git a/pumpkin-protocol/src/bedrock/client/mod.rs b/pumpkin-protocol/src/bedrock/client/mod.rs index 798925982..793a34aed 100644 --- a/pumpkin-protocol/src/bedrock/client/mod.rs +++ b/pumpkin-protocol/src/bedrock/client/mod.rs @@ -34,6 +34,7 @@ pub mod set_player_gamemode; pub mod set_time; pub mod set_title; pub mod start_game; +pub mod take_item_actor; pub mod transfer; pub mod update_abilities; pub mod update_attributes; diff --git a/pumpkin-protocol/src/bedrock/client/take_item_actor.rs b/pumpkin-protocol/src/bedrock/client/take_item_actor.rs new file mode 100644 index 000000000..7c17422c2 --- /dev/null +++ b/pumpkin-protocol/src/bedrock/client/take_item_actor.rs @@ -0,0 +1,19 @@ +use crate::{codec::var_ulong::VarULong, serial::PacketWrite}; +use pumpkin_macros::packet; + +#[derive(PacketWrite)] +#[packet(17)] +pub struct CTakeItemActor { + // https://github.com/Sandertv/gophertunnel/blob/master/minecraft/protocol/packet/take_item_actor.go + pub item_runtime_id: VarULong, + pub actor_runtime_id: VarULong, +} +impl CTakeItemActor { + #[must_use] + pub const fn new(item_runtime_id: VarULong, actor_runtime_id: VarULong) -> Self { + Self { + item_runtime_id, + actor_runtime_id, + } + } +} diff --git a/pumpkin-protocol/src/codec/var_long.rs b/pumpkin-protocol/src/codec/var_long.rs index ef8811687..066c3a643 100644 --- a/pumpkin-protocol/src/codec/var_long.rs +++ b/pumpkin-protocol/src/codec/var_long.rs @@ -52,24 +52,19 @@ impl VarLong { Err(ReadingError::TooLarge("VarLong".to_string())) } } - -impl From for VarLong { - fn from(value: i64) -> Self { - Self(value) - } +macro_rules! gen_from { + ($ty: ty) => { + impl From<$ty> for VarLong { + fn from(value: $ty) -> Self { + VarLong(value.into()) + } + } + }; } -impl From for VarLong { - fn from(value: u32) -> Self { - Self(i64::from(value)) - } -} - -impl From for VarLong { - fn from(value: u8) -> Self { - Self(i64::from(value)) - } -} +gen_from!(u8); +gen_from!(u32); +gen_from!(i64); impl From for VarLong { fn from(value: usize) -> Self { diff --git a/pumpkin-protocol/src/codec/var_ulong.rs b/pumpkin-protocol/src/codec/var_ulong.rs index 4bb8ec171..ed801e4ac 100644 --- a/pumpkin-protocol/src/codec/var_ulong.rs +++ b/pumpkin-protocol/src/codec/var_ulong.rs @@ -65,30 +65,35 @@ impl VarULong { Err(ReadingError::TooLarge("VarLong".to_string())) } } - -impl From for VarULong { - fn from(value: u64) -> Self { - Self(value) - } +macro_rules! gen_from { + ($ty: ty) => { + impl From<$ty> for VarULong { + fn from(value: $ty) -> Self { + VarULong(value.into()) + } + } + }; } +gen_from!(u8); +gen_from!(u16); +gen_from!(u32); +gen_from!(u64); -impl From for VarULong { - fn from(value: u32) -> Self { - Self(u64::from(value)) - } -} +macro_rules! gen_try_from { + ($ty: ty) => { + impl TryFrom<$ty> for VarULong { + type Error = >::Error; -impl From for VarULong { - fn from(value: u8) -> Self { - Self(u64::from(value)) - } -} - -impl From for VarULong { - fn from(value: usize) -> Self { - Self(value as u64) - } + fn try_from(value: $ty) -> Result { + Ok(VarULong(value.try_into()?)) + } + } + }; } +gen_try_from!(i32); +gen_try_from!(i64); +gen_try_from!(isize); +gen_try_from!(usize); impl From for u64 { fn from(value: VarULong) -> Self { diff --git a/pumpkin/src/entity/living.rs b/pumpkin/src/entity/living.rs index 07de73a8f..8bfc04aea 100644 --- a/pumpkin/src/entity/living.rs +++ b/pumpkin/src/entity/living.rs @@ -6,6 +6,7 @@ use pumpkin_data::tracked_data::{TrackedData, TrackedId}; use pumpkin_inventory::build_equipment_slots; use pumpkin_inventory::player::player_inventory::PlayerInventory; use pumpkin_inventory::screen_handler::InventoryPlayer; +use pumpkin_protocol::bedrock::client::take_item_actor::CTakeItemActor; use pumpkin_protocol::bedrock::server::actor_event::{ActorEventType, SActorEvent}; use pumpkin_util::GameMode; use pumpkin_util::Hand; @@ -199,15 +200,19 @@ impl LivingEntity { /// Picks up and Item entity or XP Orb pub fn pickup(&self, item: &Entity, stack_amount: u32) { - // TODO: Only nearby - self.entity - .world - .load() - .broadcast_packet_all(&CTakeItemEntity::new( + let chunk_pos = self.entity.chunk_pos.load(); + self.entity.world.load().broadcast_to_chunk_editioned_sync( + chunk_pos, + &CTakeItemEntity::new( item.entity_id.into(), self.entity.entity_id.into(), stack_amount.try_into().unwrap(), - )); + ), + &CTakeItemActor::new( + item.entity_id.try_into().unwrap(), + self.entity.entity_id.try_into().unwrap(), + ), + ); } /// Sends the Hand animation to all others, used when Eating for example