13
0
geforkt von Mirrors/Paper

Clean up hopper optimization patch

Dieser Commit ist enthalten in:
Nassim Jahnke 2023-02-23 17:37:56 +01:00
Ursprung 50eacd3c04
Commit c7a82c1a50
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 6BE3B555EBC5982B
2 geänderte Dateien mit 251 neuen und 126 gelöschten Zeilen

Datei anzeigen

@ -45,14 +45,14 @@ index 00c438de76577e7b869270df16915d1ade088c9f..79023dace09c99587b5100de29b5b0ed
itemstack.setPopTime(this.getPopTime()); itemstack.setPopTime(this.getPopTime());
if (this.tag != null) { if (this.tag != null) {
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
index 5768ff2c3e15c038d132c7ad391332fb36251871..be98a87edbe62cfcf5c1b6f6cd1d8e31b546c144 100644 index 5768ff2c3e15c038d132c7ad391332fb36251871..e5e10c30fa9020e8dbbad708ef262eb6e1d559a6 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
@@ -26,6 +26,7 @@ import co.aikar.timings.MinecraftTimings; // Paper @@ -26,6 +26,7 @@ import co.aikar.timings.MinecraftTimings; // Paper
import co.aikar.timings.Timing; // Paper import co.aikar.timings.Timing; // Paper
public abstract class BlockEntity { public abstract class BlockEntity {
+ static boolean IGNORE_TILE_UPDATES = false; // Paper + static boolean ignoreTileUpdates; // Paper
public Timing tickTimer = MinecraftTimings.getTileEntityTimings(this); // Paper public Timing tickTimer = MinecraftTimings.getTileEntityTimings(this); // Paper
// CraftBukkit start - data containers // CraftBukkit start - data containers
@ -60,88 +60,73 @@ index 5768ff2c3e15c038d132c7ad391332fb36251871..be98a87edbe62cfcf5c1b6f6cd1d8e31
public void setChanged() { public void setChanged() {
if (this.level != null) { if (this.level != null) {
+ if (IGNORE_TILE_UPDATES) return; // Paper + if (ignoreTileUpdates) return; // Paper
BlockEntity.setChanged(this.level, this.worldPosition, this.blockState); BlockEntity.setChanged(this.level, this.worldPosition, this.blockState);
} }
diff --git a/src/main/java/net/minecraft/world/level/block/entity/Hopper.java b/src/main/java/net/minecraft/world/level/block/entity/Hopper.java diff --git a/src/main/java/net/minecraft/world/level/block/entity/ChiseledBookShelfBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ChiseledBookShelfBlockEntity.java
index a05acf709735b40ca86f978508c63a86065fd405..6a1405a8630e90db3b5a3c9152259ba6f5f0c784 100644 index 5050a4dc1599c10470d65eb43d412d8926f2027f..528832949172047d34f234d876fa989288916fed 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/Hopper.java --- a/src/main/java/net/minecraft/world/level/block/entity/ChiseledBookShelfBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/Hopper.java +++ b/src/main/java/net/minecraft/world/level/block/entity/ChiseledBookShelfBlockEntity.java
@@ -14,6 +14,8 @@ public interface Hopper extends Container { @@ -146,7 +146,7 @@ public class ChiseledBookShelfBlockEntity extends BlockEntity implements Contain
return SUCK;
@Override
public void setItem(int slot, ItemStack stack) {
- if (stack.is(ItemTags.BOOKSHELF_BOOKS)) {
+ if (stack.isEmpty() || stack.is(ItemTags.BOOKSHELF_BOOKS)) { // Paper
this.items.set(slot, stack);
this.updateState(slot);
} }
+ default net.minecraft.core.BlockPos getBlockPosition() { return new net.minecraft.core.BlockPos(getLevelX(), getLevelY(), getLevelZ()); } // Paper
+
double getLevelX();
double getLevelY();
diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index a507d7f65a94e49ecd18cd18797b156474558390..a7ac6b528aecae528a17af157f8ec29371e4484c 100644 index a507d7f65a94e49ecd18cd18797b156474558390..eedc9fa0bcd30af3b229d74cfdfeffed4b60f221 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java --- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -3,7 +3,6 @@ package net.minecraft.world.level.block.entity; @@ -190,6 +190,162 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
import java.util.Iterator;
import java.util.List;
import java.util.function.BooleanSupplier;
-import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
@@ -32,7 +31,6 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.Shapes;
-import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.entity.HumanEntity;
@@ -190,6 +188,158 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
return false; return false;
} }
+ // Paper start - Optimize Hoppers + // Paper start - Optimize Hoppers
+ private static boolean skipPullModeEventFire = false; + private static boolean skipPullModeEventFire;
+ private static boolean skipPushModeEventFire = false; + private static boolean skipPushModeEventFire;
+ public static boolean skipHopperEvents = false; + public static boolean skipHopperEvents;
+ +
+ private static boolean hopperPush(Level level, BlockPos pos, Container destination, Direction enumdirection, HopperBlockEntity hopper) { + private static boolean hopperPush(final Level level, final Container destination, final Direction direction, final HopperBlockEntity hopper) {
+ skipPushModeEventFire = skipHopperEvents; + skipPushModeEventFire = skipHopperEvents;
+ boolean foundItem = false; + boolean foundItem = false;
+ for (int i = 0; i < hopper.getContainerSize(); ++i) { + for (int i = 0; i < hopper.getContainerSize(); ++i) {
+ ItemStack item = hopper.getItem(i); + final ItemStack item = hopper.getItem(i);
+ if (!item.isEmpty()) { + if (!item.isEmpty()) {
+ foundItem = true; + foundItem = true;
+ ItemStack origItemStack = item; + ItemStack origItemStack = item;
+ ItemStack itemstack = origItemStack; + ItemStack movedItem = origItemStack;
+ +
+ final int origCount = origItemStack.getCount(); + final int originalItemCount = origItemStack.getCount();
+ final int moved = Math.min(level.spigotConfig.hopperAmount, origCount); + final int movedItemCount = Math.min(level.spigotConfig.hopperAmount, originalItemCount);
+ origItemStack.setCount(moved); + origItemStack.setCount(movedItemCount);
+ +
+ // We only need to fire the event once to give protection plugins a chance to cancel this event + // We only need to fire the event once to give protection plugins a chance to cancel this event
+ // Because nothing uses getItem, every event call should end up the same result. + // Because nothing uses getItem, every event call should end up the same result.
+ if (!skipPushModeEventFire) { + if (!skipPushModeEventFire) {
+ itemstack = callPushMoveEvent(destination, itemstack, hopper); + movedItem = callPushMoveEvent(destination, movedItem, hopper);
+ if (itemstack == null) { // cancelled + if (movedItem == null) { // cancelled
+ origItemStack.setCount(origCount); + origItemStack.setCount(originalItemCount);
+ return false; + return false;
+ } + }
+ } + }
+ final ItemStack itemstack2 = addItem(hopper, destination, itemstack, enumdirection); +
+ final int remaining = itemstack2.getCount(); + final ItemStack remainingItem = addItem(hopper, destination, movedItem, direction);
+ if (remaining != moved) { + final int remainingItemCount = remainingItem.getCount();
+ if (remainingItemCount != movedItemCount) {
+ origItemStack = origItemStack.cloneItemStack(true); + origItemStack = origItemStack.cloneItemStack(true);
+ origItemStack.setCount(origCount); + origItemStack.setCount(originalItemCount);
+ if (!origItemStack.isEmpty()) { + if (!origItemStack.isEmpty()) {
+ origItemStack.setCount(origCount - moved + remaining); + origItemStack.setCount(originalItemCount - movedItemCount + remainingItemCount);
+ } + }
+ hopper.setItem(i, origItemStack); + hopper.setItem(i, origItemStack);
+ destination.setChanged(); + destination.setChanged();
+ return true; + return true;
+ } + }
+ origItemStack.setCount(origCount); + origItemStack.setCount(originalItemCount);
+ } + }
+ } + }
+ if (foundItem && level.paperConfig().hopper.cooldownWhenFull) { // Inventory was full - cooldown + if (foundItem && level.paperConfig().hopper.cooldownWhenFull) { // Inventory was full - cooldown
@ -150,16 +135,16 @@ index a507d7f65a94e49ecd18cd18797b156474558390..a7ac6b528aecae528a17af157f8ec293
+ return false; + return false;
+ } + }
+ +
+ private static boolean hopperPull(Level level, Hopper ihopper, Container iinventory, ItemStack origItemStack, int i) { + private static boolean hopperPull(final Level level, final Hopper hopper, final Container container, ItemStack origItemStack, final int i) {
+ ItemStack itemstack = origItemStack; + ItemStack movedItem = origItemStack;
+ final int origCount = origItemStack.getCount(); + final int originalItemCount = origItemStack.getCount();
+ final int moved = Math.min(level.spigotConfig.hopperAmount, origCount); + final int movedItemCount = Math.min(level.spigotConfig.hopperAmount, originalItemCount);
+ itemstack.setCount(moved); + movedItem.setCount(movedItemCount);
+ +
+ if (!skipPullModeEventFire) { + if (!skipPullModeEventFire) {
+ itemstack = callPullMoveEvent(ihopper, iinventory, itemstack); + movedItem = callPullMoveEvent(hopper, container, movedItem);
+ if (itemstack == null) { // cancelled + if (movedItem == null) { // cancelled
+ origItemStack.setCount(origCount); + origItemStack.setCount(originalItemCount);
+ // Drastically improve performance by returning true. + // Drastically improve performance by returning true.
+ // No plugin could of relied on the behavior of false as the other call + // No plugin could of relied on the behavior of false as the other call
+ // site for IMIE did not exhibit the same behavior + // site for IMIE did not exhibit the same behavior
@ -167,34 +152,36 @@ index a507d7f65a94e49ecd18cd18797b156474558390..a7ac6b528aecae528a17af157f8ec293
+ } + }
+ } + }
+ +
+ final ItemStack itemstack2 = addItem(iinventory, ihopper, itemstack, null); + final ItemStack remainingItem = addItem(container, hopper, movedItem, null);
+ final int remaining = itemstack2.getCount(); + final int remainingItemCount = remainingItem.getCount();
+ if (remaining != moved) { + if (remainingItemCount != movedItemCount) {
+ origItemStack = origItemStack.cloneItemStack(true); + origItemStack = origItemStack.cloneItemStack(true);
+ origItemStack.setCount(origCount); + origItemStack.setCount(originalItemCount);
+ if (!origItemStack.isEmpty()) { + if (!origItemStack.isEmpty()) {
+ origItemStack.setCount(origCount - moved + remaining); + origItemStack.setCount(originalItemCount - movedItemCount + remainingItemCount);
+ } + }
+ IGNORE_TILE_UPDATES = true; +
+ iinventory.setItem(i, origItemStack); + ignoreTileUpdates = true;
+ IGNORE_TILE_UPDATES = false; + container.setItem(i, origItemStack);
+ iinventory.setChanged(); + ignoreTileUpdates = false;
+ container.setChanged();
+ return true; + return true;
+ } + }
+ origItemStack.setCount(origCount); + origItemStack.setCount(originalItemCount);
+ +
+ if (level.paperConfig().hopper.cooldownWhenFull) { + if (level.paperConfig().hopper.cooldownWhenFull) {
+ cooldownHopper(ihopper); + cooldownHopper(hopper);
+ } + }
+ +
+ return false; + return false;
+ } + }
+ +
+ @Nullable
+ private static ItemStack callPushMoveEvent(Container iinventory, ItemStack itemstack, HopperBlockEntity hopper) { + private static ItemStack callPushMoveEvent(Container iinventory, ItemStack itemstack, HopperBlockEntity hopper) {
+ Inventory destinationInventory = getInventory(iinventory); + final Inventory destinationInventory = getInventory(iinventory);
+ InventoryMoveItemEvent event = new InventoryMoveItemEvent(hopper.getOwner(false).getInventory(), + final InventoryMoveItemEvent event = new InventoryMoveItemEvent(hopper.getOwner(false).getInventory(),
+ CraftItemStack.asCraftMirror(itemstack), destinationInventory, true); + CraftItemStack.asCraftMirror(itemstack), destinationInventory, true);
+ boolean result = event.callEvent(); + final boolean result = event.callEvent();
+ if (!event.calledGetItem && !event.calledSetItem) { + if (!event.calledGetItem && !event.calledSetItem) {
+ skipPushModeEventFire = true; + skipPushModeEventFire = true;
+ } + }
@ -210,14 +197,14 @@ index a507d7f65a94e49ecd18cd18797b156474558390..a7ac6b528aecae528a17af157f8ec293
+ } + }
+ } + }
+ +
+ private static ItemStack callPullMoveEvent(Hopper hopper, Container iinventory, ItemStack itemstack) { + @Nullable
+ Inventory sourceInventory = getInventory(iinventory); + private static ItemStack callPullMoveEvent(final Hopper hopper, final Container container, final ItemStack itemstack) {
+ Inventory destination = getInventory(hopper); + final Inventory sourceInventory = getInventory(container);
+ final Inventory destination = getInventory(hopper);
+ +
+ InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, + // Mirror is safe as no plugins ever use this item
+ // Mirror is safe as we no plugins ever use this item + final InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, CraftItemStack.asCraftMirror(itemstack), destination, false);
+ CraftItemStack.asCraftMirror(itemstack), destination, false); + final boolean result = event.callEvent();
+ boolean result = event.callEvent();
+ if (!event.calledGetItem && !event.calledSetItem) { + if (!event.calledGetItem && !event.calledSetItem) {
+ skipPullModeEventFire = true; + skipPullModeEventFire = true;
+ } + }
@ -233,19 +220,20 @@ index a507d7f65a94e49ecd18cd18797b156474558390..a7ac6b528aecae528a17af157f8ec293
+ } + }
+ } + }
+ +
+ private static Inventory getInventory(Container iinventory) { + private static Inventory getInventory(final Container container) {
+ Inventory sourceInventory;// Have to special case large chests as they work oddly + final Inventory sourceInventory;
+ if (iinventory instanceof CompoundContainer) { + if (container instanceof CompoundContainer compoundContainer) {
+ sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) iinventory); + // Have to special-case large chests as they work oddly
+ } else if (iinventory instanceof BlockEntity) { + sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest(compoundContainer);
+ sourceInventory = ((BlockEntity) iinventory).getOwner(false).getInventory(); + } else if (container instanceof BlockEntity blockEntity) {
+ sourceInventory = blockEntity.getOwner(false).getInventory();
+ } else { + } else {
+ sourceInventory = iinventory.getOwner().getInventory(); + sourceInventory = container.getOwner().getInventory();
+ } + }
+ return sourceInventory; + return sourceInventory;
+ } + }
+ +
+ private static void cooldownHopper(Hopper hopper) { + private static void cooldownHopper(final Hopper hopper) {
+ if (hopper instanceof HopperBlockEntity blockEntity) { + if (hopper instanceof HopperBlockEntity blockEntity) {
+ blockEntity.setCooldown(blockEntity.getLevel().spigotConfig.hopperTransfer); + blockEntity.setCooldown(blockEntity.getLevel().spigotConfig.hopperTransfer);
+ } else if (hopper instanceof MinecartHopper blockEntity) { + } else if (hopper instanceof MinecartHopper blockEntity) {
@ -256,24 +244,89 @@ index a507d7f65a94e49ecd18cd18797b156474558390..a7ac6b528aecae528a17af157f8ec293
private static boolean ejectItems(Level world, BlockPos blockposition, BlockState iblockdata, Container iinventory, HopperBlockEntity hopper) { // CraftBukkit private static boolean ejectItems(Level world, BlockPos blockposition, BlockState iblockdata, Container iinventory, HopperBlockEntity hopper) { // CraftBukkit
Container iinventory1 = HopperBlockEntity.getAttachedContainer(world, blockposition, iblockdata); Container iinventory1 = HopperBlockEntity.getAttachedContainer(world, blockposition, iblockdata);
@@ -202,6 +352,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -202,44 +358,47 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
if (HopperBlockEntity.isFullContainer(iinventory1, enumdirection)) { if (HopperBlockEntity.isFullContainer(iinventory1, enumdirection)) {
return false; return false;
} else { } else {
+ return hopperPush(world, blockposition, iinventory1, enumdirection, hopper); /* // Paper - disable rest - for (int i = 0; i < iinventory.getContainerSize(); ++i) {
for (int i = 0; i < iinventory.getContainerSize(); ++i) { - if (!iinventory.getItem(i).isEmpty()) {
if (!iinventory.getItem(i).isEmpty()) { - ItemStack itemstack = iinventory.getItem(i).copy();
ItemStack itemstack = iinventory.getItem(i).copy(); - // ItemStack itemstack1 = addItem(iinventory, iinventory1, iinventory.removeItem(i, 1), enumdirection);
@@ -239,7 +390,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen -
} - // CraftBukkit start - Call event when pushing items into other inventories
} - CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.removeItem(i, world.spigotConfig.hopperAmount)); // Spigot
-
- Inventory destinationInventory;
- // Have to special case large chests as they work oddly
- if (iinventory1 instanceof CompoundContainer) {
- destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) iinventory1);
- } else {
- destinationInventory = iinventory1.getOwner().getInventory();
- }
-
- InventoryMoveItemEvent event = new InventoryMoveItemEvent(iinventory.getOwner().getInventory(), oitemstack.clone(), destinationInventory, true);
- world.getCraftServer().getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- hopper.setItem(i, itemstack);
- hopper.setCooldown(world.spigotConfig.hopperTransfer); // Spigot
- return false;
- }
- int origCount = event.getItem().getAmount(); // Spigot
- ItemStack itemstack1 = HopperBlockEntity.addItem(iinventory, iinventory1, CraftItemStack.asNMSCopy(event.getItem()), enumdirection);
+ // Paper start - replace logic; MAKE SURE TO CHECK FOR DIFFS ON UPDATES
+ return hopperPush(world, iinventory1, enumdirection, hopper);
+ //for (int i = 0; i < iinventory.getContainerSize(); ++i) {
+ // if (!iinventory.getItem(i).isEmpty()) {
+ // ItemStack itemstack = iinventory.getItem(i).copy();
+ // // ItemStack itemstack1 = addItem(iinventory, iinventory1, iinventory.removeItem(i, 1), enumdirection);
+
+ // // CraftBukkit start - Call event when pushing items into other inventories
+ // CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.removeItem(i, world.spigotConfig.hopperAmount)); // Spigot
+
+ // Inventory destinationInventory;
+ // // Have to special case large chests as they work oddly
+ // if (iinventory1 instanceof CompoundContainer) {
+ // destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) iinventory1);
+ // } else {
+ // destinationInventory = iinventory1.getOwner().getInventory();
+ // }
+
+ // InventoryMoveItemEvent event = new InventoryMoveItemEvent(iinventory.getOwner().getInventory(), oitemstack.clone(), destinationInventory, true);
+ // world.getCraftServer().getPluginManager().callEvent(event);
+ // if (event.isCancelled()) {
+ // hopper.setItem(i, itemstack);
+ // hopper.setCooldown(world.spigotConfig.hopperTransfer); // Spigot
+ // return false;
+ // }
+ // int origCount = event.getItem().getAmount(); // Spigot
+ // ItemStack itemstack1 = HopperBlockEntity.addItem(iinventory, iinventory1, CraftItemStack.asNMSCopy(event.getItem()), enumdirection);
// CraftBukkit end
- if (itemstack1.isEmpty()) {
- iinventory1.setChanged();
- return true;
- }
+ // if (itemstack1.isEmpty()) {
+ // iinventory1.setChanged();
+ // return true;
+ // }
- itemstack.shrink(origCount - itemstack1.getCount()); // Spigot
- iinventory.setItem(i, itemstack);
- }
- }
+ // itemstack.shrink(origCount - itemstack1.getCount()); // Spigot
+ // iinventory.setItem(i, itemstack);
+ // }
+ //}
- return false; - return false;
+ return false;*/ // Paper - end commenting out replaced block for Hopper Optimizations + //return false;
+ // Paper end
} }
} }
} }
@@ -249,27 +400,68 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -249,18 +408,51 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
} }
private static boolean isFullContainer(Container inventory, Direction direction) { private static boolean isFullContainer(Container inventory, Direction direction) {
@ -308,8 +361,8 @@ index a507d7f65a94e49ecd18cd18797b156474558390..a7ac6b528aecae528a17af157f8ec293
+ } + }
+ } + }
+ return true; + return true;
} + }
+
+ private static boolean anyMatch(Container iinventory, Direction enumdirection, java.util.function.BiPredicate<ItemStack, Integer> test) { + private static boolean anyMatch(Container iinventory, Direction enumdirection, java.util.function.BiPredicate<ItemStack, Integer> test) {
+ if (iinventory instanceof WorldlyContainer) { + if (iinventory instanceof WorldlyContainer) {
+ for (int i : ((WorldlyContainer) iinventory).getSlotsForFace(enumdirection)) { + for (int i : ((WorldlyContainer) iinventory).getSlotsForFace(enumdirection)) {
@ -326,14 +379,14 @@ index a507d7f65a94e49ecd18cd18797b156474558390..a7ac6b528aecae528a17af157f8ec293
+ } + }
+ } + }
+ return true; + return true;
+ } }
+ private static final java.util.function.BiPredicate<ItemStack, Integer> STACK_SIZE_TEST = (itemstack, i) -> itemstack.getCount() >= itemstack.getMaxStackSize(); + private static final java.util.function.BiPredicate<ItemStack, Integer> STACK_SIZE_TEST = (itemstack, i) -> itemstack.getCount() >= itemstack.getMaxStackSize();
+ private static final java.util.function.BiPredicate<ItemStack, Integer> IS_EMPTY_TEST = (itemstack, i) -> itemstack.isEmpty(); + private static final java.util.function.BiPredicate<ItemStack, Integer> IS_EMPTY_TEST = (itemstack, i) -> itemstack.isEmpty();
+ // Paper end + // Paper end
+
public static boolean suckInItems(Level world, Hopper hopper) { public static boolean suckInItems(Level world, Hopper hopper) {
Container iinventory = HopperBlockEntity.getSourceContainer(world, hopper); Container iinventory = HopperBlockEntity.getSourceContainer(world, hopper);
@@ -268,8 +460,16 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
if (iinventory != null) { if (iinventory != null) {
Direction enumdirection = Direction.DOWN; Direction enumdirection = Direction.DOWN;
@ -352,7 +405,7 @@ index a507d7f65a94e49ecd18cd18797b156474558390..a7ac6b528aecae528a17af157f8ec293
}); });
} else { } else {
Iterator iterator = HopperBlockEntity.getItemsAtAndAbove(world, hopper).iterator(); Iterator iterator = HopperBlockEntity.getItemsAtAndAbove(world, hopper).iterator();
@@ -288,10 +480,12 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -288,47 +488,51 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
} }
} }
@ -361,21 +414,88 @@ index a507d7f65a94e49ecd18cd18797b156474558390..a7ac6b528aecae528a17af157f8ec293
ItemStack itemstack = iinventory.getItem(i); ItemStack itemstack = iinventory.getItem(i);
- if (!itemstack.isEmpty() && HopperBlockEntity.canTakeItemFromContainer(iinventory, itemstack, i, enumdirection)) { - if (!itemstack.isEmpty() && HopperBlockEntity.canTakeItemFromContainer(iinventory, itemstack, i, enumdirection)) {
+ if (!itemstack.isEmpty() && HopperBlockEntity.canTakeItemFromContainer(iinventory, itemstack, i, enumdirection)) { // If this logic changes, update above. this is left inused incase reflective plugins - ItemStack itemstack1 = itemstack.copy();
+ return hopperPull(world, ihopper, iinventory, itemstack, i); /* // Paper - disable rest - // ItemStack itemstack2 = addItem(iinventory, ihopper, iinventory.removeItem(i, 1), (EnumDirection) null);
ItemStack itemstack1 = itemstack.copy(); - // CraftBukkit start - Call event on collection of items from inventories into the hopper
// ItemStack itemstack2 = addItem(iinventory, ihopper, iinventory.removeItem(i, 1), (EnumDirection) null); - CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.removeItem(i, world.spigotConfig.hopperAmount)); // Spigot
// CraftBukkit start - Call event on collection of items from inventories into the hopper -
@@ -328,7 +522,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - Inventory sourceInventory;
} - // Have to special case large chests as they work oddly
- if (iinventory instanceof CompoundContainer) {
itemstack1.shrink(origCount - itemstack2.getCount()); // Spigot - sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) iinventory);
- } else {
- sourceInventory = iinventory.getOwner().getInventory();
- }
-
- InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), ihopper.getOwner().getInventory(), false);
-
- Bukkit.getServer().getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- iinventory.setItem(i, itemstack1); - iinventory.setItem(i, itemstack1);
+ iinventory.setItem(i, itemstack1);*/ // Paper - end commenting out replaced block for Hopper Optimizations -
- if (ihopper instanceof HopperBlockEntity) {
- ((HopperBlockEntity) ihopper).setCooldown(world.spigotConfig.hopperTransfer); // Spigot
- } else if (ihopper instanceof MinecartHopper) {
- ((MinecartHopper) ihopper).setCooldown(world.spigotConfig.hopperTransfer / 2); // Spigot
- }
- return false;
- }
- int origCount = event.getItem().getAmount(); // Spigot
- ItemStack itemstack2 = HopperBlockEntity.addItem(iinventory, ihopper, CraftItemStack.asNMSCopy(event.getItem()), null);
- // CraftBukkit end
-
- if (itemstack2.isEmpty()) {
- iinventory.setChanged();
- return true;
- }
-
- itemstack1.shrink(origCount - itemstack2.getCount()); // Spigot
- iinventory.setItem(i, itemstack1);
+ if (!itemstack.isEmpty() && HopperBlockEntity.canTakeItemFromContainer(iinventory, itemstack, i, enumdirection)) { // If this logic changes, update above. this is left inused incase reflective plugins
+ // Paper start - replace pull logic; MAKE SURE TO CHECK FOR DIFFS WHEN UPDATING
+ return hopperPull(world, ihopper, iinventory, itemstack, i);
+ //ItemStack itemstack1 = itemstack.copy();
+ //// ItemStack itemstack2 = addItem(iinventory, ihopper, iinventory.removeItem(i, 1), (EnumDirection) null);
+ //// CraftBukkit start - Call event on collection of items from inventories into the hopper
+ //CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.removeItem(i, world.spigotConfig.hopperAmount)); // Spigot
+
+ //Inventory sourceInventory;
+ //// Have to special case large chests as they work oddly
+ //if (iinventory instanceof CompoundContainer) {
+ // sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) iinventory);
+ //} else {
+ // sourceInventory = iinventory.getOwner().getInventory();
+ //}
+
+ //InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), ihopper.getOwner().getInventory(), false);
+
+ //Bukkit.getServer().getPluginManager().callEvent(event);
+ //if (event.isCancelled()) {
+ // iinventory.setItem(i, itemstack1);
+
+ // if (ihopper instanceof HopperBlockEntity) {
+ // ((HopperBlockEntity) ihopper).setCooldown(world.spigotConfig.hopperTransfer); // Spigot
+ // } else if (ihopper instanceof MinecartHopper) {
+ // ((MinecartHopper) ihopper).setCooldown(world.spigotConfig.hopperTransfer / 2); // Spigot
+ // }
+ // return false;
+ //}
+ //int origCount = event.getItem().getAmount(); // Spigot
+ //ItemStack itemstack2 = HopperBlockEntity.addItem(iinventory, ihopper, CraftItemStack.asNMSCopy(event.getItem()), null);
+ //// CraftBukkit end
+
+ //if (itemstack2.isEmpty()) {
+ // iinventory.setChanged();
+ // return true;
+ //}
+
+ //itemstack1.shrink(origCount - itemstack2.getCount()); // Spigot
+ //iinventory.setItem(i, itemstack1);
+ // Paper end
} }
return false; return false;
@@ -337,7 +531,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -337,7 +541,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
public static boolean addItem(Container inventory, ItemEntity itemEntity) { public static boolean addItem(Container inventory, ItemEntity itemEntity) {
boolean flag = false; boolean flag = false;
// CraftBukkit start // CraftBukkit start
@ -384,17 +504,17 @@ index a507d7f65a94e49ecd18cd18797b156474558390..a7ac6b528aecae528a17af157f8ec293
itemEntity.level.getCraftServer().getPluginManager().callEvent(event); itemEntity.level.getCraftServer().getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
return false; return false;
@@ -396,7 +590,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -396,7 +600,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
stack = stack.split(to.getMaxStackSize()); stack = stack.split(to.getMaxStackSize());
} }
// Spigot end // Spigot end
+ IGNORE_TILE_UPDATES = true; // Paper + ignoreTileUpdates = true; // Paper
to.setItem(slot, stack); to.setItem(slot, stack);
+ IGNORE_TILE_UPDATES = false; // Paper + ignoreTileUpdates = false; // Paper
stack = ItemStack.EMPTY; stack = ItemStack.EMPTY;
flag = true; flag = true;
} else if (HopperBlockEntity.canMergeItems(itemstack1, stack)) { } else if (HopperBlockEntity.canMergeItems(itemstack1, stack)) {
@@ -447,18 +643,23 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -447,18 +653,28 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
} }
public static List<ItemEntity> getItemsAtAndAbove(Level world, Hopper hopper) { public static List<ItemEntity> getItemsAtAndAbove(Level world, Hopper hopper) {
@ -416,14 +536,19 @@ index a507d7f65a94e49ecd18cd18797b156474558390..a7ac6b528aecae528a17af157f8ec293
+ return HopperBlockEntity.getContainerAt(world, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, true); // Paper + return HopperBlockEntity.getContainerAt(world, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, true); // Paper
} }
+ public static Container getContainerAt(Level world, double x, double y, double z) { return getContainerAt(world, x, y, z, false); } // Paper - overload to default false
@Nullable @Nullable
- private static Container getContainerAt(Level world, double x, double y, double z) { - private static Container getContainerAt(Level world, double x, double y, double z) {
+ private static Container getContainerAt(Level world, double x, double y, double z, boolean optimizeEntities) { + public static Container getContainerAt(Level world, double x, double y, double z) {
+ // Paper start - add optimizeEntities parameter
+ return getContainerAt(world, x, y, z, false);
+ }
+ @Nullable
+ private static Container getContainerAt(Level world, double x, double y, double z, final boolean optimizeEntities) {
+ // Paper end - add optimizeEntities parameter
Object object = null; Object object = null;
BlockPos blockposition = new BlockPos(x, y, z); BlockPos blockposition = new BlockPos(x, y, z);
if ( !world.spigotConfig.hopperCanLoadChunks && !world.hasChunkAt( blockposition ) ) return null; // Spigot if ( !world.spigotConfig.hopperCanLoadChunks && !world.hasChunkAt( blockposition ) ) return null; // Spigot
@@ -478,7 +679,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -478,7 +694,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
} }
} }

