From 5c4864398d5773ec209fb8dd64fa146c38930f73 Mon Sep 17 00:00:00 2001 From: md_5 Date: Fri, 28 Jul 2017 17:23:39 +1000 Subject: SPIGOT-3463: Spurious item drops from event --- nms-patches/Block.patch | 21 +++++++-- nms-patches/PlayerInteractManager.patch | 75 ++++++++++++++++++++------------ nms-patches/World.patch | 77 +++++++++++++++++---------------- 3 files changed, 104 insertions(+), 69 deletions(-) diff --git a/nms-patches/Block.patch b/nms-patches/Block.patch index 5933b92a..a509ae3c 100644 --- a/nms-patches/Block.patch +++ b/nms-patches/Block.patch @@ -19,7 +19,22 @@ Item item = this.getDropType(iblockdata, world.random, i); if (item != Items.a) { -@@ -923,7 +924,7 @@ +@@ -364,7 +365,13 @@ + EntityItem entityitem = new EntityItem(world, (double) blockposition.getX() + d0, (double) blockposition.getY() + d1, (double) blockposition.getZ() + d2, itemstack); + + entityitem.q(); +- world.addEntity(entityitem); ++ // CraftBukkit start ++ if (world.captureDrops != null) { ++ world.captureDrops.add(entityitem); ++ } else { ++ world.addEntity(entityitem); ++ } ++ // CraftBukkit end + } + } + +@@ -923,7 +930,7 @@ if (hashset.contains(block16)) { for (int i = 0; i < 15; ++i) { @@ -28,7 +43,7 @@ Block.REGISTRY_ID.a(block16.fromLegacyData(i), j); } -@@ -932,7 +933,7 @@ +@@ -932,7 +939,7 @@ while (unmodifiableiterator.hasNext()) { IBlockData iblockdata = (IBlockData) unmodifiableiterator.next(); @@ -37,7 +52,7 @@ Block.REGISTRY_ID.a(iblockdata, k); } -@@ -941,6 +942,12 @@ +@@ -941,6 +948,12 @@ } diff --git a/nms-patches/PlayerInteractManager.patch b/nms-patches/PlayerInteractManager.patch index f140fbe1..319bef8d 100644 --- a/nms-patches/PlayerInteractManager.patch +++ b/nms-patches/PlayerInteractManager.patch @@ -1,9 +1,10 @@ --- a/net/minecraft/server/PlayerInteractManager.java +++ b/net/minecraft/server/PlayerInteractManager.java -@@ -1,5 +1,13 @@ +@@ -1,5 +1,14 @@ package net.minecraft.server; +// CraftBukkit start ++import java.util.ArrayList; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.Event; @@ -14,7 +15,7 @@ public class PlayerInteractManager { public World world; -@@ -26,7 +34,7 @@ +@@ -26,7 +35,7 @@ this.gamemode = enumgamemode; enumgamemode.a(this.player.abilities); this.player.updateAbilities(); @@ -23,7 +24,7 @@ this.world.everyoneSleeping(); } -@@ -51,7 +59,7 @@ +@@ -51,7 +60,7 @@ } public void a() { @@ -32,7 +33,7 @@ float f; int i; -@@ -96,6 +104,19 @@ +@@ -96,6 +105,19 @@ } public void a(BlockPosition blockposition, EnumDirection enumdirection) { @@ -52,7 +53,7 @@ if (this.isCreative()) { if (!this.world.douseFire((EntityHuman) null, blockposition, enumdirection)) { this.breakBlock(blockposition); -@@ -123,14 +144,48 @@ +@@ -123,14 +145,48 @@ } } @@ -103,7 +104,7 @@ if (iblockdata.getMaterial() != Material.AIR && f >= 1.0F) { this.breakBlock(blockposition); -@@ -148,6 +203,7 @@ +@@ -148,6 +204,7 @@ public void a(BlockPosition blockposition) { if (blockposition.equals(this.f)) { @@ -111,7 +112,7 @@ int i = this.currentTick - this.lastDigTick; IBlockData iblockdata = this.world.getType(blockposition); -@@ -165,6 +221,10 @@ +@@ -165,6 +222,10 @@ this.j = this.lastDigTick; } } @@ -122,7 +123,7 @@ } } -@@ -188,13 +248,86 @@ +@@ -188,13 +249,86 @@ } public boolean breakBlock(BlockPosition blockposition) { @@ -210,7 +211,24 @@ if ((block instanceof BlockCommand || block instanceof BlockStructure) && !this.player.isCreativeAndOp()) { this.world.notify(blockposition, iblockdata, iblockdata, 3); return false; -@@ -231,10 +364,18 @@ +@@ -218,7 +352,16 @@ + } + + this.world.a(this.player, 2001, blockposition, Block.getCombinedId(iblockdata)); ++ // CraftBukkit start ++ world.captureDrops = new ArrayList<>(); + boolean flag = this.c(blockposition); ++ if (event.isDropItems()) { ++ for (EntityItem item : world.captureDrops) { ++ world.addEntity(item); ++ } ++ } ++ world.captureDrops = null; ++ // CraftBukkit end + + if (this.isCreative()) { + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); +@@ -231,11 +374,19 @@ itemstack1.a(this.world, iblockdata, blockposition, this.player); } @@ -220,17 +238,18 @@ iblockdata.getBlock().a(this.world, this.player, blockposition, iblockdata, tileentity, itemstack2); } + // CraftBukkit end -+ } -+ + } + + // CraftBukkit start - Drop event experience + if (flag && event != null) { + iblockdata.getBlock().dropExperience(this.world, blockposition, event.getExpToDrop()); - } ++ } + // CraftBukkit end - ++ return flag; } -@@ -278,63 +419,90 @@ + } +@@ -278,63 +429,90 @@ } } @@ -244,28 +263,28 @@ + EnumInteractionResult enuminteractionresult = EnumInteractionResult.FAIL; + if (blockdata.getBlock() != Blocks.AIR) { + boolean cancelledBlock = false; ++ ++ if (this.gamemode == EnumGamemode.SPECTATOR) { ++ TileEntity tileentity = world.getTileEntity(blockposition); ++ cancelledBlock = !(tileentity instanceof ITileInventory || tileentity instanceof IInventory); ++ } - if (tileentity instanceof ITileInventory) { - Block block = world.getType(blockposition).getBlock(); - ITileInventory itileinventory = (ITileInventory) tileentity; -+ if (this.gamemode == EnumGamemode.SPECTATOR) { -+ TileEntity tileentity = world.getTileEntity(blockposition); -+ cancelledBlock = !(tileentity instanceof ITileInventory || tileentity instanceof IInventory); ++ if (entityhuman.getCooldownTracker().a(itemstack.getItem())) { ++ cancelledBlock = true; + } - if (itileinventory instanceof TileEntityChest && block instanceof BlockChest) { - itileinventory = ((BlockChest) block).getInventory(world, blockposition); - } -+ if (entityhuman.getCooldownTracker().a(itemstack.getItem())) { -+ cancelledBlock = true; -+ } ++ if (itemstack.getItem() instanceof ItemBlock && !entityhuman.isCreativeAndOp()) { ++ Block block1 = ((ItemBlock) itemstack.getItem()).getBlock(); - if (itileinventory != null) { - entityhuman.openContainer(itileinventory); - return EnumInteractionResult.SUCCESS; -+ if (itemstack.getItem() instanceof ItemBlock && !entityhuman.isCreativeAndOp()) { -+ Block block1 = ((ItemBlock) itemstack.getItem()).getBlock(); -+ + if (block1 instanceof BlockCommand || block1 instanceof BlockStructure) { + cancelledBlock = true; } @@ -294,12 +313,12 @@ + enuminteractionresult = (event.useItemInHand() != Event.Result.ALLOW) ? EnumInteractionResult.SUCCESS : EnumInteractionResult.PASS; + } else if (this.gamemode == EnumGamemode.SPECTATOR) { + TileEntity tileentity = world.getTileEntity(blockposition); -+ + +- if (iblockdata.getBlock().interact(world, blockposition, iblockdata, entityhuman, enumhand, enumdirection, f, f1, f2)) { + if (tileentity instanceof ITileInventory) { + Block block = world.getType(blockposition).getBlock(); + ITileInventory itileinventory = (ITileInventory) tileentity; - -- if (iblockdata.getBlock().interact(world, blockposition, iblockdata, entityhuman, enumhand, enumdirection, f, f1, f2)) { ++ + if (itileinventory instanceof TileEntityChest && block instanceof BlockChest) { + itileinventory = ((BlockChest) block).getInventory(world, blockposition); + } @@ -338,9 +357,9 @@ + if (!itemstack.isEmpty() && enuminteractionresult != EnumInteractionResult.SUCCESS && !interactResult) { // add !interactResult SPIGOT-764 + int i = itemstack.getData(); + int j = itemstack.getCount(); - -+ enuminteractionresult = itemstack.placeItem(entityhuman, world, blockposition, enumhand, enumdirection, f, f1, f2); + ++ enuminteractionresult = itemstack.placeItem(entityhuman, world, blockposition, enumhand, enumdirection, f, f1, f2); + + // The item count should not decrement in Creative mode. + if (this.isCreative()) { itemstack.setData(i); diff --git a/nms-patches/World.patch b/nms-patches/World.patch index 2337b695..c6c7003d 100644 --- a/nms-patches/World.patch +++ b/nms-patches/World.patch @@ -22,7 +22,7 @@ public abstract class World implements IBlockAccess { private int a = 63; -@@ -58,7 +73,51 @@ +@@ -58,7 +73,52 @@ private final WorldBorder P; int[] J; @@ -49,6 +49,7 @@ + return super.add( blockState ); + } + }; ++ public List captureDrops; + public long ticksPerAnimalSpawns; + public long ticksPerMonsterSpawns; + public boolean populating; @@ -75,7 +76,7 @@ this.u = Lists.newArrayList(new IWorldAccess[] { this.t}); this.N = Calendar.getInstance(); this.scoreboard = new Scoreboard(); -@@ -71,6 +130,36 @@ +@@ -71,6 +131,36 @@ this.worldProvider = worldprovider; this.isClientSide = flag; this.P = worldprovider.getWorldBorder(); @@ -112,7 +113,7 @@ } public World b() { -@@ -208,6 +297,27 @@ +@@ -208,6 +298,27 @@ } public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) { @@ -140,7 +141,7 @@ if (this.E(blockposition)) { return false; } else if (!this.isClientSide && this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { -@@ -215,9 +325,23 @@ +@@ -215,9 +326,23 @@ } else { Chunk chunk = this.getChunkAtWorldCoords(blockposition); Block block = iblockdata.getBlock(); @@ -164,7 +165,7 @@ return false; } else { if (iblockdata.c() != iblockdata1.c() || iblockdata.d() != iblockdata1.d()) { -@@ -226,6 +350,7 @@ +@@ -226,6 +351,7 @@ this.methodProfiler.b(); } @@ -172,7 +173,7 @@ if ((i & 2) != 0 && (!this.isClientSide || (i & 4) == 0) && chunk.isReady()) { this.notify(blockposition, iblockdata1, iblockdata, i); } -@@ -238,12 +363,37 @@ +@@ -238,12 +364,37 @@ } else if (!this.isClientSide && (i & 16) == 0) { this.c(blockposition, block); } @@ -210,7 +211,7 @@ public boolean setAir(BlockPosition blockposition) { return this.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 3); } -@@ -277,6 +427,11 @@ +@@ -277,6 +428,11 @@ public void update(BlockPosition blockposition, Block block, boolean flag) { if (this.worldData.getType() != WorldType.DEBUG_ALL_BLOCK_STATES) { @@ -222,7 +223,7 @@ this.applyPhysics(blockposition, block, flag); } -@@ -365,6 +520,17 @@ +@@ -365,6 +521,17 @@ IBlockData iblockdata = this.getType(blockposition); try { @@ -240,7 +241,7 @@ iblockdata.doPhysics(this, blockposition, block, blockposition1); } catch (Throwable throwable) { CrashReport crashreport = CrashReport.a(throwable, "Exception while updating neighbours"); -@@ -582,6 +748,17 @@ +@@ -582,6 +749,17 @@ } public IBlockData getType(BlockPosition blockposition) { @@ -258,7 +259,7 @@ if (this.E(blockposition)) { return Blocks.AIR.getBlockData(); } else { -@@ -787,6 +964,13 @@ +@@ -787,6 +965,13 @@ } public boolean addEntity(Entity entity) { @@ -272,7 +273,7 @@ int i = MathHelper.floor(entity.locX / 16.0D); int j = MathHelper.floor(entity.locZ / 16.0D); boolean flag = entity.attachedToPlayer; -@@ -795,6 +979,37 @@ +@@ -795,6 +980,37 @@ flag = true; } @@ -310,7 +311,7 @@ if (!flag && !this.isChunkLoaded(i, j, false)) { return false; } else { -@@ -817,6 +1032,7 @@ +@@ -817,6 +1033,7 @@ ((IWorldAccess) this.u.get(i)).a(entity); } @@ -318,7 +319,7 @@ } protected void c(Entity entity) { -@@ -824,6 +1040,7 @@ +@@ -824,6 +1041,7 @@ ((IWorldAccess) this.u.get(i)).b(entity); } @@ -326,7 +327,7 @@ } public void kill(Entity entity) { -@@ -859,7 +1076,15 @@ +@@ -859,7 +1077,15 @@ this.getChunkAt(i, j).b(entity); } @@ -343,7 +344,7 @@ this.c(entity); } -@@ -976,7 +1201,7 @@ +@@ -976,7 +1202,7 @@ } public boolean a(AxisAlignedBB axisalignedbb) { @@ -352,7 +353,7 @@ } public int a(float f) { -@@ -1046,6 +1271,11 @@ +@@ -1046,6 +1272,11 @@ for (i = 0; i < this.j.size(); ++i) { entity = (Entity) this.j.get(i); @@ -364,7 +365,7 @@ try { ++entity.ticksLived; -@@ -1094,8 +1324,10 @@ +@@ -1094,8 +1325,10 @@ CrashReportSystemDetails crashreportsystemdetails1; CrashReport crashreport1; @@ -377,7 +378,7 @@ Entity entity1 = entity.bJ(); if (entity1 != null) { -@@ -1128,7 +1360,7 @@ +@@ -1128,7 +1361,7 @@ this.getChunkAt(j, l).b(entity); } @@ -386,7 +387,7 @@ this.c(entity); } -@@ -1137,6 +1369,13 @@ +@@ -1137,6 +1370,13 @@ this.methodProfiler.c("blockEntities"); this.O = true; @@ -400,7 +401,7 @@ Iterator iterator = this.tileEntityListTick.iterator(); while (iterator.hasNext()) { -@@ -1147,7 +1386,7 @@ +@@ -1147,7 +1387,7 @@ if (this.isLoaded(blockposition) && this.P.a(blockposition)) { try { @@ -409,7 +410,7 @@ ((ITickable) tileentity).e(); this.methodProfiler.b(); } catch (Throwable throwable2) { -@@ -1169,11 +1408,13 @@ +@@ -1169,11 +1409,13 @@ } this.O = false; @@ -423,7 +424,7 @@ this.methodProfiler.c("pendingBlockEntities"); if (!this.b.isEmpty()) { -@@ -1181,9 +1422,11 @@ +@@ -1181,9 +1423,11 @@ TileEntity tileentity1 = (TileEntity) this.b.get(i1); if (!tileentity1.y()) { @@ -435,7 +436,7 @@ if (this.isLoaded(tileentity1.getPosition())) { Chunk chunk = this.getChunkAtWorldCoords(tileentity1.getPosition()); -@@ -1191,6 +1434,12 @@ +@@ -1191,6 +1435,12 @@ chunk.a(tileentity1.getPosition(), tileentity1); this.notify(tileentity1.getPosition(), iblockdata, iblockdata, 3); @@ -448,7 +449,7 @@ } } } -@@ -1244,15 +1493,13 @@ +@@ -1244,15 +1494,13 @@ int i; int j; @@ -470,7 +471,7 @@ entity.M = entity.locX; entity.N = entity.locY; -@@ -1265,6 +1512,7 @@ +@@ -1265,6 +1513,7 @@ entity.aE(); } else { entity.B_(); @@ -478,7 +479,7 @@ } } -@@ -1556,11 +1804,18 @@ +@@ -1556,11 +1805,18 @@ } } @@ -497,7 +498,7 @@ TileEntity tileentity = null; if (this.O) { -@@ -1595,6 +1850,14 @@ +@@ -1595,6 +1851,14 @@ public void setTileEntity(BlockPosition blockposition, @Nullable TileEntity tileentity) { if (!this.E(blockposition)) { if (tileentity != null && !tileentity.y()) { @@ -512,7 +513,7 @@ if (this.O) { tileentity.setPosition(blockposition); Iterator iterator = this.b.iterator(); -@@ -1754,6 +2017,14 @@ +@@ -1754,6 +2018,14 @@ } this.o = MathHelper.a(this.o, 0.0F, 1.0F); @@ -527,7 +528,7 @@ } } } -@@ -1891,7 +2162,10 @@ +@@ -1891,7 +2163,10 @@ } public boolean c(EnumSkyBlock enumskyblock, BlockPosition blockposition) { @@ -539,7 +540,7 @@ return false; } else { int i = 0; -@@ -2058,7 +2332,7 @@ +@@ -2058,7 +2333,7 @@ while (iterator.hasNext()) { Entity entity = (Entity) iterator.next(); @@ -548,7 +549,7 @@ arraylist.add(entity); } } -@@ -2073,7 +2347,7 @@ +@@ -2073,7 +2348,7 @@ while (iterator.hasNext()) { Entity entity = (Entity) iterator.next(); @@ -557,7 +558,7 @@ arraylist.add(entity); } } -@@ -2122,7 +2396,7 @@ +@@ -2122,7 +2397,7 @@ } } @@ -566,7 +567,7 @@ } @Nullable -@@ -2143,8 +2417,17 @@ +@@ -2143,8 +2418,17 @@ while (iterator.hasNext()) { Entity entity = (Entity) iterator.next(); @@ -585,7 +586,7 @@ ++i; } } -@@ -2153,12 +2436,18 @@ +@@ -2153,12 +2437,18 @@ } public void a(Collection collection) { @@ -605,7 +606,7 @@ this.b(entity); } -@@ -2172,7 +2461,13 @@ +@@ -2172,7 +2462,13 @@ IBlockData iblockdata = this.getType(blockposition); AxisAlignedBB axisalignedbb = flag ? null : block.getBlockData().d(this, blockposition); @@ -620,7 +621,7 @@ } public int getSeaLevel() { -@@ -2282,6 +2577,11 @@ +@@ -2282,6 +2578,11 @@ for (int i = 0; i < this.players.size(); ++i) { EntityHuman entityhuman1 = (EntityHuman) this.players.get(i); @@ -632,7 +633,7 @@ if (predicate.apply(entityhuman1)) { double d5 = entityhuman1.d(d0, d1, d2); -@@ -2450,6 +2750,16 @@ +@@ -2450,6 +2751,16 @@ public void everyoneSleeping() {} @@ -649,7 +650,7 @@ public float h(float f) { return (this.p + (this.q - this.p) * f) * this.j(f); } -@@ -2667,7 +2977,7 @@ +@@ -2667,7 +2978,7 @@ int l = j * 16 + 8 - blockposition.getZ(); boolean flag = true; -- cgit v1.2.3