From dff66dfccd64280d066715340c0692f6e376be0b Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Sat, 22 Dec 2018 11:32:11 +1100
Subject: [PATCH] Reduce copying of positions from block states

---
 nms-patches/BlockSponge.patch                   |  2 +-
 nms-patches/ItemStack.patch                     | 17 +++++++----------
 nms-patches/World.patch                         |  4 ++--
 .../java/org/bukkit/craftbukkit/CraftWorld.java | 11 ++---------
 .../block/CraftBlockEntityState.java            |  4 ++--
 .../craftbukkit/block/CraftBlockState.java      |  6 +++++-
 .../bukkit/craftbukkit/block/CraftChest.java    |  3 +--
 .../craftbukkit/block/CraftDispenser.java       |  2 +-
 .../bukkit/craftbukkit/block/CraftDropper.java  |  2 +-
 .../bukkit/craftbukkit/block/CraftJukebox.java  |  6 +++---
 10 files changed, 25 insertions(+), 32 deletions(-)

diff --git a/nms-patches/BlockSponge.patch b/nms-patches/BlockSponge.patch
index f6f58628d5..5164942f8c 100644
--- a/nms-patches/BlockSponge.patch
+++ b/nms-patches/BlockSponge.patch
@@ -63,7 +63,7 @@
 +            }
 +
 +            for (CraftBlockState block : blocks) {
-+                BlockPosition blockposition2 = new BlockPosition(block.getX(), block.getY(), block.getZ());
++                BlockPosition blockposition2 = block.getPosition();
 +                IBlockData iblockdata = world.getType(blockposition2);
 +                Fluid fluid = world.getFluid(blockposition2);
 +                Material material = iblockdata.getMaterial();
diff --git a/nms-patches/ItemStack.patch b/nms-patches/ItemStack.patch
index 70188127cd..2a6f40f7a2 100644
--- a/nms-patches/ItemStack.patch
+++ b/nms-patches/ItemStack.patch
@@ -85,7 +85,7 @@
          EntityHuman entityhuman = itemactioncontext.getEntity();
          BlockPosition blockposition = itemactioncontext.getClickPosition();
          ShapeDetectorBlock shapedetectorblock = new ShapeDetectorBlock(itemactioncontext.getWorld(), blockposition, false);
-@@ -106,12 +146,147 @@
+@@ -106,12 +146,144 @@
          if (entityhuman != null && !entityhuman.abilities.mayBuild && !this.b(itemactioncontext.getWorld().F(), shapedetectorblock)) {
              return EnumInteractionResult.PASS;
          } else {
@@ -178,12 +178,9 @@
 +                    }
 +
 +                    for (BlockState blockstate : blocks) {
-+                        int x = blockstate.getX();
-+                        int y = blockstate.getY();
-+                        int z = blockstate.getZ();
 +                        int updateFlag = ((CraftBlockState) blockstate).getFlag();
 +                        IBlockData oldBlock = ((CraftBlockState) blockstate).getHandle();
-+                        BlockPosition newblockposition = new BlockPosition(x, y, z);
++                        BlockPosition newblockposition = ((CraftBlockState) blockstate).getPosition();
 +                        IBlockData block = world.getType(newblockposition);
 +
 +                        if (!(block.getBlock() instanceof BlockTileEntity)) { // Containers get placed automatically
@@ -234,7 +231,7 @@
  
              return enuminteractionresult;
          }
-@@ -135,7 +310,7 @@
+@@ -135,7 +307,7 @@
          nbttagcompound.setString("id", minecraftkey == null ? "minecraft:air" : minecraftkey.toString());
          nbttagcompound.setByte("Count", (byte) this.count);
          if (this.tag != null) {
@@ -243,7 +240,7 @@
          }
  
          return nbttagcompound;
-@@ -213,6 +388,11 @@
+@@ -213,6 +385,11 @@
                  if (this.isDamaged(i, entityliving.getRandom(), entityliving instanceof EntityPlayer ? (EntityPlayer) entityliving : null)) {
                      entityliving.c(this);
                      Item item = this.getItem();
@@ -255,7 +252,7 @@
  
                      this.subtract(1);
                      if (entityliving instanceof EntityHuman) {
-@@ -336,6 +516,17 @@
+@@ -336,6 +513,17 @@
          return this.tag;
      }
  
@@ -273,7 +270,7 @@
      public NBTTagCompound getOrCreateTag() {
          if (this.tag == null) {
              this.setTag(new NBTTagCompound());
-@@ -480,6 +671,14 @@
+@@ -480,6 +668,14 @@
      }
  
      public void setRepairCost(int i) {
@@ -288,7 +285,7 @@
          this.getOrCreateTag().setInt("RepairCost", i);
      }
  
-@@ -522,6 +721,13 @@
+@@ -522,6 +718,13 @@
          nbttaglist.add((NBTBase) nbttagcompound);
      }
  
diff --git a/nms-patches/World.patch b/nms-patches/World.patch
index 8d5309bb87..1ef6e82074 100644
--- a/nms-patches/World.patch
+++ b/nms-patches/World.patch
@@ -125,7 +125,7 @@
 +            Iterator<CraftBlockState> it = capturedBlockStates.iterator();
 +            while (it.hasNext()) {
 +                CraftBlockState previous = it.next();
-+                if (previous.getX() == blockposition.getX() && previous.getY() == blockposition.getY() && previous.getZ() == blockposition.getZ()) {
++                if (previous.getPosition().equals(blockposition)) {
 +                    blockstate = previous;
 +                    it.remove();
 +                    break;
@@ -287,7 +287,7 @@
 +            Iterator<CraftBlockState> it = capturedBlockStates.iterator();
 +            while (it.hasNext()) {
 +                CraftBlockState previous = it.next();
-+                if (previous.getX() == blockposition.getX() && previous.getY() == blockposition.getY() && previous.getZ() == blockposition.getZ()) {
++                if (previous.getPosition().equals(blockposition)) {
 +                    return previous.getHandle();
 +                }
 +            }
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 27ebfb3016..77019f79dc 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -416,13 +416,10 @@ public class CraftWorld implements World {
         world.captureTreeGeneration = false;
         if (grownTree) { // Copy block data to delegate
             for (BlockState blockstate : world.capturedBlockStates) {
-                int x = blockstate.getX();
-                int y = blockstate.getY();
-                int z = blockstate.getZ();
-                BlockPosition position = new BlockPosition(x, y, z);
+                BlockPosition position = ((CraftBlockState) blockstate).getPosition();
                 net.minecraft.server.IBlockData oldBlock = world.getType(position);
                 int flag = ((CraftBlockState) blockstate).getFlag();
-                delegate.setBlockData(x, y, z, blockstate.getBlockData());
+                delegate.setBlockData(blockstate.getX(), blockstate.getY(), blockstate.getZ(), blockstate.getBlockData());
                 net.minecraft.server.IBlockData newBlock = world.getType(position);
                 world.notifyAndUpdatePhysics(position, null, oldBlock, newBlock, newBlock, flag);
             }
@@ -434,10 +431,6 @@ public class CraftWorld implements World {
         }
     }
 
-    public TileEntity getTileEntityAt(final int x, final int y, final int z) {
-        return world.getTileEntity(new BlockPosition(x, y, z));
-    }
-
     public String getName() {
         return world.worldData.getName();
     }
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
index ac9b4297b2..8617fac6b0 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
@@ -21,7 +21,7 @@ public class CraftBlockEntityState<T extends TileEntity> extends CraftBlockState
 
         // get tile entity from block:
         CraftWorld world = (CraftWorld) this.getWorld();
-        this.tileEntity = tileEntityClass.cast(world.getTileEntityAt(this.getX(), this.getY(), this.getZ()));
+        this.tileEntity = tileEntityClass.cast(world.getHandle().getTileEntity(this.getPosition()));
 
         // copy tile entity data:
         this.snapshot = this.createSnapshot(tileEntity, world.getHandle());
@@ -74,7 +74,7 @@ public class CraftBlockEntityState<T extends TileEntity> extends CraftBlockState
     protected TileEntity getTileEntityFromWorld() {
         requirePlaced();
 
-        return ((CraftWorld) this.getWorld()).getTileEntityAt(this.getX(), this.getY(), this.getZ());
+        return ((CraftWorld) this.getWorld()).getHandle().getTileEntity(this.getPosition());
     }
 
     // gets the NBT data of the TileEntity represented by this block state
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
index 497f3da7dc..97385bd4d7 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
@@ -25,7 +25,7 @@ import net.minecraft.server.IBlockData;
 public class CraftBlockState implements BlockState {
     private final CraftWorld world;
     private final CraftChunk chunk;
-    protected final BlockPosition position;
+    private final BlockPosition position;
     protected IBlockData data;
     protected int flag;
 
@@ -83,6 +83,10 @@ public class CraftBlockState implements BlockState {
         this.data = data;
     }
 
+    public BlockPosition getPosition() {
+        return this.position;
+    }
+
     public IBlockData getHandle() {
         return this.data;
     }
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
index e0b457cd84..fa03d17a4c 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
@@ -1,7 +1,6 @@
 package org.bukkit.craftbukkit.block;
 
 import net.minecraft.server.BlockChest;
-import net.minecraft.server.BlockPosition;
 import net.minecraft.server.Blocks;
 import net.minecraft.server.ITileInventory;
 import net.minecraft.server.InventoryLargeChest;
@@ -50,7 +49,7 @@ public class CraftChest extends CraftLootable<TileEntityChest> implements Chest
         CraftWorld world = (CraftWorld) this.getWorld();
 
         BlockChest blockChest = (BlockChest) (this.getType() == Material.CHEST ? Blocks.CHEST : Blocks.TRAPPED_CHEST);
-        ITileInventory nms = blockChest.getInventory(data, world.getHandle(), position, true);
+        ITileInventory nms = blockChest.getInventory(data, world.getHandle(), this.getPosition(), true);
 
         if (nms instanceof InventoryLargeChest) {
             inventory = new CraftInventoryDoubleChest((InventoryLargeChest) nms);
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java b/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java
index 1dc8bfecd2..452ea9e4c5 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java
@@ -57,7 +57,7 @@ public class CraftDispenser extends CraftLootable<TileEntityDispenser> implement
             CraftWorld world = (CraftWorld) this.getWorld();
             BlockDispenser dispense = (BlockDispenser) Blocks.DISPENSER;
 
-            dispense.dispense(world.getHandle(), new BlockPosition(getX(), getY(), getZ()));
+            dispense.dispense(world.getHandle(), this.getPosition());
             return true;
         } else {
             return false;
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java b/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java
index 27f6e66ec8..6b4bdbc8cd 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java
@@ -44,7 +44,7 @@ public class CraftDropper extends CraftLootable<TileEntityDropper> implements Dr
             CraftWorld world = (CraftWorld) this.getWorld();
             BlockDropper drop = (BlockDropper) Blocks.DROPPER;
 
-            drop.dispense(world.getHandle(), new BlockPosition(getX(), getY(), getZ()));
+            drop.dispense(world.getHandle(), this.getPosition());
         }
     }
 }
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java b/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java
index 3914234bdc..b527cf98ca 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java
@@ -31,9 +31,9 @@ public class CraftJukebox extends CraftBlockEntityState<TileEntityJukeBox> imple
             CraftWorld world = (CraftWorld) this.getWorld();
             Material record = this.getPlaying();
             if (record == Material.AIR) {
-                world.getHandle().setTypeAndData(position, Blocks.JUKEBOX.getBlockData().set(BlockJukeBox.HAS_RECORD, false), 3);
+                world.getHandle().setTypeAndData(this.getPosition(), Blocks.JUKEBOX.getBlockData().set(BlockJukeBox.HAS_RECORD, false), 3);
             } else {
-                world.getHandle().setTypeAndData(position, Blocks.JUKEBOX.getBlockData().set(BlockJukeBox.HAS_RECORD, true), 3);
+                world.getHandle().setTypeAndData(this.getPosition(), Blocks.JUKEBOX.getBlockData().set(BlockJukeBox.HAS_RECORD, true), 3);
             }
             world.playEffect(this.getLocation(), Effect.RECORD_PLAY, record);
         }
@@ -86,7 +86,7 @@ public class CraftJukebox extends CraftBlockEntityState<TileEntityJukeBox> imple
         TileEntityJukeBox jukebox = (TileEntityJukeBox) tileEntity;
         boolean result = !jukebox.getRecord().isEmpty();
         CraftWorld world = (CraftWorld) this.getWorld();
-        ((BlockJukeBox) Blocks.JUKEBOX).dropRecord(world.getHandle(), position);
+        ((BlockJukeBox) Blocks.JUKEBOX).dropRecord(world.getHandle(), getPosition());
         return result;
     }
 }