From 2dc35bf2c21947baa1c192a5e33e92d699ff4c78 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Sat, 21 Jun 2025 20:55:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D1.20.1=E5=85=89=E7=85=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/block/BukkitCustomBlock.java | 47 +++++++++++++++++-- .../reflection/minecraft/CoreReflections.java | 14 ++++++ .../bukkit/util/BlockStateUtils.java | 8 ++-- .../craftengine/core/block/BlockSettings.java | 25 ++++++++-- .../craftengine/core/item/ItemManager.java | 1 - .../core/pack/AbstractPackManager.java | 1 - 6 files changed, 80 insertions(+), 16 deletions(-) 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 2e1e35659..872800446 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 @@ -92,12 +92,27 @@ public class BukkitCustomBlock extends AbstractCustomBlock { BlockStateUtils.setHardness(mcBlockState, settings.hardness()); BlockStateUtils.setPushReaction(mcBlockState, settings.pushReaction()); BlockStateUtils.setReplaceable(mcBlockState, settings.replaceable()); + boolean canOcclude; if (settings.canOcclude() == Tristate.TRUE) { BlockStateUtils.setCanOcclude(mcBlockState, true); + canOcclude = true; } else if (settings.canOcclude() == Tristate.FALSE) { BlockStateUtils.setCanOcclude(mcBlockState, false); + canOcclude = false; } else { - BlockStateUtils.setCanOcclude(mcBlockState, BlockStateUtils.isOcclude(state.vanillaBlockState().handle())); + canOcclude = BlockStateUtils.isOcclude(state.vanillaBlockState().handle()); + BlockStateUtils.setCanOcclude(mcBlockState, canOcclude); + } + boolean useShapeForLightOcclusion; + if (settings.useShapeForLightOcclusion() == Tristate.TRUE) { + BlockStateUtils.setUseShapeForLightOcclusion(mcBlockState, true); + useShapeForLightOcclusion = true; + } else if (settings.useShapeForLightOcclusion() == Tristate.FALSE) { + BlockStateUtils.setUseShapeForLightOcclusion(mcBlockState, false); + useShapeForLightOcclusion = false; + } else { + useShapeForLightOcclusion = CoreReflections.field$BlockStateBase$useShapeForLightOcclusion.getBoolean(state.vanillaBlockState().handle()); + BlockStateUtils.setUseShapeForLightOcclusion(mcBlockState, useShapeForLightOcclusion); } if (settings.isRedstoneConductor() == Tristate.TRUE) { BlockStateUtils.setIsRedstoneConductor(mcBlockState, ALWAYS_TRUE); @@ -144,15 +159,39 @@ public class BukkitCustomBlock extends AbstractCustomBlock { // set block side properties CoreReflections.field$BlockBehaviour$explosionResistance.set(mcBlock, settings.resistance()); CoreReflections.field$BlockBehaviour$soundType.set(mcBlock, SoundUtils.toSoundType(settings.sounds())); + // 1.21.2以前要在init cache之前设定 isConditionallyFullOpaque + if (!VersionHelper.isOrAbove1_21_2()) { + boolean isConditionallyFullOpaque = canOcclude & useShapeForLightOcclusion; + CoreReflections.field$BlockStateBase$isConditionallyFullOpaque.set(mcBlockState, isConditionallyFullOpaque); + } // init cache CoreReflections.method$BlockStateBase$initCache.invoke(mcBlockState); - // set block light - int blockLight = settings.blockLight() != -1 ? settings.blockLight() : CoreReflections.field$BlockStateBase$lightBlock.getInt(state.vanillaBlockState().handle()); + // modify cache if (VersionHelper.isOrAbove1_21_2()) { + int blockLight = settings.blockLight() != -1 ? settings.blockLight() : CoreReflections.field$BlockStateBase$lightBlock.getInt(state.vanillaBlockState().handle()); + // set block light CoreReflections.field$BlockStateBase$lightBlock.set(mcBlockState, blockLight); + // set propagates skylight + if (settings.propagatesSkylightDown() == Tristate.TRUE) { + CoreReflections.field$BlockStateBase$propagatesSkylightDown.set(mcBlockState, true); + } else if (settings.propagatesSkylightDown() == Tristate.FALSE) { + CoreReflections.field$BlockStateBase$propagatesSkylightDown.set(mcBlockState, false); + } else { + CoreReflections.field$BlockStateBase$propagatesSkylightDown.set(mcBlockState, CoreReflections.field$BlockStateBase$propagatesSkylightDown.getBoolean(state.vanillaBlockState().handle())); + } } else { Object cache = CoreReflections.field$BlockStateBase$cache.get(mcBlockState); + int blockLight = settings.blockLight() != -1 ? settings.blockLight() : CoreReflections.field$BlockStateBase$Cache$lightBlock.getInt(CoreReflections.field$BlockStateBase$cache.get(state.vanillaBlockState().handle())); + // set block light CoreReflections.field$BlockStateBase$Cache$lightBlock.set(cache, blockLight); + // set propagates skylight + if (settings.propagatesSkylightDown() == Tristate.TRUE) { + CoreReflections.field$BlockStateBase$Cache$propagatesSkylightDown.set(cache, true); + } else if (settings.propagatesSkylightDown() == Tristate.FALSE) { + CoreReflections.field$BlockStateBase$Cache$propagatesSkylightDown.set(cache, false); + } else { + CoreReflections.field$BlockStateBase$Cache$propagatesSkylightDown.set(cache, CoreReflections.field$BlockStateBase$Cache$propagatesSkylightDown.getBoolean(CoreReflections.field$BlockStateBase$cache.get(state.vanillaBlockState().handle()))); + } } // set fluid later if (settings.fluidState()) { @@ -162,8 +201,6 @@ public class BukkitCustomBlock extends AbstractCustomBlock { } // set random tick later BlockStateUtils.setIsRandomlyTicking(mcBlockState, settings.isRandomlyTicking()); - // set propagates skylight - BlockStateUtils.setPropagatesSkylightDown(mcBlockState, settings.propagatesSkylightDown()); // bind tags Object holder = BukkitCraftEngine.instance().blockManager().getMinecraftBlockHolder(state.customBlockState().registryId()); Set tags = new HashSet<>(); 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 c2a330932..4e67d8250 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 @@ -1252,6 +1252,10 @@ public final class CoreReflections { ReflectionUtils.getDeclaredField(clazz$BlockStateBase, float.class, 0) ); + public static final Field field$BlockStateBase$useShapeForLightOcclusion = requireNonNull( + ReflectionUtils.getDeclaredField(clazz$BlockStateBase, boolean.class, 0) + ); + public static final Field field$BlockStateBase$burnable = requireNonNull( ReflectionUtils.getDeclaredField(clazz$BlockStateBase, boolean.class, 2) ); @@ -1260,10 +1264,20 @@ public final class CoreReflections { ReflectionUtils.getDeclaredField(clazz$BlockStateBase, boolean.class, 9) ); + // 1.21.2以前用 + public static final Field field$BlockStateBase$isConditionallyFullOpaque = requireNonNull( + ReflectionUtils.getDeclaredField(clazz$BlockStateBase, boolean.class, VersionHelper.isOrAbove1_21() ? 10 : 11) + ); + + // 1.21.2+,其他版本在cache里 public static final Field field$BlockStateBase$propagatesSkylightDown = requireNonNull( ReflectionUtils.getDeclaredField(clazz$BlockStateBase, boolean.class, 11) ); + public static final Field field$BlockStateBase$Cache$propagatesSkylightDown = requireNonNull( + ReflectionUtils.getDeclaredField(clazz$BlockStateBase$Cache, boolean.class, 2) + ); + public static final Field field$BlockStateBase$requiresCorrectToolForDrops = requireNonNull( ReflectionUtils.getDeclaredField(clazz$BlockStateBase, boolean.class, 5) ); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockStateUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockStateUtils.java index c0079d0e9..6f87e69ca 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockStateUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockStateUtils.java @@ -197,6 +197,10 @@ public class BlockStateUtils { CoreReflections.field$BlockStateBase$burnable.set(state, burnable); } + public static void setUseShapeForLightOcclusion(Object state, boolean useShapeForLightOcclusion) throws ReflectiveOperationException { + CoreReflections.field$BlockStateBase$useShapeForLightOcclusion.set(state, useShapeForLightOcclusion); + } + public static void setPushReaction(Object state, PushReaction reaction) throws ReflectiveOperationException { Object pushReaction = ((Object[]) CoreReflections.method$PushReaction$values.invoke(null))[reaction.ordinal()]; CoreReflections.field$BlockStateBase$pushReaction.set(state, pushReaction); @@ -206,10 +210,6 @@ public class BlockStateUtils { CoreReflections.field$BlockStateBase$isRandomlyTicking.set(state, randomlyTicking); } - public static void setPropagatesSkylightDown(Object state, boolean propagatesSkylightDown) throws ReflectiveOperationException { - CoreReflections.field$BlockStateBase$propagatesSkylightDown.set(state, propagatesSkylightDown); - } - public static void setReplaceable(Object state, boolean replaceable) throws ReflectiveOperationException { CoreReflections.field$BlockStateBase$replaceable.set(state, replaceable); } 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 f18c96914..9d8bf35d1 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 @@ -23,6 +23,8 @@ public class BlockSettings { Tristate isRedstoneConductor = Tristate.UNDEFINED; Tristate isSuffocating = Tristate.UNDEFINED; Tristate isViewBlocking = Tristate.UNDEFINED; + Tristate useShapeForLightOcclusion = Tristate.UNDEFINED; + Tristate propagatesSkylightDown = Tristate.UNDEFINED; MapColor mapColor = MapColor.CLEAR; PushReaction pushReaction = PushReaction.NORMAL; int luminance; @@ -35,7 +37,6 @@ public class BlockSettings { Set correctTools = Set.of(); String name; String supportShapeBlockState; - boolean propagatesSkylightDown; private BlockSettings() {} @@ -98,6 +99,7 @@ public class BlockSettings { newSettings.incorrectToolSpeed = settings.incorrectToolSpeed; newSettings.supportShapeBlockState = settings.supportShapeBlockState; newSettings.propagatesSkylightDown = settings.propagatesSkylightDown; + newSettings.useShapeForLightOcclusion = settings.useShapeForLightOcclusion; return newSettings; } @@ -205,10 +207,14 @@ public class BlockSettings { return supportShapeBlockState; } - public boolean propagatesSkylightDown() { + public Tristate propagatesSkylightDown() { return propagatesSkylightDown; } + public Tristate useShapeForLightOcclusion() { + return useShapeForLightOcclusion; + } + public BlockSettings correctTools(Set correctTools) { this.correctTools = correctTools; return this; @@ -304,7 +310,7 @@ public class BlockSettings { return this; } - public BlockSettings propagatesSkylightDown(boolean propagatesSkylightDown) { + public BlockSettings propagatesSkylightDown(Tristate propagatesSkylightDown) { this.propagatesSkylightDown = propagatesSkylightDown; return this; } @@ -344,6 +350,11 @@ public class BlockSettings { return this; } + public BlockSettings useShapeForLightOcclusion(Tristate useShapeForLightOcclusion) { + this.useShapeForLightOcclusion = useShapeForLightOcclusion; + return this; + } + public interface Modifier { void apply(BlockSettings settings); @@ -380,7 +391,7 @@ public class BlockSettings { })); registerFactory("propagate-skylight", (value -> { boolean booleanValue = (boolean) value; - return settings -> settings.propagatesSkylightDown(booleanValue); + return settings -> settings.propagatesSkylightDown(booleanValue ? Tristate.TRUE : Tristate.FALSE); })); registerFactory("push-reaction", (value -> { PushReaction reaction = PushReaction.valueOf(value.toString().toUpperCase(Locale.ENGLISH)); @@ -440,7 +451,7 @@ public class BlockSettings { })); registerFactory("can-occlude", (value -> { boolean booleanValue = (boolean) value; - return settings -> settings.canOcclude(booleanValue ? Tristate.FALSE : Tristate.TRUE); + return settings -> settings.canOcclude(booleanValue ? Tristate.TRUE : Tristate.FALSE); })); registerFactory("correct-tools", (value -> { List tools = MiscUtils.getAsStringList(value); @@ -454,6 +465,10 @@ public class BlockSettings { boolean booleanValue = (boolean) value; return settings -> settings.respectToolComponent(booleanValue); })); + registerFactory("use-shape-for-light-occlusion", (value -> { + boolean booleanValue = (boolean) value; + return settings -> settings.useShapeForLightOcclusion(booleanValue ? Tristate.TRUE : Tristate.FALSE); + })); registerFactory("incorrect-tool-dig-speed", (value -> { float floatValue = ResourceConfigUtils.getAsFloat(value, "incorrect-tool-dig-speed"); return settings -> settings.incorrectToolSpeed(floatValue); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java index 74803b54c..9dac60b32 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java @@ -4,7 +4,6 @@ import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.item.modifier.ItemDataModifier; import net.momirealms.craftengine.core.pack.misc.EquipmentGeneration; -import net.momirealms.craftengine.core.pack.model.ItemModel; import net.momirealms.craftengine.core.pack.model.LegacyOverridesModel; import net.momirealms.craftengine.core.pack.model.ModernItemModel; import net.momirealms.craftengine.core.pack.model.generation.ModelGenerator; diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java index 7873555eb..438d489a9 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java @@ -17,7 +17,6 @@ import net.momirealms.craftengine.core.pack.host.ResourcePackHost; import net.momirealms.craftengine.core.pack.host.ResourcePackHosts; import net.momirealms.craftengine.core.pack.host.impl.NoneHost; import net.momirealms.craftengine.core.pack.misc.EquipmentGeneration; -import net.momirealms.craftengine.core.pack.model.ItemModel; import net.momirealms.craftengine.core.pack.model.LegacyOverridesModel; import net.momirealms.craftengine.core.pack.model.ModernItemModel; import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;