From 19ddbeff9e1de5821b4f2b18987c5103f30d7989 Mon Sep 17 00:00:00 2001 From: Tamion <70228790+notTamion@users.noreply.github.com> Date: Sat, 11 Jan 2025 19:50:24 +0100 Subject: [PATCH] Fix InventoryAction wrong for Bundles (#11902) --- build-data/paper.at | 1 + .../event/inventory/InventoryAction.java | 24 +++++++++++++ .../ServerGamePacketListenerImpl.java.patch | 36 ++++++++++++++++--- .../item/component/BundleContents.java.patch | 30 ++++++++++++++++ 4 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 paper-server/patches/sources/net/minecraft/world/item/component/BundleContents.java.patch diff --git a/build-data/paper.at b/build-data/paper.at index bb447c7213..4945a796a6 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -504,6 +504,7 @@ public net.minecraft.world.item.ItemStackLinkedSet TYPE_AND_TAG public net.minecraft.world.item.JukeboxSongPlayer song public net.minecraft.world.item.MapItem createNewSavedData(Lnet/minecraft/world/level/Level;IIIZZLnet/minecraft/resources/ResourceKey;)Lnet/minecraft/world/level/saveddata/maps/MapId; public net.minecraft.world.item.StandingAndWallBlockItem wallBlock +public net.minecraft.world.item.component.BundleContents$Mutable getMaxAmountToAdd(Lnet/minecraft/world/item/ItemStack;)I public net.minecraft.world.item.component.ItemContainerContents MAX_SIZE public net.minecraft.world.item.component.ItemContainerContents items public net.minecraft.world.item.context.UseOnContext (Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/phys/BlockHitResult;)V diff --git a/paper-api/src/main/java/org/bukkit/event/inventory/InventoryAction.java b/paper-api/src/main/java/org/bukkit/event/inventory/InventoryAction.java index b2bcc89119..b84aaf7f37 100644 --- a/paper-api/src/main/java/org/bukkit/event/inventory/InventoryAction.java +++ b/paper-api/src/main/java/org/bukkit/event/inventory/InventoryAction.java @@ -93,5 +93,29 @@ public enum InventoryAction { * An unrecognized ClickType. */ UNKNOWN, + /** + * The first stack of items in the clicked bundle is moved to the cursor. + */ + PICKUP_FROM_BUNDLE, + /** + * All of the items on the clicked slot are moved into the bundle on the cursor. + */ + PICKUP_ALL_INTO_BUNDLE, + /** + * Some of the items on the clicked slot are moved into the bundle on the cursor. + */ + PICKUP_SOME_INTO_BUNDLE, + /** + * The first stack of items is moved to the clicked slot. + */ + PLACE_FROM_BUNDLE, + /** + * All of the items on the cursor are moved into the bundle in the clicked slot. + */ + PLACE_ALL_INTO_BUNDLE, + /** + * Some of the items on the cursor are moved into the bundle in the clicked slot. + */ + PLACE_SOME_INTO_BUNDLE, ; } diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index 37ab47c80b..7b1d2a2d20 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -2017,7 +2017,7 @@ this.player.containerMenu.sendAllDataToRemote(); } else if (!this.player.containerMenu.stillValid(this.player)) { LOGGER.debug("Player {} interacted with invalid menu {}", this.player, this.player.containerMenu); -@@ -1713,7 +_,313 @@ +@@ -1713,7 +_,341 @@ } else { boolean flag = packet.getStateId() != this.player.containerMenu.getStateId(); this.player.containerMenu.suppressRemoteUpdates(); @@ -2056,11 +2056,19 @@ + ItemStack cursor = this.player.containerMenu.getCarried(); + if (clickedItem.isEmpty()) { + if (!cursor.isEmpty()) { -+ action = packet.getButtonNum() == 0 ? InventoryAction.PLACE_ALL : InventoryAction.PLACE_ONE; ++ if (cursor.getItem() instanceof net.minecraft.world.item.BundleItem && packet.getButtonNum() != 0) { ++ action = cursor.get(DataComponents.BUNDLE_CONTENTS).isEmpty() ? InventoryAction.NOTHING : InventoryAction.PLACE_FROM_BUNDLE; ++ } else { ++ action = packet.getButtonNum() == 0 ? InventoryAction.PLACE_ALL : InventoryAction.PLACE_ONE; ++ } + } + } else if (slot.mayPickup(this.player)) { + if (cursor.isEmpty()) { -+ action = packet.getButtonNum() == 0 ? InventoryAction.PICKUP_ALL : InventoryAction.PICKUP_HALF; ++ if (slot.getItem().getItem() instanceof net.minecraft.world.item.BundleItem && packet.getButtonNum() != 0) { ++ action = slot.getItem().get(DataComponents.BUNDLE_CONTENTS).isEmpty() ? InventoryAction.NOTHING : InventoryAction.PICKUP_FROM_BUNDLE; ++ } else { ++ action = packet.getButtonNum() == 0 ? InventoryAction.PICKUP_ALL : InventoryAction.PICKUP_HALF; ++ } + } else if (slot.mayPlace(cursor)) { + if (ItemStack.isSameItemSameComponents(clickedItem, cursor)) { + int toPlace = packet.getButtonNum() == 0 ? cursor.getCount() : 1; @@ -2076,7 +2084,27 @@ + action = InventoryAction.PLACE_SOME; + } + } else if (cursor.getCount() <= slot.getMaxStackSize()) { -+ action = InventoryAction.SWAP_WITH_CURSOR; ++ if (cursor.getItem() instanceof net.minecraft.world.item.BundleItem && packet.getButtonNum() == 0) { ++ int toPickup = cursor.get(DataComponents.BUNDLE_CONTENTS).getMaxAmountToAdd(slot.getItem()); ++ if (toPickup >= slot.getItem().getCount()) { ++ action = InventoryAction.PICKUP_ALL_INTO_BUNDLE; ++ } else if (toPickup == 0) { ++ action = InventoryAction.NOTHING; ++ } else { ++ action = InventoryAction.PICKUP_SOME_INTO_BUNDLE; ++ } ++ } else if (slot.getItem().getItem() instanceof net.minecraft.world.item.BundleItem && packet.getButtonNum() == 0) { ++ int toPickup = slot.getItem().get(DataComponents.BUNDLE_CONTENTS).getMaxAmountToAdd(cursor); ++ if (toPickup >= cursor.getCount()) { ++ action = InventoryAction.PLACE_ALL_INTO_BUNDLE; ++ } else if (toPickup == 0) { ++ action = InventoryAction.NOTHING; ++ } else { ++ action = InventoryAction.PLACE_SOME_INTO_BUNDLE; ++ } ++ } else { ++ action = InventoryAction.SWAP_WITH_CURSOR; ++ } + } + } else if (ItemStack.isSameItemSameComponents(cursor, clickedItem)) { + if (clickedItem.getCount() >= 0) { diff --git a/paper-server/patches/sources/net/minecraft/world/item/component/BundleContents.java.patch b/paper-server/patches/sources/net/minecraft/world/item/component/BundleContents.java.patch new file mode 100644 index 0000000000..cc47956906 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/component/BundleContents.java.patch @@ -0,0 +1,30 @@ +--- a/net/minecraft/world/item/component/BundleContents.java ++++ b/net/minecraft/world/item/component/BundleContents.java +@@ -76,6 +_,12 @@ + return !stack.isEmpty() && stack.getItem().canFitInsideContainerItems(); + } + ++ // Paper start - correct bundle inventory action ++ public int getMaxAmountToAdd(final ItemStack stack) { ++ return Mutable.getMaxAmountToAdd(stack, this.weight); ++ } ++ // Paper end - correct bundle inventory action ++ + public int getNumberOfItemsToShow() { + int size = this.size(); + int i = size > 12 ? 11 : 12; +@@ -171,7 +_,13 @@ + } + + public int getMaxAmountToAdd(ItemStack stack) { +- Fraction fraction = Fraction.ONE.subtract(this.weight); ++ // Paper start - correct bundle inventory action ++ // Static overload to easily compute this value without the need for an instance of mutable. ++ return getMaxAmountToAdd(stack, this.weight); ++ } ++ static int getMaxAmountToAdd(final ItemStack stack, final Fraction weight) { ++ Fraction fraction = Fraction.ONE.subtract(weight); ++ // Paper end - correct bundle inventory action + return Math.max(fraction.divideBy(BundleContents.getWeight(stack)).intValue(), 0); + } +