9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-26 02:19:23 +00:00

进一步优化简化判断

This commit is contained in:
XiaoMoMi
2025-04-14 23:54:36 +08:00
parent e33a63d19e
commit 2694c521a0
3 changed files with 69 additions and 30 deletions

View File

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

View File

@@ -159,6 +159,29 @@ public class BukkitServerPlayer extends Player {
return true;
}
public boolean canBreak(BlockPos pos, Object state) {
Item<ItemStack> 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) {

View File

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