From 85fce396bef1b5d9cd767df0bb90d7ee3187151d Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Sat, 21 Jun 2025 13:12:50 +0800 Subject: [PATCH] =?UTF-8?q?todo(block):=20=E6=8E=A8=E9=80=81=E4=BB=A3?= =?UTF-8?q?=E5=8A=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../block/behavior/StairsBlockBehavior.java | 47 +++++++++++ .../reflection/minecraft/CoreReflections.java | 82 +++++++++++++++++++ .../bukkit/util/StairsShapeUtils.java | 27 ++++++ 3 files changed, 156 insertions(+) create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/StairsShapeUtils.java 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 efc0ce047..4f63c48a3 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 @@ -87,6 +87,24 @@ public class StairsBlockBehavior extends BukkitBlockBehavior { return StairsShape.OUTER_RIGHT; } } + } else if (isStairs(blockState)) { + // 处理可能是原版楼梯 + // try { + // Object nmsHalf = CoreReflections.method$StateHolder$getValue.invoke(blockState, CoreReflections.instance$StairBlock$HALF); + // SingleBlockHalf half = SingleBlockHalf.valueOf(nmsHalf.toString().toUpperCase(Locale.ROOT)); + // if (state.get(this.halfProperty).equals(half)) { + // Object nmsFacing = CoreReflections.method$StateHolder$getValue.invoke(blockState, CoreReflections.instance$StairBlock$FACING); + // Direction direction1 = DirectionUtils.fromNMSDirection(nmsFacing); + // if (direction1.axis() != state.get(this.facingProperty).toDirection().axis() && canTakeShape(state, level, pos, direction1.opposite())) { + // if (direction1 == direction.counterClockWise()) { + // return StairsShape.OUTER_LEFT; + // } + // return StairsShape.OUTER_RIGHT; + // } + // } + // } catch (Exception e) { + // CraftEngine.instance().logger().warn("Failed to get facing from blockState", e); + // } } Object blockState1 = FastNMS.INSTANCE.method$BlockGetter$getBlockState(level, LocationUtils.toBlockPos(pos.relative(direction.opposite()))); @@ -102,6 +120,24 @@ public class StairsBlockBehavior extends BukkitBlockBehavior { return StairsShape.INNER_RIGHT; } } + } else if (isStairs(blockState1)) { + // 处理可能是原版楼梯 + // try { + // Object nmsHalf = CoreReflections.method$StateHolder$getValue.invoke(blockState1, CoreReflections.instance$StairBlock$HALF); + // SingleBlockHalf half = SingleBlockHalf.valueOf(nmsHalf.toString().toUpperCase(Locale.ROOT)); + // if (state.get(this.halfProperty).equals(half)) { + // Object nmsFacing = CoreReflections.method$StateHolder$getValue.invoke(blockState1, CoreReflections.instance$StairBlock$FACING); + // Direction direction1 = DirectionUtils.fromNMSDirection(nmsFacing); + // if (direction1.axis() != state.get(this.facingProperty).toDirection().axis() && canTakeShape(state, level, pos, direction1)) { + // if (direction1 == direction.counterClockWise()) { + // return StairsShape.INNER_LEFT; + // } + // return StairsShape.INNER_RIGHT; + // } + // } + // } catch (Exception e) { + // CraftEngine.instance().logger().warn("Failed to get facing from blockState", e); + // } } return StairsShape.STRAIGHT; @@ -120,6 +156,17 @@ public class StairsBlockBehavior extends BukkitBlockBehavior { Object blockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(level, LocationUtils.toBlockPos(pos.relative(face))); ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState)); if (immutableBlockState == null || immutableBlockState.isEmpty()) { + // 处理可能是原版楼梯 + // try { + // Object nmsFacing = CoreReflections.method$StateHolder$getValue.invoke(blockState, CoreReflections.instance$StairBlock$FACING); + // Direction direction = DirectionUtils.fromNMSDirection(nmsFacing); + // if (direction != state.get(this.facingProperty).toDirection()) return true; + // Object nmsHalf = CoreReflections.method$StateHolder$getValue.invoke(blockState, CoreReflections.instance$StairBlock$HALF); + // SingleBlockHalf half = SingleBlockHalf.valueOf(nmsHalf.toString().toUpperCase(Locale.ROOT)); + // if (half != state.get(this.halfProperty)) return true; + // } catch (Exception e) { + // CraftEngine.instance().logger().warn("Failed to handle canTakeShape", e); + // } return !isStairs(blockState); } return !isStairs(blockState) || immutableBlockState.get(this.facingProperty) != state.get(this.facingProperty) || immutableBlockState.get(this.halfProperty) != state.get(this.halfProperty); 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 0f07d09fa..c2a330932 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 @@ -3354,4 +3354,86 @@ public final class CoreReflections { "world.level.block.StairBlock" ) ); + + public static final Class clazz$StairsShape = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.state.properties.BlockPropertyStairsShape", + "world.level.block.state.properties.StairsShape" + ) + ); + + public static final Method method$StairsShape$values = requireNonNull( + ReflectionUtils.getStaticMethod(clazz$StairsShape, clazz$StairsShape.arrayType()) + ); + + public static final Method method$StairsShape$ordinal = requireNonNull( + ReflectionUtils.getMethod( + clazz$StairsShape, new String[]{"ordinal"} + ) + ); + + public static final Object instance$StairsShape$STRAIGHT; + public static final Object instance$StairsShape$INNER_LEFT; + public static final Object instance$StairsShape$INNER_RIGHT; + public static final Object instance$StairsShape$OUTER_LEFT; + public static final Object instance$StairsShape$OUTER_RIGHT; + + static { + try { + Object[] values = (Object[]) method$StairsShape$values.invoke(null); + instance$StairsShape$STRAIGHT = values[0]; + instance$StairsShape$INNER_LEFT = values[1]; + instance$StairsShape$INNER_RIGHT = values[2]; + instance$StairsShape$OUTER_LEFT = values[3]; + instance$StairsShape$OUTER_RIGHT = values[4]; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static final Class clazz$EnumProperty = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.state.properties.BlockStateEnum", + "world.level.block.state.properties.EnumProperty" + ) + ); + + // 1.20~1.21.1 + public static final Class clazz$DirectionProperty = + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.state.properties.BlockStateDirection", + "world.level.block.state.properties.DirectionProperty" + ); + + public static final Field field$StairBlock$FACING = requireNonNull( + VersionHelper.isOrAbove1_21_2() + ? ReflectionUtils.getDeclaredField(clazz$StairBlock, clazz$EnumProperty, 0) + : ReflectionUtils.getDeclaredField(clazz$StairBlock, clazz$DirectionProperty, 0) + ); + + public static final Field field$StairBlock$HALF = requireNonNull( + ReflectionUtils.getDeclaredField( + clazz$StairBlock, clazz$EnumProperty, VersionHelper.isOrAbove1_21_2() ? 1 : 0 + ) + ); + + public static final Field field$StairBlock$SHAPE = requireNonNull( + ReflectionUtils.getDeclaredField( + clazz$StairBlock, clazz$EnumProperty, VersionHelper.isOrAbove1_21_2() ? 2 : 1 + ) + ); + + public static final Object instance$StairBlock$FACING; + public static final Object instance$StairBlock$HALF; + public static final Object instance$StairBlock$SHAPE; + + static { + try { + instance$StairBlock$FACING = requireNonNull(field$StairBlock$FACING.get(null)); + instance$StairBlock$HALF = requireNonNull(field$StairBlock$HALF.get(null)); + instance$StairBlock$SHAPE = requireNonNull(field$StairBlock$SHAPE.get(null)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/StairsShapeUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/StairsShapeUtils.java new file mode 100644 index 000000000..c06c548b5 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/StairsShapeUtils.java @@ -0,0 +1,27 @@ +package net.momirealms.craftengine.bukkit.util; + +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; +import net.momirealms.craftengine.core.block.state.properties.StairsShape; + +public class StairsShapeUtils { + private StairsShapeUtils() {} + + public static StairsShape fromNMSStairsShape(Object shape) { + try { + int index = (int) CoreReflections.method$StairsShape$ordinal.invoke(shape); + return StairsShape.values()[index]; + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public static Object toNMSStairsShape(StairsShape shape) { + return switch (shape) { + case STRAIGHT -> CoreReflections.instance$StairsShape$STRAIGHT; + case INNER_LEFT -> CoreReflections.instance$StairsShape$INNER_LEFT; + case INNER_RIGHT -> CoreReflections.instance$StairsShape$INNER_RIGHT; + case OUTER_LEFT -> CoreReflections.instance$StairsShape$OUTER_LEFT; + case OUTER_RIGHT -> CoreReflections.instance$StairsShape$OUTER_RIGHT; + }; + } +}