From 2694c521a077f714965a305bb68367c747a9bb9a Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Mon, 14 Apr 2025 23:54:36 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=9B=E4=B8=80=E6=AD=A5=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E7=AE=80=E5=8C=96=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/network/PacketConsumers.java | 16 +++- .../plugin/user/BukkitServerPlayer.java | 77 ++++++++++++------- .../craftengine/bukkit/util/Reflections.java | 6 ++ 3 files changed, 69 insertions(+), 30 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index c9d341dd7..0a350d754 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -1127,10 +1127,18 @@ public class PacketConsumers { } return; } - if (player.isAdventureMode() && !Config.simplyAdventureCheck()) { - if (!player.canBreak(pos)) { - player.preventMiningBlock(); - return; + if (player.isAdventureMode()) { + if (Config.simplyAdventureCheck()) { + ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId); + if (!player.canBreak(pos, state.vanillaBlockState().handle())) { + player.preventMiningBlock(); + return; + } + } else { + if (!player.canBreak(pos)) { + player.preventMiningBlock(); + return; + } } } player.startMiningBlock(world, pos, blockState, true, BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId)); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java index 06121ad13..c8fb6acf7 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java @@ -159,6 +159,29 @@ public class BukkitServerPlayer extends Player { return true; } + public boolean canBreak(BlockPos pos, Object state) { + Item stackItem = getItemInHand(InteractionHand.MAIN_HAND); + Object itemStack = stackItem == null ? Reflections.instance$ItemStack$EMPTY : stackItem.getLiteralObject(); + Object blockPos = LocationUtils.toBlockPos(pos); + try { + Object blockInWorld = Reflections.constructor$BlockInWorld.newInstance(level().serverWorld(), blockPos, false); + Reflections.field$BlockInWorld$state.set(blockInWorld, state); + if (VersionHelper.isVersionNewerThan1_20_5()) { + if (Reflections.method$ItemStack$canBreakBlockInAdventureMode != null && !(boolean) Reflections.method$ItemStack$canBreakBlockInAdventureMode.invoke(itemStack, blockInWorld)) { + return false; + } + } else { + if (Reflections.method$ItemStack$canDestroy != null && !(boolean) Reflections.method$ItemStack$canDestroy.invoke(itemStack, Reflections.instance$BuiltInRegistries$BLOCK, blockInWorld)) { + return false; + } + } + } catch (ReflectiveOperationException e) { + this.plugin.logger().warn("Failed to run canBreak check", e); + return false; + } + return true; + } + @Override public void sendActionBar(Component text) { try { @@ -448,33 +471,35 @@ public class BukkitServerPlayer extends Player { float progressToAdd = (float) Reflections.method$BlockStateBase$getDestroyProgress.invoke(this.destroyedState, serverPlayer, Reflections.method$Entity$level.invoke(serverPlayer), blockPos); int id = BlockStateUtils.blockStateToId(this.destroyedState); ImmutableBlockState customState = BukkitBlockManager.instance().getImmutableBlockState(id); - if (customState != null && !customState.isEmpty() - && !customState.settings().isCorrectTool(item == null ? ItemKeys.AIR : item.id())) { - progressToAdd *= customState.settings().incorrectToolSpeed(); - } - - this.miningProgress = progressToAdd + miningProgress; - int packetStage = (int) (this.miningProgress * 10.0F); - if (packetStage != this.lastSentState) { - this.lastSentState = packetStage; - broadcastDestroyProgress(player, hitPos, blockPos, packetStage); - } - - if (this.miningProgress >= 1f) { - // TODO can_break component match - if (isAdventureMode() && Config.simplyAdventureCheck()) { - player.setGameMode(GameMode.SURVIVAL); - try { - Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos); - } finally { - player.setGameMode(GameMode.ADVENTURE); - } - } else { - Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos); + if (customState != null && !customState.isEmpty()) { + if (!customState.settings().isCorrectTool(item == null ? ItemKeys.AIR : item.id())) { + progressToAdd *= customState.settings().incorrectToolSpeed(); + } + + this.miningProgress = progressToAdd + miningProgress; + int packetStage = (int) (this.miningProgress * 10.0F); + if (packetStage != this.lastSentState) { + this.lastSentState = packetStage; + broadcastDestroyProgress(player, hitPos, blockPos, packetStage); + } + + if (this.miningProgress >= 1f) { + if (isAdventureMode() && Config.simplyAdventureCheck()) { + if (canBreak(hitPos, customState.vanillaBlockState().handle())) { + player.setGameMode(GameMode.SURVIVAL); + try { + Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos); + } finally { + player.setGameMode(GameMode.ADVENTURE); + } + } + } else { + Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos); + } + Object levelEventPacket = Reflections.constructor$ClientboundLevelEventPacket.newInstance(2001, blockPos, id, false); + sendPacket(levelEventPacket, false); + this.stopMiningBlock(); } - Object levelEventPacket = Reflections.constructor$ClientboundLevelEventPacket.newInstance(2001, blockPos, id, false); - sendPacket(levelEventPacket, false); - this.stopMiningBlock(); } } } catch (Exception e) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java index 43cb6780e..a6a04f5b7 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java @@ -5768,6 +5768,12 @@ public class Reflections { ) ); + public static final Field field$BlockInWorld$state = requireNonNull( + ReflectionUtils.getDeclaredField( + clazz$BlockInWorld, clazz$BlockState, 0 + ) + ); + public static final Constructor constructor$BlockInWorld = requireNonNull( ReflectionUtils.getConstructor( clazz$BlockInWorld, 0