From f1723df61604d7b608657fbec1eefa55abadad50 Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Wed, 17 Sep 2025 01:13:59 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix(sound):=20=E4=BF=AE=E5=A4=8D=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E6=B8=B8=E6=88=8F=E4=BA=8B=E4=BB=B6=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E7=9A=84=E6=96=B9=E5=9D=97=E7=A0=B4=E5=9D=8F=E9=9F=B3=E6=95=88?= =?UTF-8?q?=E8=A2=ABremap=E5=90=8E=E6=9C=AA=E8=A1=A5=E5=8C=85=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E6=97=A0=E5=A3=B0=E9=9F=B3=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/network/PacketConsumers.java | 23 +++++++++++++++++++ .../craftengine/core/util/RandomUtils.java | 4 ++++ gradle.properties | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) 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 21682150b..56260a14a 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 @@ -502,6 +502,29 @@ public class PacketConsumers { int state = buf.readInt(); boolean global = buf.readBoolean(); int newState = user.clientModEnabled() ? remapMOD(state) : remap(state); + Object blockState = BlockStateUtils.idToBlockState(newState); + Object block = BlockStateUtils.getBlockOwner(blockState); + if (BukkitBlockManager.instance().isBlockSoundRemoved(block) && !FastNMS.INSTANCE.method$BlockStateBase$isAir(blockState)) { + Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState); + Object breakSound = FastNMS.INSTANCE.field$SoundType$breakSound(soundType); + Key soundId = Key.of(FastNMS.INSTANCE.field$SoundEvent$location(breakSound).toString()); + Key mappedSoundId = BukkitBlockManager.instance().replaceSoundIfExist(soundId); + if (mappedSoundId != null) { + Object mappedBreakSound = FastNMS.INSTANCE.constructor$SoundEvent(KeyUtils.toResourceLocation(mappedSoundId), Optional.empty()); + Object mappedBreakSoundHolder = FastNMS.INSTANCE.method$Holder$direct(mappedBreakSound); + Object packet = FastNMS.INSTANCE.constructor$ClientboundSoundPacket( + mappedBreakSoundHolder, + CoreReflections.instance$SoundSource$BLOCKS, + blockPos.x() + 0.5, + blockPos.y() + 0.5, + blockPos.z() + 0.5, + (FastNMS.INSTANCE.field$SoundType$volume(soundType) + 1.0F) / 2.0F, + FastNMS.INSTANCE.field$SoundType$pitch(soundType) * 0.8F, + RandomUtils.generateRandomLong() + ); + user.sendPacket(packet, true); + } + } if (newState == state) { return; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/RandomUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/RandomUtils.java index b659d4c28..7904d1776 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/RandomUtils.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/RandomUtils.java @@ -22,6 +22,10 @@ public final class RandomUtils { return ThreadLocalRandom.current().nextBoolean(); } + public static long generateRandomLong() { + return ThreadLocalRandom.current().nextLong(); + } + public static double triangle(double mode, double deviation) { return mode + deviation * (generateRandomDouble(0,1) - generateRandomDouble(0,1)); } diff --git a/gradle.properties b/gradle.properties index c40afd9f7..873f9bbbc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -50,7 +50,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.5 anti_grief_version=0.20 -nms_helper_version=1.0.89 +nms_helper_version=1.0.90 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.33.1 From 5b1c12a3ae13f157015a6d1f4ff0f7631bbb767f Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Wed, 17 Sep 2025 01:47:30 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix(sound):=20=E4=BF=AE=E6=AD=A3=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E5=86=99=E6=B3=95=E4=B8=8D=E9=87=8D=E5=A4=8D=E5=8F=91?= =?UTF-8?q?=E5=A3=B0=E9=9F=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/api/CraftEngineBlocks.java | 32 ++++++++++++++----- .../AbstractCanSurviveBlockBehavior.java | 8 ++--- .../behavior/DoubleHighBlockBehavior.java | 8 ++--- .../behavior/PressurePlateBlockBehavior.java | 8 ++--- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java index 93ec4c025..88fa7042b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java @@ -188,16 +188,14 @@ public final class CraftEngineBlocks { * @param player player who breaks the block * @param dropLoot whether to drop block loots * @param isMoving is moving - * @param playSound whether to play break sounds - * @param sendParticles whether to send break particles + * @param sendLevelEvent whether to send break particles and sounds * @return success or not */ public static boolean remove(@NotNull Block block, @Nullable Player player, boolean isMoving, boolean dropLoot, - boolean playSound, - boolean sendParticles) { + boolean sendLevelEvent) { ImmutableBlockState state = getCustomBlockState(block); if (state == null || state.isEmpty()) return false; World world = new BukkitWorld(block.getWorld()); @@ -215,16 +213,34 @@ public final class CraftEngineBlocks { world.dropItemNaturally(position, item); } } - if (playSound) { - world.playBlockSound(position, state.settings().sounds().breakSound()); - } - if (sendParticles) { + if (sendLevelEvent) { FastNMS.INSTANCE.method$LevelAccessor$levelEvent(world.serverWorld(), WorldEvents.BLOCK_BREAK_EFFECT, LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), state.customBlockState().registryId()); } FastNMS.INSTANCE.method$Level$removeBlock(world.serverWorld(), LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), isMoving); return true; } + /** + * Removes a block from the world if it's custom + * + * @param block block to remove + * @param player player who breaks the block + * @param dropLoot whether to drop block loots + * @param isMoving is moving + * @param playSound whether to play break sounds + * @param sendParticles whether to send break particles + * @return success or not + */ + @Deprecated + public static boolean remove(@NotNull Block block, + @Nullable Player player, + boolean isMoving, + boolean dropLoot, + boolean playSound, + boolean sendParticles) { + return remove(block, player, dropLoot, isMoving, playSound || sendParticles); + } + /** * Checks if a block is custom * diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java index 2ab895fe7..6e2ef1443 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java @@ -70,11 +70,11 @@ public abstract class AbstractCanSurviveBlockBehavior extends BukkitBlockBehavio return state; } if (!canSurvive(thisBlock, new Object[] {state, level, blockPos}, () -> true)) { - BlockPos pos = LocationUtils.fromBlockPos(blockPos); + // BlockPos pos = LocationUtils.fromBlockPos(blockPos); ImmutableBlockState customState = optionalCustomState.get(); - net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level)); - WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(pos)); - world.playBlockSound(position, customState.settings().sounds().breakSound()); + // net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level)); + // WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(pos)); + // world.playBlockSound(position, customState.settings().sounds().breakSound()); // 下面触发事件也会有声音 FastNMS.INSTANCE.method$LevelAccessor$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, customState.customBlockState().registryId()); return MBlocks.AIR$defaultState; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DoubleHighBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DoubleHighBlockBehavior.java index 14305b479..7cac0ad6d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DoubleHighBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DoubleHighBlockBehavior.java @@ -50,10 +50,10 @@ public class DoubleHighBlockBehavior extends BukkitBlockBehavior { if (anotherHalfCustomState != null && !anotherHalfCustomState.isEmpty()) return blockState; // 破坏 - BlockPos pos = LocationUtils.fromBlockPos(blockPos); - net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level)); - WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(pos)); - world.playBlockSound(position, customState.settings().sounds().breakSound()); + // BlockPos pos = LocationUtils.fromBlockPos(blockPos); + // net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level)); + // WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(pos)); + // world.playBlockSound(position, customState.settings().sounds().breakSound()); // 下面触发事件也会有声音 FastNMS.INSTANCE.method$LevelAccessor$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, customState.customBlockState().registryId()); return MBlocks.AIR$defaultState; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/PressurePlateBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/PressurePlateBlockBehavior.java index da6eb9d78..3d807c87c 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/PressurePlateBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/PressurePlateBlockBehavior.java @@ -66,10 +66,10 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { return MBlocks.AIR$defaultState; } ImmutableBlockState customState = optionalCustomState.get(); - BlockPos pos = LocationUtils.fromBlockPos(blockPos); - net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level)); - WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(pos)); - world.playBlockSound(position, customState.settings().sounds().breakSound()); + // BlockPos pos = LocationUtils.fromBlockPos(blockPos); + // net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level)); + // WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(pos)); + // world.playBlockSound(position, customState.settings().sounds().breakSound()); // 下面触发事件也会有声音 FastNMS.INSTANCE.method$LevelAccessor$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, customState.customBlockState().registryId()); return MBlocks.AIR$defaultState; } From 7d3029c193f726e13f7d3136b28646fbca150311 Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Wed, 17 Sep 2025 18:43:56 +0800 Subject: [PATCH 3/3] =?UTF-8?q?refactor(bukkit):=20=E6=B8=85=E7=90=86?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/api/CraftEngineBlocks.java | 2 +- .../behavior/AbstractCanSurviveBlockBehavior.java | 10 ++-------- .../bukkit/block/behavior/DoubleHighBlockBehavior.java | 4 ---- .../block/behavior/PressurePlateBlockBehavior.java | 4 ---- 4 files changed, 3 insertions(+), 17 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java index 88fa7042b..3fb08edd3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java @@ -231,7 +231,7 @@ public final class CraftEngineBlocks { * @param sendParticles whether to send break particles * @return success or not */ - @Deprecated + @Deprecated(forRemoval = true) public static boolean remove(@NotNull Block block, @Nullable Player player, boolean isMoving, diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java index 6e2ef1443..851371fa6 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java @@ -7,7 +7,6 @@ import net.momirealms.craftengine.bukkit.util.LocationUtils; import net.momirealms.craftengine.bukkit.world.BukkitWorld; import net.momirealms.craftengine.core.block.CustomBlock; import net.momirealms.craftengine.core.block.ImmutableBlockState; -import net.momirealms.craftengine.core.world.BlockPos; import net.momirealms.craftengine.core.world.Vec3d; import net.momirealms.craftengine.core.world.WorldEvents; import net.momirealms.craftengine.core.world.WorldPosition; @@ -69,13 +68,8 @@ public abstract class AbstractCanSurviveBlockBehavior extends BukkitBlockBehavio FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(level, blockPos, thisBlock, this.delay); return state; } - if (!canSurvive(thisBlock, new Object[] {state, level, blockPos}, () -> true)) { - // BlockPos pos = LocationUtils.fromBlockPos(blockPos); - ImmutableBlockState customState = optionalCustomState.get(); - // net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level)); - // WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(pos)); - // world.playBlockSound(position, customState.settings().sounds().breakSound()); // 下面触发事件也会有声音 - FastNMS.INSTANCE.method$LevelAccessor$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, customState.customBlockState().registryId()); + if (!FastNMS.INSTANCE.method$BlockStateBase$canSurvive(state, level, blockPos)) { + FastNMS.INSTANCE.method$LevelAccessor$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, optionalCustomState.get().customBlockState().registryId()); return MBlocks.AIR$defaultState; } return state; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DoubleHighBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DoubleHighBlockBehavior.java index 7cac0ad6d..7845bddd2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DoubleHighBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/DoubleHighBlockBehavior.java @@ -50,10 +50,6 @@ public class DoubleHighBlockBehavior extends BukkitBlockBehavior { if (anotherHalfCustomState != null && !anotherHalfCustomState.isEmpty()) return blockState; // 破坏 - // BlockPos pos = LocationUtils.fromBlockPos(blockPos); - // net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level)); - // WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(pos)); - // world.playBlockSound(position, customState.settings().sounds().breakSound()); // 下面触发事件也会有声音 FastNMS.INSTANCE.method$LevelAccessor$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, customState.customBlockState().registryId()); return MBlocks.AIR$defaultState; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/PressurePlateBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/PressurePlateBlockBehavior.java index 3d807c87c..16f852fd2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/PressurePlateBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/PressurePlateBlockBehavior.java @@ -66,10 +66,6 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior { return MBlocks.AIR$defaultState; } ImmutableBlockState customState = optionalCustomState.get(); - // BlockPos pos = LocationUtils.fromBlockPos(blockPos); - // net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level)); - // WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(pos)); - // world.playBlockSound(position, customState.settings().sounds().breakSound()); // 下面触发事件也会有声音 FastNMS.INSTANCE.method$LevelAccessor$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, customState.customBlockState().registryId()); return MBlocks.AIR$defaultState; }