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 a7a3da8802
Commit 4f14496fbd
2 geänderte Dateien mit 238 neuen und 113 gelöschten Zeilen

Datei anzeigen

@ -18,9 +18,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
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;

Datei anzeigen

@ -52,7 +52,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
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 0000000000000000000000000000000000000000..00000000000000000000000000000000
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ public interface Hopper extends Container { @@ -0,0 +0,0 @@ public class ChiseledBookShelfBlockEntity extends BlockEntity implements Contain
return SUCK;
}
+ default net.minecraft.core.BlockPos getBlockPosition() { return new net.minecraft.core.BlockPos(getLevelX(), getLevelY(), getLevelZ()); } // Paper @Override
+ public void setItem(int slot, ItemStack stack) {
double getLevelX(); - if (stack.is(ItemTags.BOOKSHELF_BOOKS)) {
+ if (stack.isEmpty() || stack.is(ItemTags.BOOKSHELF_BOOKS)) { // Paper
double getLevelY(); this.items.set(slot, stack);
this.updateState(slot);
}
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ package net.minecraft.world.level.block.entity;
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;
@@ -0,0 +0,0 @@ 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;
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ 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 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ } + }
+ +
+ 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 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ } + }
+ +
+ 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 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ } + }
+ +
+ 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) {
@ -260,16 +248,81 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
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);
@@ -0,0 +0,0 @@ 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
} }
} }
} }
@ -308,8 +361,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ } + }
+ 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 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ } + }
+ 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);
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
if (iinventory != null) { if (iinventory != null) {
Direction enumdirection = Direction.DOWN; Direction enumdirection = Direction.DOWN;
@ -361,17 +414,84 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
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 -
@@ -0,0 +0,0 @@ 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);
-
- 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); - iinventory.setItem(i, itemstack1);
+ iinventory.setItem(i, itemstack1);*/ // Paper - end commenting out replaced block for Hopper Optimizations + 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;
@ -388,9 +508,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
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)) {
@ -416,10 +536,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ 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