From a6439e39a7dfa83dea738465da1ab79cd4fdab52 Mon Sep 17 00:00:00 2001 From: MagmaMac Date: Thu, 21 Sep 2023 22:12:52 +1000 Subject: [PATCH] Solve inability for items with improper NBT data to be moved out of inventories (#529) Hi, # Objective I was playing around with the chest example. After adding an item with NBT data, I noticed I was unable to remove it from the chest. Sourced the error down to this check. All I have done is not check the NBT data for now. Same as in last comment of #292 . # Solution Only item kind and count checked, nbt ignored. Kind Regards, Mac --------- Co-authored-by: Carson McManus --- crates/valence_inventory/src/validate.rs | 42 +++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/crates/valence_inventory/src/validate.rs b/crates/valence_inventory/src/validate.rs index 4cee7f4ed..086b85cd2 100644 --- a/crates/valence_inventory/src/validate.rs +++ b/crates/valence_inventory/src/validate.rs @@ -167,7 +167,10 @@ pub(super) fn validate_click_slot_packet( if should_swap { // assert that a swap occurs ensure!( - *old_slot == packet.carried_item + // There are some cases where the client will add NBT data that + // did not previously exist. + old_slot.item == packet.carried_item.item + && old_slot.count == packet.carried_item.count && cursor_item.0 == packet.slot_changes[0].stack, "swapped items must match" ); @@ -355,6 +358,8 @@ fn calculate_net_item_delta( #[cfg(test)] mod tests { + use valence_server::nbt::Compound; + use valence_server::nbt::Value::Int; use valence_server::protocol::packets::play::click_slot_c2s::SlotChange; use valence_server::protocol::VarInt; use valence_server::{ItemKind, ItemStack}; @@ -464,6 +469,41 @@ mod tests { .expect("packet should be valid"); } + #[test] + fn click_filled_slot_with_incorrect_nbt_and_empty_cursor_success() { + let player_inventory = Inventory::new(InventoryKind::Player); + let cursor_item = CursorItem(ItemStack::EMPTY); + + let mut inventory = Inventory::new(InventoryKind::Generic9x1); + // Insert an item with no NBT data that should have NBT Data. + inventory.set_slot(0, ItemStack::new(ItemKind::DiamondPickaxe, 1, None)); + + // Proper NBT Compound + let mut compound = Compound::new(); + compound.insert("Damage", Int(1)); + + let packet = ClickSlotC2s { + window_id: 1, + state_id: VarInt(0), + slot_idx: 0, + button: 0, + mode: ClickMode::Click, + slot_changes: vec![SlotChange { + idx: 0, + stack: ItemStack::EMPTY, + }] + .into(), + carried_item: ItemStack { + item: ItemKind::DiamondPickaxe, + count: 1, + nbt: Some(compound), + }, + }; + + validate_click_slot_packet(&packet, &player_inventory, Some(&inventory), &cursor_item) + .expect("packet should be valid"); + } + #[test] fn click_slot_with_filled_cursor_success() { let player_inventory = Inventory::new(InventoryKind::Player);