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 70078d29b..4542f71d2 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 @@ -225,6 +225,13 @@ public class UnsafeCompositeBlockBehavior extends BukkitBlockBehavior { } } + @Override + public void onRemove(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + for (AbstractBlockBehavior behavior : this.behaviors) { + behavior.onRemove(thisBlock, args, superMethod); + } + } + @Override public int getSignal(Object thisBlock, Object[] args, Callable superMethod) { for (AbstractBlockBehavior behavior : this.behaviors) { 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 e5a5acb85..1db5d52dc 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 @@ -188,6 +188,10 @@ public final class BlockGenerator { builder.method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$affectNeighborsAfterRemoval)) .intercept(MethodDelegation.to(AffectNeighborsAfterRemovalInterceptor.INSTANCE)); } + if (CoreReflections.method$BlockBehaviour$onRemove != null) { + builder.method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$onRemove)) + .intercept(MethodDelegation.to(OnRemoveInterceptor.INSTANCE)); + } Class clazz$CraftEngineBlock = builder.make().load(BlockGenerator.class.getClassLoader()).getLoaded(); constructor$CraftEngineBlock = MethodHandles.publicLookup().in(clazz$CraftEngineBlock) @@ -618,6 +622,20 @@ public final class BlockGenerator { } } + public static class OnRemoveInterceptor { + public static final OnRemoveInterceptor INSTANCE = new OnRemoveInterceptor(); + + @RuntimeType + public void intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable superMethod) { + ObjectHolder holder = ((DelegatingBlock) thisObj).behaviorDelegate(); + try { + holder.value().onRemove(thisObj, args, superMethod); + } catch (Exception e) { + CraftEngine.instance().logger().severe("Failed to run onRemove", e); + } + } + } + public static class EntityInsideInterceptor { public static final EntityInsideInterceptor INSTANCE = new EntityInsideInterceptor(); 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 d0c25b978..0bd7981a8 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 @@ -3822,4 +3822,12 @@ public final class CoreReflections { clazz$BlockBehaviour, void.class, clazz$BlockState, clazz$ServerLevel, clazz$BlockPos, clazz$ItemStack, boolean.class ) ); + + // 1.20~1.21.4 + public static final Method method$BlockBehaviour$onRemove = MiscUtils.requireNonNullIf( + ReflectionUtils.getDeclaredMethod( + clazz$BlockBehaviour, void.class, clazz$BlockState, clazz$Level, clazz$BlockPos, clazz$BlockState, boolean.class + ), + !VersionHelper.isOrAbove1_21_5() + ); } 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 6b805327c..9b61dd9e2 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 @@ -123,6 +123,9 @@ public abstract class BlockBehavior { public void affectNeighborsAfterRemoval(Object thisBlock, Object[] args, Callable superMethod) throws Exception { } + public void onRemove(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + } + // BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side public int getSignal(Object thisBlock, Object[] args, Callable superMethod) { return 0; @@ -145,7 +148,6 @@ public abstract class BlockBehavior { // 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) {