diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java index b051bf54f..ed086f94e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java @@ -20,7 +20,6 @@ import net.momirealms.craftengine.core.world.WorldEvents; import net.momirealms.craftengine.core.world.WorldPosition; import net.momirealms.sparrow.nbt.CompoundTag; import org.bukkit.Location; -import org.bukkit.Material; import org.bukkit.SoundCategory; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; @@ -131,22 +130,20 @@ public final class CraftEngineBlocks { * @return success or not */ public static boolean remove(@NotNull Block block) { - if (!isCustomBlock(block)) return false; - block.setType(Material.AIR, true); - return true; + return remove(block, false); } /** * Removes a block from the world if it's custom * * @param block block to remove - * @param applyPhysics whether to apply physics + * @param isMoving is moving * @return success or not */ public static boolean remove(@NotNull Block block, - boolean applyPhysics) { + boolean isMoving) { if (!isCustomBlock(block)) return false; - block.setType(Material.AIR, applyPhysics); + FastNMS.INSTANCE.method$Level$removeBlock(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(block.getWorld()), LocationUtils.toBlockPos(block.getX(), block.getY(), block.getZ()), isMoving); return true; } @@ -155,15 +152,15 @@ public final class CraftEngineBlocks { * * @param block block to remove * @param player player who breaks the block - * @param applyPhysics whether to apply physics * @param dropLoot whether to drop block loots + * @param isMoving is moving * @param playSound whether to play break sounds * @param sendParticles whether to send break particles * @return success or not */ public static boolean remove(@NotNull Block block, @Nullable Player player, - boolean applyPhysics, + boolean isMoving, boolean dropLoot, boolean playSound, boolean sendParticles) { @@ -189,7 +186,7 @@ public final class CraftEngineBlocks { if (sendParticles) { FastNMS.INSTANCE.method$Level$levelEvent(world.serverWorld(), WorldEvents.BLOCK_BREAK_EFFECT, LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), state.customBlockState().registryId()); } - block.setType(Material.AIR, applyPhysics); + FastNMS.INSTANCE.method$Level$removeBlock(world.serverWorld(), LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), isMoving); return true; } @@ -200,9 +197,8 @@ public final class CraftEngineBlocks { * @return is custom block or not */ public static boolean isCustomBlock(@NotNull Block block) { - BlockData blockData = block.getBlockData(); - int stateId = BlockStateUtils.blockDataToId(blockData); - return !BlockStateUtils.isVanillaBlock(stateId); + Object state = FastNMS.INSTANCE.method$BlockGetter$getBlockState(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(block.getWorld()), LocationUtils.toBlockPos(block.getX(), block.getY(), block.getZ())); + return BlockStateUtils.isCustomBlock(state); } /** @@ -213,9 +209,8 @@ public final class CraftEngineBlocks { */ @Nullable public static ImmutableBlockState getCustomBlockState(@NotNull Block block) { - BlockData blockData = block.getBlockData(); - int stateId = BlockStateUtils.blockDataToId(blockData); - return BukkitBlockManager.instance().getImmutableBlockState(stateId); + Object state = FastNMS.INSTANCE.method$BlockGetter$getBlockState(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(block.getWorld()), LocationUtils.toBlockPos(block.getX(), block.getY(), block.getZ())); + return BlockStateUtils.getOptionalCustomBlockState(state).orElse(null); } /** @@ -226,8 +221,8 @@ public final class CraftEngineBlocks { */ @Nullable public static ImmutableBlockState getCustomBlockState(@NotNull BlockData blockData) { - int stateId = BlockStateUtils.blockDataToId(blockData); - return BukkitBlockManager.instance().getImmutableBlockState(stateId); + Object state = BlockStateUtils.blockDataToBlockState(blockData); + return BlockStateUtils.getOptionalCustomBlockState(state).orElse(null); } /** diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java index 88e5a350d..a71b8671a 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java @@ -218,11 +218,10 @@ public class BlockEventListener implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) public void onBlockBreakBlock(BlockBreakBlockEvent event) { Block block = event.getBlock(); - Object blockState = BlockStateUtils.blockDataToBlockState(block.getBlockData()); - int stateId = BlockStateUtils.blockStateToId(blockState); - if (!BlockStateUtils.isVanillaBlock(stateId)) { + Object blockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(block.getWorld()), LocationUtils.toBlockPos(block.getX(), block.getY(), block.getZ())); + if (BlockStateUtils.isVanillaBlock(blockState)) { // override vanilla block loots - this.plugin.vanillaLootManager().getBlockLoot(stateId).ifPresent(it -> { + this.plugin.vanillaLootManager().getBlockLoot(BlockStateUtils.blockStateToId(blockState)).ifPresent(it -> { if (it.override()) { event.getDrops().clear(); event.setExpToDrop(0); @@ -249,12 +248,12 @@ public class BlockEventListener implements Listener { if (!(entity instanceof Player player)) return; BlockPos pos = EntityUtils.getOnPos(player); Block block = player.getWorld().getBlockAt(pos.x(), pos.y(), pos.z()); - Object blockState = BlockStateUtils.blockDataToBlockState(block.getBlockData()); - int stateId = BlockStateUtils.blockStateToId(blockState); - if (!BlockStateUtils.isVanillaBlock(stateId)) { + Object blockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(block.getWorld()), LocationUtils.toBlockPos(block.getX(), block.getY(), block.getZ())); + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(blockState); + if (optionalCustomState.isPresent()) { Location location = player.getLocation(); - ImmutableBlockState state = manager.getImmutableBlockStateUnsafe(stateId); - Cancellable cancellable = Cancellable.dummy(); + ImmutableBlockState state = optionalCustomState.get(); + Cancellable cancellable = Cancellable.of(event::isCancelled, event::setCancelled); state.owner().value().execute(PlayerOptionalContext.of(this.plugin.adapt(player), ContextHolder.builder() .withParameter(DirectContextParameters.EVENT, cancellable) .withParameter(DirectContextParameters.POSITION, new WorldPosition(new BukkitWorld(event.getWorld()), LocationUtils.toVec3d(location))) @@ -262,19 +261,18 @@ public class BlockEventListener implements Listener { .withParameter(DirectContextParameters.CUSTOM_BLOCK_STATE, state) ), EventTrigger.STEP); if (cancellable.isCancelled()) { - event.setCancelled(true); return; } player.playSound(location, state.sounds().stepSound().id().toString(), SoundCategory.BLOCKS, state.sounds().stepSound().volume().get(), state.sounds().stepSound().pitch().get()); } else if (Config.enableSoundSystem()) { Object ownerBlock = BlockStateUtils.getBlockOwner(blockState); - if (manager.isBlockSoundRemoved(ownerBlock)) { + if (this.manager.isBlockSoundRemoved(ownerBlock)) { try { Object soundType = CoreReflections.field$BlockBehaviour$soundType.get(ownerBlock); Object stepSound = CoreReflections.field$SoundType$stepSound.get(soundType); player.playSound(player.getLocation(), FastNMS.INSTANCE.field$SoundEvent$location(stepSound).toString(), SoundCategory.BLOCKS, 0.15f, 1f); } catch (ReflectiveOperationException e) { - plugin.logger().warn("Failed to get sound type", e); + this.plugin.logger().warn("Failed to get sound type", e); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/FallingBlockRemoveListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/FallingBlockRemoveListener.java index d9049a026..e95cff26e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/FallingBlockRemoveListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/FallingBlockRemoveListener.java @@ -14,6 +14,9 @@ import org.bukkit.entity.FallingBlock; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import java.util.Optional; + +@SuppressWarnings("DuplicatedCode") public class FallingBlockRemoveListener implements Listener { @EventHandler @@ -24,21 +27,21 @@ public class FallingBlockRemoveListener implements Listener { boolean cancelDrop = (boolean) CoreReflections.field$FallingBlockEntity$cancelDrop.get(fallingBlockEntity); if (cancelDrop) return; Object blockState = CoreReflections.field$FallingBlockEntity$blockState.get(fallingBlockEntity); - int stateId = BlockStateUtils.blockStateToId(blockState); - ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(stateId); - if (immutableBlockState == null || immutableBlockState.isEmpty()) return; + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(blockState); + if (optionalCustomState.isEmpty()) return; + ImmutableBlockState customState = optionalCustomState.get(); net.momirealms.craftengine.core.world.World world = new BukkitWorld(fallingBlock.getWorld()); WorldPosition position = new WorldPosition(world, CoreReflections.field$Entity$xo.getDouble(fallingBlockEntity), CoreReflections.field$Entity$yo.getDouble(fallingBlockEntity), CoreReflections.field$Entity$zo.getDouble(fallingBlockEntity)); ContextHolder.Builder builder = ContextHolder.builder() .withParameter(DirectContextParameters.FALLING_BLOCK, true) .withParameter(DirectContextParameters.POSITION, position); - for (Item item : immutableBlockState.getDrops(builder, world, null)) { + for (Item item : customState.getDrops(builder, world, null)) { world.dropItemNaturally(position, item); } Object entityData = CoreReflections.field$Entity$entityData.get(fallingBlockEntity); boolean isSilent = (boolean) CoreReflections.method$SynchedEntityData$get.invoke(entityData, CoreReflections.instance$Entity$DATA_SILENT); if (!isSilent) { - world.playBlockSound(position, immutableBlockState.sounds().destroySound()); + world.playBlockSound(position, customState.sounds().destroySound()); } } catch (ReflectiveOperationException e) { CraftEngine.instance().logger().warn("Failed to handle EntityRemoveEvent", e); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java index d244b23e0..d535f0030 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java @@ -73,6 +73,7 @@ public class BushBlockBehavior extends AbstractCanSurviveBlockBehavior { return new Tuple<>(mcTags, mcBlocks, customBlocks); } + @SuppressWarnings("DuplicatedCode") @Override protected boolean canSurvive(Object thisBlock, Object state, Object world, Object blockPos) throws Exception { int y = FastNMS.INSTANCE.field$Vec3i$y(blockPos); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java index 433423e5c..29186f8b9 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java @@ -34,6 +34,7 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.Callable; +@SuppressWarnings("DuplicatedCode") public class CropBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); private final IntegerProperty ageProperty; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DoorBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DoorBlockBehavior.java index b4370634c..3e822a853 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DoorBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DoorBlockBehavior.java @@ -1,6 +1,5 @@ package net.momirealms.craftengine.bukkit.block.behavior; -import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks; @@ -40,6 +39,7 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.Callable; +@SuppressWarnings("DuplicatedCode") public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior { public static final Factory FACTORY = new Factory(); private final Property halfProperty; @@ -91,10 +91,11 @@ public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior { DoubleBlockHalf half = customState.get(this.halfProperty); Object direction = VersionHelper.isOrAbove1_21_2() ? args[4] : args[1]; if (DirectionUtils.isYAxis(direction) && half == DoubleBlockHalf.LOWER == (direction == CoreReflections.instance$Direction$UP)) { - ImmutableBlockState neighborState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(VersionHelper.isOrAbove1_21_2() ? args[6] : args[2])); - if (neighborState == null || neighborState.isEmpty()) { + Optional optionalNeighborState = BlockStateUtils.getOptionalCustomBlockState(args[updateShape$neighborState]); + if (optionalNeighborState.isEmpty()) { return MBlocks.AIR$defaultState; } + ImmutableBlockState neighborState = optionalNeighborState.get(); Optional anotherDoorBehavior = neighborState.behavior().getAs(DoorBlockBehavior.class); if (anotherDoorBehavior.isEmpty()) { return MBlocks.AIR$defaultState; @@ -120,8 +121,9 @@ public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior { @Override public void onExplosionHit(Object thisBlock, Object[] args, Callable superMethod) { if (this.canOpenByWindCharge && FastNMS.INSTANCE.method$Explosion$canTriggerBlocks(args[3])) { - ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(args[0])); - if (state == null || state.isEmpty()) return; + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(args[0]); + if (optionalCustomState.isEmpty()) return; + ImmutableBlockState state = optionalCustomState.get(); if (state.get(this.poweredProperty)) return; if (state.get(this.halfProperty) == DoubleBlockHalf.LOWER) { this.setOpen(null, args[1], state, LocationUtils.fromBlockPos(args[2]), !this.isOpen(state)); @@ -193,15 +195,13 @@ public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior { } private boolean isAnotherDoor(Object blockState) { - int id = BlockStateUtils.blockStateToId(blockState); - if (BlockStateUtils.isVanillaBlock(id)) { + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(blockState); + if (optionalCustomState.isEmpty()) { BlockData blockData = BlockStateUtils.fromBlockData(blockState); return blockData instanceof Door door && door.getHalf() == Bisected.Half.BOTTOM; } else { - ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(id); - if (state.isEmpty()) return false; - Optional optional = state.behavior().getAs(DoorBlockBehavior.class); - return optional.isPresent() && state.get(optional.get().halfProperty) == DoubleBlockHalf.LOWER; + Optional optional = optionalCustomState.get().behavior().getAs(DoorBlockBehavior.class); + return optional.isPresent() && optionalCustomState.get().get(optional.get().halfProperty) == DoubleBlockHalf.LOWER; } } @@ -233,10 +233,10 @@ public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior { public boolean isPathFindable(Object thisBlock, Object[] args, Callable superMethod) { Object type = VersionHelper.isOrAbove1_20_5() ? args[1] : args[3]; Object blockState = args[0]; - ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState)); - if (state == null || state.isEmpty()) return false; + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(blockState); + if (optionalCustomState.isEmpty()) return false; if (type == CoreReflections.instance$PathComputationType$LAND || type == CoreReflections.instance$PathComputationType$AIR) { - return state.get(this.openProperty); + return optionalCustomState.get().get(this.openProperty); } return false; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java index 487976c4a..59b6a1798 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java @@ -73,6 +73,7 @@ public class FallingBlockBehavior extends BukkitBlockBehavior { } } + @SuppressWarnings("DuplicatedCode") @Override public void onBrokenAfterFall(Object thisBlock, Object[] args) throws Exception { // Use EntityRemoveEvent for 1.20.3+ diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FenceGateBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FenceGateBlockBehavior.java index c200a4d17..7040f8b58 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FenceGateBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FenceGateBlockBehavior.java @@ -42,6 +42,7 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.Callable; +@SuppressWarnings("DuplicatedCode") public class FenceGateBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); private final Property facingProperty; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/GrassBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/GrassBlockBehavior.java index 235484c8f..dfc001ca8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/GrassBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/GrassBlockBehavior.java @@ -22,6 +22,7 @@ import org.bukkit.block.Block; import java.util.Map; import java.util.Optional; +@SuppressWarnings("DuplicatedCode") public class GrassBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LampBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LampBlockBehavior.java index 45cdf6a2e..eb750aeba 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LampBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LampBlockBehavior.java @@ -1,6 +1,5 @@ package net.momirealms.craftengine.bukkit.block.behavior; -import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.LocationUtils; @@ -16,6 +15,7 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.Callable; +@SuppressWarnings("DuplicatedCode") public class LampBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); private final Property litProperty; @@ -51,11 +51,12 @@ public class LampBlockBehavior extends BukkitBlockBehavior { @Override public void neighborChanged(Object thisBlock, Object[] args, Callable superMethod) { Object blockState = args[0]; - ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState)); - if (state == null || state.isEmpty()) return; + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(blockState); + if (optionalCustomState.isEmpty()) return; Object world = args[1]; Object blockPos = args[2]; - boolean lit = state.get(this.litProperty); + ImmutableBlockState customState = optionalCustomState.get(); + boolean lit = customState.get(this.litProperty); if (lit != FastNMS.INSTANCE.method$SignalGetter$hasNeighborSignal(world, blockPos)) { if (lit) { FastNMS.INSTANCE.method$LevelAccessor$scheduleBlockTick(world, blockPos, thisBlock, 4); @@ -63,7 +64,7 @@ public class LampBlockBehavior extends BukkitBlockBehavior { if (FastNMS.INSTANCE.method$CraftEventFactory$callRedstoneChange(world, blockPos, 0, 15).getNewCurrent() != 15) { return; } - FastNMS.INSTANCE.method$LevelWriter$setBlock(world, blockPos, state.cycle(this.litProperty).customBlockState().handle(), 2); + FastNMS.INSTANCE.method$LevelWriter$setBlock(world, blockPos, customState.cycle(this.litProperty).customBlockState().handle(), 2); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java index 493da39b8..dec1efd68 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java @@ -1,6 +1,5 @@ package net.momirealms.craftengine.bukkit.block.behavior; -import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; @@ -15,7 +14,6 @@ import net.momirealms.craftengine.core.block.properties.Property; import net.momirealms.craftengine.core.util.Direction; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.ResourceConfigUtils; -import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.BlockPos; import org.bukkit.Bukkit; import org.bukkit.World; @@ -57,26 +55,17 @@ public class LeavesBlockBehavior extends BukkitBlockBehavior { @Override public Object updateShape(Object thisBlock, Object[] args, Callable superMethod) throws Exception { - Object world; - Object blockPos; - Object neighborState; + Object world = args[updateShape$level]; + Object blockPos = args[updateShape$blockPos]; + Object neighborState = args[updateShape$neighborState]; Object blockState = args[0]; - if (VersionHelper.isOrAbove1_21_2()) { - world = args[1]; - neighborState = args[6]; - blockPos = args[3]; - } else { - world = args[3]; - blockPos = args[4]; - neighborState = args[2]; - } - ImmutableBlockState thisState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState)); - if (thisState != null) { - Optional optionalBehavior = thisState.behavior().getAs(LeavesBlockBehavior.class); + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(blockState); + if (optionalCustomState.isPresent()) { + Optional optionalBehavior = optionalCustomState.get().behavior().getAs(LeavesBlockBehavior.class); if (optionalBehavior.isPresent()) { LeavesBlockBehavior behavior = optionalBehavior.get(); int distance = behavior.getDistanceAt(neighborState) + 1; - if (distance != 1 || behavior.getDistance(thisState) != distance) { + if (distance != 1 || behavior.getDistance(optionalCustomState.get()) != distance) { FastNMS.INSTANCE.method$LevelAccessor$scheduleBlockTick(world, blockPos, thisBlock, 1); } } @@ -89,13 +78,14 @@ public class LeavesBlockBehavior extends BukkitBlockBehavior { Object blockState = args[0]; Object level = args[1]; Object blockPos = args[2]; - ImmutableBlockState currentState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState)); - if (currentState != null && !currentState.isEmpty()) { - Optional optionalBehavior = currentState.behavior().getAs(LeavesBlockBehavior.class); + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(blockState); + if (optionalCustomState.isPresent()) { + ImmutableBlockState customState = optionalCustomState.get(); + Optional optionalBehavior = customState.behavior().getAs(LeavesBlockBehavior.class); if (optionalBehavior.isPresent()) { LeavesBlockBehavior behavior = optionalBehavior.get(); - ImmutableBlockState newState = behavior.updateDistance(currentState, level, blockPos); - if (newState != currentState) { + ImmutableBlockState newState = behavior.updateDistance(customState, level, blockPos); + if (newState != customState) { if (blockState == newState.customBlockState().handle()) { CoreReflections.method$BlockStateBase$updateNeighbourShapes.invoke(blockState, level, blockPos, UpdateOption.UPDATE_ALL.flags(), 512); } else { @@ -156,14 +146,14 @@ public class LeavesBlockBehavior extends BukkitBlockBehavior { private int getDistanceAt(Object blockState) throws ReflectiveOperationException { boolean isLog = FastNMS.INSTANCE.method$BlockStateBase$is(blockState, LOG_TAG); if (isLog) return 0; - int id = BlockStateUtils.blockStateToId(blockState); - if (BlockStateUtils.isVanillaBlock(id)) { + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(blockState); + if (optionalCustomState.isEmpty()) { Object distanceProperty = CoreReflections.field$LeavesBlock$DISTANCE.get(null); boolean hasDistanceProperty = (boolean) CoreReflections.method$StateHolder$hasProperty.invoke(blockState, distanceProperty); if (!hasDistanceProperty) return this.maxDistance; return (int) CoreReflections.method$StateHolder$getValue.invoke(blockState, distanceProperty); } else { - ImmutableBlockState anotherBlockState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(id); + ImmutableBlockState anotherBlockState = optionalCustomState.get(); Optional optionalAnotherBehavior = anotherBlockState.behavior().getAs(LeavesBlockBehavior.class); return optionalAnotherBehavior.map(leavesBlockBehavior -> leavesBlockBehavior.getDistance(anotherBlockState)).orElse(this.maxDistance); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java index 77817bcee..66581d144 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java @@ -47,6 +47,7 @@ public class OnLiquidBlockBehavior extends AbstractCanSurviveBlockBehavior { } } + @SuppressWarnings("DuplicatedCode") @Override protected boolean canSurvive(Object thisBlock, Object state, Object world, Object blockPos) { int y = FastNMS.INSTANCE.field$Vec3i$y(blockPos); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/PressurePlateBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/PressurePlateBlockBehavior.java index 66b2b4e28..9b5c27012 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/PressurePlateBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/PressurePlateBlockBehavior.java @@ -1,7 +1,6 @@ package net.momirealms.craftengine.bukkit.block.behavior; import io.papermc.paper.event.entity.EntityInsideBlockEvent; -import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks; @@ -54,6 +53,7 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { this.pressedTime = pressedTime; } + @SuppressWarnings("DuplicatedCode") @Override public Object updateShape(Object thisBlock, Object[] args, Callable superMethod) throws Exception { Object state = args[0]; @@ -105,6 +105,7 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { if (signalForState == 0) { this.checkPressed(args[3], args[1], args[2], state, signalForState, thisBlock); } else { + // todo 为什么 FastNMS.INSTANCE.method$LevelAccessor$scheduleBlockTick(args[1], args[2], thisBlock, this.pressedTime); } } @@ -119,9 +120,9 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { } private Object setSignalForState(Object state, int strength) { - ImmutableBlockState blockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(state)); - if (blockState == null || blockState.isEmpty()) return state; - return blockState.with(this.poweredProperty, strength > 0).customBlockState().handle(); + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(state); + if (optionalCustomState.isEmpty()) return state; + return optionalCustomState.get().with(this.poweredProperty, strength > 0).customBlockState().handle(); } private void checkPressed(@Nullable Object entity, Object level, Object pos, Object state, int currentSignal, Object thisBlock) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SaplingBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SaplingBlockBehavior.java index db1749cae..90bffc5cc 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SaplingBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SaplingBlockBehavior.java @@ -30,6 +30,7 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.Callable; +@SuppressWarnings("DuplicatedCode") public class SaplingBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); private final Key feature; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/StairsBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/StairsBlockBehavior.java index ff015f251..fb2246d5e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/StairsBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/StairsBlockBehavior.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.Callable; +@SuppressWarnings("DuplicatedCode") public class StairsBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); private final Property facingProperty; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/TrapDoorBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/TrapDoorBlockBehavior.java index 093d8f0ac..d559fd291 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/TrapDoorBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/TrapDoorBlockBehavior.java @@ -39,6 +39,7 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.Callable; +@SuppressWarnings("DuplicatedCode") public class TrapDoorBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); private final Property halfProperty; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/AxeItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/AxeItemBehavior.java index 8a62033f2..9776e248c 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/AxeItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/AxeItemBehavior.java @@ -27,7 +27,6 @@ import net.momirealms.sparrow.nbt.CompoundTag; import org.bukkit.GameEvent; import org.bukkit.Material; import org.bukkit.Statistic; -import org.bukkit.block.data.BlockData; import org.bukkit.event.entity.EntityChangeBlockEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; @@ -58,15 +57,12 @@ public class AxeItemBehavior extends ItemBehavior { return InteractionResult.PASS; } - BukkitBlockInWorld block = (BukkitBlockInWorld) context.getLevel().getBlockAt(context.getClickedPos()); - BlockData blockData = block.block().getBlockData(); - int stateId = BlockStateUtils.blockDataToId(blockData); - if (BlockStateUtils.isVanillaBlock(stateId)) return InteractionResult.PASS; + Object blockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(context.getLevel().serverWorld(), LocationUtils.toBlockPos(context.getClickedPos())); + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(blockState); + if (optionalCustomState.isEmpty()) return InteractionResult.PASS; - ImmutableBlockState customBlockState = BukkitBlockManager.instance().getImmutableBlockState(stateId); - if (customBlockState == null || customBlockState.isEmpty()) return InteractionResult.PASS; - - Optional behaviorOptional = customBlockState.behavior().getAs(StrippableBlockBehavior.class); + ImmutableBlockState customState = optionalCustomState.get(); + Optional behaviorOptional = customState.behavior().getAs(StrippableBlockBehavior.class); if (behaviorOptional.isEmpty()) return InteractionResult.PASS; Key stripped = behaviorOptional.get().stripped(); Item offHandItem = (Item) player.getItemInHand(InteractionHand.OFF_HAND); @@ -81,7 +77,7 @@ public class AxeItemBehavior extends ItemBehavior { return InteractionResult.FAIL; } CustomBlock newCustomBlock = optionalNewCustomBlock.get(); - CompoundTag compoundTag = customBlockState.propertiesNbt(); + CompoundTag compoundTag = customState.propertiesNbt(); ImmutableBlockState newState = newCustomBlock.getBlockState(compoundTag); org.bukkit.entity.Player bukkitPlayer = ((org.bukkit.entity.Player) player.platformPlayer()); @@ -103,7 +99,7 @@ public class AxeItemBehavior extends ItemBehavior { // resend swing if it's not interactable on client side if (!InteractUtils.isInteractable( - bukkitPlayer, BlockStateUtils.fromBlockData(customBlockState.vanillaBlockState().handle()), + bukkitPlayer, BlockStateUtils.fromBlockData(customState.vanillaBlockState().handle()), context.getHitResult(), item ) || player.isSecondaryUseActive()) { player.swingHand(context.getHand()); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java index 2e071a68c..e3b481714 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java @@ -99,13 +99,13 @@ public class BlockItemBehavior extends BlockBoundItemBehavior { if (player.isAdventureMode()) { Object againstBlockState = BlockStateUtils.blockDataToBlockState(againstBlock.getBlockData()); - int stateId = BlockStateUtils.blockStateToId(againstBlockState); - if (BlockStateUtils.isVanillaBlock(stateId)) { + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(againstBlockState); + if (optionalCustomState.isEmpty()) { if (!AdventureModeUtils.canPlace(context.getItem(), context.getLevel(), againstPos, againstBlockState)) { return InteractionResult.FAIL; } } else { - ImmutableBlockState customState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId); + ImmutableBlockState customState = optionalCustomState.get(); // custom block if (!AdventureModeUtils.canPlace(context.getItem(), context.getLevel(), againstPos, Config.simplifyAdventurePlaceCheck() ? customState.vanillaBlockState().handle() : againstBlockState)) { return InteractionResult.FAIL; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/DebugStickListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/DebugStickListener.java index d77a704bc..01539c6f4 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/DebugStickListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/DebugStickListener.java @@ -2,13 +2,14 @@ package net.momirealms.craftengine.bukkit.item.listener; import net.kyori.adventure.text.Component; import net.momirealms.craftengine.bukkit.api.CraftEngineBlocks; -import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.ComponentUtils; +import net.momirealms.craftengine.bukkit.util.LocationUtils; import net.momirealms.craftengine.core.block.CustomBlock; import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.block.UpdateOption; @@ -58,13 +59,11 @@ public class DebugStickListener implements Listener { return; } } - Object blockState = BlockStateUtils.blockDataToBlockState(clickedBlock.getBlockData()); - int stateId = BlockStateUtils.blockStateToId(blockState); - if (!BlockStateUtils.isVanillaBlock(stateId)) { + Object blockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(clickedBlock.getWorld()), LocationUtils.toBlockPos(clickedBlock.getX(), clickedBlock.getY(), clickedBlock.getZ())); + BlockStateUtils.getOptionalCustomBlockState(blockState).ifPresent(customState -> { event.setCancelled(true); boolean update = event.getAction() == Action.RIGHT_CLICK_BLOCK; - ImmutableBlockState clickedCustomBlock = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId); - CustomBlock block = clickedCustomBlock.owner().value(); + CustomBlock block = customState.owner().value(); Collection> properties = block.properties(); String blockId = block.id().toString(); try { @@ -84,7 +83,7 @@ public class DebugStickListener implements Listener { currentProperty = properties.iterator().next(); } if (update) { - ImmutableBlockState nextState = cycleState(clickedCustomBlock, currentProperty, player.isSecondaryUseActive()); + ImmutableBlockState nextState = cycleState(customState, currentProperty, player.isSecondaryUseActive()); CraftEngineBlocks.place(clickedBlock.getLocation(), nextState, new UpdateOption.Builder().updateClients().updateKnownShape().build(), false); Object systemChatPacket = NetworkReflections.constructor$ClientboundSystemChatPacket.newInstance( ComponentUtils.adventureToMinecraft(Component.translatable("item.minecraft.debug_stick.update") @@ -102,16 +101,16 @@ public class DebugStickListener implements Listener { ComponentUtils.adventureToMinecraft(Component.translatable("item.minecraft.debug_stick.select") .arguments( Component.text(currentProperty.name()), - Component.text(getNameHelper(clickedCustomBlock, currentProperty)) + Component.text(getNameHelper(customState, currentProperty)) )), true); player.sendPacket(systemChatPacket, false); } } } } catch (ReflectiveOperationException e) { - plugin.logger().warn("Failed to send system chat packet", e); + this.plugin.logger().warn("Failed to send system chat packet", e); } - } + }); } private static > ImmutableBlockState cycleState(ImmutableBlockState state, Property property, boolean inverse) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java index 48a136c86..cad52ce04 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java @@ -2,7 +2,6 @@ package net.momirealms.craftengine.bukkit.item.listener; import io.papermc.paper.event.block.CompostItemEvent; import net.momirealms.craftengine.bukkit.api.event.CustomBlockInteractEvent; -import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.item.BukkitCustomItem; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; @@ -112,8 +111,7 @@ public class ItemEventListener implements Listener { Block block = Objects.requireNonNull(event.getClickedBlock()); BlockData blockData = block.getBlockData(); Object blockState = BlockStateUtils.blockDataToBlockState(blockData); - ImmutableBlockState immutableBlockState = null; - int stateId = BlockStateUtils.blockStateToId(blockState); + ImmutableBlockState immutableBlockState = BlockStateUtils.getOptionalCustomBlockState(blockState).orElse(null); Item itemInHand = serverPlayer.getItemInHand(hand); Location interactionPoint = event.getInteractionPoint(); @@ -126,8 +124,7 @@ public class ItemEventListener implements Listener { } // 处理自定义方块 - if (!BlockStateUtils.isVanillaBlock(stateId)) { - immutableBlockState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId); + if (immutableBlockState != null) { // call the event if it's custom CustomBlockInteractEvent interactEvent = new CustomBlockInteractEvent( player, diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java index 285d026c8..38a6c2ae2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java @@ -12,7 +12,6 @@ import net.bytebuddy.implementation.bind.annotation.SuperCall; import net.bytebuddy.implementation.bind.annotation.This; import net.bytebuddy.implementation.bytecode.assign.Assigner; import net.bytebuddy.matcher.ElementMatchers; -import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; @@ -34,6 +33,7 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.util.List; +import java.util.Optional; import java.util.concurrent.Callable; import java.util.function.Consumer; @@ -217,10 +217,10 @@ public class WorldStorageInjector { protected static void compareAndUpdateBlockState(int x, int y, int z, Object newState, Object previousState, InjectedHolder holder) { try { - int stateId = BlockStateUtils.blockStateToId(newState); + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(newState); CESection section = holder.ceSection(); // 如果是原版方块 - if (BlockStateUtils.isVanillaBlock(stateId)) { + if (optionalCustomState.isEmpty()) { // 那么应该清空自定义块 ImmutableBlockState previous = section.setBlockState(x, y, z, EmptyBlock.STATE); // 处理 自定义块 -> 原版块 @@ -235,7 +235,7 @@ public class WorldStorageInjector { } } } else { - ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId); + ImmutableBlockState immutableBlockState = optionalCustomState.get(); ImmutableBlockState previousImmutableBlockState = section.setBlockState(x, y, z, immutableBlockState); if (previousImmutableBlockState == immutableBlockState) return; // 处理 自定义块到自定义块或原版块到自定义块 diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index 90666133a..17d10d7e1 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -9,6 +9,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntList; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TranslationArgument; +import net.momirealms.craftengine.bukkit.api.CraftEngineBlocks; import net.momirealms.craftengine.bukkit.api.CraftEngineFurniture; import net.momirealms.craftengine.bukkit.api.event.FurnitureAttemptBreakEvent; import net.momirealms.craftengine.bukkit.api.event.FurnitureBreakEvent; @@ -1316,7 +1317,7 @@ public class PacketConsumers { if (result == null) return; Block hitBlock = result.getHitBlock(); if (hitBlock == null) return; - ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockDataToId(hitBlock.getBlockData())); + ImmutableBlockState state = CraftEngineBlocks.getCustomBlockState(hitBlock); // not a custom block if (state == null || state.isEmpty()) return; Key itemId = state.settings().itemId(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java index 6730c7c63..607f725b9 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java @@ -1320,7 +1320,6 @@ public final class CoreReflections { ReflectionUtils.getDeclaredField(clazz$BlockStateBase, boolean.class, 8) ); - public static final Field field$BlockStateBase$lightEmission = requireNonNull( ReflectionUtils.getDeclaredField(clazz$BlockStateBase, int.class, 0) ); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java index 1f488f653..74078791f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java @@ -5,7 +5,7 @@ import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelHandler; import net.kyori.adventure.text.Component; -import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; +import net.momirealms.craftengine.bukkit.api.CraftEngineBlocks; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; @@ -450,15 +450,15 @@ public class BukkitServerPlayer extends Player { } return; } - int stateId = BlockStateUtils.blockDataToId(hitBlock.getBlockData()); - if (BlockStateUtils.isVanillaBlock(stateId)) { + ImmutableBlockState nextBlock = CraftEngineBlocks.getCustomBlockState(hitBlock); + if (nextBlock == null) { if (!this.clientSideCanBreak) { setClientSideCanBreakBlock(true); } - return; - } - if (this.clientSideCanBreak) { - setClientSideCanBreakBlock(false); + } else { + if (this.clientSideCanBreak) { + setClientSideCanBreakBlock(false); + } } } @@ -612,10 +612,10 @@ public class BukkitServerPlayer extends Player { } float progressToAdd = getDestroyProgress(destroyedState, hitPos); - int id = BlockStateUtils.blockStateToId(destroyedState); - ImmutableBlockState customState = BukkitBlockManager.instance().getImmutableBlockState(id); + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(destroyedState); // double check custom block - if (customState != null && !customState.isEmpty()) { + if (optionalCustomState.isPresent()) { + ImmutableBlockState customState = optionalCustomState.get(); BlockSettings blockSettings = customState.settings(); if (blockSettings.requireCorrectTool()) { if (item != null) { @@ -666,7 +666,7 @@ public class BukkitServerPlayer extends Player { CoreReflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos); } // send break particle + (removed sounds) - sendPacket(FastNMS.INSTANCE.constructor$ClientboundLevelEventPacket(WorldEvents.BLOCK_BREAK_EFFECT, blockPos, id, false), false); + sendPacket(FastNMS.INSTANCE.constructor$ClientboundLevelEventPacket(WorldEvents.BLOCK_BREAK_EFFECT, blockPos, customState.customBlockState().registryId(), false), false); this.lastSuccessfulBreak = currentTick; this.destroyPos = null; this.setIsDestroyingBlock(false, false); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/LightUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/LightUtils.java index a3021f22e..51e046ddf 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/LightUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/LightUtils.java @@ -27,8 +27,8 @@ public class LightUtils { Object chunkPos = FastNMS.INSTANCE.constructor$ChunkPos((int) chunkKey, (int) (chunkKey >> 32)); Object lightPacket = FastNMS.INSTANCE.constructor$ClientboundLightUpdatePacket(chunkPos, lightEngine, entry.getValue(), entry.getValue()); for (Object player : players) { - FastNMS.INSTANCE.method$Connection$send( - FastNMS.INSTANCE.field$ServerGamePacketListenerImpl$connection(FastNMS.INSTANCE.field$ServerGamePacketListenerImpl$connection(player)), + FastNMS.INSTANCE.method$ServerPlayerConnection$send( + FastNMS.INSTANCE.field$Player$connection(player), lightPacket); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitBlockInWorld.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitBlockInWorld.java index 9c9213aae..6b4a3bb01 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitBlockInWorld.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitBlockInWorld.java @@ -1,10 +1,8 @@ package net.momirealms.craftengine.bukkit.world; import net.momirealms.craftengine.bukkit.api.CraftEngineBlocks; -import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MFluids; -import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.LocationUtils; import net.momirealms.craftengine.core.block.CustomBlock; import net.momirealms.craftengine.core.block.ImmutableBlockState; @@ -23,7 +21,7 @@ public class BukkitBlockInWorld implements BlockInWorld { @Override public boolean canBeReplaced(BlockPlaceContext context) { - ImmutableBlockState customState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockDataToId(this.block.getBlockData())); + ImmutableBlockState customState = CraftEngineBlocks.getCustomBlockState(this.block); if (customState != null && !customState.isEmpty()) { return customState.behavior().canBeReplaced(context, customState); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java index 82931530a..33fd76243 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java @@ -32,6 +32,7 @@ import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -338,14 +339,14 @@ public class BukkitWorldManager implements WorldManager, Listener { boolean requiresSync = false; if (CoreReflections.clazz$SingleValuePalette.isInstance(palette)) { Object onlyBlockState = CoreReflections.field$SingleValuePalette$value.get(palette); - if (!BlockStateUtils.isVanillaBlock(BlockStateUtils.blockStateToId(onlyBlockState))) { + if (BlockStateUtils.isCustomBlock(onlyBlockState)) { requiresSync = true; } } else if (CoreReflections.clazz$LinearPalette.isInstance(palette)) { Object[] blockStates = (Object[]) CoreReflections.field$LinearPalette$values.get(palette); for (Object blockState : blockStates) { if (blockState != null) { - if (!BlockStateUtils.isVanillaBlock(BlockStateUtils.blockStateToId(blockState))) { + if (BlockStateUtils.isCustomBlock(blockState)) { requiresSync = true; break; } @@ -356,7 +357,7 @@ public class BukkitWorldManager implements WorldManager, Listener { Object[] blockStates = (Object[]) CoreReflections.field$CrudeIncrementalIntIdentityHashBiMap$keys.get(biMap); for (Object blockState : blockStates) { if (blockState != null) { - if (!BlockStateUtils.isVanillaBlock(BlockStateUtils.blockStateToId(blockState))) { + if (BlockStateUtils.isCustomBlock(blockState)) { requiresSync = true; break; } @@ -370,10 +371,9 @@ public class BukkitWorldManager implements WorldManager, Listener { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { Object mcState = FastNMS.INSTANCE.method$LevelChunkSection$getBlockState(section, x, y, z); - int stateId = BlockStateUtils.blockStateToId(mcState); - ImmutableBlockState customState = this.plugin.blockManager().getImmutableBlockState(stateId); - if (customState != null) { - ceSection.setBlockState(x, y, z, customState); + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(mcState); + if (optionalCustomState.isPresent()) { + ceSection.setBlockState(x, y, z, optionalCustomState.get()); } } } diff --git a/common-files/src/main/resources/resources/default/configuration/palm_tree.yml b/common-files/src/main/resources/resources/default/configuration/palm_tree.yml index 7ef443c97..7af4f7420 100644 --- a/common-files/src/main/resources/resources/default/configuration/palm_tree.yml +++ b/common-files/src/main/resources/resources/default/configuration/palm_tree.yml @@ -358,7 +358,7 @@ items: open: minecraft:block.wooden_door.open close: minecraft:block.wooden_door.close loot: - template: default:loot_table/self + template: default:loot_table/door settings: template: - default:sound/wood diff --git a/common-files/src/main/resources/resources/default/configuration/templates.yml b/common-files/src/main/resources/resources/default/configuration/templates.yml index 226102ee1..57f5fd033 100644 --- a/common-files/src/main/resources/resources/default/configuration/templates.yml +++ b/common-files/src/main/resources/resources/default/configuration/templates.yml @@ -3123,6 +3123,20 @@ templates#loot_tables: - type: furniture_item item: ${item} + # drop the door + + # template: default:loot_table/door + default:loot_table/door: + pools: + - rolls: 1 + entries: + - type: item + item: ${__NAMESPACE__}:${__ID__} + conditions: + - type: match_block_property + properties: + half: lower + # drop with silk touch # template: default:loot_table/silk_touch diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockRegistryMirror.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockRegistryMirror.java index 1b273d9e2..b5f631b68 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockRegistryMirror.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockRegistryMirror.java @@ -1,6 +1,6 @@ package net.momirealms.craftengine.core.block; -public class BlockRegistryMirror { +public final class BlockRegistryMirror { private static BlockStateWrapper[] customBlockStates; private static BlockStateWrapper stoneState;