From d4086101cfbfa14206d4edb627214167452ceb41 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Mon, 26 May 2025 01:44:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=94=AF=E6=92=91=E5=BD=A2?= =?UTF-8?q?=E7=8A=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/block/BukkitBlockShape.java | 10 +++++++++- .../bukkit/block/BukkitCustomBlock.java | 17 +++++++++++----- .../plugin/injector/BukkitInjector.java | 20 ++++++++++++++++++- .../craftengine/bukkit/util/Reflections.java | 6 ++++++ .../craftengine/core/block/BlockSettings.java | 15 ++++++++++++++ gradle.properties | 4 ++-- .../mod/block/StoneBlockShape.java | 5 +++++ .../mod/block/StoneBlockShape.java | 5 +++++ .../mod/block/StoneBlockShape.java | 5 +++++ .../craftengine/shared/block/BlockShape.java | 2 ++ 10 files changed, 80 insertions(+), 9 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockShape.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockShape.java index fb9bcfb8a..c57f78a20 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockShape.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockShape.java @@ -2,12 +2,15 @@ package net.momirealms.craftengine.bukkit.block; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.shared.block.BlockShape; +import org.jetbrains.annotations.Nullable; public class BukkitBlockShape implements BlockShape { private final Object rawBlockState; + private final Object supportBlockState; - public BukkitBlockShape(Object rawBlockState) { + public BukkitBlockShape(Object rawBlockState, @Nullable Object supportBlockState) { this.rawBlockState = rawBlockState; + this.supportBlockState = supportBlockState == null ? rawBlockState : supportBlockState; } @Override @@ -19,4 +22,9 @@ public class BukkitBlockShape implements BlockShape { public Object getCollisionShape(Object thisObj, Object[] args) { return FastNMS.INSTANCE.method$BlockState$getCollisionShape(this.rawBlockState, args[1], args[2], args[3]); } + + @Override + public Object getSupportShape(Object thisObj, Object[] args) { + return FastNMS.INSTANCE.method$BlockState$getBlockSupportShape(this.supportBlockState, args[1], args[2]); + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java index 592862fde..7cadd52e3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java @@ -21,15 +21,13 @@ import net.momirealms.craftengine.core.util.Tristate; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.shared.ObjectHolder; import net.momirealms.craftengine.shared.block.BlockBehavior; +import org.bukkit.Bukkit; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.lang.reflect.Field; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; public class BukkitCustomBlock extends AbstractCustomBlock { @@ -103,7 +101,16 @@ public class BukkitCustomBlock extends AbstractCustomBlock { Field shapeField = mcBlock.getClass().getField("shapeHolder"); @SuppressWarnings("unchecked") ObjectHolder shapeHolder = (ObjectHolder) shapeField.get(mcBlock); - shapeHolder.bindValue(new BukkitBlockShape(state.vanillaBlockState().handle())); + shapeHolder.bindValue(new BukkitBlockShape(state.vanillaBlockState().handle(), Optional.ofNullable(state.settings().supportShapeBlockState()).map(it -> { + try { + Object blockState = BlockStateUtils.blockDataToBlockState(Bukkit.createBlockData(it)); + if (!BlockStateUtils.isVanillaBlock(blockState)) return null; + return blockState; + } catch (IllegalArgumentException e) { + CraftEngine.instance().logger().warn("Illegal shape block state: " + it, e); + return null; + } + }).orElse(null))); // bind behavior Field behaviorField = mcBlock.getClass().getField("behaviorHolder"); @SuppressWarnings("unchecked") diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java index 4213341cb..ad535cb48 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java @@ -73,7 +73,7 @@ import java.util.function.Consumer; public class BukkitInjector { private static final ByteBuddy byteBuddy = new ByteBuddy(ClassFileVersion.JAVA_V17); - private static final BukkitBlockShape STONE_SHAPE = new BukkitBlockShape(Reflections.instance$Blocks$STONE$defaultState); + private static final BukkitBlockShape STONE_SHAPE = new BukkitBlockShape(Reflections.instance$Blocks$STONE$defaultState, Reflections.instance$Blocks$STONE$defaultState); private static Class clazz$InjectedPalettedContainer; private static Class clazz$InjectedLevelChunkSection; @@ -251,6 +251,9 @@ public class BukkitInjector { // getCollisionShape .method(ElementMatchers.is(Reflections.method$BlockBehaviour$getCollisionShape)) .intercept(MethodDelegation.to(GetCollisionShapeInterceptor.INSTANCE)) + // getSupportShape + .method(ElementMatchers.is(Reflections.method$BlockBehaviour$getBlockSupportShape)) + .intercept(MethodDelegation.to(GetSupportShapeInterceptor.INSTANCE)) // mirror .method(ElementMatchers.is(Reflections.method$BlockBehaviour$mirror)) .intercept(MethodDelegation.to(MirrorInterceptor.INSTANCE)) @@ -941,6 +944,21 @@ public class BukkitInjector { } } + public static class GetSupportShapeInterceptor { + public static final GetSupportShapeInterceptor INSTANCE = new GetSupportShapeInterceptor(); + + @RuntimeType + public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable superMethod) throws Exception { + ObjectHolder holder = ((ShapeHolder) thisObj).getShapeHolder(); + try { + return holder.value().getSupportShape(thisObj, args); + } catch (Exception e) { + CraftEngine.instance().logger().severe("Failed to run getSupportShape", e); + return superMethod.call(); + } + } + } + public static class MirrorInterceptor { public static final MirrorInterceptor INSTANCE = new MirrorInterceptor(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java index 72fcbeb70..5b3f765a4 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java @@ -2548,6 +2548,12 @@ public class Reflections { ) ); + public static final Method method$BlockBehaviour$getBlockSupportShape = requireNonNull( + ReflectionUtils.getDeclaredMethod( + clazz$BlockBehaviour, clazz$VoxelShape, new String[]{"getBlockSupportShape", "b_"}, clazz$BlockState, clazz$BlockGetter, clazz$BlockPos + ) + ); + public static final Method method$BlockBehaviour$tick = requireNonNull( ReflectionUtils.getDeclaredMethod( clazz$BlockBehaviour, void.class, new String[]{"tick", "a"}, clazz$BlockState, clazz$ServerLevel, clazz$BlockPos, clazz$RandomSource diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockSettings.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockSettings.java index 79e268a99..71ea2b52f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockSettings.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockSettings.java @@ -34,6 +34,7 @@ public class BlockSettings { float incorrectToolSpeed = 0.3f; Set correctTools = Set.of(); String name; + String supportShapeBlockState; private BlockSettings() {} @@ -89,6 +90,7 @@ public class BlockSettings { newSettings.blockLight = settings.blockLight; newSettings.name = settings.name; newSettings.incorrectToolSpeed = settings.incorrectToolSpeed; + newSettings.supportShapeBlockState = settings.supportShapeBlockState; return newSettings; } @@ -192,6 +194,10 @@ public class BlockSettings { return respectToolComponent; } + public String supportShapeBlockState() { + return supportShapeBlockState; + } + public BlockSettings correctTools(Set correctTools) { this.correctTools = correctTools; return this; @@ -317,6 +323,11 @@ public class BlockSettings { return this; } + public BlockSettings supportShapeBlockState(String supportShapeBlockState) { + this.supportShapeBlockState = supportShapeBlockState; + return this; + } + public interface Modifier { void apply(BlockSettings settings); @@ -431,6 +442,10 @@ public class BlockSettings { String name = value.toString(); return settings -> settings.name(name); })); + registerFactory("support-shape", (value -> { + String shape = value.toString(); + return settings -> settings.supportShapeBlockState(shape); + })); } private static void registerFactory(String id, Modifier.Factory factory) { diff --git a/gradle.properties b/gradle.properties index 6179e467c..a771bb053 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.54.10 +project_version=0.0.54.11 config_version=34 lang_version=14 project_group=net.momirealms @@ -50,7 +50,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.4 anti_grief_version=0.17 -nms_helper_version=0.65.30 +nms_helper_version=0.65.32 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23 diff --git a/server-mod/v1_20_1/src/main/java/net/momirealms/craftengine/mod/block/StoneBlockShape.java b/server-mod/v1_20_1/src/main/java/net/momirealms/craftengine/mod/block/StoneBlockShape.java index 348530720..8766f8568 100644 --- a/server-mod/v1_20_1/src/main/java/net/momirealms/craftengine/mod/block/StoneBlockShape.java +++ b/server-mod/v1_20_1/src/main/java/net/momirealms/craftengine/mod/block/StoneBlockShape.java @@ -22,4 +22,9 @@ public class StoneBlockShape implements BlockShape { public Object getCollisionShape(Object thisObj, Object[] args) { return rawBlockState.getCollisionShape((BlockGetter) args[1], (BlockPos) args[2], (CollisionContext) args[3]); } + + @Override + public Object getSupportShape(Object thisObj, Object[] args) { + return rawBlockState.getBlockSupportShape((BlockGetter) args[1], (BlockPos) args[2]); + } } diff --git a/server-mod/v1_20_5/src/main/java/net/momirealms/craftengine/mod/block/StoneBlockShape.java b/server-mod/v1_20_5/src/main/java/net/momirealms/craftengine/mod/block/StoneBlockShape.java index 348530720..8766f8568 100644 --- a/server-mod/v1_20_5/src/main/java/net/momirealms/craftengine/mod/block/StoneBlockShape.java +++ b/server-mod/v1_20_5/src/main/java/net/momirealms/craftengine/mod/block/StoneBlockShape.java @@ -22,4 +22,9 @@ public class StoneBlockShape implements BlockShape { public Object getCollisionShape(Object thisObj, Object[] args) { return rawBlockState.getCollisionShape((BlockGetter) args[1], (BlockPos) args[2], (CollisionContext) args[3]); } + + @Override + public Object getSupportShape(Object thisObj, Object[] args) { + return rawBlockState.getBlockSupportShape((BlockGetter) args[1], (BlockPos) args[2]); + } } diff --git a/server-mod/v1_21_5/src/main/java/net/momirealms/craftengine/mod/block/StoneBlockShape.java b/server-mod/v1_21_5/src/main/java/net/momirealms/craftengine/mod/block/StoneBlockShape.java index 348530720..8766f8568 100644 --- a/server-mod/v1_21_5/src/main/java/net/momirealms/craftengine/mod/block/StoneBlockShape.java +++ b/server-mod/v1_21_5/src/main/java/net/momirealms/craftengine/mod/block/StoneBlockShape.java @@ -22,4 +22,9 @@ public class StoneBlockShape implements BlockShape { public Object getCollisionShape(Object thisObj, Object[] args) { return rawBlockState.getCollisionShape((BlockGetter) args[1], (BlockPos) args[2], (CollisionContext) args[3]); } + + @Override + public Object getSupportShape(Object thisObj, Object[] args) { + return rawBlockState.getBlockSupportShape((BlockGetter) args[1], (BlockPos) args[2]); + } } diff --git a/shared/src/main/java/net/momirealms/craftengine/shared/block/BlockShape.java b/shared/src/main/java/net/momirealms/craftengine/shared/block/BlockShape.java index b33a42a03..8f11da262 100644 --- a/shared/src/main/java/net/momirealms/craftengine/shared/block/BlockShape.java +++ b/shared/src/main/java/net/momirealms/craftengine/shared/block/BlockShape.java @@ -5,4 +5,6 @@ public interface BlockShape { Object getShape(Object thisObj, Object[] args) throws Exception; Object getCollisionShape(Object thisObj, Object[] args); + + Object getSupportShape(Object thisObj, Object[] args); }