Datei anzeigen

@ -5,10 +5,10 @@ Subject: [PATCH] Make hoppers respect inventory max stack size
diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index a7ac6b528aecae528a17af157f8ec29371e4484c..ccad692aba2ed77259f6814d88f01b91ed9d229b 100644 index eedc9fa0bcd30af3b229d74cfdfeffed4b60f221..d76603c4172aa10889949c6c2acff05fee02a13d 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java --- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -586,17 +586,19 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -596,17 +596,19 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
if (itemstack1.isEmpty()) { if (itemstack1.isEmpty()) {
// Spigot start - SPIGOT-6693, InventorySubcontainer#setItem // Spigot start - SPIGOT-6693, InventorySubcontainer#setItem
@ -18,9 +18,9 @@ index a7ac6b528aecae528a17af157f8ec29371e4484c..ccad692aba2ed77259f6814d88f01b91
stack = stack.split(to.getMaxStackSize()); stack = stack.split(to.getMaxStackSize());
} }
// Spigot end // Spigot end
IGNORE_TILE_UPDATES = true; // Paper ignoreTileUpdates = true; // Paper
to.setItem(slot, stack); to.setItem(slot, stack);
IGNORE_TILE_UPDATES = false; // Paper ignoreTileUpdates = false; // Paper
- stack = ItemStack.EMPTY; - stack = ItemStack.EMPTY;
+ stack = leftover; // Paper + stack = leftover; // Paper
flag = true; flag = true;