9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-30 20:39:10 +00:00

优化一下canbreak方法

This commit is contained in:
XiaoMoMi
2025-04-14 22:41:49 +08:00
parent e2e8ef0f6a
commit f6f0927393
5 changed files with 38 additions and 35 deletions

View File

@@ -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

View File

@@ -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));

View File

@@ -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<ItemStack> 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);
}