From 6ed54af7ab634675ef451bfee01a86e18fc6bcfe Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Fri, 19 Sep 2025 09:16:26 +0800 Subject: [PATCH 01/10] =?UTF-8?q?feat(block):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E6=96=B9=E5=9D=97=E8=A1=8C=E4=B8=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../block/behavior/BukkitBlockBehaviors.java | 4 + .../block/behavior/ButtonBlockBehavior.java | 217 ++++++++++++++++++ .../DirectionalAttachedBlockBehavior.java | 20 +- ...hedHorizontalDirectionalBlockBehavior.java | 150 ++++++++++++ .../behavior/PressurePlateBlockBehavior.java | 7 +- .../item/recipe/BukkitRecipeManager.java | 2 +- .../plugin/network/BukkitNetworkManager.java | 9 +- .../reflection/minecraft/CoreReflections.java | 6 + .../minecraft/MBuiltInRegistries.java | 5 + .../reflection/minecraft/MEntitySelector.java | 12 + .../reflection/minecraft/MGameEvent.java | 15 ++ .../craftengine/core/block/BlockBehavior.java | 10 +- .../core/block/properties/Properties.java | 2 + .../block/state/properties/AttachFace.java | 7 + gradle.properties | 2 +- 15 files changed, 444 insertions(+), 24 deletions(-) create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FaceAttachedHorizontalDirectionalBlockBehavior.java create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MEntitySelector.java create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MGameEvent.java create mode 100644 core/src/main/java/net/momirealms/craftengine/core/block/state/properties/AttachFace.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 4070b0f48..fc8ba1cc6 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 @@ -37,6 +37,8 @@ public class BukkitBlockBehaviors extends BlockBehaviors { public static final Key SIMPLE_PARTICLE_BLOCK = Key.from("craftengine:simple_particle_block"); public static final Key WALL_TORCH_PARTICLE_BLOCK = Key.from("craftengine:wall_torch_particle_block"); public static final Key FENCE_BLOCK = Key.from("craftengine:fence_block"); + public static final Key BUTTON_BLOCK = Key.from("craftengine:button_block"); + public static final Key FACE_ATTACHED_HORIZONTAL_DIRECTIONAL_BLOCK = Key.from("craftengine:face_attached_horizontal_directional_block"); public static void init() { register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE); @@ -72,5 +74,7 @@ public class BukkitBlockBehaviors extends BlockBehaviors { register(SIMPLE_PARTICLE_BLOCK, SimpleParticleBlockBehavior.FACTORY); register(WALL_TORCH_PARTICLE_BLOCK, WallTorchParticleBlockBehavior.FACTORY); register(FENCE_BLOCK, FenceBlockBehavior.FACTORY); + register(BUTTON_BLOCK, ButtonBlockBehavior.FACTORY); + register(FACE_ATTACHED_HORIZONTAL_DIRECTIONAL_BLOCK, FaceAttachedHorizontalDirectionalBlockBehavior.FACTORY); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java new file mode 100644 index 000000000..3be8fa890 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java @@ -0,0 +1,217 @@ +package net.momirealms.craftengine.bukkit.block.behavior; + +import net.momirealms.craftengine.bukkit.nms.FastNMS; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntitySelector; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MGameEvent; +import net.momirealms.craftengine.bukkit.util.BlockStateUtils; +import net.momirealms.craftengine.bukkit.util.DirectionUtils; +import net.momirealms.craftengine.bukkit.util.KeyUtils; +import net.momirealms.craftengine.bukkit.util.LocationUtils; +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.UpdateOption; +import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; +import net.momirealms.craftengine.core.block.properties.BooleanProperty; +import net.momirealms.craftengine.core.block.properties.Property; +import net.momirealms.craftengine.core.entity.player.InteractionResult; +import net.momirealms.craftengine.core.item.context.UseOnContext; +import net.momirealms.craftengine.core.sound.SoundData; +import net.momirealms.craftengine.core.util.Direction; +import net.momirealms.craftengine.core.util.HorizontalDirection; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import net.momirealms.craftengine.core.util.VersionHelper; + +import javax.annotation.Nullable; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.Callable; + +public class ButtonBlockBehavior extends BukkitBlockBehavior { + public static final Factory FACTORY = new Factory(); + private final BooleanProperty poweredProperty; + private final int ticksToStayPressed; + private final boolean canButtonBeActivatedByArrows; + private final SoundData buttonClickOnSound; + private final SoundData buttonClickOffSound; + + public ButtonBlockBehavior(CustomBlock customBlock, + BooleanProperty powered, + int ticksToStayPressed, + boolean canButtonBeActivatedByArrows, + SoundData buttonClickOnSound, + SoundData buttonClickOffSound) { + super(customBlock); + this.poweredProperty = powered; + this.ticksToStayPressed = ticksToStayPressed; + this.canButtonBeActivatedByArrows = canButtonBeActivatedByArrows; + this.buttonClickOnSound = buttonClickOnSound; + this.buttonClickOffSound = buttonClickOffSound; + } + + @Override + public InteractionResult useWithoutItem(UseOnContext context, ImmutableBlockState state) { + if (!state.get(this.poweredProperty)) { + press(BlockStateUtils.getBlockOwner(state.customBlockState().literalObject()), + state, context.getLevel().serverWorld(), LocationUtils.toBlockPos(context.getClickedPos()), + context.getPlayer() != null ? context.getPlayer().serverPlayer() : null); + return InteractionResult.SUCCESS_AND_CANCEL; + } + return InteractionResult.PASS; + } + + @Override + public void onExplosionHit(Object thisBlock, Object[] args, Callable superMethod) { + ImmutableBlockState blockState = BlockStateUtils.getOptionalCustomBlockState(args[0]).orElse(null); + if (blockState == null) return; + if (FastNMS.INSTANCE.method$Explosion$canTriggerBlocks(args[3]) && !blockState.get(this.poweredProperty)) { + press(thisBlock, blockState, args[1], args[2], null); + } + } + + @Override + public void affectNeighborsAfterRemoval(Object thisBlock, Object[] args, Callable superMethod) { + ImmutableBlockState blockState = BlockStateUtils.getOptionalCustomBlockState(args[0]).orElse(null); + if (blockState == null) return; + if (!(boolean) args[3] && blockState.get(this.poweredProperty)) { + updateNeighbours(thisBlock, blockState, args[1], args[2]); + } + } + + @Override + public void onRemove(Object thisBlock, Object[] args, Callable superMethod) { + ImmutableBlockState blockState = BlockStateUtils.getOptionalCustomBlockState(args[0]).orElse(null); + if (blockState == null) return; + if (!(boolean) args[4] && blockState.get(this.poweredProperty)) { + updateNeighbours(thisBlock, blockState, args[1], args[2]); + } + } + + @Override + public int getSignal(Object thisBlock, Object[] args, Callable superMethod) { + ImmutableBlockState blockState = BlockStateUtils.getOptionalCustomBlockState(args[0]).orElse(null); + if (blockState == null) return 0; + return blockState.get(this.poweredProperty) ? 15 : 0; + } + + @Override + public int getDirectSignal(Object thisBlock, Object[] args, Callable superMethod) { + ImmutableBlockState blockState = BlockStateUtils.getOptionalCustomBlockState(args[0]).orElse(null); + if (blockState == null) return 0; + return blockState.get(this.poweredProperty) + && FaceAttachedHorizontalDirectionalBlockBehavior.getConnectedDirection(blockState) + == DirectionUtils.fromNMSDirection(args[3]) ? 15 : 0; + } + + @Override + public boolean isSignalSource(Object thisBlock, Object[] args, Callable superMethod) { + return true; + } + + @Override + public void tick(Object thisBlock, Object[] args, Callable superMethod) { + Object state = args[0]; + Object level = args[1]; + Object pos = args[2]; + ImmutableBlockState blockState = BlockStateUtils.getOptionalCustomBlockState(state).orElse(null); + if (blockState == null) return; + if (blockState.get(this.poweredProperty)) { + checkPressed(thisBlock, state, level, pos); + } + } + + @Override + public void entityInside(Object thisBlock, Object[] args, Callable superMethod) { + Object state = args[0]; + Object level = args[1]; + Object pos = args[2]; + ImmutableBlockState blockState = BlockStateUtils.getOptionalCustomBlockState(state).orElse(null); + if (blockState == null) return; + if (this.canButtonBeActivatedByArrows && !blockState.get(this.poweredProperty)) { + checkPressed(thisBlock, state, level, pos); + } + } + + private void checkPressed(Object thisBlock, Object state, Object level, Object pos) { + Object abstractArrow = this.canButtonBeActivatedByArrows ? FastNMS.INSTANCE.method$EntityGetter$getEntitiesOfClass( + level, CoreReflections.clazz$AbstractArrow, FastNMS.INSTANCE.method$AABB$move( + FastNMS.INSTANCE.method$VoxelShape$bounds(FastNMS.INSTANCE.method$BlockState$getShape( + state, level, pos, CoreReflections.instance$CollisionContext$empty + )), pos), MEntitySelector.NO_SPECTATORS).stream().findFirst().orElse(null) : null; + boolean flag = abstractArrow != null; + ImmutableBlockState blockState = BlockStateUtils.getOptionalCustomBlockState(state).orElse(null); + if (blockState == null) return; + boolean poweredValue = blockState.get(this.poweredProperty); + if (flag != poweredValue) { + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, blockState.with(this.poweredProperty, flag).customBlockState().literalObject(), UpdateOption.UPDATE_ALL.flags()); + updateNeighbours(thisBlock, blockState, level, pos); + playSound(null, level, pos, flag); + Object gameEvent = VersionHelper.isOrAbove1_20_5() + ? FastNMS.INSTANCE.method$Holder$direct(flag ? MGameEvent.BLOCK_ACTIVATE : MGameEvent.BLOCK_DEACTIVATE) + : flag ? MGameEvent.BLOCK_ACTIVATE : MGameEvent.BLOCK_DEACTIVATE; + FastNMS.INSTANCE.method$LevelAccessor$gameEvent(level, abstractArrow, gameEvent, pos); + } + + if (flag) { + FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, thisBlock, this.ticksToStayPressed); + } + } + + private void updateNeighbours(Object thisBlock, ImmutableBlockState state, Object level, Object pos) { + Direction direction = FaceAttachedHorizontalDirectionalBlockBehavior.getConnectedDirection(state); + if (direction == null) return; + Direction opposite = direction.opposite(); + Object nmsDirection = DirectionUtils.toNMSDirection(opposite); + Object orientation = null; + if (VersionHelper.isOrAbove1_21_2()) { + @SuppressWarnings("unchecked") + Property facing = (Property) state.owner().value().getProperty("facing"); + if (facing != null) { + orientation = FastNMS.INSTANCE.method$ExperimentalRedstoneUtils$initialOrientation( + level, nmsDirection, opposite.axis().isHorizontal() ? CoreReflections.instance$Direction$UP : DirectionUtils.toNMSDirection(state.get(facing).toDirection()) + ); + } + } + FastNMS.INSTANCE.method$Level$updateNeighborsAt(level, pos, thisBlock, orientation); + FastNMS.INSTANCE.method$Level$updateNeighborsAt(level, FastNMS.INSTANCE.method$BlockPos$relative(pos, nmsDirection), thisBlock, orientation); + } + + private void playSound(@Nullable Object player, Object level, Object pos, boolean hitByArrow) { + SoundData soundData = getSound(hitByArrow); + if (soundData == null) return; + Object sound = FastNMS.INSTANCE.constructor$SoundEvent(KeyUtils.toResourceLocation(soundData.id()), Optional.empty()); + FastNMS.INSTANCE.method$LevelAccessor$playSound(level, player, pos, sound, CoreReflections.instance$SoundSource$BLOCKS, soundData.volume().get(), soundData.pitch().get()); + } + + private SoundData getSound(boolean isOn) { + return isOn ? this.buttonClickOnSound : this.buttonClickOffSound; + } + + private void press(Object thisBlock, ImmutableBlockState state, Object level, Object pos, @Nullable Object player) { + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, state.with(this.poweredProperty, true).customBlockState().literalObject(), UpdateOption.UPDATE_ALL.flags()); + FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, thisBlock, this.ticksToStayPressed); + playSound(player, level, pos, true); + Object gameEvent = VersionHelper.isOrAbove1_20_5() ? FastNMS.INSTANCE.method$Holder$direct(MGameEvent.BLOCK_ACTIVATE) : MGameEvent.BLOCK_ACTIVATE; + FastNMS.INSTANCE.method$LevelAccessor$gameEvent(level, player, gameEvent, pos); + } + + public static class Factory implements BlockBehaviorFactory { + + @SuppressWarnings({"unchecked", "DuplicatedCode"}) + @Override + public BlockBehavior create(CustomBlock block, Map arguments) { + BooleanProperty powered = (BooleanProperty) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("powered"), "warning.config.block.behavior.button.missing_powered"); + int ticksToStayPressed = ResourceConfigUtils.getAsInt(arguments.getOrDefault("ticks-to-stay-pressed", 30), "ticks-to-stay-pressed"); + boolean canButtonBeActivatedByArrows = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("can-button-be-activated-by-arrows", true), "can-button-be-activated-by-arrows"); + Map sounds = (Map) arguments.get("sounds"); + SoundData buttonClickOnSound = null; + SoundData buttonClickOffSound = null; + if (sounds != null) { + buttonClickOnSound = Optional.ofNullable(sounds.get("on")).map(obj -> SoundData.create(obj, SoundData.SoundValue.FIXED_1, SoundData.SoundValue.ranged(0.9f, 1f))).orElse(null); + buttonClickOffSound = Optional.ofNullable(sounds.get("off")).map(obj -> SoundData.create(obj, SoundData.SoundValue.FIXED_1, SoundData.SoundValue.ranged(0.9f, 1f))).orElse(null); + } + return new ButtonBlockBehavior(block, powered, ticksToStayPressed, canButtonBeActivatedByArrows, buttonClickOnSound, buttonClickOffSound); + } + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DirectionalAttachedBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DirectionalAttachedBlockBehavior.java index a155235db..f2e4d9987 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DirectionalAttachedBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DirectionalAttachedBlockBehavior.java @@ -25,7 +25,7 @@ import org.bukkit.Registry; import java.util.*; import java.util.concurrent.Callable; -public class DirectionalAttachedBlockBehavior extends AbstractCanSurviveBlockBehavior { +public class DirectionalAttachedBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); private final Property facingProperty; private final boolean isSixDirection; @@ -37,12 +37,11 @@ public class DirectionalAttachedBlockBehavior extends AbstractCanSurviveBlockBeh public DirectionalAttachedBlockBehavior(CustomBlock customBlock, Property facingProperty, boolean isSixDirection, - int delay, boolean blacklist, List tagsCanSurviveOn, Set blockStatesCanSurviveOn, Set customBlocksCansSurviveOn) { - super(customBlock, delay); + super(customBlock); this.facingProperty = facingProperty; this.isSixDirection = isSixDirection; this.tagsCanSurviveOn = tagsCanSurviveOn; @@ -69,8 +68,8 @@ public class DirectionalAttachedBlockBehavior extends AbstractCanSurviveBlockBeh } @Override - protected boolean canSurvive(Object thisBlock, Object blockState, Object world, Object pos) throws Exception { - ImmutableBlockState state = BlockStateUtils.getOptionalCustomBlockState(blockState).orElse(null); + public boolean canSurvive(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + ImmutableBlockState state = BlockStateUtils.getOptionalCustomBlockState(args[0]).orElse(null); if (state == null) return false; DirectionalAttachedBlockBehavior behavior = state.behavior().getAs(DirectionalAttachedBlockBehavior.class).orElse(null); if (behavior == null) return false; @@ -80,10 +79,10 @@ public class DirectionalAttachedBlockBehavior extends AbstractCanSurviveBlockBeh } else { direction = ((HorizontalDirection) state.get(behavior.facingProperty)).opposite().toDirection(); } - BlockPos blockPos = LocationUtils.fromBlockPos(pos).relative(direction); + BlockPos blockPos = LocationUtils.fromBlockPos(args[2]).relative(direction); Object nmsPos = LocationUtils.toBlockPos(blockPos); - Object nmsState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(world, nmsPos); - return FastNMS.INSTANCE.method$BlockStateBase$isFaceSturdy(nmsState, world, nmsPos, DirectionUtils.toNMSDirection(direction), CoreReflections.instance$SupportType$FULL) + Object nmsState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(args[1], nmsPos); + return FastNMS.INSTANCE.method$BlockStateBase$isFaceSturdy(nmsState, args[1], nmsPos, DirectionUtils.toNMSDirection(direction), CoreReflections.instance$SupportType$FULL) && mayPlaceOn(nmsState); } @@ -144,14 +143,13 @@ public class DirectionalAttachedBlockBehavior extends AbstractCanSurviveBlockBeh throw new LocalizedResourceConfigException("warning.config.block.behavior.directional_attached.missing_facing"); } Tuple, Set, Set> tuple = readTagsAndState(arguments); - int delay = ResourceConfigUtils.getAsInt(arguments.getOrDefault("delay", 0), "delay"); boolean blacklistMode = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("blacklist", true), "blacklist"); - return new DirectionalAttachedBlockBehavior(block, facing, isDirection, delay, blacklistMode, tuple.left(), tuple.mid(), tuple.right()); + return new DirectionalAttachedBlockBehavior(block, facing, isDirection, blacklistMode, tuple.left(), tuple.mid(), tuple.right()); } } @SuppressWarnings("DuplicatedCode") - private static Tuple, Set, Set> readTagsAndState(Map arguments) { + public static Tuple, Set, Set> readTagsAndState(Map arguments) { List mcTags = new ArrayList<>(); for (String tag : MiscUtils.getAsStringList(arguments.getOrDefault("attached-block-tags", List.of()))) { mcTags.add(BlockTags.getOrCreate(Key.of(tag))); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FaceAttachedHorizontalDirectionalBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FaceAttachedHorizontalDirectionalBlockBehavior.java new file mode 100644 index 000000000..cc877ef06 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FaceAttachedHorizontalDirectionalBlockBehavior.java @@ -0,0 +1,150 @@ +package net.momirealms.craftengine.bukkit.block.behavior; + +import net.momirealms.craftengine.bukkit.nms.FastNMS; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks; +import net.momirealms.craftengine.bukkit.util.BlockStateUtils; +import net.momirealms.craftengine.bukkit.util.DirectionUtils; +import net.momirealms.craftengine.bukkit.util.LocationUtils; +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.block.state.properties.AttachFace; +import net.momirealms.craftengine.core.item.context.BlockPlaceContext; +import net.momirealms.craftengine.core.util.Direction; +import net.momirealms.craftengine.core.util.HorizontalDirection; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import net.momirealms.craftengine.core.util.Tuple; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.Callable; + +public class FaceAttachedHorizontalDirectionalBlockBehavior extends BukkitBlockBehavior { + public static final Factory FACTORY = new Factory(); + private final Property attachFaceProperty; + private final Property facingProperty; + private final List tagsCanSurviveOn; + private final Set blockStatesCanSurviveOn; + private final Set customBlocksCansSurviveOn; + private final boolean blacklistMode; + + public FaceAttachedHorizontalDirectionalBlockBehavior(CustomBlock customBlock, + boolean blacklist, + List tagsCanSurviveOn, + Set blockStatesCanSurviveOn, + Set customBlocksCansSurviveOn, + Property attachFace, + Property facing) { + super(customBlock); + this.tagsCanSurviveOn = tagsCanSurviveOn; + this.blockStatesCanSurviveOn = blockStatesCanSurviveOn; + this.customBlocksCansSurviveOn = customBlocksCansSurviveOn; + this.blacklistMode = blacklist; + this.attachFaceProperty = attachFace; + this.facingProperty = facing; + } + + @Override + public boolean canSurvive(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + Direction direction = getConnectedDirection(BlockStateUtils.getOptionalCustomBlockState(args[0]).orElse(null)); + if (direction == null) return false; + direction = direction.opposite(); + Object nmsDirection = DirectionUtils.toNMSDirection(direction); + Object targetPos = FastNMS.INSTANCE.method$BlockPos$relative(args[2], nmsDirection); + Object targetState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(args[1], targetPos); + return canAttach(args[1], targetPos, nmsDirection, targetState) && mayPlaceOn(targetState); + } + + @SuppressWarnings("unchecked") + @Override + public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) { + Property face = (Property) state.owner().value().getProperty("face"); + Property facing = (Property) state.owner().value().getProperty("facing"); + if (face == null || facing == null) return null; + for (Direction direction : context.getNearestLookingDirections()) { + if (direction.axis() == Direction.Axis.Y) { + state = state + .with(face, direction == Direction.UP ? AttachFace.CEILING : AttachFace.FLOOR) + .with(facing, context.getHorizontalDirection().toHorizontalDirection()); + } else { + state = state.with(face, AttachFace.WALL).with(facing, direction.opposite().toHorizontalDirection()); + } + if (FastNMS.INSTANCE.method$BlockStateBase$canSurvive(state.customBlockState().literalObject(), context.getLevel().serverWorld(), LocationUtils.toBlockPos(context.getClickedPos()))) { + return state; + } + } + return null; + } + + @Override + public Object updateShape(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + Direction direction = getConnectedDirection(BlockStateUtils.getOptionalCustomBlockState(args[0]).orElse(null)); + if (direction == null) return MBlocks.AIR$defaultState; + if (DirectionUtils.toNMSDirection(direction.opposite()) == args[updateShape$direction] && !FastNMS.INSTANCE.method$BlockStateBase$canSurvive(args[0], args[updateShape$level], args[updateShape$blockPos])) { + return MBlocks.AIR$defaultState; + } + return superMethod.call(); + } + + private boolean mayPlaceOn(Object state) { + for (Object tag : this.tagsCanSurviveOn) { + if (FastNMS.INSTANCE.method$BlockStateBase$is(state, tag)) { + return !this.blacklistMode; + } + } + Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(state); + if (optionalCustomState.isEmpty()) { + if (!this.blockStatesCanSurviveOn.isEmpty() && this.blockStatesCanSurviveOn.contains(state)) { + return !this.blacklistMode; + } + } else { + ImmutableBlockState belowCustomState = optionalCustomState.get(); + if (this.customBlocksCansSurviveOn.contains(belowCustomState.owner().value().id().toString())) { + return !this.blacklistMode; + } + if (this.customBlocksCansSurviveOn.contains(belowCustomState.toString())) { + return !this.blacklistMode; + } + } + return this.blacklistMode; + } + + public static boolean canAttach(Object level, Object targetPos, Object direction, Object targetState) { + return FastNMS.INSTANCE.method$BlockStateBase$isFaceSturdy( + targetState, level, targetPos, + FastNMS.INSTANCE.method$Direction$getOpposite(direction), + CoreReflections.instance$SupportType$FULL + ); + } + + @Nullable + public static Direction getConnectedDirection(ImmutableBlockState state) { + if (state == null) return null; + FaceAttachedHorizontalDirectionalBlockBehavior behavior = state.behavior().getAs(FaceAttachedHorizontalDirectionalBlockBehavior.class).orElse(null); + if (behavior == null) return null; + return switch (state.get(behavior.attachFaceProperty)) { + case CEILING -> Direction.DOWN; + case FLOOR -> Direction.UP; + default -> state.get(behavior.facingProperty).toDirection(); + }; + } + + public static class Factory implements BlockBehaviorFactory { + + @SuppressWarnings("unchecked") + @Override + public BlockBehavior create(CustomBlock block, Map arguments) { + Property attachFace = (Property) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("face"), "warning.config.block.behavior.face_attached_horizontal_directional.missing_face"); + Property facing = (Property) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("facing"), "warning.config.block.behavior.face_attached_horizontal_directional.missing_facing"); + Tuple, Set, Set> tuple = DirectionalAttachedBlockBehavior.readTagsAndState(arguments); + boolean blacklistMode = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("blacklist", true), "blacklist"); + return new FaceAttachedHorizontalDirectionalBlockBehavior(block, blacklistMode, tuple.left(), tuple.mid(), tuple.right(), attachFace, facing); + } + } +} 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 09c8c920d..5ec5cc268 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 @@ -4,6 +4,7 @@ import io.papermc.paper.event.entity.EntityInsideBlockEvent; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntitySelector; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.DirectionUtils; import net.momirealms.craftengine.bukkit.util.EventUtils; @@ -28,6 +29,7 @@ import javax.annotation.Nullable; import java.util.Map; import java.util.Optional; import java.util.concurrent.Callable; +import java.util.function.Predicate; public class PressurePlateBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); @@ -111,7 +113,10 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { case MOBS -> CoreReflections.clazz$LivingEntity; }; Object box = FastNMS.INSTANCE.method$AABB$move(CoreReflections.instance$BasePressurePlateBlock$TOUCH_AABB, pos); - return FastNMS.INSTANCE.method$EntityGetter$getEntitiesOfClass(level, box, clazz) > 0 ? 15 : 0; + return !FastNMS.INSTANCE.method$EntityGetter$getEntitiesOfClass( + level, clazz, box, + MEntitySelector.NO_SPECTATORS.and(entity -> !FastNMS.INSTANCE.method$Entity$isIgnoringBlockTriggers(entity)) + ).isEmpty() ? 15 : 0; } private Object setSignalForState(Object state, int strength) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java index 06d11bf38..e385ffca4 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java @@ -395,7 +395,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { JsonObject jsonObject = entry.getValue(); Key serializerType = Key.of(jsonObject.get("type").getAsString()); - // noinspection unchecked + @SuppressWarnings("unchecked") RecipeSerializer> serializer = (RecipeSerializer>) BuiltInRegistries.RECIPE_SERIALIZER.getValue(serializerType); if (serializer == null) { continue; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java index 2952fe1bc..4671b7ed5 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java @@ -961,6 +961,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes */ public static class HelloListener implements NMSPacketListener { + @SuppressWarnings("unchecked") @Override public void onPacketReceive(NetWorkUser user, NMSPacketEvent event, Object packet) { BukkitServerPlayer player = (BukkitServerPlayer) user; @@ -984,7 +985,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes } else { Optional uuid; try { - // noinspection unchecked uuid = (Optional) NetworkReflections.methodHandle$ServerboundHelloPacket$uuidGetter.invokeExact(packet); } catch (Throwable t) { CraftEngine.instance().logger().severe("Failed to get uuid from ServerboundHelloPacket", t); @@ -1478,6 +1478,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes public static class EditBookListener implements NMSPacketListener { + @SuppressWarnings("unchecked") @Override public void onPacketReceive(NetWorkUser user, NMSPacketEvent event, Object packet) { if (!Config.filterBook()) return; @@ -1492,7 +1493,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes List pages; try { - // noinspection unchecked pages = (List) NetworkReflections.methodHandle$ServerboundEditBookPacket$pagesGetter.invokeExact(packet); } catch (Throwable t) { CraftEngine.instance().logger().warn("Failed to get pages from ServerboundEditBookPacket", t); @@ -1501,7 +1501,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes List newPages = new ArrayList<>(pages.size()); Optional title; try { - // noinspection unchecked title = (Optional) NetworkReflections.methodHandle$ServerboundEditBookPacket$titleGetter.invokeExact(packet); } catch (Throwable t) { CraftEngine.instance().logger().warn("Failed to get title from ServerboundEditBookPacket", t); @@ -1733,6 +1732,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes public static class FinishConfigurationListener implements NMSPacketListener { + @SuppressWarnings("unchecked") @Override public void onPacketSend(NetWorkUser user, NMSPacketEvent event, Object packet) { if (!VersionHelper.isOrAbove1_20_2() || !Config.sendPackOnJoin()) { @@ -1793,7 +1793,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes } Queue configurationTasks; try { - // noinspection unchecked configurationTasks = (Queue) CoreReflections.methodHandle$ServerConfigurationPacketListenerImpl$configurationTasksGetter.invokeExact(packetListener); } catch (Throwable e) { CraftEngine.instance().logger().warn("Failed to get configuration tasks for player " + user.name(), e); @@ -3665,7 +3664,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes Object packedItem = packedItems.get(i); int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem); if (entityDataId != BaseEntityData.CustomName.id()) continue; - // noinspection unchecked + @SuppressWarnings("unchecked") Optional optionalTextComponent = (Optional) FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem); if (optionalTextComponent.isEmpty()) continue; Object textComponent = optionalTextComponent.get(); 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 859f826ed..4fb178606 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 @@ -4400,4 +4400,10 @@ public final class CoreReflections { "world.level.block.FenceGateBlock" ) ); + + public static final Class clazz$GameEvent = requireNonNull( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("world.level.gameevent.GameEvent") + ) + ); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBuiltInRegistries.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBuiltInRegistries.java index ef6d7a8b1..565ae69c3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBuiltInRegistries.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBuiltInRegistries.java @@ -22,6 +22,7 @@ public final class MBuiltInRegistries { public static final Object PARTICLE_TYPE; public static final Object DATA_COMPONENT_TYPE; public static final Object LOOT_POOL_ENTRY_TYPE; + public static final Object GAME_EVENT; static { Field[] fields = CoreReflections.clazz$BuiltInRegistries.getDeclaredFields(); @@ -37,6 +38,7 @@ public final class MBuiltInRegistries { Object registries$RecipeType = null; Object registries$DataComponentType = null; Object registries$LootPoolEntryType = null; + Object registries$GameEvent = null; for (Field field : fields) { Type fieldType = field.getGenericType(); if (fieldType instanceof ParameterizedType paramType) { @@ -67,6 +69,8 @@ public final class MBuiltInRegistries { registries$Fluid = field.get(null); } else if (type == CoreReflections.clazz$LootPoolEntryType) { registries$LootPoolEntryType = field.get(null); + } else if (type == CoreReflections.clazz$GameEvent) { + registries$GameEvent = field.get(null); } } } @@ -82,6 +86,7 @@ public final class MBuiltInRegistries { RECIPE_TYPE = requireNonNull(registries$RecipeType); LOOT_POOL_ENTRY_TYPE = requireNonNull(registries$LootPoolEntryType); DATA_COMPONENT_TYPE = registries$DataComponentType; + GAME_EVENT = requireNonNull(registries$GameEvent); } catch (ReflectiveOperationException e) { throw new ReflectionInitException("Failed to init BuiltInRegistries", e); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MEntitySelector.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MEntitySelector.java new file mode 100644 index 000000000..7a2b43ab7 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MEntitySelector.java @@ -0,0 +1,12 @@ +package net.momirealms.craftengine.bukkit.plugin.reflection.minecraft; + +import net.momirealms.craftengine.bukkit.nms.FastNMS; + +import java.util.function.Predicate; + +public final class MEntitySelector { + private MEntitySelector() {} + + public static final Predicate NO_SPECTATORS = entity -> !FastNMS.INSTANCE.method$Entity$isSpectator(entity); + +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MGameEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MGameEvent.java new file mode 100644 index 000000000..500f39d8c --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MGameEvent.java @@ -0,0 +1,15 @@ +package net.momirealms.craftengine.bukkit.plugin.reflection.minecraft; + +import net.momirealms.craftengine.bukkit.nms.FastNMS; + +public final class MGameEvent { + private MGameEvent() {} + + public static final Object BLOCK_ACTIVATE = getById("block_activate"); + public static final Object BLOCK_DEACTIVATE = getById("block_deactivate"); + + private static Object getById(String id) { + Object rl = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", id); + return FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.GAME_EVENT, rl); + } +} 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 f1aba39ce..e969cab8c 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 @@ -55,18 +55,18 @@ public abstract class BlockBehavior { superMethod.call(); } - // ServerLevel level, BlockPos pos, RandomSource random + // BlockState state, ServerLevel level, BlockPos pos, RandomSource random public void tick(Object thisBlock, Object[] args, Callable superMethod) throws Exception { superMethod.call(); } - // ServerLevel level, BlockPos pos, RandomSource random + // BlockState state, ServerLevel level, BlockPos pos, RandomSource random public void randomTick(Object thisBlock, Object[] args, Callable superMethod) throws Exception { superMethod.call(); } // 1.20-1.20.4 BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify, UseOnContext context - // 1.20.5+ Level level, BlockPos pos, BlockState oldState, boolean movedByPiston + // 1.20.5+ BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston public void onPlace(Object thisBlock, Object[] args, Callable superMethod) throws Exception { superMethod.call(); } @@ -95,12 +95,12 @@ public abstract class BlockBehavior { return false; } - //BlockState state + // BlockState state public boolean hasAnalogOutputSignal(Object thisBlock, Object[] args) throws Exception { return false; } - //BlockState state, Level level, BlockPos pos + // BlockState state, Level level, BlockPos pos public int getAnalogOutputSignal(Object thisBlock, Object[] args) throws Exception { return 0; } 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 e5a143264..e559a080a 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 @@ -22,6 +22,7 @@ public final class Properties { public static final Key STAIRS_SHAPE = Key.of("craftengine:stairs_shape"); public static final Key SLAB_TYPE = Key.of("craftengine:slab_type"); public static final Key SOFA_SHAPE = Key.of("craftengine:sofa_shape"); + public static final Key ATTACH_FACE = Key.of("craftengine:attach_face"); static { register(BOOLEAN, BooleanProperty.FACTORY); @@ -38,6 +39,7 @@ public final class Properties { register(STAIRS_SHAPE, new EnumProperty.Factory<>(StairsShape.class)); register(SLAB_TYPE, new EnumProperty.Factory<>(SlabType.class)); register(SOFA_SHAPE, new EnumProperty.Factory<>(SofaShape.class)); + register(ATTACH_FACE, new EnumProperty.Factory<>(AttachFace.class)); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/state/properties/AttachFace.java b/core/src/main/java/net/momirealms/craftengine/core/block/state/properties/AttachFace.java new file mode 100644 index 000000000..de9d6267b --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/block/state/properties/AttachFace.java @@ -0,0 +1,7 @@ +package net.momirealms.craftengine.core.block.state.properties; + +public enum AttachFace { + FLOOR, + WALL, + CEILING +} diff --git a/gradle.properties b/gradle.properties index e6e8440a9..e0c51c8a7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -50,7 +50,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.5 anti_grief_version=0.20 -nms_helper_version=1.0.91 +nms_helper_version=1.0.92 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.33.1 From 1d500a580de7b39a5bbcf2945d813379e0b1aa88 Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Fri, 19 Sep 2025 09:59:40 +0800 Subject: [PATCH 02/10] =?UTF-8?q?fix(block):=20=E4=BF=AE=E5=A4=8D=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84tick=E6=96=B9=E5=9D=97=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 这个逆天问题,终于被我解决了真的是折磨死我了 - 解释下是如何解决的,因为ce是一个方块一个状态,所以说直接拿获取到的thisblock去tick方块会导致前面如果你做了一个setblock来更新ce内部的方块状态就会导致thisblock和实际tick的这个方块对不上然后导致tick失效,需要在setblock拿一下设置的方块状态然后重新获取正确的block才能被之前tick,这次更新顺手把压力板修了,之前用的是不正确的解决方案,然后修复下保险箱的切换 - 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊漏电了(不是 --- .../block/behavior/ButtonBlockBehavior.java | 26 +++++++++------- .../behavior/PressurePlateBlockBehavior.java | 20 ++++++------ .../entity/SimpleStorageBlockEntity.java | 31 +++++++++++-------- 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java index 3be8fa890..7bca026c1 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java @@ -53,8 +53,7 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { @Override public InteractionResult useWithoutItem(UseOnContext context, ImmutableBlockState state) { if (!state.get(this.poweredProperty)) { - press(BlockStateUtils.getBlockOwner(state.customBlockState().literalObject()), - state, context.getLevel().serverWorld(), LocationUtils.toBlockPos(context.getClickedPos()), + press(state, context.getLevel().serverWorld(), LocationUtils.toBlockPos(context.getClickedPos()), context.getPlayer() != null ? context.getPlayer().serverPlayer() : null); return InteractionResult.SUCCESS_AND_CANCEL; } @@ -66,7 +65,7 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { ImmutableBlockState blockState = BlockStateUtils.getOptionalCustomBlockState(args[0]).orElse(null); if (blockState == null) return; if (FastNMS.INSTANCE.method$Explosion$canTriggerBlocks(args[3]) && !blockState.get(this.poweredProperty)) { - press(thisBlock, blockState, args[1], args[2], null); + press(blockState, args[1], args[2], null); } } @@ -117,7 +116,7 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { ImmutableBlockState blockState = BlockStateUtils.getOptionalCustomBlockState(state).orElse(null); if (blockState == null) return; if (blockState.get(this.poweredProperty)) { - checkPressed(thisBlock, state, level, pos); + checkPressed(state, level, pos); } } @@ -129,11 +128,12 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { ImmutableBlockState blockState = BlockStateUtils.getOptionalCustomBlockState(state).orElse(null); if (blockState == null) return; if (this.canButtonBeActivatedByArrows && !blockState.get(this.poweredProperty)) { - checkPressed(thisBlock, state, level, pos); + checkPressed(state, level, pos); } } - private void checkPressed(Object thisBlock, Object state, Object level, Object pos) { + private void checkPressed(Object state, Object level, Object pos) { + Object tickState = state; Object abstractArrow = this.canButtonBeActivatedByArrows ? FastNMS.INSTANCE.method$EntityGetter$getEntitiesOfClass( level, CoreReflections.clazz$AbstractArrow, FastNMS.INSTANCE.method$AABB$move( FastNMS.INSTANCE.method$VoxelShape$bounds(FastNMS.INSTANCE.method$BlockState$getShape( @@ -144,8 +144,9 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { if (blockState == null) return; boolean poweredValue = blockState.get(this.poweredProperty); if (flag != poweredValue) { - FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, blockState.with(this.poweredProperty, flag).customBlockState().literalObject(), UpdateOption.UPDATE_ALL.flags()); - updateNeighbours(thisBlock, blockState, level, pos); + tickState = blockState.with(this.poweredProperty, flag).customBlockState().literalObject(); + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, tickState, UpdateOption.UPDATE_ALL.flags()); + updateNeighbours(BlockStateUtils.getBlockOwner(tickState), blockState, level, pos); playSound(null, level, pos, flag); Object gameEvent = VersionHelper.isOrAbove1_20_5() ? FastNMS.INSTANCE.method$Holder$direct(flag ? MGameEvent.BLOCK_ACTIVATE : MGameEvent.BLOCK_DEACTIVATE) @@ -154,7 +155,7 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { } if (flag) { - FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, thisBlock, this.ticksToStayPressed); + FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, BlockStateUtils.getBlockOwner(tickState), this.ticksToStayPressed); } } @@ -188,9 +189,10 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { return isOn ? this.buttonClickOnSound : this.buttonClickOffSound; } - private void press(Object thisBlock, ImmutableBlockState state, Object level, Object pos, @Nullable Object player) { - FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, state.with(this.poweredProperty, true).customBlockState().literalObject(), UpdateOption.UPDATE_ALL.flags()); - FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, thisBlock, this.ticksToStayPressed); + private void press(ImmutableBlockState state, Object level, Object pos, @Nullable Object player) { + Object tickState = state.with(this.poweredProperty, true).customBlockState().literalObject(); + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, tickState, UpdateOption.UPDATE_ALL.flags()); + FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, BlockStateUtils.getBlockOwner(tickState), this.ticksToStayPressed); playSound(player, level, pos, true); Object gameEvent = VersionHelper.isOrAbove1_20_5() ? FastNMS.INSTANCE.method$Holder$direct(MGameEvent.BLOCK_ACTIVATE) : MGameEvent.BLOCK_ACTIVATE; FastNMS.INSTANCE.method$LevelAccessor$gameEvent(level, player, gameEvent, pos); 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..a3e85d6ae 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 @@ -29,7 +29,6 @@ import javax.annotation.Nullable; import java.util.Map; import java.util.Optional; import java.util.concurrent.Callable; -import java.util.function.Predicate; public class PressurePlateBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); @@ -87,7 +86,7 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { Object state = args[0]; int signalForState = this.getSignalForState(state); if (signalForState > 0) { - this.checkPressed(null, args[1], args[2], state, signalForState, thisBlock); + this.checkPressed(null, args[1], args[2], state, signalForState); } } @@ -101,9 +100,7 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { Object state = args[0]; 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); + this.checkPressed(args[3], args[1], args[2], state, signalForState); } } @@ -125,16 +122,17 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { return optionalCustomState.get().with(this.poweredProperty, strength > 0).customBlockState().literalObject(); } - private void checkPressed(@Nullable Object entity, Object level, Object pos, Object state, int currentSignal, Object thisBlock) { + private void checkPressed(@Nullable Object entity, Object level, Object pos, Object state, int currentSignal) { + Object tickState = state; int signalStrength = this.getSignalStrength(level, pos); boolean wasActive = currentSignal > 0; boolean isActive = signalStrength > 0; if (currentSignal != signalStrength) { - Object blockState = this.setSignalForState(state, signalStrength); - FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, blockState, 2); - this.updateNeighbours(level, pos, thisBlock); - FastNMS.INSTANCE.method$Level$setBlocksDirty(level, pos, state, blockState); + tickState = this.setSignalForState(state, signalStrength); + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, tickState, 2); + this.updateNeighbours(level, pos, BlockStateUtils.getBlockOwner(tickState)); + FastNMS.INSTANCE.method$Level$setBlocksDirty(level, pos, state, tickState); } org.bukkit.World craftWorld = FastNMS.INSTANCE.method$Level$getCraftWorld(level); @@ -150,7 +148,7 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { } if (isActive) { - FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, thisBlock, this.pressedTime); + FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, BlockStateUtils.getBlockOwner(tickState), this.pressedTime); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SimpleStorageBlockEntity.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SimpleStorageBlockEntity.java index fcb654c71..f889df503 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SimpleStorageBlockEntity.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SimpleStorageBlockEntity.java @@ -107,8 +107,8 @@ public class SimpleStorageBlockEntity extends BlockEntity { // 有非观察者的人,那么就不触发开启音效和事件 if (!hasNoViewer(this.inventory.getViewers())) return; this.maxInteractionDistance = Math.max(player.getCachedInteractionRange(), this.maxInteractionDistance); - this.setOpen(player); - FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(super.world.world().serverWorld(), LocationUtils.toBlockPos(this.pos), BlockStateUtils.getBlockOwner(this.blockState.customBlockState().literalObject()), 5); + ImmutableBlockState state = this.setOpen(player); + FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(super.world.world().serverWorld(), LocationUtils.toBlockPos(this.pos), BlockStateUtils.getBlockOwner(state.customBlockState().literalObject()), 5); } } @@ -127,8 +127,8 @@ public class SimpleStorageBlockEntity extends BlockEntity { } } - private void setOpen(@Nullable Player player) { - this.updateOpenBlockState(true); + private ImmutableBlockState setOpen(@Nullable Player player) { + ImmutableBlockState state = this.updateOpenBlockState(true); org.bukkit.World bukkitWorld = (org.bukkit.World) super.world.world().platformWorld(); if (player != null) { bukkitWorld.sendGameEvent((org.bukkit.entity.Player) player.platformPlayer(), GameEvent.CONTAINER_OPEN, new Vector(this.pos.x(), this.pos.y(), this.pos.z())); @@ -140,10 +140,11 @@ public class SimpleStorageBlockEntity extends BlockEntity { if (soundData != null) { super.world.world().playBlockSound(Vec3d.atCenterOf(this.pos), soundData); } + return state; } - private void setClose(@Nullable Player player) { - this.updateOpenBlockState(false); + private ImmutableBlockState setClose(@Nullable Player player) { + ImmutableBlockState state = this.updateOpenBlockState(false); org.bukkit.World bukkitWorld = (org.bukkit.World) super.world.world().platformWorld(); if (player != null) { bukkitWorld.sendGameEvent((org.bukkit.entity.Player) player.platformPlayer(), GameEvent.CONTAINER_CLOSE, new Vector(this.pos.x(), this.pos.y(), this.pos.z())); @@ -155,6 +156,7 @@ public class SimpleStorageBlockEntity extends BlockEntity { if (soundData != null) { super.world.world().playBlockSound(Vec3d.atCenterOf(this.pos), soundData); } + return state; } private boolean hasNoViewer(List viewers) { @@ -170,16 +172,19 @@ public class SimpleStorageBlockEntity extends BlockEntity { return this.isValid() && this.inventory != null && this.behavior != null; } - public void updateOpenBlockState(boolean open) { + public ImmutableBlockState updateOpenBlockState(boolean open) { ImmutableBlockState state = super.world.getBlockStateAtIfLoaded(this.pos); - if (state == null || state.behavior() != this.behavior) return; + if (state == null || state.behavior() != this.behavior) return this.blockState; Property property = this.behavior.openProperty(); - if (property == null) return; - super.world.world().setBlockAt(this.pos.x(), this.pos.y(), this.pos.z(), state.with(property, open), UpdateOption.UPDATE_ALL.flags()); + if (property == null) return state; + state = state.with(property, open); + super.world.world().setBlockAt(this.pos.x(), this.pos.y(), this.pos.z(), state, UpdateOption.UPDATE_ALL.flags()); + return state; } public void checkOpeners(Object level, Object pos, Object blockState) { if (!this.isValidContainer()) return; + Object tickState = blockState; double maxInteractionDistance = 0d; List viewers = this.inventory.getViewers(); int validViewers = 0; @@ -193,14 +198,14 @@ public class SimpleStorageBlockEntity extends BlockEntity { } boolean shouldOpen = validViewers != 0; if (shouldOpen && !this.openState) { - this.setOpen(null); + tickState = this.setOpen(null).customBlockState().literalObject(); } else if (!shouldOpen && this.openState) { - this.setClose(null); + tickState = this.setClose(null).customBlockState().literalObject(); } this.maxInteractionDistance = maxInteractionDistance; if (!viewers.isEmpty()) { - FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, BlockStateUtils.getBlockOwner(blockState), 5); + FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, BlockStateUtils.getBlockOwner(tickState), 5); } } From 09c60273be08b758b632f886c257f204f18c7551 Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Fri, 19 Sep 2025 10:42:57 +0800 Subject: [PATCH 03/10] =?UTF-8?q?Revert=20"fix(block):=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E9=94=99=E8=AF=AF=E7=9A=84tick=E6=96=B9=E5=9D=97?= =?UTF-8?q?=E6=96=B9=E5=BC=8F"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 1d500a580de7b39a5bbcf2945d813379e0b1aa88. --- .../block/behavior/ButtonBlockBehavior.java | 26 +++++++--------- .../behavior/PressurePlateBlockBehavior.java | 20 ++++++------ .../entity/SimpleStorageBlockEntity.java | 31 ++++++++----------- 3 files changed, 36 insertions(+), 41 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java index 7bca026c1..3be8fa890 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java @@ -53,7 +53,8 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { @Override public InteractionResult useWithoutItem(UseOnContext context, ImmutableBlockState state) { if (!state.get(this.poweredProperty)) { - press(state, context.getLevel().serverWorld(), LocationUtils.toBlockPos(context.getClickedPos()), + press(BlockStateUtils.getBlockOwner(state.customBlockState().literalObject()), + state, context.getLevel().serverWorld(), LocationUtils.toBlockPos(context.getClickedPos()), context.getPlayer() != null ? context.getPlayer().serverPlayer() : null); return InteractionResult.SUCCESS_AND_CANCEL; } @@ -65,7 +66,7 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { ImmutableBlockState blockState = BlockStateUtils.getOptionalCustomBlockState(args[0]).orElse(null); if (blockState == null) return; if (FastNMS.INSTANCE.method$Explosion$canTriggerBlocks(args[3]) && !blockState.get(this.poweredProperty)) { - press(blockState, args[1], args[2], null); + press(thisBlock, blockState, args[1], args[2], null); } } @@ -116,7 +117,7 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { ImmutableBlockState blockState = BlockStateUtils.getOptionalCustomBlockState(state).orElse(null); if (blockState == null) return; if (blockState.get(this.poweredProperty)) { - checkPressed(state, level, pos); + checkPressed(thisBlock, state, level, pos); } } @@ -128,12 +129,11 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { ImmutableBlockState blockState = BlockStateUtils.getOptionalCustomBlockState(state).orElse(null); if (blockState == null) return; if (this.canButtonBeActivatedByArrows && !blockState.get(this.poweredProperty)) { - checkPressed(state, level, pos); + checkPressed(thisBlock, state, level, pos); } } - private void checkPressed(Object state, Object level, Object pos) { - Object tickState = state; + private void checkPressed(Object thisBlock, Object state, Object level, Object pos) { Object abstractArrow = this.canButtonBeActivatedByArrows ? FastNMS.INSTANCE.method$EntityGetter$getEntitiesOfClass( level, CoreReflections.clazz$AbstractArrow, FastNMS.INSTANCE.method$AABB$move( FastNMS.INSTANCE.method$VoxelShape$bounds(FastNMS.INSTANCE.method$BlockState$getShape( @@ -144,9 +144,8 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { if (blockState == null) return; boolean poweredValue = blockState.get(this.poweredProperty); if (flag != poweredValue) { - tickState = blockState.with(this.poweredProperty, flag).customBlockState().literalObject(); - FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, tickState, UpdateOption.UPDATE_ALL.flags()); - updateNeighbours(BlockStateUtils.getBlockOwner(tickState), blockState, level, pos); + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, blockState.with(this.poweredProperty, flag).customBlockState().literalObject(), UpdateOption.UPDATE_ALL.flags()); + updateNeighbours(thisBlock, blockState, level, pos); playSound(null, level, pos, flag); Object gameEvent = VersionHelper.isOrAbove1_20_5() ? FastNMS.INSTANCE.method$Holder$direct(flag ? MGameEvent.BLOCK_ACTIVATE : MGameEvent.BLOCK_DEACTIVATE) @@ -155,7 +154,7 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { } if (flag) { - FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, BlockStateUtils.getBlockOwner(tickState), this.ticksToStayPressed); + FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, thisBlock, this.ticksToStayPressed); } } @@ -189,10 +188,9 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { return isOn ? this.buttonClickOnSound : this.buttonClickOffSound; } - private void press(ImmutableBlockState state, Object level, Object pos, @Nullable Object player) { - Object tickState = state.with(this.poweredProperty, true).customBlockState().literalObject(); - FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, tickState, UpdateOption.UPDATE_ALL.flags()); - FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, BlockStateUtils.getBlockOwner(tickState), this.ticksToStayPressed); + private void press(Object thisBlock, ImmutableBlockState state, Object level, Object pos, @Nullable Object player) { + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, state.with(this.poweredProperty, true).customBlockState().literalObject(), UpdateOption.UPDATE_ALL.flags()); + FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, thisBlock, this.ticksToStayPressed); playSound(player, level, pos, true); Object gameEvent = VersionHelper.isOrAbove1_20_5() ? FastNMS.INSTANCE.method$Holder$direct(MGameEvent.BLOCK_ACTIVATE) : MGameEvent.BLOCK_ACTIVATE; FastNMS.INSTANCE.method$LevelAccessor$gameEvent(level, player, gameEvent, pos); 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 a3e85d6ae..5ec5cc268 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 @@ -29,6 +29,7 @@ import javax.annotation.Nullable; import java.util.Map; import java.util.Optional; import java.util.concurrent.Callable; +import java.util.function.Predicate; public class PressurePlateBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); @@ -86,7 +87,7 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { Object state = args[0]; int signalForState = this.getSignalForState(state); if (signalForState > 0) { - this.checkPressed(null, args[1], args[2], state, signalForState); + this.checkPressed(null, args[1], args[2], state, signalForState, thisBlock); } } @@ -100,7 +101,9 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { Object state = args[0]; int signalForState = this.getSignalForState(state); if (signalForState == 0) { - this.checkPressed(args[3], args[1], args[2], state, signalForState); + this.checkPressed(args[3], args[1], args[2], state, signalForState, thisBlock); + } else { + FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(args[1], args[2], thisBlock, this.pressedTime); } } @@ -122,17 +125,16 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { return optionalCustomState.get().with(this.poweredProperty, strength > 0).customBlockState().literalObject(); } - private void checkPressed(@Nullable Object entity, Object level, Object pos, Object state, int currentSignal) { - Object tickState = state; + private void checkPressed(@Nullable Object entity, Object level, Object pos, Object state, int currentSignal, Object thisBlock) { int signalStrength = this.getSignalStrength(level, pos); boolean wasActive = currentSignal > 0; boolean isActive = signalStrength > 0; if (currentSignal != signalStrength) { - tickState = this.setSignalForState(state, signalStrength); - FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, tickState, 2); - this.updateNeighbours(level, pos, BlockStateUtils.getBlockOwner(tickState)); - FastNMS.INSTANCE.method$Level$setBlocksDirty(level, pos, state, tickState); + Object blockState = this.setSignalForState(state, signalStrength); + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, blockState, 2); + this.updateNeighbours(level, pos, thisBlock); + FastNMS.INSTANCE.method$Level$setBlocksDirty(level, pos, state, blockState); } org.bukkit.World craftWorld = FastNMS.INSTANCE.method$Level$getCraftWorld(level); @@ -148,7 +150,7 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { } if (isActive) { - FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, BlockStateUtils.getBlockOwner(tickState), this.pressedTime); + FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, thisBlock, this.pressedTime); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SimpleStorageBlockEntity.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SimpleStorageBlockEntity.java index f889df503..fcb654c71 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SimpleStorageBlockEntity.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SimpleStorageBlockEntity.java @@ -107,8 +107,8 @@ public class SimpleStorageBlockEntity extends BlockEntity { // 有非观察者的人,那么就不触发开启音效和事件 if (!hasNoViewer(this.inventory.getViewers())) return; this.maxInteractionDistance = Math.max(player.getCachedInteractionRange(), this.maxInteractionDistance); - ImmutableBlockState state = this.setOpen(player); - FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(super.world.world().serverWorld(), LocationUtils.toBlockPos(this.pos), BlockStateUtils.getBlockOwner(state.customBlockState().literalObject()), 5); + this.setOpen(player); + FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(super.world.world().serverWorld(), LocationUtils.toBlockPos(this.pos), BlockStateUtils.getBlockOwner(this.blockState.customBlockState().literalObject()), 5); } } @@ -127,8 +127,8 @@ public class SimpleStorageBlockEntity extends BlockEntity { } } - private ImmutableBlockState setOpen(@Nullable Player player) { - ImmutableBlockState state = this.updateOpenBlockState(true); + private void setOpen(@Nullable Player player) { + this.updateOpenBlockState(true); org.bukkit.World bukkitWorld = (org.bukkit.World) super.world.world().platformWorld(); if (player != null) { bukkitWorld.sendGameEvent((org.bukkit.entity.Player) player.platformPlayer(), GameEvent.CONTAINER_OPEN, new Vector(this.pos.x(), this.pos.y(), this.pos.z())); @@ -140,11 +140,10 @@ public class SimpleStorageBlockEntity extends BlockEntity { if (soundData != null) { super.world.world().playBlockSound(Vec3d.atCenterOf(this.pos), soundData); } - return state; } - private ImmutableBlockState setClose(@Nullable Player player) { - ImmutableBlockState state = this.updateOpenBlockState(false); + private void setClose(@Nullable Player player) { + this.updateOpenBlockState(false); org.bukkit.World bukkitWorld = (org.bukkit.World) super.world.world().platformWorld(); if (player != null) { bukkitWorld.sendGameEvent((org.bukkit.entity.Player) player.platformPlayer(), GameEvent.CONTAINER_CLOSE, new Vector(this.pos.x(), this.pos.y(), this.pos.z())); @@ -156,7 +155,6 @@ public class SimpleStorageBlockEntity extends BlockEntity { if (soundData != null) { super.world.world().playBlockSound(Vec3d.atCenterOf(this.pos), soundData); } - return state; } private boolean hasNoViewer(List viewers) { @@ -172,19 +170,16 @@ public class SimpleStorageBlockEntity extends BlockEntity { return this.isValid() && this.inventory != null && this.behavior != null; } - public ImmutableBlockState updateOpenBlockState(boolean open) { + public void updateOpenBlockState(boolean open) { ImmutableBlockState state = super.world.getBlockStateAtIfLoaded(this.pos); - if (state == null || state.behavior() != this.behavior) return this.blockState; + if (state == null || state.behavior() != this.behavior) return; Property property = this.behavior.openProperty(); - if (property == null) return state; - state = state.with(property, open); - super.world.world().setBlockAt(this.pos.x(), this.pos.y(), this.pos.z(), state, UpdateOption.UPDATE_ALL.flags()); - return state; + if (property == null) return; + super.world.world().setBlockAt(this.pos.x(), this.pos.y(), this.pos.z(), state.with(property, open), UpdateOption.UPDATE_ALL.flags()); } public void checkOpeners(Object level, Object pos, Object blockState) { if (!this.isValidContainer()) return; - Object tickState = blockState; double maxInteractionDistance = 0d; List viewers = this.inventory.getViewers(); int validViewers = 0; @@ -198,14 +193,14 @@ public class SimpleStorageBlockEntity extends BlockEntity { } boolean shouldOpen = validViewers != 0; if (shouldOpen && !this.openState) { - tickState = this.setOpen(null).customBlockState().literalObject(); + this.setOpen(null); } else if (!shouldOpen && this.openState) { - tickState = this.setClose(null).customBlockState().literalObject(); + this.setClose(null); } this.maxInteractionDistance = maxInteractionDistance; if (!viewers.isEmpty()) { - FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, BlockStateUtils.getBlockOwner(tickState), 5); + FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, BlockStateUtils.getBlockOwner(blockState), 5); } } From 1ac958cf659124482837c2a6de225334720fd926 Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Fri, 19 Sep 2025 10:48:08 +0800 Subject: [PATCH 04/10] =?UTF-8?q?fix(block):=20=E6=9B=B4=E5=A5=BD=E7=9A=84?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=94=99=E8=AF=AF=E7=9A=84tick=E6=96=B9?= =?UTF-8?q?=E5=9D=97=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 之前的方法太麻烦了可能会导致一些第三方开发者不知道这个问题,通过修改匹配方式解决此问题 --- .../plugin/injector/BlockStateGenerator.java | 29 ++++++++++++++++--- .../reflection/minecraft/CoreReflections.java | 4 +++ 2 files changed, 29 insertions(+), 4 deletions(-) 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 825f90a50..4dee54943 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 @@ -12,6 +12,7 @@ import net.bytebuddy.implementation.FieldAccessor; import net.bytebuddy.implementation.MethodDelegation; import net.bytebuddy.implementation.bind.annotation.AllArguments; import net.bytebuddy.implementation.bind.annotation.RuntimeType; +import net.bytebuddy.implementation.bind.annotation.SuperCall; import net.bytebuddy.implementation.bind.annotation.This; import net.bytebuddy.matcher.ElementMatchers; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; @@ -21,14 +22,15 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflect import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlockStateProperties; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MLootContextParams; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; +import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.world.BukkitWorld; -import net.momirealms.craftengine.core.block.BlockSettings; -import net.momirealms.craftengine.core.block.DelegatingBlockState; -import net.momirealms.craftengine.core.block.ImmutableBlockState; +import net.momirealms.craftengine.core.block.*; import net.momirealms.craftengine.core.block.properties.Property; import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.context.ContextHolder; import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters; +import net.momirealms.craftengine.core.util.ObjectHolder; import net.momirealms.craftengine.core.util.ReflectionUtils; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.World; @@ -39,6 +41,8 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.util.List; +import java.util.Optional; +import java.util.concurrent.Callable; public final class BlockStateGenerator { private static MethodHandle constructor$CraftEngineBlockState; @@ -64,7 +68,9 @@ public final class BlockStateGenerator { .method(ElementMatchers.is(CoreReflections.method$StateHolder$getValue)) .intercept(MethodDelegation.to(GetPropertyValueInterceptor.INSTANCE)) .method(ElementMatchers.is(CoreReflections.method$StateHolder$setValue)) - .intercept(MethodDelegation.to(SetPropertyValueInterceptor.INSTANCE)); + .intercept(MethodDelegation.to(SetPropertyValueInterceptor.INSTANCE)) + .method(ElementMatchers.is(CoreReflections.method$BlockStateBase$isBlock)) + .intercept(MethodDelegation.to(IsBlockInterceptor.INSTANCE)); Class clazz$CraftEngineBlock = stateBuilder.make().load(BlockStateGenerator.class.getClassLoader()).getLoaded(); constructor$CraftEngineBlockState = VersionHelper.isOrAbove1_20_5() ? MethodHandles.publicLookup().in(clazz$CraftEngineBlock) @@ -183,6 +189,21 @@ public final class BlockStateGenerator { } } + public static class IsBlockInterceptor { + public static final IsBlockInterceptor INSTANCE = new IsBlockInterceptor(); + + @RuntimeType + public boolean intercept(@This Object thisObj, @AllArguments Object[] args) { + DelegatingBlockState customState = (DelegatingBlockState) thisObj; + ImmutableBlockState thisState = customState.blockState(); + if (thisState == null) return false; + if (!(args[0] instanceof DelegatingBlock delegatingBlock)) return false; + BlockBehavior behavior = delegatingBlock.behaviorDelegate().value(); + if (behavior == null) return false; + return behavior.equals(thisState.owner().value()); + } + } + public static class CreateStateInterceptor { public static final CreateStateInterceptor INSTANCE = new CreateStateInterceptor(); 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 4fb178606..e3eded271 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 @@ -4406,4 +4406,8 @@ public final class CoreReflections { BukkitReflectionUtils.assembleMCClass("world.level.gameevent.GameEvent") ) ); + + public static final Method method$BlockStateBase$isBlock = requireNonNull( + ReflectionUtils.getDeclaredMethod(clazz$BlockStateBase, boolean.class, new String[]{"is", "a"}, clazz$Block) + ); } From ecab22cc9b0a85d85b28a14a545a8b98d411fa24 Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Fri, 19 Sep 2025 11:24:08 +0800 Subject: [PATCH 05/10] =?UTF-8?q?feat(block):=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E5=8C=B9=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() + ); } From 3ec61174180088f1379b2bd3b7651dbe6a6ea86f Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Fri, 19 Sep 2025 23:33:16 +0800 Subject: [PATCH 06/10] =?UTF-8?q?fix(compatibility):=20=E6=94=B9=E8=BF=9B?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/compatibility/BukkitCompatibilityManager.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java index c4ca0328e..8e4f5785e 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java @@ -20,6 +20,7 @@ import net.momirealms.craftengine.bukkit.compatibility.worldedit.WorldEditBlockR import net.momirealms.craftengine.bukkit.font.BukkitFontManager; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; +import net.momirealms.craftengine.bukkit.util.KeyUtils; import net.momirealms.craftengine.core.entity.furniture.ExternalModel; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.loot.LootConditions; @@ -32,6 +33,7 @@ import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.WorldManager; import org.bukkit.Bukkit; +import org.bukkit.Registry; import org.bukkit.plugin.Plugin; import java.util.*; @@ -250,6 +252,8 @@ public class BukkitCompatibilityManager implements CompatibilityManager { weBlockRegister.register(newBlockId); } } catch (Exception e) { + // 检查是不是有插件干预了注册表 + if (Registry.MATERIAL.get(KeyUtils.toNamespacedKey(BukkitBlockManager.instance().blockRegisterOrder().getFirst())) != null) return; this.plugin.logger().warn("Failed to initialize world edit hook", e); } } From 51a641ed91fd6f2f9e4903464bd6461e7b623a23 Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Sat, 20 Sep 2025 02:18:05 +0800 Subject: [PATCH 07/10] =?UTF-8?q?fix(network):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E9=94=99=E8=AF=AF=E7=9A=84=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/network/handler/MinecartPacketHandler.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/MinecartPacketHandler.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/MinecartPacketHandler.java index 718946298..ff4c81023 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/MinecartPacketHandler.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/MinecartPacketHandler.java @@ -25,7 +25,7 @@ import java.util.Optional; public class MinecartPacketHandler implements EntityPacketHandler { public static final MinecartPacketHandler INSTANCE = new MinecartPacketHandler(); - private static final BlockStateHandler BLOCK_STATE_HANDLER = VersionHelper.isOrAbove1_21_3() ? BlockStateHandler_1_21_3.INSTANCE : BlockStateHandler_1_20.INSTANCE; + private static final BlockStateHandler BLOCK_STATE_HANDLER = VersionHelper.isOrAbove1_21_5() ? BlockStateHandler_1_21_5.INSTANCE : BlockStateHandler_1_20.INSTANCE; @Override public void handleSetEntityData(Player user, ByteBufPacketEvent event) { @@ -69,8 +69,8 @@ public class MinecartPacketHandler implements EntityPacketHandler { Object handle(NetWorkUser user, Object packedItem, int entityDataId); } - static class BlockStateHandler_1_21_3 implements BlockStateHandler { - protected static final BlockStateHandler INSTANCE = new BlockStateHandler_1_21_3(); + static class BlockStateHandler_1_21_5 implements BlockStateHandler { + protected static final BlockStateHandler INSTANCE = new BlockStateHandler_1_21_5(); @Override public Object handle(NetWorkUser user, Object packedItem, int entityDataId) { From 862203ca2a730d31010cdfeec20651ecb3c151b8 Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Sat, 20 Sep 2025 02:32:12 +0800 Subject: [PATCH 08/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BukkitCompatibilityManager.java | 4 ---- .../plugin/injector/BlockStateGenerator.java | 16 ++++++++-------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java index 8e4f5785e..c4ca0328e 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java @@ -20,7 +20,6 @@ import net.momirealms.craftengine.bukkit.compatibility.worldedit.WorldEditBlockR import net.momirealms.craftengine.bukkit.font.BukkitFontManager; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; -import net.momirealms.craftengine.bukkit.util.KeyUtils; import net.momirealms.craftengine.core.entity.furniture.ExternalModel; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.loot.LootConditions; @@ -33,7 +32,6 @@ import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.WorldManager; import org.bukkit.Bukkit; -import org.bukkit.Registry; import org.bukkit.plugin.Plugin; import java.util.*; @@ -252,8 +250,6 @@ public class BukkitCompatibilityManager implements CompatibilityManager { weBlockRegister.register(newBlockId); } } catch (Exception e) { - // 检查是不是有插件干预了注册表 - if (Registry.MATERIAL.get(KeyUtils.toNamespacedKey(BukkitBlockManager.instance().blockRegisterOrder().getFirst())) != null) return; this.plugin.logger().warn("Failed to initialize world edit hook", e); } } 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 9281595d8..148fa9e3d 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 @@ -243,14 +243,14 @@ public final class BlockStateGenerator { @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; + DelegatingBlockState customState = (DelegatingBlockState) thisObj; + ImmutableBlockState thisState = customState.blockState(); + if (thisState == null) return false; + CustomBlock thisBlock = thisState.owner().value(); return behavior.block().equals(thisBlock); } } @@ -260,16 +260,16 @@ public final class BlockStateGenerator { @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; + DelegatingBlockState customState = (DelegatingBlockState) thisObj; + ImmutableBlockState thisState = customState.blockState(); + if (thisState == null) return false; + CustomBlock thisBlock = thisState.owner().value(); return behavior.block().equals(thisBlock); } } From ea1b684982dd803d7c35d5208df84baf2478c4a1 Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Sat, 20 Sep 2025 02:35:21 +0800 Subject: [PATCH 09/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/block/behavior/ButtonBlockBehavior.java | 12 ++++++------ .../block/behavior/PressurePlateBlockBehavior.java | 5 ++--- .../{MEntitySelector.java => MEntitySelectors.java} | 4 ++-- .../minecraft/{MGameEvent.java => MGameEvents.java} | 4 ++-- 4 files changed, 12 insertions(+), 13 deletions(-) rename bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/{MEntitySelector.java => MEntitySelectors.java} (80%) rename bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/{MGameEvent.java => MGameEvents.java} (89%) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java index 3be8fa890..afa85f737 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ButtonBlockBehavior.java @@ -2,8 +2,8 @@ package net.momirealms.craftengine.bukkit.block.behavior; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; -import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntitySelector; -import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MGameEvent; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntitySelectors; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MGameEvents; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.DirectionUtils; import net.momirealms.craftengine.bukkit.util.KeyUtils; @@ -138,7 +138,7 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { level, CoreReflections.clazz$AbstractArrow, FastNMS.INSTANCE.method$AABB$move( FastNMS.INSTANCE.method$VoxelShape$bounds(FastNMS.INSTANCE.method$BlockState$getShape( state, level, pos, CoreReflections.instance$CollisionContext$empty - )), pos), MEntitySelector.NO_SPECTATORS).stream().findFirst().orElse(null) : null; + )), pos), MEntitySelectors.NO_SPECTATORS).stream().findFirst().orElse(null) : null; boolean flag = abstractArrow != null; ImmutableBlockState blockState = BlockStateUtils.getOptionalCustomBlockState(state).orElse(null); if (blockState == null) return; @@ -148,8 +148,8 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { updateNeighbours(thisBlock, blockState, level, pos); playSound(null, level, pos, flag); Object gameEvent = VersionHelper.isOrAbove1_20_5() - ? FastNMS.INSTANCE.method$Holder$direct(flag ? MGameEvent.BLOCK_ACTIVATE : MGameEvent.BLOCK_DEACTIVATE) - : flag ? MGameEvent.BLOCK_ACTIVATE : MGameEvent.BLOCK_DEACTIVATE; + ? FastNMS.INSTANCE.method$Holder$direct(flag ? MGameEvents.BLOCK_ACTIVATE : MGameEvents.BLOCK_DEACTIVATE) + : flag ? MGameEvents.BLOCK_ACTIVATE : MGameEvents.BLOCK_DEACTIVATE; FastNMS.INSTANCE.method$LevelAccessor$gameEvent(level, abstractArrow, gameEvent, pos); } @@ -192,7 +192,7 @@ public class ButtonBlockBehavior extends BukkitBlockBehavior { FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, state.with(this.poweredProperty, true).customBlockState().literalObject(), UpdateOption.UPDATE_ALL.flags()); FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, pos, thisBlock, this.ticksToStayPressed); playSound(player, level, pos, true); - Object gameEvent = VersionHelper.isOrAbove1_20_5() ? FastNMS.INSTANCE.method$Holder$direct(MGameEvent.BLOCK_ACTIVATE) : MGameEvent.BLOCK_ACTIVATE; + Object gameEvent = VersionHelper.isOrAbove1_20_5() ? FastNMS.INSTANCE.method$Holder$direct(MGameEvents.BLOCK_ACTIVATE) : MGameEvents.BLOCK_ACTIVATE; FastNMS.INSTANCE.method$LevelAccessor$gameEvent(level, player, gameEvent, pos); } 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 0453403b5..3d8263e77 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 @@ -4,7 +4,7 @@ import io.papermc.paper.event.entity.EntityInsideBlockEvent; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks; -import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntitySelector; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntitySelectors; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.DirectionUtils; import net.momirealms.craftengine.bukkit.util.EventUtils; @@ -29,7 +29,6 @@ import javax.annotation.Nullable; import java.util.Map; import java.util.Optional; import java.util.concurrent.Callable; -import java.util.function.Predicate; public class PressurePlateBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); @@ -113,7 +112,7 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { Object box = FastNMS.INSTANCE.method$AABB$move(CoreReflections.instance$BasePressurePlateBlock$TOUCH_AABB, pos); return !FastNMS.INSTANCE.method$EntityGetter$getEntitiesOfClass( level, clazz, box, - MEntitySelector.NO_SPECTATORS.and(entity -> !FastNMS.INSTANCE.method$Entity$isIgnoringBlockTriggers(entity)) + MEntitySelectors.NO_SPECTATORS.and(entity -> !FastNMS.INSTANCE.method$Entity$isIgnoringBlockTriggers(entity)) ).isEmpty() ? 15 : 0; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MEntitySelector.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MEntitySelectors.java similarity index 80% rename from bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MEntitySelector.java rename to bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MEntitySelectors.java index 7a2b43ab7..76bbaf19b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MEntitySelector.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MEntitySelectors.java @@ -4,8 +4,8 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS; import java.util.function.Predicate; -public final class MEntitySelector { - private MEntitySelector() {} +public final class MEntitySelectors { + private MEntitySelectors() {} public static final Predicate NO_SPECTATORS = entity -> !FastNMS.INSTANCE.method$Entity$isSpectator(entity); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MGameEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MGameEvents.java similarity index 89% rename from bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MGameEvent.java rename to bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MGameEvents.java index 500f39d8c..fad931574 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MGameEvent.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MGameEvents.java @@ -2,8 +2,8 @@ package net.momirealms.craftengine.bukkit.plugin.reflection.minecraft; import net.momirealms.craftengine.bukkit.nms.FastNMS; -public final class MGameEvent { - private MGameEvent() {} +public final class MGameEvents { + private MGameEvents() {} public static final Object BLOCK_ACTIVATE = getById("block_activate"); public static final Object BLOCK_DEACTIVATE = getById("block_deactivate"); From 150444819c9df01ee1eafcf757d14af8c30d69f7 Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Sat, 20 Sep 2025 02:46:42 +0800 Subject: [PATCH 10/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...hedHorizontalDirectionalBlockBehavior.java | 20 +++++++++---------- .../src/main/resources/translations/en.yml | 3 +++ .../src/main/resources/translations/zh_cn.yml | 3 +++ .../core/block/properties/Properties.java | 4 ++-- .../{AttachFace.java => AnchorType.java} | 2 +- 5 files changed, 19 insertions(+), 13 deletions(-) rename core/src/main/java/net/momirealms/craftengine/core/block/state/properties/{AttachFace.java => AnchorType.java} (80%) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FaceAttachedHorizontalDirectionalBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FaceAttachedHorizontalDirectionalBlockBehavior.java index cc877ef06..597470895 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FaceAttachedHorizontalDirectionalBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FaceAttachedHorizontalDirectionalBlockBehavior.java @@ -11,7 +11,7 @@ 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.block.state.properties.AttachFace; +import net.momirealms.craftengine.core.block.state.properties.AnchorType; import net.momirealms.craftengine.core.item.context.BlockPlaceContext; import net.momirealms.craftengine.core.util.Direction; import net.momirealms.craftengine.core.util.HorizontalDirection; @@ -27,7 +27,7 @@ import java.util.concurrent.Callable; public class FaceAttachedHorizontalDirectionalBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); - private final Property attachFaceProperty; + private final Property anchorTypeProperty; private final Property facingProperty; private final List tagsCanSurviveOn; private final Set blockStatesCanSurviveOn; @@ -39,14 +39,14 @@ public class FaceAttachedHorizontalDirectionalBlockBehavior extends BukkitBlockB List tagsCanSurviveOn, Set blockStatesCanSurviveOn, Set customBlocksCansSurviveOn, - Property attachFace, + Property anchorType, Property facing) { super(customBlock); this.tagsCanSurviveOn = tagsCanSurviveOn; this.blockStatesCanSurviveOn = blockStatesCanSurviveOn; this.customBlocksCansSurviveOn = customBlocksCansSurviveOn; this.blacklistMode = blacklist; - this.attachFaceProperty = attachFace; + this.anchorTypeProperty = anchorType; this.facingProperty = facing; } @@ -64,16 +64,16 @@ public class FaceAttachedHorizontalDirectionalBlockBehavior extends BukkitBlockB @SuppressWarnings("unchecked") @Override public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) { - Property face = (Property) state.owner().value().getProperty("face"); + Property face = (Property) state.owner().value().getProperty("face"); Property facing = (Property) state.owner().value().getProperty("facing"); if (face == null || facing == null) return null; for (Direction direction : context.getNearestLookingDirections()) { if (direction.axis() == Direction.Axis.Y) { state = state - .with(face, direction == Direction.UP ? AttachFace.CEILING : AttachFace.FLOOR) + .with(face, direction == Direction.UP ? AnchorType.CEILING : AnchorType.FLOOR) .with(facing, context.getHorizontalDirection().toHorizontalDirection()); } else { - state = state.with(face, AttachFace.WALL).with(facing, direction.opposite().toHorizontalDirection()); + state = state.with(face, AnchorType.WALL).with(facing, direction.opposite().toHorizontalDirection()); } if (FastNMS.INSTANCE.method$BlockStateBase$canSurvive(state.customBlockState().literalObject(), context.getLevel().serverWorld(), LocationUtils.toBlockPos(context.getClickedPos()))) { return state; @@ -128,7 +128,7 @@ public class FaceAttachedHorizontalDirectionalBlockBehavior extends BukkitBlockB if (state == null) return null; FaceAttachedHorizontalDirectionalBlockBehavior behavior = state.behavior().getAs(FaceAttachedHorizontalDirectionalBlockBehavior.class).orElse(null); if (behavior == null) return null; - return switch (state.get(behavior.attachFaceProperty)) { + return switch (state.get(behavior.anchorTypeProperty)) { case CEILING -> Direction.DOWN; case FLOOR -> Direction.UP; default -> state.get(behavior.facingProperty).toDirection(); @@ -140,11 +140,11 @@ public class FaceAttachedHorizontalDirectionalBlockBehavior extends BukkitBlockB @SuppressWarnings("unchecked") @Override public BlockBehavior create(CustomBlock block, Map arguments) { - Property attachFace = (Property) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("face"), "warning.config.block.behavior.face_attached_horizontal_directional.missing_face"); + Property anchorType = (Property) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("face"), "warning.config.block.behavior.face_attached_horizontal_directional.missing_face"); Property facing = (Property) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("facing"), "warning.config.block.behavior.face_attached_horizontal_directional.missing_facing"); Tuple, Set, Set> tuple = DirectionalAttachedBlockBehavior.readTagsAndState(arguments); boolean blacklistMode = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("blacklist", true), "blacklist"); - return new FaceAttachedHorizontalDirectionalBlockBehavior(block, blacklistMode, tuple.left(), tuple.mid(), tuple.right(), attachFace, facing); + return new FaceAttachedHorizontalDirectionalBlockBehavior(block, blacklistMode, tuple.left(), tuple.mid(), tuple.right(), anchorType, facing); } } } diff --git a/common-files/src/main/resources/translations/en.yml b/common-files/src/main/resources/translations/en.yml index 71250f8c3..e2ea5b94a 100644 --- a/common-files/src/main/resources/translations/en.yml +++ b/common-files/src/main/resources/translations/en.yml @@ -325,6 +325,9 @@ warning.config.block.behavior.fence.missing_north: "Issue found in file warning.config.block.behavior.fence.missing_east: "Issue found in file - The block '' is missing the required 'east' property for 'fence_block' behavior." warning.config.block.behavior.fence.missing_south: "Issue found in file - The block '' is missing the required 'south' property for 'fence_block' behavior." warning.config.block.behavior.fence.missing_west: "Issue found in file - The block '' is missing the required 'west' property for 'fence_block' behavior." +warning.config.block.behavior.face_attached_horizontal_directional.missing_face: "Issue found in file - The block '' is missing the required 'face' property for 'face_attached_horizontal_directional_block' behavior." +warning.config.block.behavior.face_attached_horizontal_directional.missing_facing: "Issue found in file - The block '' is missing the required 'facing' property for 'face_attached_horizontal_directional_block' behavior." +warning.config.block.behavior.button.missing_powered: "Issue found in file - The block '' is missing the required 'powered' property for 'button_block' behavior." warning.config.model.generation.missing_parent: "Issue found in file - The config '' is missing the required 'parent' argument in 'generation' section." warning.config.model.generation.conflict: "Issue found in file - Failed to generate model for '' as two or more configurations attempt to generate different json models with the same path: ''." warning.config.model.generation.invalid_display_position: "Issue found in file - The config '' is using an invalid display position '' in 'generation.display' section. Allowed display positions: []" diff --git a/common-files/src/main/resources/translations/zh_cn.yml b/common-files/src/main/resources/translations/zh_cn.yml index 1c2c4ca57..add5680d3 100644 --- a/common-files/src/main/resources/translations/zh_cn.yml +++ b/common-files/src/main/resources/translations/zh_cn.yml @@ -319,6 +319,9 @@ warning.config.block.behavior.fence.missing_north: "在文件 warning.config.block.behavior.fence.missing_east: "在文件 发现问题 - 方块 '' 的 'fence_block' 行为缺少必需的 'east' 属性" warning.config.block.behavior.fence.missing_south: "在文件 发现问题 - 方块 '' 的 'fence_block' 行为缺少必需的 'south' 属性" warning.config.block.behavior.fence.missing_west: "在文件 发现问题 - 方块 '' 的 'fence_block' 行为缺少必需的 'west' 属性" +warning.config.block.behavior.face_attached_horizontal_directional.missing_face: "在文件 发现问题 - 方块 '' 的 'face_attached_horizontal_directional_block' 行为缺少必需的 'face' 属性" +warning.config.block.behavior.face_attached_horizontal_directional.missing_facing: "在文件 发现问题 - 方块 '' 的 'face_attached_horizontal_directional_block' 行为缺少必需的 'facing' 属性" +warning.config.block.behavior.button.missing_powered: "在文件 发现问题 - 方块 '' 的 'button_block' 行为缺少必需的 'powered' 属性" warning.config.model.generation.missing_parent: "在文件 发现问题 - 配置项 '' 的 'generation' 段落缺少必需的 'parent' 参数" warning.config.model.generation.conflict: "在文件 发现问题 - 无法为 '' 生成模型 存在多个配置尝试使用相同路径 '' 生成不同的 JSON 模型" warning.config.model.generation.invalid_display_position: "在文件 发现问题 - 配置项 '' 在 'generation.display' 区域使用了无效的 display 位置类型 ''. 可用展示类型: []" 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 e559a080a..42753ec45 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 @@ -22,7 +22,7 @@ public final class Properties { public static final Key STAIRS_SHAPE = Key.of("craftengine:stairs_shape"); public static final Key SLAB_TYPE = Key.of("craftengine:slab_type"); public static final Key SOFA_SHAPE = Key.of("craftengine:sofa_shape"); - public static final Key ATTACH_FACE = Key.of("craftengine:attach_face"); + public static final Key ANCHOR_TYPE = Key.of("craftengine:anchor_type"); static { register(BOOLEAN, BooleanProperty.FACTORY); @@ -39,7 +39,7 @@ public final class Properties { register(STAIRS_SHAPE, new EnumProperty.Factory<>(StairsShape.class)); register(SLAB_TYPE, new EnumProperty.Factory<>(SlabType.class)); register(SOFA_SHAPE, new EnumProperty.Factory<>(SofaShape.class)); - register(ATTACH_FACE, new EnumProperty.Factory<>(AttachFace.class)); + register(ANCHOR_TYPE, new EnumProperty.Factory<>(AnchorType.class)); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/state/properties/AttachFace.java b/core/src/main/java/net/momirealms/craftengine/core/block/state/properties/AnchorType.java similarity index 80% rename from core/src/main/java/net/momirealms/craftengine/core/block/state/properties/AttachFace.java rename to core/src/main/java/net/momirealms/craftengine/core/block/state/properties/AnchorType.java index de9d6267b..65bec0f74 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/state/properties/AttachFace.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/state/properties/AnchorType.java @@ -1,6 +1,6 @@ package net.momirealms.craftengine.core.block.state.properties; -public enum AttachFace { +public enum AnchorType { FLOOR, WALL, CEILING