9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-31 12:56:28 +00:00

优化冒险模式挖掘

This commit is contained in:
XiaoMoMi
2025-04-14 21:14:12 +08:00
parent b7e7c9990f
commit e2e8ef0f6a
11 changed files with 233 additions and 182 deletions

View File

@@ -105,6 +105,27 @@ public class BlockEventListener implements Listener {
ImmutableBlockState state = manager.getImmutableBlockStateUnsafe(stateId);
if (!state.isEmpty()) {
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;
}
}
// trigger event
CustomBlockBreakEvent customBreakEvent = new CustomBlockBreakEvent(event.getPlayer(), location, block, state);
@@ -131,7 +152,6 @@ public class BlockEventListener implements Listener {
return;
}
BukkitServerPlayer serverPlayer = this.plugin.adapt(player);
Item<ItemStack> itemInHand = serverPlayer.getItemInHand(InteractionHand.MAIN_HAND);
Key itemId = Optional.ofNullable(itemInHand).map(Item::id).orElse(ItemKeys.AIR);
// do not drop if it's not the correct tool

View File

@@ -76,22 +76,25 @@ public class BlockItemBehavior extends ItemBehavior {
return InteractionResult.FAIL;
}
Player player = placeContext.getPlayer();
int gameTicks = player.gameTicks();
if (!player.updateLastSuccessfulInteractionTick(gameTicks)) {
return InteractionResult.FAIL;
}
BlockPos pos = placeContext.getClickedPos();
BlockPos againstPos = placeContext.getAgainstPos();
World world = (World) placeContext.getLevel().platformWorld();
Location placeLocation = new Location(world, pos.x(), pos.y(), pos.z());
// todo adventure check
if (player.isAdventureMode()) {
}
int gameTicks = player.gameTicks();
if (!player.updateLastSuccessfulInteractionTick(gameTicks)) {
return InteractionResult.FAIL;
}
Block bukkitBlock = world.getBlockAt(placeLocation);
Block againstBlock = world.getBlockAt(againstPos.x(), againstPos.y(), againstPos.z());
org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) player.platformPlayer();
// todo adventure check
// trigger event
CustomBlockAttemptPlaceEvent attemptPlaceEvent = new CustomBlockAttemptPlaceEvent(bukkitPlayer, placeLocation.clone(), blockStateToPlace,
DirectionUtils.toBlockFace(context.getClickedFace()), bukkitBlock, context.getHand());

View File

@@ -1127,23 +1127,17 @@ public class PacketConsumers {
}
return;
}
if (player.isAdventureMode()) {
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
)) {
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
)) {
if (Reflections.method$ItemStack$canDestroy != null && !(boolean) Reflections.method$ItemStack$canDestroy.invoke(itemStack, Reflections.instance$BuiltInRegistries$BLOCK, blockInWorld)) {
player.preventMiningBlock();
return;
}

View File

@@ -16,6 +16,7 @@ import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.ItemKeys;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.plugin.network.ConnectionState;
import net.momirealms.craftengine.core.util.Direction;
import net.momirealms.craftengine.core.util.Key;
@@ -215,31 +216,6 @@ public class BukkitServerPlayer extends Player {
platformPlayer().closeInventory();
}
// TODO DO NOT USE BUKKIT API
@Override
public BlockHitResult rayTrace(double distance, FluidCollisionRule collisionRule) {
RayTraceResult result = platformPlayer().rayTraceBlocks(distance, FluidUtils.toCollisionRule(collisionRule));
if (result == null) {
Location eyeLocation = platformPlayer().getEyeLocation();
Location targetLocation = eyeLocation.clone();
targetLocation.add(eyeLocation.getDirection().multiply(distance));
return BlockHitResult.miss(new Vec3d(eyeLocation.getX(), eyeLocation.getY(), eyeLocation.getZ()),
Direction.getApproximateNearest(eyeLocation.getX() - targetLocation.getX(), eyeLocation.getY() - targetLocation.getY(), eyeLocation.getZ() - targetLocation.getZ()),
new BlockPos(targetLocation.getBlockX(), targetLocation.getBlockY(), targetLocation.getBlockZ())
);
} else {
Vector hitPos = result.getHitPosition();
Block hitBlock = result.getHitBlock();
Location hitBlockLocation = hitBlock.getLocation();
return new BlockHitResult(
new Vec3d(hitPos.getX(), hitPos.getY(), hitPos.getZ()),
DirectionUtils.toDirection(result.getHitBlockFace()),
new BlockPos(hitBlockLocation.getBlockX(), hitBlockLocation.getBlockY(), hitBlockLocation.getBlockZ()),
false
);
}
}
@Override
public void sendPacket(Object packet, boolean immediately) {
this.plugin.networkManager().sendPacket(this, packet, immediately);
@@ -463,8 +439,13 @@ public class BukkitServerPlayer extends Player {
}
if (this.miningProgress >= 1f) {
//Reflections.method$ServerLevel$levelEvent.invoke(Reflections.field$CraftWorld$ServerLevel.get(player.getWorld()), null, 2001, blockPos, BlockStateUtils.blockStateToId(this.destroyedState));
Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos);
if (isAdventureMode() && Config.simplyAdventureCheck()) {
player.setGameMode(GameMode.SURVIVAL);
Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos);
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();