From 960f31098d3dce07482c771a938ac111abfbeed3 Mon Sep 17 00:00:00 2001 From: blablubbabc Date: Sun, 10 Oct 2021 07:55:53 +1100 Subject: [PATCH] #937: Fixes related to unplaced BlockStates and the recent world generation changes. * CraftBlockState#getWorldHandle() would previously run into a NPE when being invoked for a non-placed BlockState. It now returns null in this case. * CraftChest#getInventory() would previously encounter this NPE when being called for a non-placed BlockState. It will now automatically forward the call to #getBlockInventory() when it is being called for either a non-placed BlockState, or during world generation. * CraftStructureBlock#applyTo was able to run into a NPE when being called for non-placed BlockStates (this is for example called by #getSnapshotNBT()). * Replaced all no-world-generation preconditions with a general 'ensureNoWorldGeneration' method. * Removed a few superfluous #isPlaced() calls. If getWorldHandle() reutrns a World, this already implies that the BlockState is placed. --- .../bukkit/craftbukkit/block/CraftBeacon.java | 2 +- .../bukkit/craftbukkit/block/CraftBeehive.java | 2 +- .../craftbukkit/block/CraftBlockState.java | 17 +++++++++++++++-- .../bukkit/craftbukkit/block/CraftChest.java | 4 +--- .../craftbukkit/block/CraftDispenser.java | 4 +--- .../bukkit/craftbukkit/block/CraftDropper.java | 4 +--- .../bukkit/craftbukkit/block/CraftJukebox.java | 3 +-- .../bukkit/craftbukkit/block/CraftLectern.java | 2 +- .../craftbukkit/block/CraftStructureBlock.java | 2 +- 9 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java index 72e77b908..10c076bac 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java @@ -23,7 +23,7 @@ public class CraftBeacon extends CraftBlockEntityState impleme @Override public Collection getEntitiesInRange() { - Preconditions.checkState(getWorldHandle() instanceof net.minecraft.world.level.World, "Can't get entities during world generation"); + ensureNoWorldGeneration(); TileEntity tileEntity = this.getTileEntityFromWorld(); if (tileEntity instanceof TileEntityBeacon) { diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java index 1cca73d58..d7485cc1a 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java @@ -60,7 +60,7 @@ public class CraftBeehive extends CraftBlockEntityState imple @Override public List releaseEntities() { - Preconditions.checkState(getWorldHandle() instanceof net.minecraft.world.level.World, "Can't release entities during world generation"); + ensureNoWorldGeneration(); List bees = new ArrayList<>(); diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java index b23f0260c..d29c7bd9b 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java @@ -57,20 +57,33 @@ public class CraftBlockState implements BlockState { } } + // Returns null if weakWorld is not available and the BlockState is not placed. + // If this returns a World instead of only a GeneratorAccess, this implies that this BlockState is placed. public GeneratorAccess getWorldHandle() { if (weakWorld == null) { - return world.getHandle(); + return this.isPlaced() ? world.getHandle() : null; } GeneratorAccess access = weakWorld.get(); if (access == null) { weakWorld = null; - return world.getHandle(); + return this.isPlaced() ? world.getHandle() : null; } return access; } + protected final boolean isWorldGeneration() { + GeneratorAccess generatorAccess = this.getWorldHandle(); + return generatorAccess != null && !(generatorAccess instanceof World); + } + + protected final void ensureNoWorldGeneration() { + if (isWorldGeneration()) { + throw new IllegalStateException("This operation is not supported during world generation!"); + } + } + @Override public World getWorld() { requirePlaced(); diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java index adbab4032..3a20de0aa 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java @@ -37,10 +37,8 @@ public class CraftChest extends CraftLootable implements Chest @Override public Inventory getInventory() { - Preconditions.checkState(getWorldHandle() instanceof net.minecraft.world.level.World, "Can't get inventory during world generation, use getBlockInventory() instead"); - CraftInventory inventory = (CraftInventory) this.getBlockInventory(); - if (!isPlaced()) { + if (!isPlaced() || isWorldGeneration()) { return inventory; } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java b/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java index 7e429362f..474fe3c77 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java @@ -47,10 +47,8 @@ public class CraftDispenser extends CraftLootable implement @Override public boolean dispense() { - Preconditions.checkState(getWorldHandle() instanceof net.minecraft.world.level.World, "Can't dispense during world generation"); - + ensureNoWorldGeneration(); Block block = getBlock(); - if (block.getType() == Material.DISPENSER) { CraftWorld world = (CraftWorld) this.getWorld(); BlockDispenser dispense = (BlockDispenser) Blocks.DISPENSER; diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java b/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java index f11296ec1..7df00f693 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java @@ -34,10 +34,8 @@ public class CraftDropper extends CraftLootable implements Dr @Override public void drop() { - Preconditions.checkState(getWorldHandle() instanceof net.minecraft.world.level.World, "Can't drop during world generation"); - + ensureNoWorldGeneration(); Block block = getBlock(); - if (block.getType() == Material.DROPPER) { CraftWorld world = (CraftWorld) this.getWorld(); BlockDropper drop = (BlockDropper) Blocks.DROPPER; diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java b/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java index 76770318f..469904ee9 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java @@ -81,9 +81,8 @@ public class CraftJukebox extends CraftBlockEntityState imple @Override public boolean eject() { - Preconditions.checkState(getWorldHandle() instanceof net.minecraft.world.level.World, "Can't eject during world generation"); + ensureNoWorldGeneration(); - requirePlaced(); TileEntity tileEntity = this.getTileEntityFromWorld(); if (!(tileEntity instanceof TileEntityJukeBox)) return false; diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftLectern.java b/src/main/java/org/bukkit/craftbukkit/block/CraftLectern.java index 6375e1667..99cf060b6 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftLectern.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftLectern.java @@ -42,7 +42,7 @@ public class CraftLectern extends CraftBlockEntityState imple public boolean update(boolean force, boolean applyPhysics) { boolean result = super.update(force, applyPhysics); - if (result && this.isPlaced() && this.getType() == Material.LECTERN && getWorldHandle() instanceof net.minecraft.world.level.World) { + if (result && this.getType() == Material.LECTERN && getWorldHandle() instanceof net.minecraft.world.level.World) { BlockLectern.a(this.world.getHandle(), this.getPosition(), this.getHandle()); } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftStructureBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftStructureBlock.java index 1dd43643a..53ee38485 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftStructureBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftStructureBlock.java @@ -180,7 +180,7 @@ public class CraftStructureBlock extends CraftBlockEntityState