aboutsummaryrefslogtreecommitdiffhomepage
path: root/removed
diff options
context:
space:
mode:
authorShane Freeder <[email protected]>2019-12-13 21:31:04 +0000
committerShane Freeder <[email protected]>2019-12-13 21:53:20 +0000
commit3b93c5b112ea1afe2eebe45c89895753303b72aa (patch)
tree9709096d1edf885a8e1700a13763e5de6aa93e56 /removed
parent31bc07cb658c55937439fd9c23cae5a594a360af (diff)
downloadPaper-3b93c5b112ea1afe2eebe45c89895753303b72aa.tar.gz
Paper-3b93c5b112ea1afe2eebe45c89895753303b72aa.zip
Drop fix zero-tick farms (Fixes #2736)
Fixed by mojang in 1.15, farm blocks are no longer in the next tick list Also, add hopper optimization patch to the removed folder
Diffstat (limited to 'removed')
-rw-r--r--removed/1.15/0281-Optimize-Hoppers.patch308
1 files changed, 308 insertions, 0 deletions
diff --git a/removed/1.15/0281-Optimize-Hoppers.patch b/removed/1.15/0281-Optimize-Hoppers.patch
new file mode 100644
index 0000000000..a301f0aad4
--- /dev/null
+++ b/removed/1.15/0281-Optimize-Hoppers.patch
@@ -0,0 +1,308 @@
+From bd7c380b8e4238b100012405cf46a02a0e05990d Mon Sep 17 00:00:00 2001
+From: Aikar <[email protected]>
+Date: Wed, 27 Apr 2016 22:09:52 -0400
+Subject: [PATCH] Optimize Hoppers
+
+* Removes unnecessary extra calls to .update() that are very expensive
+* Lots of itemstack cloning removed. Only clone if the item is actually moved
+* Return true when a plugin cancels inventory move item event instead of false, as false causes pulls to cycle through all items.
+ However, pushes do not exhibit the same behavior, so this is not something plugins could of been relying on.
+* Add option (Default on) to cooldown hoppers when they fail to move an item due to full inventory
+* Skip subsequent InventoryMoveItemEvents if a plugin does not use the item after first event fire for an iteration
+
+diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+index 42d14fac2..80d66c647 100644
+--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
++++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+@@ -397,4 +397,13 @@ public class PaperWorldConfig {
+ this.armorStandTick = this.getBoolean("armor-stands-tick", this.armorStandTick);
+ log("ArmorStand ticking is " + (this.armorStandTick ? "enabled" : "disabled") + " by default");
+ }
++
++ public boolean cooldownHopperWhenFull = true;
++ public boolean disableHopperMoveEvents = false;
++ private void hopperOptimizations() {
++ cooldownHopperWhenFull = getBoolean("hopper.cooldown-when-full", cooldownHopperWhenFull);
++ log("Cooldown Hoppers when Full: " + (cooldownHopperWhenFull ? "enabled" : "disabled"));
++ disableHopperMoveEvents = getBoolean("hopper.disable-move-event", disableHopperMoveEvents);
++ log("Hopper Move Item Events: " + (disableHopperMoveEvents ? "disabled" : "enabled"));
++ }
+ }
+diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java
+index 33d9cac4d..627fa465c 100644
+--- a/src/main/java/net/minecraft/server/ItemStack.java
++++ b/src/main/java/net/minecraft/server/ItemStack.java
+@@ -481,11 +481,12 @@ public final class ItemStack {
+ return this.getItem().a(this, entityhuman, entityliving, enumhand);
+ }
+
+- public ItemStack cloneItemStack() {
++ public ItemStack cloneItemStack() { return cloneItemStack(false); } // Paper
++ public ItemStack cloneItemStack(boolean origItem) { // Paper
+ if (this.isEmpty()) {
+ return ItemStack.a;
+ } else {
+- ItemStack itemstack = new ItemStack(this.getItem(), this.count);
++ ItemStack itemstack = new ItemStack(origItem ? this.item : this.getItem(), this.count); // Paper
+
+ itemstack.d(this.C());
+ if (this.tag != null) {
+diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
+index dd2d8712e..206a4ad64 100644
+--- a/src/main/java/net/minecraft/server/MinecraftServer.java
++++ b/src/main/java/net/minecraft/server/MinecraftServer.java
+@@ -1168,6 +1168,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
+ WorldServer worldserver = (WorldServer) iterator.next();
+
+ worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
++ TileEntityHopper.skipHopperEvents = worldserver.paperConfig.disableHopperMoveEvents || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper
+ if (true || worldserver.worldProvider.getDimensionManager() == DimensionManager.OVERWORLD || this.getAllowNether()) { // CraftBukkit
+ this.methodProfiler.a(() -> {
+ return worldserver.getWorldData().getName() + " " + IRegistry.DIMENSION_TYPE.getKey(worldserver.worldProvider.getDimensionManager());
+diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
+index 958279249..a8e64dfda 100644
+--- a/src/main/java/net/minecraft/server/TileEntity.java
++++ b/src/main/java/net/minecraft/server/TileEntity.java
+@@ -62,6 +62,7 @@ public abstract class TileEntity implements KeyedObject { // Paper
+ public void setCurrentChunk(Chunk chunk) {
+ this.currentChunk = chunk != null ? new java.lang.ref.WeakReference<>(chunk) : null;
+ }
++ static boolean IGNORE_TILE_UPDATES = false;
+ // Paper end
+
+ @Nullable
+@@ -140,6 +141,7 @@ public abstract class TileEntity implements KeyedObject { // Paper
+
+ public void update() {
+ if (this.world != null) {
++ if (IGNORE_TILE_UPDATES) return; // Paper
+ this.c = this.world.getType(this.position);
+ this.world.b(this.position, this);
+ if (!this.c.isAir()) {
+diff --git a/src/main/java/net/minecraft/server/TileEntityHopper.java b/src/main/java/net/minecraft/server/TileEntityHopper.java
+index e08faf538..e7cf14d10 100644
+--- a/src/main/java/net/minecraft/server/TileEntityHopper.java
++++ b/src/main/java/net/minecraft/server/TileEntityHopper.java
+@@ -168,6 +168,158 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
+ return false;
+ }
+
++ // Paper start - Optimize Hoppers
++ private static boolean skipPullModeEventFire = false;
++ private static boolean skipPushModeEventFire = false;
++ static boolean skipHopperEvents = false;
++
++ private boolean hopperPush(IInventory iinventory, EnumDirection enumdirection) {
++ skipPushModeEventFire = skipHopperEvents;
++ boolean foundItem = false;
++ for (int i = 0; i < this.getSize(); ++i) {
++ if (!this.getItem(i).isEmpty()) {
++ foundItem = true;
++ ItemStack origItemStack = this.getItem(i);
++ ItemStack itemstack = origItemStack;
++
++ final int origCount = origItemStack.getCount();
++ final int moved = Math.min(world.spigotConfig.hopperAmount, origCount);
++ origItemStack.setCount(moved);
++
++ // 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.
++ if (!skipPushModeEventFire) {
++ itemstack = callPushMoveEvent(iinventory, itemstack);
++ if (itemstack == null) { // cancelled
++ origItemStack.setCount(origCount);
++ return false;
++ }
++ }
++ final ItemStack itemstack2 = addItem(this, iinventory, itemstack, enumdirection);
++ final int remaining = itemstack2.getCount();
++ if (remaining != moved) {
++ origItemStack = origItemStack.cloneItemStack(true);
++ if (!origItemStack.isEmpty()) {
++ origItemStack.setCount(origCount - moved + remaining);
++ }
++ this.setItem(i, origItemStack);
++ iinventory.update();
++ return true;
++ }
++ origItemStack.setCount(origCount);
++ }
++ }
++ if (foundItem && world.paperConfig.cooldownHopperWhenFull) { // Inventory was full - cooldown
++ this.setCooldown(world.spigotConfig.hopperTransfer);
++ }
++ return false;
++ }
++
++ private static boolean hopperPull(IHopper ihopper, IInventory iinventory, int i) {
++ ItemStack origItemStack = iinventory.getItem(i);
++ ItemStack itemstack = origItemStack;
++ final int origCount = origItemStack.getCount();
++ final World world = ihopper.getWorld();
++ final int moved = Math.min(world.spigotConfig.hopperAmount, origCount);
++ itemstack.setCount(moved);
++
++ if (!skipPullModeEventFire) {
++ itemstack = callPullMoveEvent(ihopper, iinventory, itemstack);
++ if (itemstack == null) { // cancelled
++ origItemStack.setCount(origCount);
++ // Drastically improve performance by returning true.
++ // No plugin could of relied on the behavior of false as the other call
++ // site for IMIE did not exhibit the same behavior
++ return true;
++ }
++ }
++
++ final ItemStack itemstack2 = addItem(iinventory, ihopper, itemstack, null);
++ final int remaining = itemstack2.getCount();
++ if (remaining != moved) {
++ origItemStack = origItemStack.cloneItemStack(true);
++ if (!origItemStack.isEmpty()) {
++ origItemStack.setCount(origCount - moved + remaining);
++ }
++ IGNORE_TILE_UPDATES = true;
++ iinventory.setItem(i, origItemStack);
++ IGNORE_TILE_UPDATES = false;
++ iinventory.update();
++ return true;
++ }
++ origItemStack.setCount(origCount);
++
++ if (world.paperConfig.cooldownHopperWhenFull) {
++ cooldownHopper(ihopper);
++ }
++
++ return false;
++ }
++
++ private ItemStack callPushMoveEvent(IInventory iinventory, ItemStack itemstack) {
++ Inventory destinationInventory = getInventory(iinventory);
++ InventoryMoveItemEvent event = new InventoryMoveItemEvent(this.getOwner(false).getInventory(),
++ CraftItemStack.asCraftMirror(itemstack), destinationInventory, true);
++ boolean result = event.callEvent();
++ if (!event.calledGetItem && !event.calledSetItem) {
++ skipPushModeEventFire = true;
++ }
++ if (!result) {
++ cooldownHopper(this);
++ return null;
++ }
++
++ if (event.calledSetItem) {
++ return CraftItemStack.asNMSCopy(event.getItem());
++ } else {
++ return itemstack;
++ }
++ }
++
++ private static ItemStack callPullMoveEvent(IHopper hopper, IInventory iinventory, ItemStack itemstack) {
++ Inventory sourceInventory = getInventory(iinventory);
++ Inventory destination = getInventory(hopper);
++
++ InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory,
++ // Mirror is safe as we no plugins ever use this item
++ CraftItemStack.asCraftMirror(itemstack), destination, false);
++ boolean result = event.callEvent();
++ if (!event.calledGetItem && !event.calledSetItem) {
++ skipPullModeEventFire = true;
++ }
++ if (!result) {
++ cooldownHopper(hopper);
++ return null;
++ }
++
++ if (event.calledSetItem) {
++ return CraftItemStack.asNMSCopy(event.getItem());
++ } else {
++ return itemstack;
++ }
++ }
++
++ private static Inventory getInventory(IInventory iinventory) {
++ Inventory sourceInventory;// Have to special case large chests as they work oddly
++ if (iinventory instanceof InventoryLargeChest) {
++ sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory);
++ } else if (iinventory instanceof TileEntity) {
++ sourceInventory = ((TileEntity) iinventory).getOwner(false).getInventory();
++ } else {
++ sourceInventory = iinventory.getOwner().getInventory();
++ }
++ return sourceInventory;
++ }
++
++ private static void cooldownHopper(IHopper hopper) {
++ if (hopper instanceof TileEntityHopper) {
++ ((TileEntityHopper) hopper).setCooldown(hopper.getWorld().spigotConfig.hopperTransfer);
++ } else if (hopper instanceof EntityMinecartHopper) {
++ ((EntityMinecartHopper) hopper).setCooldown(hopper.getWorld().spigotConfig.hopperTransfer / 2);
++ }
++ }
++ // Paper end
++
+ private boolean j() {
+ IInventory iinventory = this.k();
+
+@@ -179,6 +331,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
+ if (this.b(iinventory, enumdirection)) {
+ return false;
+ } else {
++ return hopperPush(iinventory, enumdirection); /* // Paper - disable rest
+ for (int i = 0; i < this.getSize(); ++i) {
+ if (!this.getItem(i).isEmpty()) {
+ ItemStack itemstack = this.getItem(i).cloneItemStack();
+@@ -216,7 +369,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
+ }
+ }
+
+- return false;
++ return false;*/ // Paper - end commenting out replaced block for Hopper Optimizations
+ }
+ }
+ }
+@@ -246,6 +399,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
+ EnumDirection enumdirection = EnumDirection.DOWN;
+
+ return c(iinventory, enumdirection) ? false : a(iinventory, enumdirection).anyMatch((i) -> {
++ skipPullModeEventFire = skipHopperEvents; // Paper
+ return a(ihopper, iinventory, i, enumdirection);
+ });
+ } else {
+@@ -269,6 +423,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
+ ItemStack itemstack = iinventory.getItem(i);
+
+ if (!itemstack.isEmpty() && b(iinventory, itemstack, i, enumdirection)) {
++ return hopperPull(ihopper, iinventory, i); /* // Paper - disable rest
+ ItemStack itemstack1 = itemstack.cloneItemStack();
+ // ItemStack itemstack2 = addItem(iinventory, ihopper, iinventory.splitStack(i, 1), (EnumDirection) null);
+ // CraftBukkit start - Call event on collection of items from inventories into the hopper
+@@ -305,7 +460,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
+ }
+
+ itemstack1.subtract(origCount - itemstack2.getCount()); // Spigot
+- iinventory.setItem(i, itemstack1);
++ iinventory.setItem(i, itemstack1);*/ // Paper - end commenting out replaced block for Hopper Optimizations
+ }
+
+ return false;
+@@ -314,7 +469,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
+ public static boolean a(IInventory iinventory, EntityItem entityitem) {
+ boolean flag = false;
+ // CraftBukkit start
+- InventoryPickupItemEvent event = new InventoryPickupItemEvent(iinventory.getOwner().getInventory(), (org.bukkit.entity.Item) entityitem.getBukkitEntity());
++ InventoryPickupItemEvent event = new InventoryPickupItemEvent(getInventory(iinventory), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); // Paper - use getInventory() to avoid snapshot creation
+ entityitem.world.getServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return false;
+@@ -368,7 +523,9 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
+ boolean flag1 = iinventory1.isNotEmpty();
+
+ if (itemstack1.isEmpty()) {
++ IGNORE_TILE_UPDATES = true; // Paper
+ iinventory1.setItem(i, itemstack);
++ IGNORE_TILE_UPDATES = false; // Paper
+ itemstack = ItemStack.a;
+ flag = true;
+ } else if (a(itemstack1, itemstack)) {
+--
+2.24.1
+