SPIGOT-6754: We ignore any still present TileEntity now when we create a BlockState for a block of type AIR.

During block destruction, the type of the block may already have been set to AIR while the TileEntity has not yet been removed.
Also, TileEntity#getOwner() skips the whole BlockState construction now if the block is of type AIR.

This removes the previous workaround again of returning a dummy CraftBlockEntityState in this case.

By: blablubbabc <lukas@wirsindwir.de>
This commit is contained in:
CraftBukkit/Spigot 2021-10-10 07:55:53 +11:00
parent e9ecd12983
commit 82e8261d70
3 changed files with 7 additions and 9 deletions

View File

@ -49,7 +49,7 @@
return nbttagcompound; return nbttagcompound;
} }
} }
@@ -164,4 +188,13 @@ @@ -164,4 +188,15 @@
public void b(IBlockData iblockdata) { public void b(IBlockData iblockdata) {
this.blockState = iblockdata; this.blockState = iblockdata;
} }
@ -57,7 +57,9 @@
+ // CraftBukkit start - add method + // CraftBukkit start - add method
+ public InventoryHolder getOwner() { + public InventoryHolder getOwner() {
+ if (level == null) return null; + if (level == null) return null;
+ org.bukkit.block.BlockState state = level.getWorld().getBlockAt(worldPosition.getX(), worldPosition.getY(), worldPosition.getZ()).getState(); + org.bukkit.block.Block block = level.getWorld().getBlockAt(worldPosition.getX(), worldPosition.getY(), worldPosition.getZ());
+ if (block.getType() == org.bukkit.Material.AIR) return null;
+ org.bukkit.block.BlockState state = block.getState();
+ if (state instanceof InventoryHolder) return (InventoryHolder) state; + if (state instanceof InventoryHolder) return (InventoryHolder) state;
+ return null; + return null;
+ } + }

View File

@ -6,7 +6,7 @@ import org.bukkit.World;
import org.bukkit.block.TileState; import org.bukkit.block.TileState;
import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataContainer;
public class CraftBlockEntityState<T extends TileEntity> extends CraftBlockState implements TileState { public abstract class CraftBlockEntityState<T extends TileEntity> extends CraftBlockState implements TileState {
private final T tileEntity; private final T tileEntity;
private final T snapshot; private final T snapshot;

View File

@ -106,12 +106,8 @@ public final class CraftBlockStates {
private static final BlockStateFactory<?> DEFAULT_FACTORY = new BlockStateFactory<CraftBlockState>(CraftBlockState.class) { private static final BlockStateFactory<?> DEFAULT_FACTORY = new BlockStateFactory<CraftBlockState>(CraftBlockState.class) {
@Override @Override
public CraftBlockState createBlockState(World world, BlockPosition blockPosition, IBlockData blockData, TileEntity tileEntity) { public CraftBlockState createBlockState(World world, BlockPosition blockPosition, IBlockData blockData, TileEntity tileEntity) {
// SPIGOT-6754: Temporarily restore previous behaviour for tile entities with removed blocks // When a block is being destroyed, the TileEntity may temporarily still exist while the block's type has already been set to AIR. We ignore the TileEntity in this case.
if (tileEntity != null) { Preconditions.checkState(tileEntity == null || CraftMagicNumbers.getMaterial(blockData.getBlock()) == Material.AIR, "Unexpected BlockState for %s", CraftMagicNumbers.getMaterial(blockData.getBlock()));
// block with unhandled TileEntity:
return new CraftBlockEntityState<>(world, tileEntity);
}
Preconditions.checkState(tileEntity == null, "Unexpected BlockState for %s", CraftMagicNumbers.getMaterial(blockData.getBlock()));
return new CraftBlockState(world, blockPosition, blockData); return new CraftBlockState(world, blockPosition, blockData);
} }
}; };