From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: MrHua269 Date: Thu, 9 Jul 2026 11:54:24 +0800 Subject: [PATCH] Leaves Vanilla Hopper A part from leaves Origin patch link: https://github.com/LeavesMC/Leaves/blob/master/leaves-server/minecraft-patches/features/0092-Vanilla-hopper.patch Origin license: https://github.com/LeavesMC/Leaves/blob/master/LICENSE.md diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java index a858cb658af70f07614fa1f4d9e8a3435d5c161f..95f0b3276137cb9d1fc296e97cc25a08a5200c95 100644 --- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -281,36 +281,67 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen ItemStack movedItem = origItemStack; final int originalItemCount = origItemStack.getCount(); final int movedItemCount = Math.min(level.spigotConfig.hopperAmount, originalItemCount); - container.setChanged(); // original logic always marks source inv as changed even if no move happens. - movedItem.setCount(movedItemCount); - - if (!worldData.skipPullModeEventFire) { // Folia - region threading - movedItem = callPullMoveEvent(hopper, container, movedItem); - if (movedItem == null) { // cancelled - origItemStack.setCount(originalItemCount); - // Drastically improve performance by returning true. - // No plugin could have relied on the behavior of false as the other call - // site for IMIE did not exhibit the same behavior + // Leaves start - fix vanilla hopper + if (movedItem.getCount() <= movedItemCount) { + if (!worldData.skipPullModeEventFire) { + movedItem = callPullMoveEvent(hopper, container, movedItem); + if (movedItem == null) { // cancelled + origItemStack.setCount(originalItemCount); + container.setChanged(); // keep parity with vanilla: source inv always marked changed + return true; + } + } + final int toRemove = Math.min(movedItem.getCount(), container.getItem(i).getCount()); + final ItemStack remainingItem = addItem(container, hopper, container.removeItem(i, toRemove), null); + final int remainingItemCount = remainingItem.getCount(); + if (remainingItem.isEmpty()) { + container.setChanged(); return true; } - } - - final ItemStack remainingItem = addItem(container, hopper, movedItem, null); - final int remainingItemCount = remainingItem.getCount(); - if (remainingItemCount != movedItemCount) { - origItemStack = origItemStack.copy(true); - origItemStack.setCount(originalItemCount); - if (!origItemStack.isEmpty()) { - origItemStack.setCount(originalItemCount - movedItemCount + remainingItemCount); + if (remainingItemCount != toRemove) { + IGNORE_TILE_UPDATES.set(true); // Folia - region threading + container.setItem(i, remainingItem); + IGNORE_TILE_UPDATES.set(false); // Folia - region threading + container.setChanged(); + return true; } - IGNORE_TILE_UPDATES.set(true); // Folia - region threading - container.setItem(i, origItemStack); + container.setItem(i, remainingItem); IGNORE_TILE_UPDATES.set(false); // Folia - region threading container.setChanged(); - return true; + } else { + container.setChanged(); // original logic always marks source inv as changed even if no move happens. + movedItem.setCount(movedItemCount); + + if (!worldData.skipPullModeEventFire) { + movedItem = callPullMoveEvent(hopper, container, movedItem); + if (movedItem == null) { // cancelled + origItemStack.setCount(originalItemCount); + // Drastically improve performance by returning true. + // No plugin could have relied on the behavior of false as the other call + // site for IMIE did not exhibit the same behavior + return true; + } + } + + final ItemStack remainingItem = addItem(container, hopper, movedItem, null); + final int remainingItemCount = remainingItem.getCount(); + if (remainingItemCount != movedItemCount) { + origItemStack = origItemStack.copy(true); + origItemStack.setCount(originalItemCount); + if (!origItemStack.isEmpty()) { + origItemStack.setCount(originalItemCount - movedItemCount + remainingItemCount); + } + + IGNORE_TILE_UPDATES.set(true); + container.setItem(i, origItemStack); + IGNORE_TILE_UPDATES.set(false); + container.setChanged(); + return true; + } + origItemStack.setCount(originalItemCount); } - origItemStack.setCount(originalItemCount); + // Leaves end - fix vanilla hopper if (level.paperConfig().hopper.cooldownWhenFull) { applyCooldown(hopper);