PaperMC/Spigot-Server-Patches/0253-Do-not-use-a-snapshot-for-hoppers.patch
Aikar 71c18fd5c9
Add PlayerProfile API to replace GameProfile
This simply provides the base API to create the objects. Further commits will come that adds
adds usage of this API to existing GameProfile based API's, as well as new API's.
2018-01-18 23:19:30 -05:00

67 lines
4.1 KiB
Diff

From ddc7428566ea2644e807eec0adc9f06829661059 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
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.1