mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-16 14:33:09 +01:00
Fix upstreams block state factories
Sometimes, blocks are changed and then logic is called before the associated tile entity is removed. When this happens, the factories were relying on the block at the position, not the tile entity. This change prioritizes using the tile entity type to determine the block state factory and falls back on the material type of the block at that location. == AT == public net.minecraft.world.level.block.entity.BlockEntityType validBlocks
This commit is contained in:
parent
5f4779fc86
commit
e259cfeb72
4 changed files with 106 additions and 248 deletions
|
@ -122,7 +122,7 @@
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
+ if (this.level == null) return null;
|
+ if (this.level == null) return null;
|
||||||
+ org.bukkit.block.Block block = this.level.getWorld().getBlockAt(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ());
|
+ org.bukkit.block.Block block = this.level.getWorld().getBlockAt(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ());
|
||||||
+ if (block.getType() == org.bukkit.Material.AIR) return null;
|
+ // if (block.getType() == org.bukkit.Material.AIR) return null; // Paper - actually get the tile entity if it still exists
|
||||||
+ org.bukkit.block.BlockState state = block.getState(useSnapshot); // Paper
|
+ org.bukkit.block.BlockState state = block.getState(useSnapshot); // Paper
|
||||||
+ if (state instanceof InventoryHolder) return (InventoryHolder) state;
|
+ if (state instanceof InventoryHolder) return (InventoryHolder) state;
|
||||||
+ return null;
|
+ return null;
|
||||||
|
|
|
@ -20,7 +20,7 @@ import org.bukkit.persistence.PersistentDataContainer;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockState implements TileState {
|
public abstract class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockState implements TileState { // Paper - revert upstream's revert of the block state changes
|
||||||
|
|
||||||
private final T tileEntity;
|
private final T tileEntity;
|
||||||
private final T snapshot;
|
private final T snapshot;
|
||||||
|
@ -196,14 +196,10 @@ public class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockStat
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CraftBlockEntityState<T> copy() {
|
public abstract CraftBlockEntityState<T> copy(); // Paper - make abstract
|
||||||
return new CraftBlockEntityState<>(this, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CraftBlockEntityState<T> copy(Location location) {
|
public abstract CraftBlockEntityState<T> copy(Location location); // Paper - make abstract
|
||||||
return new CraftBlockEntityState<>(this, location);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Paper start
|
// Paper start
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -22,6 +22,7 @@ import net.minecraft.world.level.block.entity.BeehiveBlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BellBlockEntity;
|
import net.minecraft.world.level.block.entity.BellBlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BlastFurnaceBlockEntity;
|
import net.minecraft.world.level.block.entity.BlastFurnaceBlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType; // Paper
|
||||||
import net.minecraft.world.level.block.entity.BrewingStandBlockEntity;
|
import net.minecraft.world.level.block.entity.BrewingStandBlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BrushableBlockEntity;
|
import net.minecraft.world.level.block.entity.BrushableBlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.CalibratedSculkSensorBlockEntity;
|
import net.minecraft.world.level.block.entity.CalibratedSculkSensorBlockEntity;
|
||||||
|
@ -88,9 +89,9 @@ public final class CraftBlockStates {
|
||||||
private static class BlockEntityStateFactory<T extends BlockEntity, B extends CraftBlockEntityState<T>> extends BlockStateFactory<B> {
|
private static class BlockEntityStateFactory<T extends BlockEntity, B extends CraftBlockEntityState<T>> extends BlockStateFactory<B> {
|
||||||
|
|
||||||
private final BiFunction<World, T, B> blockStateConstructor;
|
private final BiFunction<World, T, B> blockStateConstructor;
|
||||||
private final BiFunction<BlockPos, net.minecraft.world.level.block.state.BlockState, T> tileEntityConstructor;
|
private final BlockEntityType<? extends T> tileEntityConstructor; // Paper
|
||||||
|
|
||||||
protected BlockEntityStateFactory(Class<B> blockStateType, BiFunction<World, T, B> blockStateConstructor, BiFunction<BlockPos, net.minecraft.world.level.block.state.BlockState, T> tileEntityConstructor) {
|
protected BlockEntityStateFactory(Class<B> blockStateType, BiFunction<World, T, B> blockStateConstructor, BlockEntityType<? extends T> tileEntityConstructor) { // Paper
|
||||||
super(blockStateType);
|
super(blockStateType);
|
||||||
this.blockStateConstructor = blockStateConstructor;
|
this.blockStateConstructor = blockStateConstructor;
|
||||||
this.tileEntityConstructor = tileEntityConstructor;
|
this.tileEntityConstructor = tileEntityConstructor;
|
||||||
|
@ -107,7 +108,7 @@ public final class CraftBlockStates {
|
||||||
}
|
}
|
||||||
|
|
||||||
private T createTileEntity(BlockPos blockPosition, net.minecraft.world.level.block.state.BlockState blockData) {
|
private T createTileEntity(BlockPos blockPosition, net.minecraft.world.level.block.state.BlockState blockData) {
|
||||||
return this.tileEntityConstructor.apply(blockPosition, blockData);
|
return this.tileEntityConstructor.create(blockPosition, blockData); // Paper
|
||||||
}
|
}
|
||||||
|
|
||||||
private B createBlockState(World world, T tileEntity) {
|
private B createBlockState(World world, T tileEntity) {
|
||||||
|
@ -119,233 +120,66 @@ 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, BlockPos blockPosition, net.minecraft.world.level.block.state.BlockState blockData, BlockEntity tileEntity) {
|
public CraftBlockState createBlockState(World world, BlockPos blockPosition, net.minecraft.world.level.block.state.BlockState blockData, BlockEntity tileEntity) {
|
||||||
// SPIGOT-6754, SPIGOT-6817: Restore previous behaviour for tile entities with removed blocks (loot generation post-destroy)
|
// Paper - revert upstream's revert of the block state changes. Block entities that have already had the block type set to AIR are still valid, upstream decided to ignore them
|
||||||
if (tileEntity != null) {
|
|
||||||
// block with unhandled TileEntity:
|
|
||||||
return new CraftBlockEntityState<>(world, tileEntity);
|
|
||||||
}
|
|
||||||
Preconditions.checkState(tileEntity == null, "Unexpected BlockState for %s", CraftBlockType.minecraftToBukkit(blockData.getBlock()));
|
Preconditions.checkState(tileEntity == null, "Unexpected BlockState for %s", CraftBlockType.minecraftToBukkit(blockData.getBlock()));
|
||||||
return new CraftBlockState(world, blockPosition, blockData);
|
return new CraftBlockState(world, blockPosition, blockData);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// Paper start
|
||||||
|
private static final Map<BlockEntityType<?>, BlockStateFactory<?>> FACTORIES_BY_BLOCK_ENTITY_TYPE = new HashMap<>();
|
||||||
|
private static void register(BlockEntityType<?> type, BlockStateFactory<?> factory) {
|
||||||
|
FACTORIES_BY_BLOCK_ENTITY_TYPE.put(type, factory);
|
||||||
|
}
|
||||||
|
// Paper end
|
||||||
|
|
||||||
static {
|
static {
|
||||||
register(
|
// Paper start - simplify
|
||||||
Arrays.asList(
|
register(BlockEntityType.SIGN, CraftSign.class, CraftSign::new);
|
||||||
Material.ACACIA_SIGN,
|
register(BlockEntityType.HANGING_SIGN, CraftHangingSign.class, CraftHangingSign::new);
|
||||||
Material.ACACIA_WALL_SIGN,
|
register(BlockEntityType.SKULL, CraftSkull.class, CraftSkull::new);
|
||||||
Material.BAMBOO_SIGN,
|
register(BlockEntityType.COMMAND_BLOCK, CraftCommandBlock.class, CraftCommandBlock::new);
|
||||||
Material.BAMBOO_WALL_SIGN,
|
register(BlockEntityType.BANNER, CraftBanner.class, CraftBanner::new);
|
||||||
Material.BIRCH_SIGN,
|
register(BlockEntityType.SHULKER_BOX, CraftShulkerBox.class, CraftShulkerBox::new);
|
||||||
Material.BIRCH_WALL_SIGN,
|
register(BlockEntityType.BED, CraftBed.class, CraftBed::new);
|
||||||
Material.CHERRY_SIGN,
|
register(BlockEntityType.BEEHIVE, CraftBeehive.class, CraftBeehive::new);
|
||||||
Material.CHERRY_WALL_SIGN,
|
register(BlockEntityType.CAMPFIRE, CraftCampfire.class, CraftCampfire::new);
|
||||||
Material.CRIMSON_SIGN,
|
register(BlockEntityType.BARREL, CraftBarrel.class, CraftBarrel::new);
|
||||||
Material.CRIMSON_WALL_SIGN,
|
register(BlockEntityType.BEACON, CraftBeacon.class, CraftBeacon::new);
|
||||||
Material.DARK_OAK_SIGN,
|
register(BlockEntityType.BELL, CraftBell.class, CraftBell::new);
|
||||||
Material.DARK_OAK_WALL_SIGN,
|
register(BlockEntityType.BLAST_FURNACE, CraftBlastFurnace.class, CraftBlastFurnace::new);
|
||||||
Material.JUNGLE_SIGN,
|
register(BlockEntityType.BREWING_STAND, CraftBrewingStand.class, CraftBrewingStand::new);
|
||||||
Material.JUNGLE_WALL_SIGN,
|
register(BlockEntityType.CHEST, CraftChest.class, CraftChest::new);
|
||||||
Material.MANGROVE_SIGN,
|
register(BlockEntityType.CHISELED_BOOKSHELF, CraftChiseledBookshelf.class, CraftChiseledBookshelf::new);
|
||||||
Material.MANGROVE_WALL_SIGN,
|
register(BlockEntityType.COMPARATOR, CraftComparator.class, CraftComparator::new);
|
||||||
Material.OAK_SIGN,
|
register(BlockEntityType.CONDUIT, CraftConduit.class, CraftConduit::new);
|
||||||
Material.OAK_WALL_SIGN,
|
register(BlockEntityType.CREAKING_HEART, CraftCreakingHeart.class, CraftCreakingHeart::new);
|
||||||
Material.PALE_OAK_SIGN,
|
register(BlockEntityType.DAYLIGHT_DETECTOR, CraftDaylightDetector.class, CraftDaylightDetector::new);
|
||||||
Material.PALE_OAK_WALL_SIGN,
|
register(BlockEntityType.DECORATED_POT, CraftDecoratedPot.class, CraftDecoratedPot::new);
|
||||||
Material.SPRUCE_SIGN,
|
register(BlockEntityType.DISPENSER, CraftDispenser.class, CraftDispenser::new);
|
||||||
Material.SPRUCE_WALL_SIGN,
|
register(BlockEntityType.DROPPER, CraftDropper.class, CraftDropper::new);
|
||||||
Material.WARPED_SIGN,
|
register(BlockEntityType.ENCHANTING_TABLE, CraftEnchantingTable.class, CraftEnchantingTable::new);
|
||||||
Material.WARPED_WALL_SIGN
|
register(BlockEntityType.ENDER_CHEST, CraftEnderChest.class, CraftEnderChest::new);
|
||||||
), CraftSign.class, CraftSign::new, SignBlockEntity::new
|
register(BlockEntityType.END_GATEWAY, CraftEndGateway.class, CraftEndGateway::new);
|
||||||
);
|
register(BlockEntityType.END_PORTAL, CraftEndPortal.class, CraftEndPortal::new);
|
||||||
|
register(BlockEntityType.FURNACE, CraftFurnaceFurnace.class, CraftFurnaceFurnace::new);
|
||||||
register(
|
register(BlockEntityType.HOPPER, CraftHopper.class, CraftHopper::new);
|
||||||
Arrays.asList(
|
register(BlockEntityType.JIGSAW, CraftJigsaw.class, CraftJigsaw::new);
|
||||||
Material.ACACIA_HANGING_SIGN,
|
register(BlockEntityType.JUKEBOX, CraftJukebox.class, CraftJukebox::new);
|
||||||
Material.ACACIA_WALL_HANGING_SIGN,
|
register(BlockEntityType.LECTERN, CraftLectern.class, CraftLectern::new);
|
||||||
Material.BAMBOO_HANGING_SIGN,
|
register(BlockEntityType.PISTON, CraftMovingPiston.class, CraftMovingPiston::new);
|
||||||
Material.BAMBOO_WALL_HANGING_SIGN,
|
register(BlockEntityType.SCULK_CATALYST, CraftSculkCatalyst.class, CraftSculkCatalyst::new);
|
||||||
Material.BIRCH_HANGING_SIGN,
|
register(BlockEntityType.SCULK_SENSOR, CraftSculkSensor.class, CraftSculkSensor::new);
|
||||||
Material.BIRCH_WALL_HANGING_SIGN,
|
register(BlockEntityType.SCULK_SHRIEKER, CraftSculkShrieker.class, CraftSculkShrieker::new);
|
||||||
Material.CHERRY_HANGING_SIGN,
|
register(BlockEntityType.CALIBRATED_SCULK_SENSOR, CraftCalibratedSculkSensor.class, CraftCalibratedSculkSensor::new);
|
||||||
Material.CHERRY_WALL_HANGING_SIGN,
|
register(BlockEntityType.SMOKER, CraftSmoker.class, CraftSmoker::new);
|
||||||
Material.CRIMSON_HANGING_SIGN,
|
register(BlockEntityType.MOB_SPAWNER, CraftCreatureSpawner.class, CraftCreatureSpawner::new);
|
||||||
Material.CRIMSON_WALL_HANGING_SIGN,
|
register(BlockEntityType.STRUCTURE_BLOCK, CraftStructureBlock.class, CraftStructureBlock::new);
|
||||||
Material.DARK_OAK_HANGING_SIGN,
|
register(BlockEntityType.BRUSHABLE_BLOCK, CraftBrushableBlock.class, CraftBrushableBlock::new); // note: spigot still uses CraftSuspiciousSand impl for that block type
|
||||||
Material.DARK_OAK_WALL_HANGING_SIGN,
|
register(BlockEntityType.TRAPPED_CHEST, CraftChest.class, CraftChest::new);
|
||||||
Material.JUNGLE_HANGING_SIGN,
|
register(BlockEntityType.CRAFTER, CraftCrafter.class, CraftCrafter::new);
|
||||||
Material.JUNGLE_WALL_HANGING_SIGN,
|
register(BlockEntityType.TRIAL_SPAWNER, CraftTrialSpawner.class, CraftTrialSpawner::new);
|
||||||
Material.MANGROVE_HANGING_SIGN,
|
register(BlockEntityType.VAULT, CraftVault.class, CraftVault::new);
|
||||||
Material.MANGROVE_WALL_HANGING_SIGN,
|
// Paper end
|
||||||
Material.OAK_HANGING_SIGN,
|
|
||||||
Material.OAK_WALL_HANGING_SIGN,
|
|
||||||
Material.PALE_OAK_HANGING_SIGN,
|
|
||||||
Material.PALE_OAK_WALL_HANGING_SIGN,
|
|
||||||
Material.SPRUCE_HANGING_SIGN,
|
|
||||||
Material.SPRUCE_WALL_HANGING_SIGN,
|
|
||||||
Material.WARPED_HANGING_SIGN,
|
|
||||||
Material.WARPED_WALL_HANGING_SIGN
|
|
||||||
), CraftHangingSign.class, CraftHangingSign::new, HangingSignBlockEntity::new
|
|
||||||
);
|
|
||||||
|
|
||||||
register(
|
|
||||||
Arrays.asList(
|
|
||||||
Material.CREEPER_HEAD,
|
|
||||||
Material.CREEPER_WALL_HEAD,
|
|
||||||
Material.DRAGON_HEAD,
|
|
||||||
Material.DRAGON_WALL_HEAD,
|
|
||||||
Material.PIGLIN_HEAD,
|
|
||||||
Material.PIGLIN_WALL_HEAD,
|
|
||||||
Material.PLAYER_HEAD,
|
|
||||||
Material.PLAYER_WALL_HEAD,
|
|
||||||
Material.SKELETON_SKULL,
|
|
||||||
Material.SKELETON_WALL_SKULL,
|
|
||||||
Material.WITHER_SKELETON_SKULL,
|
|
||||||
Material.WITHER_SKELETON_WALL_SKULL,
|
|
||||||
Material.ZOMBIE_HEAD,
|
|
||||||
Material.ZOMBIE_WALL_HEAD
|
|
||||||
), CraftSkull.class, CraftSkull::new, SkullBlockEntity::new
|
|
||||||
);
|
|
||||||
|
|
||||||
register(
|
|
||||||
Arrays.asList(
|
|
||||||
Material.COMMAND_BLOCK,
|
|
||||||
Material.REPEATING_COMMAND_BLOCK,
|
|
||||||
Material.CHAIN_COMMAND_BLOCK
|
|
||||||
), CraftCommandBlock.class, CraftCommandBlock::new, CommandBlockEntity::new
|
|
||||||
);
|
|
||||||
|
|
||||||
register(
|
|
||||||
Arrays.asList(
|
|
||||||
Material.BLACK_BANNER,
|
|
||||||
Material.BLACK_WALL_BANNER,
|
|
||||||
Material.BLUE_BANNER,
|
|
||||||
Material.BLUE_WALL_BANNER,
|
|
||||||
Material.BROWN_BANNER,
|
|
||||||
Material.BROWN_WALL_BANNER,
|
|
||||||
Material.CYAN_BANNER,
|
|
||||||
Material.CYAN_WALL_BANNER,
|
|
||||||
Material.GRAY_BANNER,
|
|
||||||
Material.GRAY_WALL_BANNER,
|
|
||||||
Material.GREEN_BANNER,
|
|
||||||
Material.GREEN_WALL_BANNER,
|
|
||||||
Material.LIGHT_BLUE_BANNER,
|
|
||||||
Material.LIGHT_BLUE_WALL_BANNER,
|
|
||||||
Material.LIGHT_GRAY_BANNER,
|
|
||||||
Material.LIGHT_GRAY_WALL_BANNER,
|
|
||||||
Material.LIME_BANNER,
|
|
||||||
Material.LIME_WALL_BANNER,
|
|
||||||
Material.MAGENTA_BANNER,
|
|
||||||
Material.MAGENTA_WALL_BANNER,
|
|
||||||
Material.ORANGE_BANNER,
|
|
||||||
Material.ORANGE_WALL_BANNER,
|
|
||||||
Material.PINK_BANNER,
|
|
||||||
Material.PINK_WALL_BANNER,
|
|
||||||
Material.PURPLE_BANNER,
|
|
||||||
Material.PURPLE_WALL_BANNER,
|
|
||||||
Material.RED_BANNER,
|
|
||||||
Material.RED_WALL_BANNER,
|
|
||||||
Material.WHITE_BANNER,
|
|
||||||
Material.WHITE_WALL_BANNER,
|
|
||||||
Material.YELLOW_BANNER,
|
|
||||||
Material.YELLOW_WALL_BANNER
|
|
||||||
), CraftBanner.class, CraftBanner::new, BannerBlockEntity::new
|
|
||||||
);
|
|
||||||
|
|
||||||
register(
|
|
||||||
Arrays.asList(
|
|
||||||
Material.SHULKER_BOX,
|
|
||||||
Material.WHITE_SHULKER_BOX,
|
|
||||||
Material.ORANGE_SHULKER_BOX,
|
|
||||||
Material.MAGENTA_SHULKER_BOX,
|
|
||||||
Material.LIGHT_BLUE_SHULKER_BOX,
|
|
||||||
Material.YELLOW_SHULKER_BOX,
|
|
||||||
Material.LIME_SHULKER_BOX,
|
|
||||||
Material.PINK_SHULKER_BOX,
|
|
||||||
Material.GRAY_SHULKER_BOX,
|
|
||||||
Material.LIGHT_GRAY_SHULKER_BOX,
|
|
||||||
Material.CYAN_SHULKER_BOX,
|
|
||||||
Material.PURPLE_SHULKER_BOX,
|
|
||||||
Material.BLUE_SHULKER_BOX,
|
|
||||||
Material.BROWN_SHULKER_BOX,
|
|
||||||
Material.GREEN_SHULKER_BOX,
|
|
||||||
Material.RED_SHULKER_BOX,
|
|
||||||
Material.BLACK_SHULKER_BOX
|
|
||||||
), CraftShulkerBox.class, CraftShulkerBox::new, ShulkerBoxBlockEntity::new
|
|
||||||
);
|
|
||||||
|
|
||||||
register(
|
|
||||||
Arrays.asList(
|
|
||||||
Material.BLACK_BED,
|
|
||||||
Material.BLUE_BED,
|
|
||||||
Material.BROWN_BED,
|
|
||||||
Material.CYAN_BED,
|
|
||||||
Material.GRAY_BED,
|
|
||||||
Material.GREEN_BED,
|
|
||||||
Material.LIGHT_BLUE_BED,
|
|
||||||
Material.LIGHT_GRAY_BED,
|
|
||||||
Material.LIME_BED,
|
|
||||||
Material.MAGENTA_BED,
|
|
||||||
Material.ORANGE_BED,
|
|
||||||
Material.PINK_BED,
|
|
||||||
Material.PURPLE_BED,
|
|
||||||
Material.RED_BED,
|
|
||||||
Material.WHITE_BED,
|
|
||||||
Material.YELLOW_BED
|
|
||||||
), CraftBed.class, CraftBed::new, BedBlockEntity::new
|
|
||||||
);
|
|
||||||
|
|
||||||
register(
|
|
||||||
Arrays.asList(
|
|
||||||
Material.BEEHIVE,
|
|
||||||
Material.BEE_NEST
|
|
||||||
), CraftBeehive.class, CraftBeehive::new, BeehiveBlockEntity::new
|
|
||||||
);
|
|
||||||
|
|
||||||
register(
|
|
||||||
Arrays.asList(
|
|
||||||
Material.CAMPFIRE,
|
|
||||||
Material.SOUL_CAMPFIRE
|
|
||||||
), CraftCampfire.class, CraftCampfire::new, CampfireBlockEntity::new
|
|
||||||
);
|
|
||||||
|
|
||||||
register(Material.BARREL, CraftBarrel.class, CraftBarrel::new, BarrelBlockEntity::new);
|
|
||||||
register(Material.BEACON, CraftBeacon.class, CraftBeacon::new, BeaconBlockEntity::new);
|
|
||||||
register(Material.BELL, CraftBell.class, CraftBell::new, BellBlockEntity::new);
|
|
||||||
register(Material.BLAST_FURNACE, CraftBlastFurnace.class, CraftBlastFurnace::new, BlastFurnaceBlockEntity::new);
|
|
||||||
register(Material.BREWING_STAND, CraftBrewingStand.class, CraftBrewingStand::new, BrewingStandBlockEntity::new);
|
|
||||||
register(Material.CHEST, CraftChest.class, CraftChest::new, ChestBlockEntity::new);
|
|
||||||
register(Material.CHISELED_BOOKSHELF, CraftChiseledBookshelf.class, CraftChiseledBookshelf::new, ChiseledBookShelfBlockEntity::new);
|
|
||||||
register(Material.COMPARATOR, CraftComparator.class, CraftComparator::new, ComparatorBlockEntity::new);
|
|
||||||
register(Material.CONDUIT, CraftConduit.class, CraftConduit::new, ConduitBlockEntity::new);
|
|
||||||
register(Material.CREAKING_HEART, CraftCreakingHeart.class, CraftCreakingHeart::new, CreakingHeartBlockEntity::new);
|
|
||||||
register(Material.DAYLIGHT_DETECTOR, CraftDaylightDetector.class, CraftDaylightDetector::new, DaylightDetectorBlockEntity::new);
|
|
||||||
register(Material.DECORATED_POT, CraftDecoratedPot.class, CraftDecoratedPot::new, DecoratedPotBlockEntity::new);
|
|
||||||
register(Material.DISPENSER, CraftDispenser.class, CraftDispenser::new, DispenserBlockEntity::new);
|
|
||||||
register(Material.DROPPER, CraftDropper.class, CraftDropper::new, DropperBlockEntity::new);
|
|
||||||
register(Material.ENCHANTING_TABLE, CraftEnchantingTable.class, CraftEnchantingTable::new, EnchantingTableBlockEntity::new);
|
|
||||||
register(Material.ENDER_CHEST, CraftEnderChest.class, CraftEnderChest::new, EnderChestBlockEntity::new);
|
|
||||||
register(Material.END_GATEWAY, CraftEndGateway.class, CraftEndGateway::new, TheEndGatewayBlockEntity::new);
|
|
||||||
register(Material.END_PORTAL, CraftEndPortal.class, CraftEndPortal::new, TheEndPortalBlockEntity::new);
|
|
||||||
register(Material.FURNACE, CraftFurnaceFurnace.class, CraftFurnaceFurnace::new, FurnaceBlockEntity::new);
|
|
||||||
register(Material.HOPPER, CraftHopper.class, CraftHopper::new, HopperBlockEntity::new);
|
|
||||||
register(Material.JIGSAW, CraftJigsaw.class, CraftJigsaw::new, JigsawBlockEntity::new);
|
|
||||||
register(Material.JUKEBOX, CraftJukebox.class, CraftJukebox::new, JukeboxBlockEntity::new);
|
|
||||||
register(Material.LECTERN, CraftLectern.class, CraftLectern::new, LecternBlockEntity::new);
|
|
||||||
register(Material.MOVING_PISTON, CraftMovingPiston.class, CraftMovingPiston::new, PistonMovingBlockEntity::new);
|
|
||||||
register(Material.SCULK_CATALYST, CraftSculkCatalyst.class, CraftSculkCatalyst::new, SculkCatalystBlockEntity::new);
|
|
||||||
register(Material.CALIBRATED_SCULK_SENSOR, CraftCalibratedSculkSensor.class, CraftCalibratedSculkSensor::new, CalibratedSculkSensorBlockEntity::new);
|
|
||||||
register(Material.SCULK_SENSOR, CraftSculkSensor.class, CraftSculkSensor::new, SculkSensorBlockEntity::new);
|
|
||||||
register(Material.SCULK_SHRIEKER, CraftSculkShrieker.class, CraftSculkShrieker::new, SculkShriekerBlockEntity::new);
|
|
||||||
register(Material.SMOKER, CraftSmoker.class, CraftSmoker::new, SmokerBlockEntity::new);
|
|
||||||
register(Material.SPAWNER, CraftCreatureSpawner.class, CraftCreatureSpawner::new, SpawnerBlockEntity::new);
|
|
||||||
register(Material.STRUCTURE_BLOCK, CraftStructureBlock.class, CraftStructureBlock::new, StructureBlockEntity::new);
|
|
||||||
register(Material.SUSPICIOUS_SAND, CraftSuspiciousSand.class, CraftSuspiciousSand::new, BrushableBlockEntity::new);
|
|
||||||
register(Material.SUSPICIOUS_GRAVEL, CraftBrushableBlock.class, CraftBrushableBlock::new, BrushableBlockEntity::new);
|
|
||||||
register(Material.TRAPPED_CHEST, CraftChest.class, CraftChest::new, TrappedChestBlockEntity::new);
|
|
||||||
register(Material.CRAFTER, CraftCrafter.class, CraftCrafter::new, CrafterBlockEntity::new);
|
|
||||||
register(Material.TRIAL_SPAWNER, CraftTrialSpawner.class, CraftTrialSpawner::new, TrialSpawnerBlockEntity::new);
|
|
||||||
register(Material.VAULT, CraftVault.class, CraftVault::new, VaultBlockEntity::new);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void register(Material blockType, BlockStateFactory<?> factory) {
|
private static void register(Material blockType, BlockStateFactory<?> factory) {
|
||||||
|
@ -353,30 +187,33 @@ public final class CraftBlockStates {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T extends BlockEntity, B extends CraftBlockEntityState<T>> void register(
|
private static <T extends BlockEntity, B extends CraftBlockEntityState<T>> void register(
|
||||||
Material blockType,
|
net.minecraft.world.level.block.entity.BlockEntityType<? extends T> blockEntityType, // Paper
|
||||||
Class<B> blockStateType,
|
Class<B> blockStateType,
|
||||||
BiFunction<World, T, B> blockStateConstructor,
|
BiFunction<World, T, B> blockStateConstructor // Paper
|
||||||
BiFunction<BlockPos, net.minecraft.world.level.block.state.BlockState, T> tileEntityConstructor
|
|
||||||
) {
|
) {
|
||||||
CraftBlockStates.register(Collections.singletonList(blockType), blockStateType, blockStateConstructor, tileEntityConstructor);
|
// Paper start
|
||||||
}
|
BlockStateFactory<B> factory = new BlockEntityStateFactory<>(blockStateType, blockStateConstructor, blockEntityType); // Paper
|
||||||
|
for (net.minecraft.world.level.block.Block block : blockEntityType.validBlocks) {
|
||||||
private static <T extends BlockEntity, B extends CraftBlockEntityState<T>> void register(
|
CraftBlockStates.register(CraftBlockType.minecraftToBukkit(block), factory);
|
||||||
List<Material> blockTypes,
|
|
||||||
Class<B> blockStateType,
|
|
||||||
BiFunction<World, T, B> blockStateConstructor,
|
|
||||||
BiFunction<BlockPos, net.minecraft.world.level.block.state.BlockState, T> tileEntityConstructor
|
|
||||||
) {
|
|
||||||
BlockStateFactory<B> factory = new BlockEntityStateFactory<>(blockStateType, blockStateConstructor, tileEntityConstructor);
|
|
||||||
for (Material blockType : blockTypes) {
|
|
||||||
CraftBlockStates.register(blockType, factory);
|
|
||||||
}
|
}
|
||||||
|
CraftBlockStates.register(blockEntityType, factory);
|
||||||
|
// Paper end
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BlockStateFactory<?> getFactory(Material material) {
|
private static BlockStateFactory<?> getFactory(Material material) {
|
||||||
return CraftBlockStates.FACTORIES.getOrDefault(material, CraftBlockStates.DEFAULT_FACTORY);
|
return CraftBlockStates.FACTORIES.getOrDefault(material, CraftBlockStates.DEFAULT_FACTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Paper start
|
||||||
|
private static BlockStateFactory<?> getFactory(Material material, BlockEntityType<?> type) {
|
||||||
|
if (type != null) {
|
||||||
|
return CraftBlockStates.FACTORIES_BY_BLOCK_ENTITY_TYPE.getOrDefault(type, getFactory(material));
|
||||||
|
} else {
|
||||||
|
return getFactory(material);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Paper end
|
||||||
|
|
||||||
public static Class<? extends CraftBlockState> getBlockStateType(Material material) {
|
public static Class<? extends CraftBlockState> getBlockStateType(Material material) {
|
||||||
Preconditions.checkNotNull(material, "material is null");
|
Preconditions.checkNotNull(material, "material is null");
|
||||||
return CraftBlockStates.getFactory(material).blockStateType;
|
return CraftBlockStates.getFactory(material).blockStateType;
|
||||||
|
@ -392,6 +229,13 @@ public final class CraftBlockStates {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Paper start
|
||||||
|
public static Class<? extends CraftBlockState> getBlockStateType(BlockEntityType<?> blockEntityType) {
|
||||||
|
Preconditions.checkNotNull(blockEntityType, "blockEntityType is null");
|
||||||
|
return CraftBlockStates.getFactory(null, blockEntityType).blockStateType;
|
||||||
|
}
|
||||||
|
// Paper end
|
||||||
|
|
||||||
public static BlockState getBlockState(Block block) {
|
public static BlockState getBlockState(Block block) {
|
||||||
// Paper start
|
// Paper start
|
||||||
return CraftBlockStates.getBlockState(block, true);
|
return CraftBlockStates.getBlockState(block, true);
|
||||||
|
@ -459,7 +303,7 @@ public final class CraftBlockStates {
|
||||||
if (world != null && tileEntity == null && CraftBlockStates.isTileEntityOptional(material)) {
|
if (world != null && tileEntity == null && CraftBlockStates.isTileEntityOptional(material)) {
|
||||||
factory = CraftBlockStates.DEFAULT_FACTORY;
|
factory = CraftBlockStates.DEFAULT_FACTORY;
|
||||||
} else {
|
} else {
|
||||||
factory = CraftBlockStates.getFactory(material);
|
factory = CraftBlockStates.getFactory(material, tileEntity != null ? tileEntity.getType() : null); // Paper
|
||||||
}
|
}
|
||||||
return factory.createBlockState(world, blockPosition, blockData, tileEntity);
|
return factory.createBlockState(world, blockPosition, blockData, tileEntity);
|
||||||
}
|
}
|
||||||
|
@ -478,6 +322,14 @@ public final class CraftBlockStates {
|
||||||
return new CraftBlockState(CraftBlock.at(world, pos), flag);
|
return new CraftBlockState(CraftBlock.at(world, pos), flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Paper start
|
||||||
|
@Nullable
|
||||||
|
public static BlockEntityType<?> getBlockEntityType(final Material material) {
|
||||||
|
final BlockStateFactory<?> factory = org.bukkit.craftbukkit.block.CraftBlockStates.FACTORIES.get(material);
|
||||||
|
return factory instanceof final BlockEntityStateFactory<?,?> blockEntityStateFactory ? blockEntityStateFactory.tileEntityConstructor : null;
|
||||||
|
}
|
||||||
|
// Paper end
|
||||||
|
|
||||||
private CraftBlockStates() {
|
private CraftBlockStates() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.EntityBlock;
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.support.environment.AllFeatures;
|
import org.bukkit.support.environment.AllFeatures;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -42,4 +43,13 @@ public class BlockStateTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Paper start
|
||||||
|
@Test
|
||||||
|
public void testBlockEntityTypes() {
|
||||||
|
for (var blockEntityType : BuiltInRegistries.BLOCK_ENTITY_TYPE) {
|
||||||
|
org.junit.jupiter.api.Assertions.assertNotNull(CraftBlockStates.getBlockStateType(blockEntityType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Paper end
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue