From ecab22cc9b0a85d85b28a14a545a8b98d411fa24 Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Fri, 19 Sep 2025 11:24:08 +0800 Subject: [PATCH] =?UTF-8?q?feat(block):=20=E5=AE=8C=E5=96=84=E5=8C=B9?= =?UTF-8?q?=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../behavior/PressurePlateBlockBehavior.java | 2 - .../plugin/injector/BlockStateGenerator.java | 74 ++++++++++++++++++- .../reflection/minecraft/CoreReflections.java | 22 ++++++ 3 files changed, 94 insertions(+), 4 deletions(-) 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 5ec5cc268..0453403b5 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 @@ -102,8 +102,6 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { int signalForState = this.getSignalForState(state); if (signalForState == 0) { this.checkPressed(args[3], args[1], args[2], state, signalForState, thisBlock); - } else { - FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(args[1], args[2], thisBlock, this.pressedTime); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockStateGenerator.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockStateGenerator.java index 4dee54943..9281595d8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockStateGenerator.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockStateGenerator.java @@ -20,6 +20,7 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlockStateProperties; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MLootContextParams; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; @@ -70,7 +71,19 @@ public final class BlockStateGenerator { .method(ElementMatchers.is(CoreReflections.method$StateHolder$setValue)) .intercept(MethodDelegation.to(SetPropertyValueInterceptor.INSTANCE)) .method(ElementMatchers.is(CoreReflections.method$BlockStateBase$isBlock)) - .intercept(MethodDelegation.to(IsBlockInterceptor.INSTANCE)); + .intercept(MethodDelegation.to(IsBlockInterceptor.INSTANCE)) + .method(ElementMatchers.is(CoreReflections.method$BlockStateBase$isHolderSetBlock)) + .intercept(MethodDelegation.to(IsHolderSetBlockInterceptor.INSTANCE)); + if (CoreReflections.method$BlockStateBase$isHolderBlock != null) { + stateBuilder = stateBuilder + .method(ElementMatchers.is(CoreReflections.method$BlockStateBase$isHolderBlock)) + .intercept(MethodDelegation.to(IsHolderBlockInterceptor.INSTANCE)); + } + if (CoreReflections.method$BlockStateBase$isResourceKeyBlock != null) { + stateBuilder = stateBuilder + .method(ElementMatchers.is(CoreReflections.method$BlockStateBase$isResourceKeyBlock)) + .intercept(MethodDelegation.to(IsResourceKeyBlockInterceptor.INSTANCE)); + } Class clazz$CraftEngineBlock = stateBuilder.make().load(BlockStateGenerator.class.getClassLoader()).getLoaded(); constructor$CraftEngineBlockState = VersionHelper.isOrAbove1_20_5() ? MethodHandles.publicLookup().in(clazz$CraftEngineBlock) @@ -200,7 +213,64 @@ public final class BlockStateGenerator { if (!(args[0] instanceof DelegatingBlock delegatingBlock)) return false; BlockBehavior behavior = delegatingBlock.behaviorDelegate().value(); if (behavior == null) return false; - return behavior.equals(thisState.owner().value()); + return behavior.block().equals(thisState.owner().value()); + } + } + + public static class IsHolderSetBlockInterceptor { + public static final IsHolderSetBlockInterceptor INSTANCE = new IsHolderSetBlockInterceptor(); + + @SuppressWarnings("unchecked") + @RuntimeType + public boolean intercept(@This Object thisObj, @AllArguments Object[] args) { + DelegatingBlockState customState = (DelegatingBlockState) thisObj; + ImmutableBlockState thisState = customState.blockState(); + if (thisState == null) return false; + CustomBlock thisBlock = thisState.owner().value(); + for (Object holder : (Iterable) args[0]) { + Object block = FastNMS.INSTANCE.method$Holder$value(holder); + if (!(block instanceof DelegatingBlock delegatingBlock)) continue; + BlockBehavior behavior = delegatingBlock.behaviorDelegate().value(); + if (behavior == null) continue; + if (behavior.block().equals(thisBlock)) return true; + } + return false; + } + } + + public static class IsHolderBlockInterceptor { + public static final IsHolderBlockInterceptor INSTANCE = new IsHolderBlockInterceptor(); + + @RuntimeType + public boolean intercept(@This Object thisObj, @AllArguments Object[] args) { + DelegatingBlockState customState = (DelegatingBlockState) thisObj; + ImmutableBlockState thisState = customState.blockState(); + if (thisState == null) return false; + CustomBlock thisBlock = thisState.owner().value(); + Object block = FastNMS.INSTANCE.method$Holder$value(args[0]); + if (!(block instanceof DelegatingBlock delegatingBlock)) return false; + BlockBehavior behavior = delegatingBlock.behaviorDelegate().value(); + if (behavior == null) return false; + return behavior.block().equals(thisBlock); + } + } + + public static class IsResourceKeyBlockInterceptor { + public static final IsResourceKeyBlockInterceptor INSTANCE = new IsResourceKeyBlockInterceptor(); + + @RuntimeType + public boolean intercept(@This Object thisObj, @AllArguments Object[] args) { + DelegatingBlockState customState = (DelegatingBlockState) thisObj; + ImmutableBlockState thisState = customState.blockState(); + if (thisState == null) return false; + CustomBlock thisBlock = thisState.owner().value(); + Object block = FastNMS.INSTANCE.method$HolderGetter$getResourceKey(MBuiltInRegistries.BLOCK, args[0]) + .map(FastNMS.INSTANCE::method$Holder$value) + .orElse(null); + if (!(block instanceof DelegatingBlock delegatingBlock)) return false; + BlockBehavior behavior = delegatingBlock.behaviorDelegate().value(); + if (behavior == null) return false; + return behavior.block().equals(thisBlock); } } 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 e3eded271..571f99f4a 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 @@ -4407,7 +4407,29 @@ public final class CoreReflections { ) ); + public static final Class clazz$HolderSet = requireNonNull( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("core.HolderSet") + ) + ); + public static final Method method$BlockStateBase$isBlock = requireNonNull( ReflectionUtils.getDeclaredMethod(clazz$BlockStateBase, boolean.class, new String[]{"is", "a"}, clazz$Block) ); + + public static final Method method$BlockStateBase$isHolderSetBlock = requireNonNull( + ReflectionUtils.getDeclaredMethod(clazz$BlockStateBase, boolean.class, new String[]{"is", "a"}, clazz$HolderSet) + ); + + // 1.20.2+ + public static final Method method$BlockStateBase$isHolderBlock = MiscUtils.requireNonNullIf( + ReflectionUtils.getDeclaredMethod(clazz$BlockStateBase, boolean.class, new String[]{"is", "a"}, clazz$Holder), + VersionHelper.isOrAbove1_20_2() + ); + + // 1.20.3+ + public static final Method method$BlockStateBase$isResourceKeyBlock = MiscUtils.requireNonNullIf( + ReflectionUtils.getDeclaredMethod(clazz$BlockStateBase, boolean.class, new String[]{"is", "a"}, clazz$ResourceKey), + VersionHelper.isOrAbove1_20_3() + ); }