From f6f0927393807a4340f809eb05af259b8cf497a2 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Mon, 14 Apr 2025 22:41:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=80=E4=B8=8Bcanbreak?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bukkit/loader/src/main/resources/config.yml | 2 +- .../bukkit/block/BlockEventListener.java | 21 ++---------- .../plugin/network/PacketConsumers.java | 16 ++-------- .../plugin/user/BukkitServerPlayer.java | 32 +++++++++++++++++-- .../core/entity/player/Player.java | 2 ++ 5 files changed, 38 insertions(+), 35 deletions(-) diff --git a/bukkit/loader/src/main/resources/config.yml b/bukkit/loader/src/main/resources/config.yml index 73ef75e8d..df8d3d5a8 100644 --- a/bukkit/loader/src/main/resources/config.yml +++ b/bukkit/loader/src/main/resources/config.yml @@ -147,7 +147,7 @@ block: # ✅ Solution: # - Use `client-bound-item-data` to safely sync custom block data to clients. # Documentation: https://mo-mi.gitbook.io/xiaomomi-plugins/craftengine/plugin-wiki/craftengine/add-new-contents/items/item-data/client-bound-item-data - simplify-adventure-break-check: true + simplify-adventure-break-check: false furniture: # Automatically remove outdated furniture entities when a chunk is loaded. diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java index 6e8b19e0d..86e14ff7f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java @@ -107,24 +107,9 @@ public class BlockEventListener implements Listener { Location location = block.getLocation(); BukkitServerPlayer serverPlayer = this.plugin.adapt(player); // double check to prevent dupe - if (serverPlayer.isAdventureMode()) { - Object itemStack = FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(player.getInventory().getItemInMainHand()); - Object blockPos = LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()); - try { - Object blockInWorld = Reflections.constructor$BlockInWorld.newInstance(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(location.getWorld()), blockPos, false); - if (VersionHelper.isVersionNewerThan1_20_5()) { - if (Reflections.method$ItemStack$canBreakBlockInAdventureMode != null && !(boolean) Reflections.method$ItemStack$canBreakBlockInAdventureMode.invoke(itemStack, blockInWorld)) { - return; - } - } else { - if (Reflections.method$ItemStack$canDestroy != null && !(boolean) Reflections.method$ItemStack$canDestroy.invoke(itemStack, Reflections.instance$BuiltInRegistries$BLOCK, blockInWorld)) { - return; - } - } - } catch (ReflectiveOperationException e) { - this.plugin.logger().warn("Failed to double check adventure mode", e); - return; - } + // if simply adventure check, player would be survival mode for the moment + if (serverPlayer.isAdventureMode() && !serverPlayer.canBreak(LocationUtils.toBlockPos(location))) { + return; } // trigger event 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 98a1187b6..c9d341dd7 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 @@ -1128,19 +1128,9 @@ public class PacketConsumers { return; } if (player.isAdventureMode() && !Config.simplyAdventureCheck()) { - Object itemStack = FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(player.platformPlayer().getInventory().getItemInMainHand()); - Object blockPos = LocationUtils.toBlockPos(pos); - Object blockInWorld = Reflections.constructor$BlockInWorld.newInstance(serverLevel, blockPos, false); - if (VersionHelper.isVersionNewerThan1_20_5()) { - if (Reflections.method$ItemStack$canBreakBlockInAdventureMode != null && !(boolean) Reflections.method$ItemStack$canBreakBlockInAdventureMode.invoke(itemStack, blockInWorld)) { - player.preventMiningBlock(); - return; - } - } else { - if (Reflections.method$ItemStack$canDestroy != null && !(boolean) Reflections.method$ItemStack$canDestroy.invoke(itemStack, Reflections.instance$BuiltInRegistries$BLOCK, blockInWorld)) { - player.preventMiningBlock(); - return; - } + 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 ecdf99d2e..aa0b6add4 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 @@ -29,7 +29,6 @@ import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.util.RayTraceResult; -import org.bukkit.util.Vector; import org.jetbrains.annotations.Nullable; import java.lang.ref.Reference; @@ -137,6 +136,29 @@ public class BukkitServerPlayer extends Player { return platformPlayer().getGameMode() == GameMode.ADVENTURE; } + @Override + public boolean canBreak(BlockPos pos) { + Item stackItem = getItemInHand(InteractionHand.MAIN_HAND); + Object itemStack = stackItem == null ? Reflections.instance$ItemStack$EMPTY : stackItem.getItem(); + Object blockPos = LocationUtils.toBlockPos(pos); + try { + Object blockInWorld = Reflections.constructor$BlockInWorld.newInstance(level().serverWorld(), blockPos, false); + 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 { @@ -439,10 +461,14 @@ public class BukkitServerPlayer extends Player { } if (this.miningProgress >= 1f) { + // TODO can_break component match if (isAdventureMode() && Config.simplyAdventureCheck()) { player.setGameMode(GameMode.SURVIVAL); - Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos); - player.setGameMode(GameMode.ADVENTURE); + try { + Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos); + } finally { + player.setGameMode(GameMode.ADVENTURE); + } } else { Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java b/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java index 55ce16f34..70b9853c5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java @@ -49,6 +49,8 @@ public abstract class Player extends Entity implements NetWorkUser { public abstract boolean isAdventureMode(); + public abstract boolean canBreak(BlockPos pos); + public abstract void sendActionBar(Component text); public abstract boolean updateLastSuccessfulInteractionTick(int tick);