From b893e3bc6cd0b1c1a048de6d3459d1e8f20f141c Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Sun, 13 Jul 2025 12:56:43 +0800 Subject: [PATCH] =?UTF-8?q?feat(core):=20=E6=B7=BB=E5=8A=A0=E7=9B=91?= =?UTF-8?q?=E5=90=ACspawnAfterBreak=E5=86=85=E9=83=A8=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UnsafeCompositeBlockBehavior.java | 7 +++++++ .../plugin/injector/BlockGenerator.java | 19 ++++++++++++++++++- .../reflection/minecraft/CoreReflections.java | 6 ++++++ .../craftengine/core/block/BlockBehavior.java | 5 +++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/UnsafeCompositeBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/UnsafeCompositeBlockBehavior.java index e70881894..70078d29b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/UnsafeCompositeBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/UnsafeCompositeBlockBehavior.java @@ -268,4 +268,11 @@ public class UnsafeCompositeBlockBehavior extends BukkitBlockBehavior { } return previous; } + + @Override + public void spawnAfterBreak(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + for (AbstractBlockBehavior behavior : this.behaviors) { + behavior.spawnAfterBreak(thisBlock, args, superMethod); + } + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java index e92214714..e5a5acb85 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java @@ -180,7 +180,10 @@ public final class BlockGenerator { .intercept(MethodDelegation.to(IsSignalSourceInterceptor.INSTANCE)) // playerWillDestroy .method(ElementMatchers.is(CoreReflections.method$Block$playerWillDestroy)) - .intercept(MethodDelegation.to(PlayerWillDestroyInterceptor.INSTANCE)); + .intercept(MethodDelegation.to(PlayerWillDestroyInterceptor.INSTANCE)) + // spawnAfterBreak + .method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$spawnAfterBreak)) + .intercept(MethodDelegation.to(SpawnAfterBreakInterceptor.INSTANCE)); if (CoreReflections.method$BlockBehaviour$affectNeighborsAfterRemoval != null) { builder.method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$affectNeighborsAfterRemoval)) .intercept(MethodDelegation.to(AffectNeighborsAfterRemovalInterceptor.INSTANCE)); @@ -643,4 +646,18 @@ public final class BlockGenerator { } } } + + public static class SpawnAfterBreakInterceptor { + public static final SpawnAfterBreakInterceptor INSTANCE = new SpawnAfterBreakInterceptor(); + + @RuntimeType + public void intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable superMethod) { + ObjectHolder holder = ((DelegatingBlock) thisObj).behaviorDelegate(); + try { + holder.value().spawnAfterBreak(thisObj, args, superMethod); + } catch (Exception e) { + CraftEngine.instance().logger().severe("Failed to run spawnAfterBreak", e); + } + } + } } 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 927ff1e16..d0c25b978 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 @@ -3816,4 +3816,10 @@ public final class CoreReflections { VersionHelper.isOrAbove1_20_2() ? ReflectionUtils.getStaticMethod(clazz$ArmorTrim, Optional.class, clazz$RegistryAccess, clazz$ItemStack, boolean.class) : ReflectionUtils.getStaticMethod(clazz$ArmorTrim, Optional.class, clazz$RegistryAccess, clazz$ItemStack); + + public static final Method method$BlockBehaviour$spawnAfterBreak = requireNonNull( + ReflectionUtils.getDeclaredMethod( + clazz$BlockBehaviour, void.class, clazz$BlockState, clazz$ServerLevel, clazz$BlockPos, clazz$ItemStack, boolean.class + ) + ); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockBehavior.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockBehavior.java index 0cca29faf..6b805327c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockBehavior.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockBehavior.java @@ -143,6 +143,11 @@ public abstract class BlockBehavior { return superMethod.call(); } + // BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience + public void spawnAfterBreak(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + superMethod.call(); + } + public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) { return state; }