From c7f74337238bdead08db1c40d3f4b1d74e2ffb6c Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Mon, 16 Jun 2025 16:59:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=87=86=E5=A4=87=E5=B7=A5=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../block/behavior/BukkitBlockBehaviors.java | 2 + .../block/behavior/TrapDoorBlockBehavior.java | 64 +++++++++++++++++++ .../plugin/injector/BlockGenerator.java | 18 ++++++ .../reflection/minecraft/CoreReflections.java | 32 ++++++++++ .../craftengine/core/block/BlockBehavior.java | 4 ++ .../core/block/properties/Properties.java | 2 + .../item/modifier/DynamicLoreModifier.java | 8 ++- .../craftengine/core/util/Half.java | 5 ++ 8 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/TrapDoorBlockBehavior.java create mode 100644 core/src/main/java/net/momirealms/craftengine/core/util/Half.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehaviors.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehaviors.java index 042c5947b..867914a61 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehaviors.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehaviors.java @@ -19,6 +19,7 @@ public class BukkitBlockBehaviors extends BlockBehaviors { public static final Key CROP_BLOCK = Key.from("craftengine:crop_block"); public static final Key GRASS_BLOCK = Key.from("craftengine:grass_block"); public static final Key LAMP_BLOCK = Key.from("craftengine:lamp_block"); + public static final Key TRAPDOOR_BLOCK = Key.from("craftengine:trapdoor_block"); public static void init() { register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE); @@ -36,5 +37,6 @@ public class BukkitBlockBehaviors extends BlockBehaviors { register(CROP_BLOCK, CropBlockBehavior.FACTORY); register(GRASS_BLOCK, GrassBlockBehavior.FACTORY); register(LAMP_BLOCK, LampBlockBehavior.FACTORY); + register(TRAPDOOR_BLOCK, TrapDoorBlockBehavior.FACTORY); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/TrapDoorBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/TrapDoorBlockBehavior.java new file mode 100644 index 000000000..86387b3fd --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/TrapDoorBlockBehavior.java @@ -0,0 +1,64 @@ +package net.momirealms.craftengine.bukkit.block.behavior; + +import net.momirealms.craftengine.core.block.BlockBehavior; +import net.momirealms.craftengine.core.block.CustomBlock; +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; +import net.momirealms.craftengine.core.block.properties.Property; +import net.momirealms.craftengine.core.item.context.BlockPlaceContext; +import net.momirealms.craftengine.core.util.Half; +import net.momirealms.craftengine.core.util.HorizontalDirection; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; +import java.util.concurrent.Callable; + +public class TrapDoorBlockBehavior extends WaterLoggedBlockBehavior { + public static final Factory FACTORY = new Factory(); + private final Property halfProperty; + private final Property directionProperty; + private final Property poweredProperty; + private final Property openProperty; + + public TrapDoorBlockBehavior(CustomBlock block, + @Nullable Property waterloggedProperty, + Property halfProperty, + Property directionProperty, + Property poweredProperty, + Property openProperty) { + super(block, waterloggedProperty); + this.halfProperty = halfProperty; + this.directionProperty = directionProperty; + this.poweredProperty = poweredProperty; + this.openProperty = openProperty; + } +// +// @Override +// public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) { +// +// } + + @Override + public void tick(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + + } + + @Override + public void neighborChanged(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + + } + + @SuppressWarnings("unchecked") + public static class Factory implements BlockBehaviorFactory { + @Override + public BlockBehavior create(CustomBlock block, Map arguments) { + Property waterlogged = (Property) block.getProperty("waterlogged"); + Property half = (Property) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("half"), "warning.config.block.behavior.trapdoor.missing_half"); + Property direction = (Property) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("direction"), "warning.config.block.behavior.trapdoor.missing_direction"); + Property open = (Property) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("open"), "warning.config.block.behavior.trapdoor.missing_open"); + Property powered = (Property) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("open"), "warning.config.block.behavior.trapdoor.missing_powered"); + return new TrapDoorBlockBehavior(block, waterlogged, half, direction, powered, open); + } + } +} 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 e6b543954..e27aeb338 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 @@ -76,6 +76,9 @@ public final class BlockGenerator { // getSupportShape .method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$getBlockSupportShape)) .intercept(MethodDelegation.to(GetSupportShapeInterceptor.INSTANCE)) + // isPathFindable + .method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$isPathFindable)) + .intercept(MethodDelegation.to(IsPathFindableInterceptor.INSTANCE)) // mirror .method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$mirror)) .intercept(MethodDelegation.to(MirrorInterceptor.INSTANCE)) @@ -254,6 +257,21 @@ public final class BlockGenerator { } } + public static class IsPathFindableInterceptor { + public static final IsPathFindableInterceptor INSTANCE = new IsPathFindableInterceptor(); + + @RuntimeType + public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable superMethod) throws Exception { + ObjectHolder holder = ((BehaviorHolder) thisObj).getBehaviorHolder(); + try { + return holder.value().isPathFindable(thisObj, args, superMethod); + } catch (Exception e) { + CraftEngine.instance().logger().severe("Failed to run isPathFindable", 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/plugin/reflection/minecraft/CoreReflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java index 65b944856..c67515c75 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 @@ -1344,6 +1344,38 @@ public final class CoreReflections { ) ); + public static final Class clazz$PathComputationType = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.pathfinder.PathMode", + "world.level.pathfinder.PathComputationType" + ) + ); + + public static final Method method$PathComputationType$values = requireNonNull( + ReflectionUtils.getStaticMethod(clazz$PathComputationType, clazz$PathComputationType.arrayType()) + ); + + public static final Object instance$PathComputationType$LAND; + public static final Object instance$PathComputationType$WATER; + public static final Object instance$PathComputationType$AIR; + + static { + try { + Object[] objs = (Object[]) method$PathComputationType$values.invoke(null); + instance$PathComputationType$LAND = objs[0]; + instance$PathComputationType$WATER = objs[1]; + instance$PathComputationType$AIR = objs[2]; + } catch (ReflectiveOperationException e) { + throw new ReflectionInitException("Failed to initialize PathComputationType", e); + } + } + + public static final Method method$BlockBehaviour$isPathFindable = requireNonNull( + VersionHelper.isOrAbove1_20_5() ? + ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, boolean.class, clazz$BlockState, clazz$PathComputationType) : + ReflectionUtils.getMethod(clazz$BlockBehaviour, boolean.class, clazz$BlockState, clazz$BlockGetter, clazz$BlockPos, clazz$PathComputationType) + ); + public static final Method method$BlockBehaviour$getShape = requireNonNull( ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, clazz$VoxelShape, new String[]{"getShape", "a"}, clazz$BlockState, clazz$BlockGetter, CoreReflections.clazz$BlockPos, clazz$CollisionContext) ); 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 97eaa68cd..f4ad8fb6c 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 @@ -49,6 +49,10 @@ public abstract class BlockBehavior { return (boolean) superMethod.call(); } + public boolean isPathFindable(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + return (boolean) superMethod.call(); + } + public void onBrokenAfterFall(Object thisBlock, Object[] args) throws Exception { } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/properties/Properties.java b/core/src/main/java/net/momirealms/craftengine/core/block/properties/Properties.java index 44194f07a..2538f1fe1 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/properties/Properties.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/properties/Properties.java @@ -16,6 +16,7 @@ public class Properties { public static final Key AXIS = Key.of("craftengine:axis"); public static final Key HORIZONTAL_DIRECTION = Key.of("craftengine:4-direction"); public static final Key DIRECTION = Key.of("craftengine:6-direction"); + public static final Key HALF = Key.of("craftengine:half"); static { register(BOOLEAN, BooleanProperty.FACTORY); @@ -24,6 +25,7 @@ public class Properties { register(AXIS, new EnumProperty.Factory<>(Direction.Axis.class)); register(DIRECTION, new EnumProperty.Factory<>(Direction.class)); register(HORIZONTAL_DIRECTION, new EnumProperty.Factory<>(HorizontalDirection.class)); + register(HALF, new EnumProperty.Factory<>(Half.class)); } public static void register(Key key, PropertyFactory factory) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/DynamicLoreModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/DynamicLoreModifier.java index 01e8d92be..8962c63e0 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/DynamicLoreModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/DynamicLoreModifier.java @@ -9,11 +9,13 @@ import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.sparrow.nbt.CompoundTag; import net.momirealms.sparrow.nbt.Tag; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; public class DynamicLoreModifier implements ItemDataModifier { + public static final String CONTEXT_TAG_KEY = "craftengine:display_context"; private final Map> displayContexts; private final String defaultContext; @@ -22,6 +24,10 @@ public class DynamicLoreModifier implements ItemDataModifier { this.displayContexts = displayContexts; } + public Map> displayContexts() { + return Collections.unmodifiableMap(this.displayContexts); + } + @Override public String name() { return "dynamic-lore"; @@ -29,7 +35,7 @@ public class DynamicLoreModifier implements ItemDataModifier { @Override public Item apply(Item item, ItemBuildContext context) { - String displayContext = Optional.ofNullable(item.getJavaTag("craftengine:display_context")).orElse(this.defaultContext).toString(); + String displayContext = Optional.ofNullable(item.getJavaTag(CONTEXT_TAG_KEY)).orElse(this.defaultContext).toString(); List lore = this.displayContexts.get(displayContext); if (lore == null) { lore = this.displayContexts.get(this.defaultContext); diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/Half.java b/core/src/main/java/net/momirealms/craftengine/core/util/Half.java new file mode 100644 index 000000000..6567ea1c5 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/util/Half.java @@ -0,0 +1,5 @@ +package net.momirealms.craftengine.core.util; + +public enum Half { + TOP, BOTTOM +}