forked from PaperMC/Paper
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
In 1.12, Spigot improved their blockstate implementation to take a full copy of the TE, this allows for a much better snapshot in that it will actually retain all of the TE's state, it is a much more expensive implementation. This is also implicated with their backwards compat for inventories meaning that accessing of a snapshots inventory of a placed block will actually access the inventory of the live TE, making creation of a snapshot redundant if the only intent is to interact with the TEs inventory. Hoppers are a horrible hit, every attempt to transfer an ItemStack will result in two TileEntity snapshots, with two hoppers and a double chest ontop, I managed to log 380 cases per second where a snapshot would have been taken in cases where the snapshot is redundant.
- Loading branch information
1 parent
79f57aa
commit f4e9f47
Showing
1 changed file
with
67 additions
and
0 deletions.
There are no files selected for viewing
67 changes: 67 additions & 0 deletions
67
Spigot-Server-Patches/0255-Do-not-use-a-snapshot-for-hoppers.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
From b0456f32941d38b616e2e3f3f37583cb7a5713ef Mon Sep 17 00:00:00 2001 | ||
From: Shane Freeder <[email protected]> | ||
Date: Sat, 25 Nov 2017 17:02:33 +0000 | ||
Subject: [PATCH] Do not use a snapshot for hoppers | ||
|
||
In 1.12, Spigot improved their blockstate implementation to take a full | ||
copy of the TE, this allows for a much better snapshot in that it will | ||
actually retain all of the TE's state, it is a much more expensive | ||
implementation. This is also implicated with their backwards compat | ||
for inventories meaning that accessing of a snapshots inventory of a | ||
placed block will actually access the inventory of the live TE, making | ||
creation of a snapshot redundant if the only intent is to interact with | ||
the TEs inventory. | ||
|
||
Hoppers are a horrible hit, every attempt to transfer an ItemStack will | ||
result in two TileEntity state snapshots, with two hoppers and a double chest | ||
ontop, I managed to log 380 cases per second where a snapshot would have been | ||
taken in cases where the snapshot is redundant. | ||
|
||
diff --git a/src/main/java/net/minecraft/server/TileEntityHopper.java b/src/main/java/net/minecraft/server/TileEntityHopper.java | ||
index 8ad081316..ebbe5d326 100644 | ||
--- a/src/main/java/net/minecraft/server/TileEntityHopper.java | ||
+++ b/src/main/java/net/minecraft/server/TileEntityHopper.java | ||
@@ -219,11 +219,15 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi | ||
// Have to special case large chests as they work oddly | ||
if (iinventory instanceof InventoryLargeChest) { | ||
destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); | ||
+ // Paper start - avoid redundant snapshot creation of a TE | ||
+ } else if (iinventory instanceof TileEntity) { | ||
+ destinationInventory = ((TileEntity) iinventory).getOwner(false).getInventory(); | ||
} else { | ||
destinationInventory = iinventory.getOwner().getInventory(); | ||
} | ||
|
||
- InventoryMoveItemEvent event = new InventoryMoveItemEvent(this.getOwner().getInventory(), oitemstack.clone(), destinationInventory, true); | ||
+ InventoryMoveItemEvent event = new InventoryMoveItemEvent(this.getOwner(false).getInventory(), oitemstack.clone(), destinationInventory, true); | ||
+ // Paper end - avoid redundant snapshot creation of a TE | ||
this.getWorld().getServer().getPluginManager().callEvent(event); | ||
if (event.isCancelled()) { | ||
this.setItem(i, itemstack); | ||
@@ -379,12 +383,22 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi | ||
// Have to special case large chests as they work oddly | ||
if (iinventory instanceof InventoryLargeChest) { | ||
sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); | ||
+ // Paper start - avoid redundant snapshot creation of a TE | ||
+ } else if (iinventory instanceof TileEntity){ | ||
+ sourceInventory = ((TileEntity) iinventory).getOwner(false).getInventory(); | ||
} else { | ||
sourceInventory = iinventory.getOwner().getInventory(); | ||
} | ||
|
||
- InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), ihopper.getOwner().getInventory(), false); | ||
+ Inventory destination; | ||
+ if (ihopper instanceof TileEntity) { | ||
+ destination = ((TileEntity) ihopper).getOwner(false).getInventory(); | ||
+ } else { | ||
+ destination = ihopper.getOwner().getInventory(); | ||
+ } | ||
|
||
+ InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), destination, false); | ||
+ // Paper end - avoid redundant snapshot creation of a TE | ||
ihopper.getWorld().getServer().getPluginManager().callEvent(event); | ||
if (event.isCancelled()) { | ||
iinventory.setItem(i, itemstack1); | ||
-- | ||
2.15.0 | ||
|