SPIGOT-3463: Spurious item drops from event

This commit is contained in:
md_5 2017-07-28 17:23:39 +10:00
parent d2aa6845f0
commit 5c4864398d
3 changed files with 105 additions and 70 deletions

View File

@ -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 @@
}

View File

@ -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 (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 (itileinventory instanceof TileEntityChest && block instanceof BlockChest) {
- itileinventory = ((BlockChest) block).getInventory(world, blockposition);
- }
- if (tileentity instanceof ITileInventory) {
- Block block = world.getType(blockposition).getBlock();
- ITileInventory itileinventory = (ITileInventory) tileentity;
+ if (entityhuman.getCooldownTracker().a(itemstack.getItem())) {
+ cancelledBlock = true;
+ }
- if (itileinventory instanceof TileEntityChest && block instanceof BlockChest) {
- itileinventory = ((BlockChest) block).getInventory(world, blockposition);
- }
+ 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);

View File

@ -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<EntityItem> 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<Entity> 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;