diff --git a/1todos/server/luminol-patches/features/0003-Leaves-Item-overstack-util.patch b/1todos/server/luminol-patches/features/0003-Leaves-Item-overstack-util.patch deleted file mode 100644 index 1a54c6a..0000000 --- a/1todos/server/luminol-patches/features/0003-Leaves-Item-overstack-util.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Helvetica Volubi -Date: Wed, 13 Aug 2025 22:23:46 +0800 -Subject: [PATCH] Leaves: Item overstack util - -Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com> -As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/d93e9766d3797d130f66179e70a1b374c546fef7/leaves-server/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java) -Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html) - -diff --git a/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java b/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java -index 112dc08eb62c4c50fb4859f51a366cedf027ca00..b5f661fd20b382725ad117c56ce2c94ded32b1b7 100644 ---- a/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java -+++ b/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java -@@ -17,6 +17,7 @@ - - package org.leavesmc.leaves.util; - -+import fun.bm.lophine.config.modules.function.ContainerExpansionConfig; - import io.papermc.paper.datacomponent.DataComponentTypes; - import io.papermc.paper.datacomponent.item.ItemEnchantments; - import net.minecraft.core.component.DataComponents; -@@ -135,9 +136,9 @@ public class ItemOverstackUtils { - - private static class ShulkerBox implements ItemUtil { - public static boolean shulkerBoxCheck(@NotNull ItemStack stack1, @NotNull ItemStack stack2) { -- /*if (LeavesConfig.modify.shulkerBox.sameNbtStackable) { -+ if (ContainerExpansionConfig.nbtShulkerStackable) { - return Objects.equals(stack1.getComponents(), stack2.getComponents()); -- }*/ // Luminol -+ } - return shulkerBoxNoItem(stack1) && shulkerBoxNoItem(stack2) && Objects.equals(stack1.getComponents(), stack2.getComponents()); - } - -@@ -147,16 +148,15 @@ public class ItemOverstackUtils { - - @Override - public boolean isEnabled() { -- // return LeavesConfig.modify.shulkerBox.stackableShulkerBoxes > 1; // Luminol -- return false; // Luminol -+ return ContainerExpansionConfig.shulkerCount > 1; - } - - @Override - public boolean tryStackItems(ItemEntity self, ItemEntity other) { - ItemStack selfStack = self.getItem(); - if (!isEnabled() || -- !(selfStack.getItem() instanceof net.minecraft.world.item.BlockItem blockItem) || -- !(blockItem.getBlock() instanceof net.minecraft.world.level.block.ShulkerBoxBlock) -+ !(selfStack.getItem() instanceof BlockItem blockItem) || -+ !(blockItem.getBlock() instanceof ShulkerBoxBlock) - ) { - return false; - } -@@ -164,8 +164,8 @@ public class ItemOverstackUtils { - ItemStack otherStack = other.getItem(); - if (selfStack.getItem() == otherStack.getItem() - && shulkerBoxCheck(selfStack, otherStack) -- && selfStack.getCount() != /*org.leavesmc.leaves.LeavesConfig.modify.shulkerBox.stackableShulkerBoxes*/ 1) { // Luminol -- int amount = Math.min(otherStack.getCount(), /*org.leavesmc.leaves.LeavesConfig.modify.shulkerBox.stackableShulkerBoxes*/1 - selfStack.getCount()); // Luminol -+ && selfStack.getCount() != ContainerExpansionConfig.shulkerCount) { -+ int amount = Math.min(otherStack.getCount(), ContainerExpansionConfig.shulkerCount - selfStack.getCount()); - - selfStack.grow(amount); - self.setItem(selfStack); -@@ -187,9 +187,8 @@ public class ItemOverstackUtils { - @Override - public int getMaxServerStackCount(ItemStack stack) { - if (isEnabled() && stack.getItem() instanceof BlockItem bi && -- bi.getBlock() instanceof ShulkerBoxBlock && (/*LeavesConfig.modify.shulkerBox.sameNbtStackable ||*/ shulkerBoxNoItem(stack))) { // Luminol -- // return LeavesConfig.modify.shulkerBox.stackableShulkerBoxes; // Luminol -- return 1; // Luminol -+ bi.getBlock() instanceof ShulkerBoxBlock && (ContainerExpansionConfig.nbtShulkerStackable || shulkerBoxNoItem(stack))) { -+ return ContainerExpansionConfig.shulkerCount; - } - return -1; - } diff --git a/1todos/server/minecraft-patches/features/0011-Leaves-Item-overstack-util.patch b/1todos/server/minecraft-patches/features/0011-Leaves-Item-overstack-util.patch deleted file mode 100644 index 3b8b86c..0000000 --- a/1todos/server/minecraft-patches/features/0011-Leaves-Item-overstack-util.patch +++ /dev/null @@ -1,472 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Helvetica Volubi -Date: Sat, 26 Jul 2025 01:11:54 +0800 -Subject: [PATCH] Leaves: Item overstack util - -Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com> -As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/46cccfc39cafbca1681620d03947bc3ad558327f/leaves-server/minecraft-patches/features/0034-Item-overstack-util.patch) -Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html) - -diff --git a/net/minecraft/commands/arguments/item/ItemInput.java b/net/minecraft/commands/arguments/item/ItemInput.java -index 8e08cb90dc94171a8da7126fe18c46eaa49a58f2..a7804a0d099c79c81eb45eb20402a001d8734529 100644 ---- a/net/minecraft/commands/arguments/item/ItemInput.java -+++ b/net/minecraft/commands/arguments/item/ItemInput.java -@@ -39,11 +39,13 @@ public class ItemInput { - public ItemStack createItemStack(int count, boolean allowOversizedStacks) throws CommandSyntaxException { - ItemStack itemStack = new ItemStack(this.item, count); - itemStack.applyComponents(this.components); -- if (allowOversizedStacks && count > itemStack.getMaxStackSize()) { -- throw ERROR_STACK_TOO_BIG.create(this.getItemName(), itemStack.getMaxStackSize()); -+ // Leaves start - item over-stack util -+ if (allowOversizedStacks && count > org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack)) { -+ throw ERROR_STACK_TOO_BIG.create(this.getItemName(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack)); - } else { - return itemStack; - } -+ // Leaves end - item over-stack util - } - - public String serialize(HolderLookup.Provider levelRegistry) { -diff --git a/net/minecraft/server/commands/GiveCommand.java b/net/minecraft/server/commands/GiveCommand.java -index 1281eadb2d0c5b4ce5e3afd51d8205f9a4ef011c..b1446dfb4689174ee9f55cec6080622ec34de250 100644 ---- a/net/minecraft/server/commands/GiveCommand.java -+++ b/net/minecraft/server/commands/GiveCommand.java -@@ -54,7 +54,7 @@ public class GiveCommand { - - private static int giveItem(CommandSourceStack source, ItemInput item, Collection targets, int count) throws CommandSyntaxException { - ItemStack itemStack = item.createItemStack(1, false); -- int maxStackSize = itemStack.getMaxStackSize(); -+ int maxStackSize = org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack); // Leaves - item over-stack util - int i = maxStackSize * 100; - if (count > i) { - source.sendFailure(Component.translatable("commands.give.failed.toomanyitems", i, itemStack.getDisplayName())); -diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 5c5dfcefd9ce6c9d7f69fb6d03216805b9e63822..d35ef52a6adb9a560138d1a2af32969c3a73f42b 100644 ---- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java -+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3170,7 +3170,7 @@ public class ServerGamePacketListenerImpl - } else if (slot.mayPlace(cursor)) { - if (ItemStack.isSameItemSameComponents(clickedItem, cursor)) { - int toPlace = packet.buttonNum() == 0 ? cursor.getCount() : 1; -- toPlace = Math.min(toPlace, clickedItem.getMaxStackSize() - clickedItem.getCount()); -+ toPlace = Math.min(toPlace, org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(clickedItem) - clickedItem.getCount()); // Leaves - item over-stack util - toPlace = Math.min(toPlace, slot.container.getMaxStackSize() - clickedItem.getCount()); - if (toPlace == 1) { - action = InventoryAction.PLACE_ONE; -@@ -3206,7 +3206,7 @@ public class ServerGamePacketListenerImpl - } - } else if (ItemStack.isSameItemSameComponents(cursor, clickedItem)) { - if (clickedItem.getCount() >= 0) { -- if (clickedItem.getCount() + cursor.getCount() <= cursor.getMaxStackSize()) { -+ if (clickedItem.getCount() + cursor.getCount() <= org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(cursor)) { // Leaves - item over-stack util - // As of 1.5, this is result slots only - action = InventoryAction.PICKUP_ALL; - } -@@ -3423,6 +3423,7 @@ public class ServerGamePacketListenerImpl - this.player.containerMenu.broadcastFullState(); - } else { - this.player.containerMenu.broadcastChanges(); -+ if (org.leavesmc.leaves.util.ItemOverstackUtils.hasOverstackingItem()) this.player.containerMenu.broadcastCarriedItem(); // Leaves - item over-stack util - force send carried item - } - if (packet.buttonNum() == Inventory.SLOT_OFFHAND && this.player.containerMenu != this.player.inventoryMenu) this.player.containerSynchronizer.sendOffHandSlotChange(); // Paper - update offhand data when the player is clicking in an inventory not their own as the sychronizer does not include offhand slots - if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes. -@@ -3534,7 +3535,7 @@ public class ServerGamePacketListenerImpl - } - - boolean flag1 = packet.slotNum() >= 1 && packet.slotNum() <= 45; -- boolean flag2 = itemStack.isEmpty() || itemStack.getCount() <= itemStack.getMaxStackSize(); -+ boolean flag2 = itemStack.isEmpty() || itemStack.getCount() <= org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack); // Leaves - item over-stack util - if (flag || (flag1 && !ItemStack.matches(this.player.inventoryMenu.getSlot(packet.slotNum()).getItem(), packet.itemStack()))) { // Insist on valid slot - // CraftBukkit start - Call click event - org.bukkit.inventory.InventoryView inventory = this.player.inventoryMenu.getBukkitView(); -@@ -3576,6 +3577,7 @@ public class ServerGamePacketListenerImpl - this.player.inventoryMenu.getSlot(packet.slotNum()).setByPlayer(itemStack); - this.player.inventoryMenu.setRemoteSlot(packet.slotNum(), itemStack); - this.player.inventoryMenu.broadcastChanges(); -+ if (org.leavesmc.leaves.util.ItemOverstackUtils.hasOverstackingItem()) this.player.containerMenu.sendSingleSlot(packet.slotNum(), itemStack); // Leaves - item over-stack util - force send carried item - if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes. - } else if (flag && flag2) { - if (this.dropSpamThrottler.isUnderThreshold()) { -diff --git a/net/minecraft/world/Container.java b/net/minecraft/world/Container.java -index b63cecafd841b97a694f6d2610141dcdb8f30574..392678778dc2a036c1e3db4b6bb2800e452d3cd0 100644 ---- a/net/minecraft/world/Container.java -+++ b/net/minecraft/world/Container.java -@@ -37,6 +37,12 @@ public interface Container extends Clearable, SlotProvider, Iterable, - return Math.min(this.getMaxStackSize(), stack.getMaxStackSize()); - } - -+ // Leaves start - item over-stack util -+ default int getMaxStackLeaves(ItemStack stack) { -+ return Math.min(this.getMaxStackSize(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack)); -+ } -+ // Leaves end - item over-stack util -+ - void setChanged(); - - boolean stillValid(Player player); -diff --git a/net/minecraft/world/SimpleContainer.java b/net/minecraft/world/SimpleContainer.java -index 0233c2b5e40c33330870e598431897a2ff98c2a3..3cf1819a9c82da2d2e0c43187e204353e3643369 100644 ---- a/net/minecraft/world/SimpleContainer.java -+++ b/net/minecraft/world/SimpleContainer.java -@@ -210,7 +210,7 @@ public class SimpleContainer implements Container, StackedContentsCompatible { - @Override - public void setItem(int index, ItemStack stack) { - this.items.set(index, stack); -- stack.limitSize(this.getMaxStackSize(stack)); -+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util - this.setChanged(); - } - -@@ -285,7 +285,7 @@ public class SimpleContainer implements Container, StackedContentsCompatible { - } - - private void moveItemsBetweenStacks(ItemStack stack, ItemStack other) { -- int maxStackSize = this.getMaxStackSize(other); -+ int maxStackSize = this.getMaxStackLeaves(other); // Leaves - item over-stack util - int min = Math.min(stack.getCount(), maxStackSize - other.getCount()); - if (min > 0) { - other.grow(min); -diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java -index 16c42a5e35c6ee1df640e5831818099fab6338f1..f3f067c62dc024a747d059608ae7a2e8740dbff2 100644 ---- a/net/minecraft/world/entity/item/ItemEntity.java -+++ b/net/minecraft/world/entity/item/ItemEntity.java -@@ -271,10 +271,15 @@ public class ItemEntity extends Entity implements TraceableEntity, ChangePublish - - private boolean isMergable() { - ItemStack item = this.getItem(); -- return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < this.despawnRate && item.getCount() < item.getMaxStackSize(); // Paper - Alternative item-despawn-rate -+ return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < this.despawnRate && item.getCount() < org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(item); // Paper - Alternative item-despawn-rate // Leaves - item over-stack util - } - - private void tryToMerge(ItemEntity itemEntity) { -+ // Leaves start - item over-stack util -+ if (org.leavesmc.leaves.util.ItemOverstackUtils.tryStackItems(this, itemEntity)) { -+ return; -+ } -+ // Leaves end - item over-stack util - ItemStack item = this.getItem(); - ItemStack item1 = itemEntity.getItem(); - if (Objects.equals(this.target, itemEntity.target) && areMergable(item, item1)) { -diff --git a/net/minecraft/world/entity/player/Inventory.java b/net/minecraft/world/entity/player/Inventory.java -index 41e59f3739945ca7f6ab710c993b5c0f15fcd529..b849b04f227b43d036f4f6b3ae7accfafc389d9f 100644 ---- a/net/minecraft/world/entity/player/Inventory.java -+++ b/net/minecraft/world/entity/player/Inventory.java -@@ -166,10 +166,12 @@ public class Inventory implements Container, Nameable { - } - - private boolean hasRemainingSpaceForItem(ItemStack destination, ItemStack origin) { -+ // Leaves start - item over-stack util - return !destination.isEmpty() -- && destination.isStackable() -- && destination.getCount() < this.getMaxStackSize(destination) -+ && org.leavesmc.leaves.util.ItemOverstackUtils.isStackable(destination) -+ && destination.getCount() < org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(destination) - && ItemStack.isSameItemSameComponents(destination, origin); // Paper - check if itemstack is stackable first -+ // Leaves end - item over-stack util - } - - // CraftBukkit start - Watch method above! :D -@@ -182,7 +184,7 @@ public class Inventory implements Container, Nameable { - } - - if (this.hasRemainingSpaceForItem(itemInSlot, itemStack)) { -- remains -= (itemInSlot.getMaxStackSize() < this.getMaxStackSize() ? itemInSlot.getMaxStackSize() : this.getMaxStackSize()) - itemInSlot.getCount(); -+ remains -= (org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInSlot) < this.getMaxStackSize() ? org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInSlot) : this.getMaxStackSize()) - itemInSlot.getCount(); // Leaves - item over-stack util - } - if (remains <= 0) { - return itemStack.getCount(); -@@ -191,7 +193,7 @@ public class Inventory implements Container, Nameable { - - ItemStack itemInOffhand = this.equipment.get(EquipmentSlot.OFFHAND); - if (this.hasRemainingSpaceForItem(itemInOffhand, itemStack)) { -- remains -= (itemInOffhand.getMaxStackSize() < this.getMaxStackSize() ? itemInOffhand.getMaxStackSize() : this.getMaxStackSize()) - itemInOffhand.getCount(); -+ remains -= (org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInOffhand) < this.getMaxStackSize() ? org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInOffhand) : this.getMaxStackSize()) - itemInOffhand.getCount(); // Leaves - item over-stack util - } - if (remains <= 0) { - return itemStack.getCount(); -@@ -315,7 +317,7 @@ public class Inventory implements Container, Nameable { - this.setItem(slot, item); - } - -- int i = this.getMaxStackSize(item) - item.getCount(); -+ int i = this.getMaxStackLeaves(item) - item.getCount(); // Leaves - item over-stack util - int min = Math.min(count, i); - if (min == 0) { - return count; -@@ -421,7 +423,7 @@ public class Inventory implements Container, Nameable { - break; - } - -- int i = stack.getMaxStackSize() - this.getItem(slotWithRemainingSpace).getCount(); -+ int i = org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack) - this.getItem(slotWithRemainingSpace).getCount(); // Leaves - item over-stack util - if (this.add(slotWithRemainingSpace, stack.split(i)) && sendPacket && this.player instanceof ServerPlayer serverPlayer) { - serverPlayer.connection.send(this.createInventoryUpdatePacket(slotWithRemainingSpace)); - } -diff --git a/net/minecraft/world/entity/player/StackedItemContents.java b/net/minecraft/world/entity/player/StackedItemContents.java -index 00dbc0d125b2c8c208ffa46f9084c6317efaba90..1f57b3c60fd0cbfdd65e06f8994525ade6dc6bd9 100644 ---- a/net/minecraft/world/entity/player/StackedItemContents.java -+++ b/net/minecraft/world/entity/player/StackedItemContents.java -@@ -36,7 +36,7 @@ public class StackedItemContents { - } - - public void accountStack(ItemStack stack) { -- this.accountStack(stack, stack.getMaxStackSize()); -+ this.accountStack(stack, org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack)); // Leaves - item over-stack util - } - - public void accountStack(ItemStack stack, int maxStackSize) { -diff --git a/net/minecraft/world/entity/vehicle/ContainerEntity.java b/net/minecraft/world/entity/vehicle/ContainerEntity.java -index 44276ba9c7aab306cfd12833a834ebe61cf64e7c..0a19a7782f3fa27c41e02393e887ba7cc727012b 100644 ---- a/net/minecraft/world/entity/vehicle/ContainerEntity.java -+++ b/net/minecraft/world/entity/vehicle/ContainerEntity.java -@@ -162,7 +162,7 @@ public interface ContainerEntity extends Container, MenuProvider { - default void setChestVehicleItem(int slot, ItemStack stack) { - this.unpackChestVehicleLootTable(null); - this.getItemStacks().set(slot, stack); -- stack.limitSize(this.getMaxStackSize(stack)); -+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util - } - - default @Nullable SlotAccess getChestVehicleSlot(final int slot) { -diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java -index 3b1c6a2397950ceb167890961b635cc69aaf8950..e7ea8849e8fa942709f505145e8076f064476206 100644 ---- a/net/minecraft/world/inventory/AbstractContainerMenu.java -+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java -@@ -292,6 +292,13 @@ public abstract class AbstractContainerMenu { - this.sendAllDataToRemote(); - } - -+ // Leaves start - item over-stack util -+ public void sendSingleSlot(int slotIndex, ItemStack item) { -+ if (this.synchronizer != null) { -+ this.synchronizer.sendSlotChange(this, slotIndex, item); -+ } -+ } -+ // Leaves end - item over-stack util - private void updateDataSlotListeners(int slotIndex, int value) { - for (ContainerListener containerListener : this.containerListeners) { - containerListener.dataChanged(this, slotIndex, value); -@@ -448,7 +455,7 @@ public abstract class AbstractContainerMenu { - && (this.quickcraftType == 2 || carried1.getCount() >= this.quickcraftSlots.size()) - && this.canDragTo(slot1)) { - int i2 = slot1.hasItem() ? slot1.getItem().getCount() : 0; -- int min = Math.min(itemStack.getMaxStackSize(), slot1.getMaxStackSize(itemStack)); -+ int min = Math.min(org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack), slot1.getMaxStackSize(itemStack)); // Leaves - item over-stack util - int min1 = Math.min(getQuickCraftPlaceCount(this.quickcraftSlots, this.quickcraftType, itemStack) + i2, min); - count -= min1 - i2; - // slot1.setByPlayer(itemStack.copyWithCount(min1)); -@@ -556,7 +563,7 @@ public abstract class AbstractContainerMenu { - slot.setByPlayer(carried2); - } - } else if (ItemStack.isSameItemSameComponents(carried, carried2)) { -- Optional optional1 = slot.tryRemove(carried.getCount(), carried2.getMaxStackSize() - carried2.getCount(), player); -+ Optional optional1 = slot.tryRemove(carried.getCount(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(carried2) - carried2.getCount(), player); // Leaves - item over-stack util - optional1.ifPresent(itemStack2 -> { - carried2.grow(itemStack2.getCount()); - slot.onTake(player, itemStack2); -@@ -618,7 +625,7 @@ public abstract class AbstractContainerMenu { - Slot slot2 = this.slots.get(slotIndex); - if (slot2.hasItem()) { - ItemStack itemStack = slot2.getItem(); -- this.setCarried(itemStack.copyWithCount(itemStack.getMaxStackSize())); -+ this.setCarried(itemStack.copyWithCount(org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack))); // Leaves - item over-stack util - } - } else if (clickType == ClickType.THROW && this.getCarried().isEmpty() && slotIndex >= 0) { - Slot slot2 = this.slots.get(slotIndex); -@@ -653,15 +660,15 @@ public abstract class AbstractContainerMenu { - int maxStackSize = button == 0 ? 1 : -1; - - for (int i3 = 0; i3 < 2; i3++) { -- for (int i4 = count; i4 >= 0 && i4 < this.slots.size() && itemStack.getCount() < itemStack.getMaxStackSize(); i4 += maxStackSize) { -+ for (int i4 = count; i4 >= 0 && i4 < this.slots.size() && itemStack.getCount() < org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack); i4 += maxStackSize) { // Leaves - item over-stack util - Slot slot3 = this.slots.get(i4); - if (slot3.hasItem() - && canItemQuickReplace(slot3, itemStack, true) - && slot3.mayPickup(player) - && this.canTakeItemForPickAll(itemStack, slot3)) { - ItemStack item1 = slot3.getItem(); -- if (i3 != 0 || item1.getCount() != item1.getMaxStackSize()) { -- ItemStack itemStack1 = slot3.safeTake(item1.getCount(), itemStack.getMaxStackSize() - itemStack.getCount(), player); -+ if (i3 != 0 || item1.getCount() != org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(item1)) { // Leaves - item over-stack util -+ ItemStack itemStack1 = slot3.safeTake(item1.getCount(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack) - itemStack.getCount(), player); // Leaves - item over-stack util - itemStack.grow(itemStack1.getCount()); - } - } -@@ -763,7 +770,7 @@ public abstract class AbstractContainerMenu { - i = endIndex - 1; - } - -- if (stack.isStackable()) { -+ if (org.leavesmc.leaves.util.ItemOverstackUtils.isStackable(stack)) { // Leaves - item over-stack util - while (!stack.isEmpty() && (reverseDirection ? i >= startIndex : i < endIndex)) { - Slot slot = this.slots.get(i); - ItemStack item = slot.getItem(); -@@ -864,7 +871,7 @@ public abstract class AbstractContainerMenu { - public static boolean canItemQuickReplace(@Nullable Slot slot, ItemStack stack, boolean stackSizeMatters) { - boolean flag = slot == null || !slot.hasItem(); - return !flag && ItemStack.isSameItemSameComponents(stack, slot.getItem()) -- ? slot.getItem().getCount() + (stackSizeMatters ? 0 : stack.getCount()) <= stack.getMaxStackSize() -+ ? slot.getItem().getCount() + (stackSizeMatters ? 0 : stack.getCount()) <= org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack) // Leaves - item over-stack util - : flag; - } - -@@ -872,7 +879,7 @@ public abstract class AbstractContainerMenu { - return switch (type) { - case 0 -> Mth.floor((float)stack.getCount() / slots.size()); - case 1 -> 1; -- case 2 -> stack.getMaxStackSize(); -+ case 2 -> org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack); // Leaves - item over-stack util - default -> stack.getCount(); - }; - } -@@ -895,7 +902,7 @@ public abstract class AbstractContainerMenu { - for (int i = 0; i < container.getContainerSize(); i++) { - ItemStack item = container.getItem(i); - if (!item.isEmpty()) { -- f += (float)item.getCount() / container.getMaxStackSize(item); -+ f += Math.clamp((float) item.getCount() / container.getMaxStackSize(item), 0f, 1f); // Leaves - item over-stack util - } - } - -diff --git a/net/minecraft/world/inventory/MerchantContainer.java b/net/minecraft/world/inventory/MerchantContainer.java -index a4203c416c7a83557055099a9ea8f43ac2b18b21..46c8026876e851ec4a31fd34c9b64623469ffb8d 100644 ---- a/net/minecraft/world/inventory/MerchantContainer.java -+++ b/net/minecraft/world/inventory/MerchantContainer.java -@@ -108,7 +108,7 @@ public class MerchantContainer implements Container { - @Override - public void setItem(int index, ItemStack stack) { - this.itemStacks.set(index, stack); -- stack.limitSize(this.getMaxStackSize(stack)); -+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util - if (this.isPaymentSlot(index)) { - this.updateSellItem(); - } -diff --git a/net/minecraft/world/inventory/Slot.java b/net/minecraft/world/inventory/Slot.java -index 2b7e245ebf3bb471a1d817c4b5d56a64790cbab7..00083df87439ff0fa56e09853931b60579520d0e 100644 ---- a/net/minecraft/world/inventory/Slot.java -+++ b/net/minecraft/world/inventory/Slot.java -@@ -75,7 +75,7 @@ public class Slot { - } - - public int getMaxStackSize(ItemStack stack) { -- return Math.min(this.getMaxStackSize(), stack.getMaxStackSize()); -+ return Math.min(this.getMaxStackSize(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack)); // Leaves - item over-stack util - } - - public @Nullable Identifier getNoItemIcon() { -diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java -index ed2971b54afbebe37a7ff61798778a4249b79856..73a97f4f62fe7d27b441cab58c6c86ffce011060 100644 ---- a/net/minecraft/world/item/ItemStack.java -+++ b/net/minecraft/world/item/ItemStack.java -@@ -174,7 +174,7 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher validateStrict(ItemStack stack) { -@@ -200,7 +200,8 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher holder = Item.STREAM_CODEC.decode(buffer); - DataComponentPatch dataComponentPatch = codec.decode(buffer); -- return new ItemStack(holder, varInt, dataComponentPatch); -+ ItemStack itemStack = new ItemStack(holder, varInt, dataComponentPatch); -+ return org.leavesmc.leaves.util.ItemOverstackUtils.decodeMaxStackSize(itemStack); - } - } - -@@ -209,13 +210,15 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher c.itemStack(value))) { // pass the itemstack as context to the obfuscation session -+ try (final io.papermc.paper.util.SafeAutoClosable ignored = io.papermc.paper.util.sanitizer.ItemObfuscationSession.withContext(c -> c.itemStack(itemStack))) { // pass the itemstack as context to the obfuscation session - net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(true); -- codec.encode(buffer, value.components.asPatch()); -+ codec.encode(buffer, itemStack.components.asPatch()); - } finally { - net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(prev); - } -@@ -309,7 +312,7 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher maxStackSize) { - return DataResult.error(() -> "Item stack with count of " + count + " was larger than maximum: " + maxStackSize); - } -diff --git a/net/minecraft/world/level/block/CrafterBlock.java b/net/minecraft/world/level/block/CrafterBlock.java -index c5fe15844d405a27cdae18c903dd481c25b437de..3faa541c4a4623e915269d6241e1a3a3c6e374ff 100644 ---- a/net/minecraft/world/level/block/CrafterBlock.java -+++ b/net/minecraft/world/level/block/CrafterBlock.java -@@ -191,7 +191,7 @@ public class CrafterBlock extends BaseEntityBlock { - Direction direction = state.getValue(ORIENTATION).front(); - Container containerAt = HopperBlockEntity.getContainerAt(level, pos.relative(direction)); - ItemStack itemStack = stack.copy(); -- if (containerAt != null && (containerAt instanceof CrafterBlockEntity || stack.getCount() > containerAt.getMaxStackSize(stack))) { -+ if (containerAt != null && (containerAt instanceof CrafterBlockEntity || stack.getCount() > containerAt.getMaxStackLeaves(stack))) { // Leaves - item over-stack util - // CraftBukkit start - InventoryMoveItemEvent - org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack); - -diff --git a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index 9346f2deca8eeca29fa2fced416247fd1609249e..07236e86638faa3231917af507cdd37ac49b1270 100644 ---- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -+++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -412,7 +412,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit - ItemStack itemStack = this.items.get(index); - boolean flag = !stack.isEmpty() && ItemStack.isSameItemSameComponents(itemStack, stack); - this.items.set(index, stack); -- stack.limitSize(this.getMaxStackSize(stack)); -+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util - if (index == 0 && !flag && this.level instanceof ServerLevel serverLevel) { - this.cookingTotalTime = getTotalCookTime(serverLevel, this, this.recipeType, this.cookSpeedMultiplier); // Paper - cook speed multiplier API - this.cookingTimer = 0; -diff --git a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java -index 8f80c469c309bf61328c4f98037495f47a38c3c1..b4127d4b4386b98205275a9a0ef8067ccf287e67 100644 ---- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java -+++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java -@@ -134,7 +134,7 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co - @Override - public void setItem(int slot, ItemStack stack) { - this.getItems().set(slot, stack); -- stack.limitSize(this.getMaxStackSize(stack)); -+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util - this.setChanged(); - } - -diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index 53c50d776e5ca66e5903a464d763a7df5b7672be..6cdb59762b5b223a220d420ff99fa9eadc64f3e0 100644 ---- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java -+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java -@@ -145,7 +145,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - public void setItem(int index, ItemStack stack) { - this.unpackLootTable(null); - this.getItems().set(index, stack); -- stack.limitSize(this.getMaxStackSize(stack)); -+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util - } - - @Override -@@ -741,9 +741,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - if (item.isEmpty()) { - // Spigot start - SPIGOT-6693, SimpleContainer#setItem - ItemStack leftover = ItemStack.EMPTY; // Paper - Make hoppers respect inventory max stack size -- if (!stack.isEmpty() && stack.getCount() > destination.getMaxStackSize()) { -+ if (!stack.isEmpty() && (stack.getCount() > destination.getMaxStackSize() || stack.getCount() > stack.getMaxStackSize())) { // Leaves - item over-stack util - leftover = stack; // Paper - Make hoppers respect inventory max stack size -- stack = stack.split(destination.getMaxStackSize()); -+ stack = stack.split(Math.min(destination.getMaxStackSize(), stack.getMaxStackSize())); // Leaves - item over-stack util - } - // Spigot end - //IGNORE_TILE_UPDATES.set(Boolean.TRUE); // Paper - Perf: Optimize Hoppers // Folia - region threading // Luminol - vanilla hopper diff --git a/gradle.properties b/gradle.properties index 09bb64c..86a74ee 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ weightVersion=2.0.12 # 0 for skip release, 1 for pre-release, 2 for release release=0 -luminolRef=fdc658896ce6920a57d118c929646e0740d9ddd2 +luminolRef=c85c062a3b0679ae4ad2fdf86dd51719a6d42be5 org.gradle.configuration-cache=true org.gradle.caching=true diff --git a/lophine-server/luminol-patches/features/0003-Leaves-Item-overstack-util.patch b/lophine-server/luminol-patches/features/0003-Leaves-Item-overstack-util.patch new file mode 100644 index 0000000..377a4b8 --- /dev/null +++ b/lophine-server/luminol-patches/features/0003-Leaves-Item-overstack-util.patch @@ -0,0 +1,190 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Helvetica Volubi +Date: Wed, 13 Aug 2025 22:23:46 +0800 +Subject: [PATCH] Leaves: Item overstack util + + +diff --git a/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java b/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java +index a5df7e40369cf2c309f4d37fede6615f34a467e2..84d0e1a7cd687ac4ed9f1bf824ca28940c2fab1e 100644 +--- a/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java ++++ b/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java +@@ -17,10 +17,98 @@ + + package org.leavesmc.leaves.util; + ++import fun.bm.lophine.config.modules.function.ContainerExpansionConfig; ++import net.minecraft.core.component.DataComponents; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.world.entity.item.ItemEntity; ++import net.minecraft.world.item.BlockItem; + import net.minecraft.world.item.ItemStack; ++import net.minecraft.world.item.component.CustomData; ++import net.minecraft.world.item.component.ItemContainerContents; ++import net.minecraft.world.level.block.ShulkerBoxBlock; ++import org.jetbrains.annotations.NotNull; ++ ++import java.util.List; ++import java.util.Objects; ++import java.util.Optional; + + // Only used part of the original code was copied + public class ItemOverstackUtils { ++ ++ private static final List overstackUtils = List.of( ++ new ShulkerBox() ++ ); ++ ++ public static int getItemStackMaxCount(ItemStack stack) { ++ int size; ++ for (ItemUtil util : overstackUtils) { ++ if (util.isEnabled() && (size = util.getMaxServerStackCount(stack)) != -1) { ++ return size; ++ } ++ } ++ return stack.getMaxStackSize(); ++ } ++ ++ public static int getNetworkMaxCount(ItemStack stack) { ++ int size; ++ for (ItemUtil util : overstackUtils) { ++ if (util.isEnabled() && (size = util.getMaxClientStackCount(stack)) != -1) { ++ return size; ++ } ++ } ++ return stack.getMaxStackSize(); ++ } ++ ++ public static boolean tryStackItems(ItemEntity self, ItemEntity other) { ++ for (ItemUtil util : overstackUtils) { ++ if (util.isEnabled() && util.tryStackItems(self, other)) { ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ public static boolean hasOverstackingItem() { ++ for (ItemUtil util : overstackUtils) { ++ if (util.isEnabled()) { ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ public static int getItemStackMaxCountReal(ItemStack stack) { ++ CompoundTag nbt = Optional.ofNullable(stack.get(DataComponents.CUSTOM_DATA)).orElse(CustomData.EMPTY).copyTag(); ++ return nbt.getInt("Leaves.RealStackSize").orElse(stack.getMaxStackSize()); ++ } ++ ++ public static ItemStack encodeMaxStackSize(ItemStack itemStack) { ++ int realMaxStackSize = getItemStackMaxCountReal(itemStack); ++ int modifiedMaxStackSize = getNetworkMaxCount(itemStack); ++ if (itemStack.getMaxStackSize() != modifiedMaxStackSize) { ++ itemStack.set(DataComponents.MAX_STACK_SIZE, modifiedMaxStackSize); ++ CompoundTag nbt = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag(); ++ nbt.putInt("Leaves.RealStackSize", realMaxStackSize); ++ itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(nbt)); ++ } ++ return itemStack; ++ } ++ ++ public static ItemStack decodeMaxStackSize(ItemStack itemStack) { ++ int realMaxStackSize = getItemStackMaxCountReal(itemStack); ++ if (itemStack.getMaxStackSize() != realMaxStackSize) { ++ itemStack.set(DataComponents.MAX_STACK_SIZE, realMaxStackSize); ++ CompoundTag nbt = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag(); ++ nbt.remove("Leaves.RealStackSize"); ++ if (nbt.isEmpty()) { ++ itemStack.remove(DataComponents.CUSTOM_DATA); ++ } else { ++ itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(nbt)); ++ } ++ } ++ return itemStack; ++ } ++ + public static float getItemStackSignalStrength(int maxStackSize, ItemStack itemStack) { + float result = (float) itemStack.getCount() / Math.min(maxStackSize, itemStack.getMaxStackSize()); + /*if (LeavesConfig.modify.oldMC.allowGrindstoneOverstacking && CurseEnchantedBook.isCursedEnchantedBook(itemStack)) { // Luminol +@@ -28,4 +116,80 @@ public class ItemOverstackUtils { + }*/ // Luminol + return Math.clamp(result, 0f, 1f); + } ++ ++ public static boolean isStackable(ItemStack itemStack) { ++ return getItemStackMaxCount(itemStack) > 1 && (!itemStack.isDamageableItem() || !itemStack.isDamaged()); ++ } ++ ++ private interface ItemUtil { ++ boolean isEnabled(); ++ ++ boolean tryStackItems(ItemEntity self, ItemEntity other); ++ ++ // number -> modified count, -1 -> I don't care ++ int getMaxServerStackCount(ItemStack stack); ++ ++ // number -> modified count, -1 -> I don't care ++ default int getMaxClientStackCount(ItemStack stack) { ++ return getMaxServerStackCount(stack); ++ } ++ } ++ ++ private static class ShulkerBox implements ItemUtil { ++ public static boolean shulkerBoxCheck(@NotNull ItemStack stack1, @NotNull ItemStack stack2) { ++ if (ContainerExpansionConfig.nbtShulkerStackable) { ++ return Objects.equals(stack1.getComponents(), stack2.getComponents()); ++ } ++ return shulkerBoxNoItem(stack1) && shulkerBoxNoItem(stack2) && Objects.equals(stack1.getComponents(), stack2.getComponents()); ++ } ++ ++ public static boolean shulkerBoxNoItem(@NotNull ItemStack stack) { ++ // Leaves - Paper 26.1: ItemContainerContents#stream() removed, use nonEmptyItemCopyStream() ++ return stack.getComponents().getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).nonEmptyItemCopyStream().findAny().isEmpty(); ++ } ++ ++ @Override ++ public boolean isEnabled() { ++ return ContainerExpansionConfig.shulkerCount > 1; ++ } ++ ++ @Override ++ public boolean tryStackItems(ItemEntity self, ItemEntity other) { ++ ItemStack selfStack = self.getItem(); ++ if (!(selfStack.getItem() instanceof BlockItem blockItem) || !(blockItem.getBlock() instanceof ShulkerBoxBlock)) { ++ return false; ++ } ++ ++ ItemStack otherStack = other.getItem(); ++ if (selfStack.getItem() == otherStack.getItem() ++ && shulkerBoxCheck(selfStack, otherStack) ++ && selfStack.getCount() != ContainerExpansionConfig.shulkerCount) { ++ int amount = Math.min(otherStack.getCount(), ContainerExpansionConfig.shulkerCount - selfStack.getCount()); ++ ++ selfStack.grow(amount); ++ self.setItem(selfStack); ++ ++ self.pickupDelay = Math.max(other.pickupDelay, self.pickupDelay); ++ self.age = Math.min(other.getAge(), self.age); ++ ++ otherStack.shrink(amount); ++ if (otherStack.isEmpty()) { ++ other.discard(); ++ } else { ++ other.setItem(otherStack); ++ } ++ return true; ++ } ++ return false; ++ } ++ ++ @Override ++ public int getMaxServerStackCount(ItemStack stack) { ++ if (stack.getItem() instanceof BlockItem bi && ++ bi.getBlock() instanceof ShulkerBoxBlock && (ContainerExpansionConfig.nbtShulkerStackable || shulkerBoxNoItem(stack))) { ++ return ContainerExpansionConfig.shulkerCount; ++ } ++ return -1; ++ } ++ } + } diff --git a/lophine-server/minecraft-patches/features/0013-Leaves-Item-overstack-util.patch b/lophine-server/minecraft-patches/features/0013-Leaves-Item-overstack-util.patch new file mode 100644 index 0000000..8a1b6e0 --- /dev/null +++ b/lophine-server/minecraft-patches/features/0013-Leaves-Item-overstack-util.patch @@ -0,0 +1,466 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Helvetica Volubi +Date: Sat, 26 Jul 2025 01:11:54 +0800 +Subject: [PATCH] Leaves: Item overstack util + +Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com> +As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/f3784ec0525069a37e9ab8921b196f5533edbd56/leaves-server/minecraft-patches/features/0118-Item-overstack-util.patch) +Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html) + +diff --git a/net/minecraft/commands/arguments/item/ItemInput.java b/net/minecraft/commands/arguments/item/ItemInput.java +index 28aab52fb14e9086d81dd7a3fa32e7f12136d53a..1f033b970be82b0bdb4e51b6e1c5bb03170066ae 100644 +--- a/net/minecraft/commands/arguments/item/ItemInput.java ++++ b/net/minecraft/commands/arguments/item/ItemInput.java +@@ -20,8 +20,10 @@ public record ItemInput(Holder item, DataComponentPatch components) { + + public ItemStack createItemStack(final int count) throws CommandSyntaxException { + ItemStack result = new ItemStack(this.item, count, this.components); +- if (count > result.getMaxStackSize()) { +- throw ERROR_STACK_TOO_BIG.create(this.item.getRegisteredName(), result.getMaxStackSize()); ++ // Leaves start - item over-stack util ++ if (count > org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(result)) { ++ throw ERROR_STACK_TOO_BIG.create(this.item.getRegisteredName(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(result)); ++ // Leaves end - item over-stack util + } else { + DataResult validationResult = ItemStack.validateStrict(result); + return validationResult.getOrThrow(ERROR_MALFORMED_ITEM::create); +diff --git a/net/minecraft/server/commands/GiveCommand.java b/net/minecraft/server/commands/GiveCommand.java +index c147a1acd4fd9f94c73bee69febf651ca00c28ce..f8004bf74edeabce871515fb73fa00f331941dca 100644 +--- a/net/minecraft/server/commands/GiveCommand.java ++++ b/net/minecraft/server/commands/GiveCommand.java +@@ -47,7 +47,7 @@ public class GiveCommand { + + private static int giveItem(final CommandSourceStack source, final ItemInput input, final Collection players, final int count) throws CommandSyntaxException { + ItemStack prototypeItemStack = input.createItemStack(1); +- int maxStackSize = prototypeItemStack.getMaxStackSize(); ++ int maxStackSize = org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(prototypeItemStack); // Leaves - item over-stack util + int maxAllowedCount = maxStackSize * 100; + if (count > maxAllowedCount) { + source.sendFailure(Component.translatable("commands.give.failed.toomanyitems", maxAllowedCount, prototypeItemStack.getDisplayName())); +diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index 47beff71ed33e7fbd6fe6cd47aa955233af41f04..8e5b79db12882432de575f2a76aa36eac6fc8f51 100644 +--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -3229,7 +3229,7 @@ public class ServerGamePacketListenerImpl + } else if (slot.mayPlace(cursor)) { + if (ItemStack.isSameItemSameComponents(clickedItem, cursor)) { + int toPlace = packet.buttonNum() == 0 ? cursor.getCount() : 1; +- toPlace = Math.min(toPlace, clickedItem.getMaxStackSize() - clickedItem.getCount()); ++ toPlace = Math.min(toPlace, org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(clickedItem) - clickedItem.getCount()); // Leaves - item over-stack util + toPlace = Math.min(toPlace, slot.container.getMaxStackSize() - clickedItem.getCount()); + if (toPlace == 1) { + action = InventoryAction.PLACE_ONE; +@@ -3265,7 +3265,7 @@ public class ServerGamePacketListenerImpl + } + } else if (ItemStack.isSameItemSameComponents(cursor, clickedItem)) { + if (clickedItem.getCount() >= 0) { +- if (clickedItem.getCount() + cursor.getCount() <= cursor.getMaxStackSize()) { ++ if (clickedItem.getCount() + cursor.getCount() <= org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(cursor)) { // Leaves - item over-stack util + // As of 1.5, this is result slots only + action = InventoryAction.PICKUP_ALL; + } +@@ -3482,6 +3482,7 @@ public class ServerGamePacketListenerImpl + this.player.containerMenu.broadcastFullState(); + } else { + this.player.containerMenu.broadcastChanges(); ++ if (org.leavesmc.leaves.util.ItemOverstackUtils.hasOverstackingItem()) this.player.containerMenu.broadcastCarriedItem(); // Leaves - item over-stack util - force send carried item + } + if (packet.buttonNum() == Inventory.SLOT_OFFHAND && this.player.containerMenu != this.player.inventoryMenu) this.player.containerSynchronizer.sendOffHandSlotChange(); // Paper - update offhand data when the player is clicking in an inventory not their own as the sychronizer does not include offhand slots + if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes. +@@ -3593,7 +3594,7 @@ public class ServerGamePacketListenerImpl + } + + boolean validSlot = packet.slotNum() >= 1 && packet.slotNum() <= 45; +- boolean validData = itemStack.isEmpty() || itemStack.getCount() <= itemStack.getMaxStackSize(); ++ boolean validData = itemStack.isEmpty() || itemStack.getCount() <= org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack); // Leaves - item over-stack util + if (drop || (validSlot && !ItemStack.matches(this.player.inventoryMenu.getSlot(packet.slotNum()).getItem(), packet.itemStack()))) { // Insist on valid slot + // CraftBukkit start - Call click event + org.bukkit.inventory.InventoryView inventory = this.player.inventoryMenu.getBukkitView(); +@@ -3635,6 +3636,7 @@ public class ServerGamePacketListenerImpl + this.player.inventoryMenu.getSlot(packet.slotNum()).setByPlayer(itemStack); + this.player.inventoryMenu.setRemoteSlot(packet.slotNum(), itemStack); + this.player.inventoryMenu.broadcastChanges(); ++ if (org.leavesmc.leaves.util.ItemOverstackUtils.hasOverstackingItem()) this.player.containerMenu.sendSingleSlot(packet.slotNum(), itemStack); // Leaves - item over-stack util - force send carried item + if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes. + } else if (drop && validData) { + if (this.dropSpamThrottler.isUnderThreshold()) { +diff --git a/net/minecraft/world/Container.java b/net/minecraft/world/Container.java +index 54d99625cfec60530e8a3288871e6dc21e179b2d..2a1c1bd2e9c326b7298978cec1fe13112e670d33 100644 +--- a/net/minecraft/world/Container.java ++++ b/net/minecraft/world/Container.java +@@ -38,6 +38,12 @@ public interface Container extends Clearable, Iterable, SlotProvider, + return Math.min(this.getMaxStackSize(), itemStack.getMaxStackSize()); + } + ++ // Leaves start - item over-stack util ++ default int getMaxStackLeaves(final ItemStack stack) { ++ return Math.min(this.getMaxStackSize(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack)); ++ } ++ // Leaves end - item over-stack util ++ + void setChanged(); + + boolean stillValid(Player player); +diff --git a/net/minecraft/world/SimpleContainer.java b/net/minecraft/world/SimpleContainer.java +index 21f576bb39bfd78dca87606ba3a044db8e13e28e..049c6ab6472415479435f2caab0444c3cbd33902 100644 +--- a/net/minecraft/world/SimpleContainer.java ++++ b/net/minecraft/world/SimpleContainer.java +@@ -193,7 +193,7 @@ public class SimpleContainer implements Container, StackedContentsCompatible { + @Override + public void setItem(final int slot, final ItemStack itemStack) { + this.items.set(slot, itemStack); +- itemStack.limitSize(this.getMaxStackSize(itemStack)); ++ itemStack.limitSize(this.getMaxStackLeaves(itemStack)); // Leaves - item over-stack util + this.setChanged(); + } + +@@ -263,7 +263,7 @@ public class SimpleContainer implements Container, StackedContentsCompatible { + } + + private void moveItemsBetweenStacks(final ItemStack sourceStack, final ItemStack targetStack) { +- int maxCount = this.getMaxStackSize(targetStack); ++ int maxCount = this.getMaxStackLeaves(targetStack); // Leaves - item over-stack util + int diff = Math.min(sourceStack.getCount(), maxCount - targetStack.getCount()); + if (diff > 0) { + targetStack.grow(diff); +diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java +index 44b06b1585e7630fa17d8dfb01f737b14efebcbc..679a941a2af886697fbfcbc7f21e5f4e0ec77dc3 100644 +--- a/net/minecraft/world/entity/item/ItemEntity.java ++++ b/net/minecraft/world/entity/item/ItemEntity.java +@@ -280,10 +280,15 @@ public class ItemEntity extends Entity implements TraceableEntity, ChangePublish + + private boolean isMergable() { + ItemStack item = this.getItem(); +- return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < this.despawnRate && item.getCount() < item.getMaxStackSize(); // Paper - Alternative item-despawn-rate ++ return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < this.despawnRate && item.getCount() < org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(item); // Paper - Alternative item-despawn-rate // Leaves - item over-stack util + } + + private void tryToMerge(final ItemEntity other) { ++ // Leaves start - item over-stack util ++ if (org.leavesmc.leaves.util.ItemOverstackUtils.tryStackItems(this, other)) { ++ return; ++ } ++ // Leaves end - item over-stack util + ItemStack thisItemStack = this.getItem(); + ItemStack otherItemStack = other.getItem(); + if (Objects.equals(this.target, other.target) && areMergable(thisItemStack, otherItemStack)) { +diff --git a/net/minecraft/world/entity/player/Inventory.java b/net/minecraft/world/entity/player/Inventory.java +index da8bab81e135a9b240fbeac0e9e1d2aa12c6212d..4711bfe454dbb9925531f61554fbf110dfe596fd 100644 +--- a/net/minecraft/world/entity/player/Inventory.java ++++ b/net/minecraft/world/entity/player/Inventory.java +@@ -166,10 +166,12 @@ public class Inventory implements Container, Nameable { + } + + private boolean hasRemainingSpaceForItem(final ItemStack slotItemStack, final ItemStack newItemStack) { ++ // Leaves start - item over-stack util + return !slotItemStack.isEmpty() +- && slotItemStack.isStackable() +- && slotItemStack.getCount() < this.getMaxStackSize(slotItemStack) ++ && org.leavesmc.leaves.util.ItemOverstackUtils.isStackable(slotItemStack) ++ && slotItemStack.getCount() < org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(slotItemStack) + && ItemStack.isSameItemSameComponents(slotItemStack, newItemStack); // Paper - check if itemstack is stackable first ++ // Leaves end - item over-stack util + } + + // CraftBukkit start - Watch method above! :D +@@ -182,7 +184,7 @@ public class Inventory implements Container, Nameable { + } + + if (this.hasRemainingSpaceForItem(itemInSlot, itemStack)) { +- remains -= (itemInSlot.getMaxStackSize() < this.getMaxStackSize() ? itemInSlot.getMaxStackSize() : this.getMaxStackSize()) - itemInSlot.getCount(); ++ remains -= (org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInSlot) < this.getMaxStackSize() ? org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInSlot) : this.getMaxStackSize()) - itemInSlot.getCount(); // Leaves - item over-stack util + } + if (remains <= 0) { + return itemStack.getCount(); +@@ -191,7 +193,7 @@ public class Inventory implements Container, Nameable { + + ItemStack itemInOffhand = this.equipment.get(EquipmentSlot.OFFHAND); + if (this.hasRemainingSpaceForItem(itemInOffhand, itemStack)) { +- remains -= (itemInOffhand.getMaxStackSize() < this.getMaxStackSize() ? itemInOffhand.getMaxStackSize() : this.getMaxStackSize()) - itemInOffhand.getCount(); ++ remains -= (org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInOffhand) < this.getMaxStackSize() ? org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInOffhand) : this.getMaxStackSize()) - itemInOffhand.getCount(); // Leaves - item over-stack util + } + if (remains <= 0) { + return itemStack.getCount(); +@@ -315,7 +317,7 @@ public class Inventory implements Container, Nameable { + this.setItem(slot, itemStackInSlot); + } + +- int maxToAdd = this.getMaxStackSize(itemStackInSlot) - itemStackInSlot.getCount(); ++ int maxToAdd = this.getMaxStackLeaves(itemStackInSlot) - itemStackInSlot.getCount(); // Leaves - item over-stack util + int toAdd = Math.min(count, maxToAdd); + if (toAdd == 0) { + return count; +@@ -421,7 +423,7 @@ public class Inventory implements Container, Nameable { + break; + } + +- int slotHasSpaceFor = itemStack.getMaxStackSize() - this.getItem(slot).getCount(); ++ int slotHasSpaceFor = org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack) - this.getItem(slot).getCount(); // Leaves - item over-stack util + if (this.add(slot, itemStack.split(slotHasSpaceFor)) && shouldSendSetSlotPacket && this.player instanceof ServerPlayer serverPlayer) { + serverPlayer.connection.send(this.createInventoryUpdatePacket(slot)); + } +diff --git a/net/minecraft/world/entity/player/StackedItemContents.java b/net/minecraft/world/entity/player/StackedItemContents.java +index ffaa8e450a11a01060b6847d1b66a76323f9d8ba..4419eb2996639c7d60b96204b4ded9d8883c8016 100644 +--- a/net/minecraft/world/entity/player/StackedItemContents.java ++++ b/net/minecraft/world/entity/player/StackedItemContents.java +@@ -18,7 +18,7 @@ public class StackedItemContents { + } + + public void accountStack(final ItemStack itemStack) { +- this.accountStack(itemStack, itemStack.getMaxStackSize()); ++ this.accountStack(itemStack, org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack)); // Leaves - item over-stack util + } + + public void accountStack(final ItemStack itemStack, final int maxCount) { +diff --git a/net/minecraft/world/entity/vehicle/ContainerEntity.java b/net/minecraft/world/entity/vehicle/ContainerEntity.java +index 9c9a08752b54222e8ac8d9a38c7a28a775bd1164..42716cf2c864eba50628dc64c59ab29c1d51dc9b 100644 +--- a/net/minecraft/world/entity/vehicle/ContainerEntity.java ++++ b/net/minecraft/world/entity/vehicle/ContainerEntity.java +@@ -161,7 +161,7 @@ public interface ContainerEntity extends Container, MenuProvider { + default void setChestVehicleItem(final int slot, final ItemStack itemStack) { + this.unpackChestVehicleLootTable(null); + this.getItemStacks().set(slot, itemStack); +- itemStack.limitSize(this.getMaxStackSize(itemStack)); ++ itemStack.limitSize(this.getMaxStackLeaves(itemStack)); // Leaves - item over-stack util + } + + default @Nullable SlotAccess getChestVehicleSlot(final int slot) { +diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java +index 4a177b4e714ba52cc18024d1233c9425afb93741..fa1f7dd22959632aaa54e72c8caf13ea072e7ca7 100644 +--- a/net/minecraft/world/inventory/AbstractContainerMenu.java ++++ b/net/minecraft/world/inventory/AbstractContainerMenu.java +@@ -294,6 +294,14 @@ public abstract class AbstractContainerMenu { + this.sendAllDataToRemote(); + } + ++ // Leaves start - item over-stack util ++ public void sendSingleSlot(final int slotIndex, final ItemStack item) { ++ if (this.synchronizer != null) { ++ this.synchronizer.sendSlotChange(this, slotIndex, item); ++ } ++ } ++ // Leaves end - item over-stack util ++ + private void updateDataSlotListeners(final int id, final int currentValue) { + for (ContainerListener containerListener : this.containerListeners) { + containerListener.dataChanged(this, id, currentValue); +@@ -450,7 +458,7 @@ public abstract class AbstractContainerMenu { + && (this.quickcraftType == QUICKCRAFT_TYPE_CLONE || carriedItemStack.getCount() >= this.quickcraftSlots.size()) + && this.canDragTo(slot)) { + int carry = slot.hasItem() ? slot.getItem().getCount() : 0; +- int maxSize = Math.min(source.getMaxStackSize(), slot.getMaxStackSize(source)); ++ int maxSize = Math.min(org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(source), slot.getMaxStackSize(source)); // Leaves - item over-stack util + int newCount = Math.min(getQuickCraftPlaceCount(this.quickcraftSlots.size(), this.quickcraftType, source) + carry, maxSize); + remaining -= newCount - carry; + // slot.setByPlayer(source.copyWithCount(newCount)); +@@ -558,7 +566,7 @@ public abstract class AbstractContainerMenu { + slotx.setByPlayer(carried); + } + } else if (ItemStack.isSameItemSameComponents(clicked, carried)) { +- Optional newCarried = slotx.tryRemove(clicked.getCount(), carried.getMaxStackSize() - carried.getCount(), player); ++ Optional newCarried = slotx.tryRemove(clicked.getCount(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(carried) - carried.getCount(), player); // Leaves - item over-stack util + newCarried.ifPresent(itemsTaken -> { + carried.grow(itemsTaken.getCount()); + slotx.onTake(player, itemsTaken); +@@ -620,7 +628,7 @@ public abstract class AbstractContainerMenu { + Slot slotx = this.slots.get(slotIndex); + if (slotx.hasItem()) { + ItemStack item = slotx.getItem(); +- this.setCarried(item.copyWithCount(item.getMaxStackSize())); ++ this.setCarried(item.copyWithCount(org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(item))); // Leaves - item over-stack util + } + } else if (containerInput == ContainerInput.THROW && this.getCarried().isEmpty() && slotIndex >= 0) { + Slot slotx = this.slots.get(slotIndex); +@@ -655,15 +663,15 @@ public abstract class AbstractContainerMenu { + int step = buttonNum == 0 ? 1 : -1; + + for (int pass = 0; pass < 2; pass++) { +- for (int i = start; i >= 0 && i < this.slots.size() && carried.getCount() < carried.getMaxStackSize(); i += step) { ++ for (int i = start; i >= 0 && i < this.slots.size() && carried.getCount() < org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(carried); i += step) { // Leaves - item over-stack util + Slot target = this.slots.get(i); + if (target.hasItem() + && canItemQuickReplace(target, carried, true) + && target.mayPickup(player) + && this.canTakeItemForPickAll(carried, target)) { + ItemStack itemStack = target.getItem(); +- if (pass != 0 || itemStack.getCount() != itemStack.getMaxStackSize()) { +- ItemStack removed = target.safeTake(itemStack.getCount(), carried.getMaxStackSize() - carried.getCount(), player); ++ if (pass != 0 || itemStack.getCount() != org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack)) { // Leaves - item over-stack util ++ ItemStack removed = target.safeTake(itemStack.getCount(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(carried) - carried.getCount(), player); // Leaves - item over-stack util + carried.grow(removed.getCount()); + } + } +@@ -770,7 +778,7 @@ public abstract class AbstractContainerMenu { + destSlot = endSlot - 1; + } + +- if (itemStack.isStackable()) { ++ if (org.leavesmc.leaves.util.ItemOverstackUtils.isStackable(itemStack)) { // Leaves - item over-stack util + while (!itemStack.isEmpty() && (backwards ? destSlot >= startSlot : destSlot < endSlot)) { + Slot slot = this.slots.get(destSlot); + ItemStack target = slot.getItem(); +@@ -871,7 +879,7 @@ public abstract class AbstractContainerMenu { + public static boolean canItemQuickReplace(final @Nullable Slot slot, final ItemStack itemStack, final boolean ignoreSize) { + boolean slotIsEmpty = slot == null || !slot.hasItem(); + return !slotIsEmpty && ItemStack.isSameItemSameComponents(itemStack, slot.getItem()) +- ? slot.getItem().getCount() + (ignoreSize ? 0 : itemStack.getCount()) <= itemStack.getMaxStackSize() ++ ? slot.getItem().getCount() + (ignoreSize ? 0 : itemStack.getCount()) <= org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack) // Leaves - item over-stack util + : slotIsEmpty; + } + +@@ -879,7 +887,7 @@ public abstract class AbstractContainerMenu { + return switch (quickCraftingType) { + case 0 -> Mth.floor((float)itemStack.getCount() / quickCraftSlotsSize); + case 1 -> 1; +- case 2 -> itemStack.getMaxStackSize(); ++ case 2 -> org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack); // Leaves - item over-stack util + default -> itemStack.getCount(); + }; + } +@@ -902,7 +910,7 @@ public abstract class AbstractContainerMenu { + for (int i = 0; i < container.getContainerSize(); i++) { + ItemStack itemStack = container.getItem(i); + if (!itemStack.isEmpty()) { +- totalPercent += (float)itemStack.getCount() / container.getMaxStackSize(itemStack); ++ totalPercent += org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackSignalStrength(container.getMaxStackSize(), itemStack); // Leaves - item over-stack util + } + } + +diff --git a/net/minecraft/world/inventory/MerchantContainer.java b/net/minecraft/world/inventory/MerchantContainer.java +index e1b1a261a5f7a3702c1788daa38e7d367195382e..cb95fa63c585b1c3859bfd3e5d4d0e5dd84c7f0d 100644 +--- a/net/minecraft/world/inventory/MerchantContainer.java ++++ b/net/minecraft/world/inventory/MerchantContainer.java +@@ -108,7 +108,7 @@ public class MerchantContainer implements Container { + @Override + public void setItem(final int slot, final ItemStack itemStack) { + this.itemStacks.set(slot, itemStack); +- itemStack.limitSize(this.getMaxStackSize(itemStack)); ++ itemStack.limitSize(this.getMaxStackLeaves(itemStack)); // Leaves - item over-stack util + if (this.isPaymentSlot(slot)) { + this.updateSellItem(); + } +diff --git a/net/minecraft/world/inventory/Slot.java b/net/minecraft/world/inventory/Slot.java +index ee86a63c8d0d4c798ad09da87598d22c0e516840..57061d97bd368bfe934157293471fd546bb105ee 100644 +--- a/net/minecraft/world/inventory/Slot.java ++++ b/net/minecraft/world/inventory/Slot.java +@@ -75,7 +75,7 @@ public class Slot { + } + + public int getMaxStackSize(final ItemStack itemStack) { +- return Math.min(this.getMaxStackSize(), itemStack.getMaxStackSize()); ++ return Math.min(this.getMaxStackSize(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack)); // Leaves - item over-stack util + } + + public @Nullable Identifier getNoItemIcon() { +diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java +index fa588ab87f978b8aeaef0f1849aa532e5a4ad940..dd4a92a0ea94d16669535bde9b6728515dafe7f4 100644 +--- a/net/minecraft/world/item/ItemStack.java ++++ b/net/minecraft/world/item/ItemStack.java +@@ -160,7 +160,7 @@ public final class ItemStack implements DataComponentHolder, ItemInstance, Chang + private int popTime; + @Deprecated + private @Nullable Holder item; +- private PatchedDataComponentMap components; ++ public PatchedDataComponentMap components; // Leaves - item over-stack util + + public static DataResult validateStrict(final ItemStack itemStack) { + DataResult result = validateComponents(itemStack.getComponents()); +@@ -185,7 +185,8 @@ public final class ItemStack implements DataComponentHolder, ItemInstance, Chang + } else { + Holder item = Item.STREAM_CODEC.decode(input); + DataComponentPatch patch = patchCodec.decode(input); +- return new ItemStack(item, count, patch); ++ ItemStack stack = new ItemStack(item, count, patch); ++ return org.leavesmc.leaves.util.ItemOverstackUtils.decodeMaxStackSize(stack); // Leaves - item over-stack util + } + } + +@@ -194,17 +195,20 @@ public final class ItemStack implements DataComponentHolder, ItemInstance, Chang + if (itemStack.isEmpty() || itemStack.getItem() == null) { // CraftBukkit - NPE fix itemstack.getItem() + output.writeVarInt(0); + } else { +- output.writeVarInt(io.papermc.paper.util.sanitizer.ItemComponentSanitizer.sanitizeCount(io.papermc.paper.util.sanitizer.ItemObfuscationSession.currentSession(), itemStack, itemStack.getCount())); // Paper - potentially sanitize count +- Item.STREAM_CODEC.encode(output, itemStack.typeHolder()); ++ // Leaves start - item over-stack util ++ final ItemStack encodedStack = org.leavesmc.leaves.util.ItemOverstackUtils.encodeMaxStackSize(itemStack.copy()); ++ output.writeVarInt(io.papermc.paper.util.sanitizer.ItemComponentSanitizer.sanitizeCount(io.papermc.paper.util.sanitizer.ItemObfuscationSession.currentSession(), encodedStack, encodedStack.getCount())); // Paper - potentially sanitize count ++ Item.STREAM_CODEC.encode(output, encodedStack.typeHolder()); + // Paper start - adventure; conditionally render translatable components + boolean prev = net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.get(); +- try (final io.papermc.paper.util.SafeAutoClosable ignored = io.papermc.paper.util.sanitizer.ItemObfuscationSession.withContext(c -> c.itemStack(itemStack))) { // pass the itemstack as context to the obfuscation session ++ try (final io.papermc.paper.util.SafeAutoClosable ignored = io.papermc.paper.util.sanitizer.ItemObfuscationSession.withContext(c -> c.itemStack(encodedStack))) { // pass the itemstack as context to the obfuscation session + net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(true); +- patchCodec.encode(output, itemStack.components.asPatch()); ++ patchCodec.encode(output, encodedStack.components.asPatch()); + } finally { + net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(prev); + } + // Paper end - adventure; conditionally render translatable components ++ // Leaves end - item over-stack util + } + } + }; +diff --git a/net/minecraft/world/level/block/CrafterBlock.java b/net/minecraft/world/level/block/CrafterBlock.java +index 15ed625105539f402fb39275b292531fe388a7a0..2b97fd6af1c4956eb173b8c66c2a3efc8772a798 100644 +--- a/net/minecraft/world/level/block/CrafterBlock.java ++++ b/net/minecraft/world/level/block/CrafterBlock.java +@@ -202,7 +202,7 @@ public class CrafterBlock extends BaseEntityBlock { + Direction direction = blockState.getValue(ORIENTATION).front(); + Container into = HopperBlockEntity.getContainerAt(level, pos.relative(direction)); + ItemStack remaining = results.copy(); +- if (into != null && (into instanceof CrafterBlockEntity || results.getCount() > into.getMaxStackSize(results))) { ++ if (into != null && (into instanceof CrafterBlockEntity || results.getCount() > into.getMaxStackLeaves(results))) { // Leaves - item over-stack util + // CraftBukkit start - InventoryMoveItemEvent + org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(remaining); + +diff --git a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +index 72a258f046c67c8970c91b8da31c0e745ec1e7ae..86a13f11fa6730f85add3e2ff47781d0fbcae170 100644 +--- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java ++++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +@@ -397,7 +397,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit + ItemStack oldStack = this.items.get(slot); + boolean same = !itemStack.isEmpty() && ItemStack.isSameItemSameComponents(oldStack, itemStack); + this.items.set(slot, itemStack); +- itemStack.limitSize(this.getMaxStackSize(itemStack)); ++ itemStack.limitSize(this.getMaxStackLeaves(itemStack)); // Leaves - item over-stack util + if (slot == 0 && !same && this.level instanceof ServerLevel serverLevel) { + this.cookingTotalTime = getTotalCookTime(serverLevel, this, this.recipeType, this.cookSpeedMultiplier); // Paper - cook speed multiplier API + this.cookingTimer = 0; +diff --git a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java +index 65ca3c97fdd60ebbdd366673c81c4375488f0cde..a7a13fb017a4c98db7639b8d672f3ad9d7814b7f 100644 +--- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java ++++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java +@@ -134,7 +134,7 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co + @Override + public void setItem(final int slot, final ItemStack itemStack) { + this.getItems().set(slot, itemStack); +- itemStack.limitSize(this.getMaxStackSize(itemStack)); ++ itemStack.limitSize(this.getMaxStackLeaves(itemStack)); // Leaves - item over-stack util + this.setChanged(); + } + +diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java +index 75a8c007ba710aa6e77ba3ed9ae5f7868894629d..d036018ee64995ee754296014888ee70c0ea5ab3 100644 +--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java ++++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java +@@ -155,7 +155,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + public void setItem(final int slot, final ItemStack itemStack) { + this.unpackLootTable(null); + this.getItems().set(slot, itemStack); +- itemStack.limitSize(this.getMaxStackSize(itemStack)); ++ itemStack.limitSize(this.getMaxStackLeaves(itemStack)); // Leaves - item over-stack util + } + + @Override +@@ -670,9 +670,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + if (current.isEmpty()) { + // Spigot start - SPIGOT-6693, SimpleContainer#setItem + ItemStack leftover = ItemStack.EMPTY; // Paper - Make hoppers respect inventory max stack size +- if (!itemStack.isEmpty() && itemStack.getCount() > container.getMaxStackSize()) { ++ if (!itemStack.isEmpty() && (itemStack.getCount() > container.getMaxStackSize() || itemStack.getCount() > itemStack.getMaxStackSize())) { // Leaves - item over-stack util + leftover = itemStack; // Paper - Make hoppers respect inventory max stack size +- itemStack = itemStack.split(container.getMaxStackSize()); ++ itemStack = itemStack.split(Math.min(container.getMaxStackSize(), itemStack.getMaxStackSize())); // Leaves - item over-stack util + } + // Spigot end + IGNORE_TILE_UPDATES.set(Boolean.TRUE); // Paper - Perf: Optimize Hoppers // Folia - region threading diff --git a/lophine-server/src/main/java/fun/bm/lophine/config/modules/function/ContainerExpansionConfig.java b/lophine-server/src/main/java/fun/bm/lophine/config/modules/function/ContainerExpansionConfig.java index acee30f..9cf11d8 100644 --- a/lophine-server/src/main/java/fun/bm/lophine/config/modules/function/ContainerExpansionConfig.java +++ b/lophine-server/src/main/java/fun/bm/lophine/config/modules/function/ContainerExpansionConfig.java @@ -23,12 +23,12 @@ public class ContainerExpansionConfig implements IConfigModule { range: 1~6""") public static int enderchestRows = 3; -// @CommandSuggestions(suggest = {"1", "2", "32", "64"}) -// @ConfigInfo(name = "shulker_stackable_count", directory = {"shulker_box"}, comments = -// """ -// range: 1~64""") -// public static int shulkerCount = 1; -// -// @ConfigInfo(name = "same_nbt_shulker_stackable", directory = {"shulker_box"}) -// public static boolean nbtShulkerStackable = false; + @CommandSuggestions(suggest = {"1", "2", "32", "64"}) + @ConfigInfo(name = "shulker_stackable_count", directory = {"shulker_box"}, comments = + """ + range: 1~64""") + public static int shulkerCount = 1; + + @ConfigInfo(name = "same_nbt_shulker_stackable", directory = {"shulker_box"}) + public static boolean nbtShulkerStackable = false; } \ No newline at end of file