From 1be3bd058faf4fc0f2a351e92a99786e53f770b9 Mon Sep 17 00:00:00 2001
From: Thinkofdeath <thinkofdeath@spigotmc.org>
Date: Tue, 1 Mar 2016 21:37:08 +0000
Subject: [PATCH] SPIGOT-1607: Fix BlockPlaceEvent and BlockMultiPlaceEvent
 sometimes showing the wrong item used

---
 nms-patches/ItemFlintAndSteel.patch           |  2 +-
 nms-patches/ItemStack.patch                   |  4 +--
 nms-patches/ItemWaterLily.patch               |  2 +-
 .../craftbukkit/event/CraftEventFactory.java  | 26 ++++++++++++++-----
 4 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/nms-patches/ItemFlintAndSteel.patch b/nms-patches/ItemFlintAndSteel.patch
index 20d31fe8c6..d6fa0787c4 100644
--- a/nms-patches/ItemFlintAndSteel.patch
+++ b/nms-patches/ItemFlintAndSteel.patch
@@ -33,7 +33,7 @@
                  world.setTypeAndData(blockposition, Blocks.FIRE.getBlockData(), 11);
 +
 +                // CraftBukkit start
-+                org.bukkit.event.block.BlockPlaceEvent placeEvent = CraftEventFactory.callBlockPlaceEvent(world, entityhuman, blockState, clicked.getX(), clicked.getY(), clicked.getZ());
++                org.bukkit.event.block.BlockPlaceEvent placeEvent = CraftEventFactory.callBlockPlaceEvent(world, entityhuman, enumhand, blockState, clicked.getX(), clicked.getY(), clicked.getZ());
 +
 +                if (placeEvent.isCancelled() || !placeEvent.canBuild()) {
 +                    placeEvent.getBlockPlaced().setTypeIdAndData(0, (byte) 0, false);
diff --git a/nms-patches/ItemStack.patch b/nms-patches/ItemStack.patch
index 5854616313..b271b49bd1 100644
--- a/nms-patches/ItemStack.patch
+++ b/nms-patches/ItemStack.patch
@@ -97,9 +97,9 @@
 +            List<BlockState> blocks = (List<BlockState>) world.capturedBlockStates.clone();
 +            world.capturedBlockStates.clear();
 +            if (blocks.size() > 1) {
-+                placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ());
++                placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, enumhand, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ());
 +            } else if (blocks.size() == 1) {
-+                placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, blocks.get(0), blockposition.getX(), blockposition.getY(), blockposition.getZ());
++                placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, enumhand, blocks.get(0), blockposition.getX(), blockposition.getY(), blockposition.getZ());
 +            }
 +
 +            if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) {
diff --git a/nms-patches/ItemWaterLily.patch b/nms-patches/ItemWaterLily.patch
index 18718a9074..ab27cf91ae 100644
--- a/nms-patches/ItemWaterLily.patch
+++ b/nms-patches/ItemWaterLily.patch
@@ -7,7 +7,7 @@
 +                    // CraftBukkit start - special case for handling block placement with water lilies
 +                    org.bukkit.block.BlockState blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(world, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ());
                      world.setTypeAndData(blockposition1, Blocks.WATERLILY.getBlockData(), 11);
-+                    org.bukkit.event.block.BlockPlaceEvent placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, blockstate, blockposition.getX(), blockposition.getY(), blockposition.getZ());
++                    org.bukkit.event.block.BlockPlaceEvent placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, enumhand, blockstate, blockposition.getX(), blockposition.getY(), blockposition.getZ());
 +                    if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) {
 +                        blockstate.update(true, false);
 +                        return new InteractionResultWrapper(EnumInteractionResult.PASS, itemstack);
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index b7d747cb35..f9ab0622c7 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -91,10 +91,10 @@ public class CraftEventFactory {
     /**
      * Block place methods
      */
-    public static BlockMultiPlaceEvent callBlockMultiPlaceEvent(World world, EntityHuman who, List<BlockState> blockStates, int clickedX, int clickedY, int clickedZ) {
+    public static BlockMultiPlaceEvent callBlockMultiPlaceEvent(World world, EntityHuman who, EnumHand hand, List<BlockState> blockStates, int clickedX, int clickedY, int clickedZ) {
         CraftWorld craftWorld = world.getWorld();
         CraftServer craftServer = world.getServer();
-        Player player = (who == null) ? null : (Player) who.getBukkitEntity();
+        Player player = (Player) who.getBukkitEntity();
 
         Block blockClicked = craftWorld.getBlockAt(clickedX, clickedY, clickedZ);
 
@@ -106,24 +106,38 @@ public class CraftEventFactory {
             }
         }
 
-        BlockMultiPlaceEvent event = new BlockMultiPlaceEvent(blockStates, blockClicked, player.getItemInHand(), player, canBuild);
+        org.bukkit.inventory.ItemStack item;
+        if (hand == EnumHand.MAIN_HAND) {
+            item = player.getInventory().getItemInMainHand();
+        } else {
+            item = player.getInventory().getItemInOffHand();
+        }
+
+        BlockMultiPlaceEvent event = new BlockMultiPlaceEvent(blockStates, blockClicked, item, player, canBuild);
         craftServer.getPluginManager().callEvent(event);
 
         return event;
     }
 
-    public static BlockPlaceEvent callBlockPlaceEvent(World world, EntityHuman who, BlockState replacedBlockState, int clickedX, int clickedY, int clickedZ) {
+    public static BlockPlaceEvent callBlockPlaceEvent(World world, EntityHuman who, EnumHand hand, BlockState replacedBlockState, int clickedX, int clickedY, int clickedZ) {
         CraftWorld craftWorld = world.getWorld();
         CraftServer craftServer = world.getServer();
 
-        Player player = (who == null) ? null : (Player) who.getBukkitEntity();
+        Player player = (Player) who.getBukkitEntity();
 
         Block blockClicked = craftWorld.getBlockAt(clickedX, clickedY, clickedZ);
         Block placedBlock = replacedBlockState.getBlock();
 
         boolean canBuild = canBuild(craftWorld, player, placedBlock.getX(), placedBlock.getZ());
 
-        BlockPlaceEvent event = new BlockPlaceEvent(placedBlock, replacedBlockState, blockClicked, player.getItemInHand(), player, canBuild);
+        org.bukkit.inventory.ItemStack item;
+        if (hand == EnumHand.MAIN_HAND) {
+            item = player.getInventory().getItemInMainHand();
+        } else {
+            item = player.getInventory().getItemInOffHand();
+        }
+
+        BlockPlaceEvent event = new BlockPlaceEvent(placedBlock, replacedBlockState, blockClicked, item, player, canBuild);
         craftServer.getPluginManager().callEvent(event);
 
         return event;