From 3c35fd303f6b3ba8d38d67a6a93d1a459720c41e Mon Sep 17 00:00:00 2001 From: Ethan <68365423+letsgoawaydev@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:50:19 +0800 Subject: [PATCH] Fix toggleable block opening sounds (doors, trapdoors, fence gates) (#4815) * Initial Commit * Fix minor copy and paste comment mistake * Remove debug log Co-authored-by: chris * Remove iron check on fence gate sound translator iron fence gates dont exist lol * Remove iron check from fence gate sound translator. Iron fence gates dont exist (yet) * Remove unnecessary curly braces * Rewrite the code, now functioning correctly with the runtime id * Update mappings * Better formatting Co-authored-by: chris * fix comment because it is referring to code that has been changed * Hopefully fix double closing * Seems like the double closing issue isnt from my code and from somewhere else * Fix issue where doors would update twice when opening/closing them using the upper half * change weird variable name --------- Co-authored-by: chris --- .../geyser/level/block/type/DoorBlock.java | 15 +++++++- .../java/level/JavaBlockUpdateTranslator.java | 4 +-- .../BlockSoundInteractionTranslator.java | 12 +++---- .../BucketSoundInteractionTranslator.java | 4 ++- .../ComparatorSoundInteractionTranslator.java | 4 ++- .../FlintAndSteelInteractionTranslator.java | 3 +- .../block/GrassPathInteractionTranslator.java | 4 ++- .../sound/block/HoeInteractionTranslator.java | 4 ++- .../LeverSoundInteractionTranslator.java | 4 ++- ...> OpenableSoundInteractionTranslator.java} | 35 +++++++++++++++---- .../org/geysermc/geyser/util/SoundUtils.java | 4 +-- 11 files changed, 69 insertions(+), 24 deletions(-) rename core/src/main/java/org/geysermc/geyser/translator/sound/block/{DoorSoundInteractionTranslator.java => OpenableSoundInteractionTranslator.java} (55%) diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/DoorBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/DoorBlock.java index bfde51a79..2efbdb523 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/DoorBlock.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/DoorBlock.java @@ -37,9 +37,22 @@ public class DoorBlock extends Block { @Override public void updateBlock(GeyserSession session, BlockState state, Vector3i position) { + // Needed to check whether we must force the client to update the door state. + String doubleBlockHalf = state.getValue(Properties.DOUBLE_BLOCK_HALF); + + if (doubleBlockHalf.equals("lower")) { + BlockState oldBlockState = session.getGeyser().getWorldManager().blockAt(session, position); + // If these are the same, it means that we already updated the lower door block (manually in the workaround below), + // and we do not need to update the block in the cache/on the client side using the super.updateBlock() method again. + // Otherwise, we send the door updates twice which will cause visual glitches on the client side + if (oldBlockState == state) { + return; + } + } + super.updateBlock(session, state, position); - if (state.getValue(Properties.DOUBLE_BLOCK_HALF).equals("upper")) { + if (doubleBlockHalf.equals("upper")) { // Update the lower door block as Bedrock client doesn't like door to be closed from the top // See https://github.com/GeyserMC/Geyser/issues/4358 Vector3i belowDoorPosition = position.sub(0, 1, 0); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockUpdateTranslator.java index 74b961996..d89775662 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockUpdateTranslator.java @@ -100,8 +100,8 @@ public class JavaBlockUpdateTranslator extends PacketTranslator { - +public interface BlockSoundInteractionTranslator extends SoundInteractionTranslator { /** * Handles the block interaction when a player * right-clicks a block. * * @param session the session interacting with the block * @param position the position of the block - * @param identifier the identifier of the block + * @param state the state of the block */ - static void handleBlockInteraction(GeyserSession session, Vector3f position, String identifier) { + static void handleBlockInteraction(GeyserSession session, Vector3f position, BlockState state) { // If we need to get the hand identifier, only get it once and save it to a variable String handIdentifier = null; @@ -58,7 +58,7 @@ public interface BlockSoundInteractionTranslator extends SoundInteractionTransla if (interactionEntry.getKey().blocks().length != 0) { boolean contains = false; for (String blockIdentifier : interactionEntry.getKey().blocks()) { - if (identifier.contains(blockIdentifier)) { + if (state.toString().contains(blockIdentifier)) { contains = true; break; } @@ -87,7 +87,7 @@ public interface BlockSoundInteractionTranslator extends SoundInteractionTransla continue; } } - ((BlockSoundInteractionTranslator) interactionEntry.getValue()).translate(session, position, identifier); + ((BlockSoundInteractionTranslator) interactionEntry.getValue()).translate(session, position, state); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/sound/block/BucketSoundInteractionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/sound/block/BucketSoundInteractionTranslator.java index 7a5e86af7..45800e1ab 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/sound/block/BucketSoundInteractionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/sound/block/BucketSoundInteractionTranslator.java @@ -29,6 +29,7 @@ import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; import org.geysermc.geyser.inventory.GeyserItemStack; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator; import org.geysermc.geyser.translator.sound.SoundTranslator; @@ -37,7 +38,8 @@ import org.geysermc.geyser.translator.sound.SoundTranslator; public class BucketSoundInteractionTranslator implements BlockSoundInteractionTranslator { @Override - public void translate(GeyserSession session, Vector3f position, String identifier) { + public void translate(GeyserSession session, Vector3f position, BlockState state) { + String identifier = state.toString(); if (!session.isPlacedBucket()) { return; // No bucket was really interacted with } diff --git a/core/src/main/java/org/geysermc/geyser/translator/sound/block/ComparatorSoundInteractionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/sound/block/ComparatorSoundInteractionTranslator.java index e77539e6e..9d5d3cd59 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/sound/block/ComparatorSoundInteractionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/sound/block/ComparatorSoundInteractionTranslator.java @@ -28,6 +28,7 @@ package org.geysermc.geyser.translator.sound.block; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator; import org.geysermc.geyser.translator.sound.SoundTranslator; @@ -36,7 +37,8 @@ import org.geysermc.geyser.translator.sound.SoundTranslator; public class ComparatorSoundInteractionTranslator implements BlockSoundInteractionTranslator { @Override - public void translate(GeyserSession session, Vector3f position, String identifier) { + public void translate(GeyserSession session, Vector3f position, BlockState state) { + String identifier = state.toString(); boolean powered = identifier.contains("mode=compare"); LevelEventPacket levelEventPacket = new LevelEventPacket(); levelEventPacket.setPosition(position); diff --git a/core/src/main/java/org/geysermc/geyser/translator/sound/block/FlintAndSteelInteractionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/sound/block/FlintAndSteelInteractionTranslator.java index a822f3520..e8225a336 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/sound/block/FlintAndSteelInteractionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/sound/block/FlintAndSteelInteractionTranslator.java @@ -28,6 +28,7 @@ package org.geysermc.geyser.translator.sound.block; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator; import org.geysermc.geyser.translator.sound.SoundTranslator; @@ -36,7 +37,7 @@ import org.geysermc.geyser.translator.sound.SoundTranslator; public class FlintAndSteelInteractionTranslator implements BlockSoundInteractionTranslator { @Override - public void translate(GeyserSession session, Vector3f position, String identifier) { + public void translate(GeyserSession session, Vector3f position, BlockState state) { LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket(); levelSoundEventPacket.setPosition(position); levelSoundEventPacket.setBabySound(false); diff --git a/core/src/main/java/org/geysermc/geyser/translator/sound/block/GrassPathInteractionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/sound/block/GrassPathInteractionTranslator.java index 0a91f8896..a25beaa50 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/sound/block/GrassPathInteractionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/sound/block/GrassPathInteractionTranslator.java @@ -28,6 +28,7 @@ package org.geysermc.geyser.translator.sound.block; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator; @@ -37,7 +38,8 @@ import org.geysermc.geyser.translator.sound.SoundTranslator; public class GrassPathInteractionTranslator implements BlockSoundInteractionTranslator { @Override - public void translate(GeyserSession session, Vector3f position, String identifier) { + public void translate(GeyserSession session, Vector3f position, BlockState state) { + String identifier = state.toString(); LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket(); levelSoundEventPacket.setPosition(position); levelSoundEventPacket.setBabySound(false); diff --git a/core/src/main/java/org/geysermc/geyser/translator/sound/block/HoeInteractionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/sound/block/HoeInteractionTranslator.java index 410422b4a..1a583ab8a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/sound/block/HoeInteractionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/sound/block/HoeInteractionTranslator.java @@ -28,6 +28,7 @@ package org.geysermc.geyser.translator.sound.block; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator; @@ -37,7 +38,8 @@ import org.geysermc.geyser.translator.sound.SoundTranslator; public class HoeInteractionTranslator implements BlockSoundInteractionTranslator { @Override - public void translate(GeyserSession session, Vector3f position, String identifier) { + public void translate(GeyserSession session, Vector3f position, BlockState state) { + String identifier = state.toString(); LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket(); levelSoundEventPacket.setPosition(position); levelSoundEventPacket.setBabySound(false); diff --git a/core/src/main/java/org/geysermc/geyser/translator/sound/block/LeverSoundInteractionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/sound/block/LeverSoundInteractionTranslator.java index 17b8768bc..fd045739c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/sound/block/LeverSoundInteractionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/sound/block/LeverSoundInteractionTranslator.java @@ -28,6 +28,7 @@ package org.geysermc.geyser.translator.sound.block; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator; import org.geysermc.geyser.translator.sound.SoundTranslator; @@ -36,7 +37,8 @@ import org.geysermc.geyser.translator.sound.SoundTranslator; public class LeverSoundInteractionTranslator implements BlockSoundInteractionTranslator { @Override - public void translate(GeyserSession session, Vector3f position, String identifier) { + public void translate(GeyserSession session, Vector3f position, BlockState state) { + String identifier = state.toString(); boolean powered = identifier.contains("powered=true"); LevelEventPacket levelEventPacket = new LevelEventPacket(); levelEventPacket.setPosition(position); diff --git a/core/src/main/java/org/geysermc/geyser/translator/sound/block/DoorSoundInteractionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/sound/block/OpenableSoundInteractionTranslator.java similarity index 55% rename from core/src/main/java/org/geysermc/geyser/translator/sound/block/DoorSoundInteractionTranslator.java rename to core/src/main/java/org/geysermc/geyser/translator/sound/block/OpenableSoundInteractionTranslator.java index 8f8ab8bf6..93d55ca33 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/sound/block/DoorSoundInteractionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/sound/block/OpenableSoundInteractionTranslator.java @@ -27,21 +27,42 @@ package org.geysermc.geyser.translator.sound.block; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; +import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; +import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator; import org.geysermc.geyser.translator.sound.SoundTranslator; @SoundTranslator(blocks = {"door", "fence_gate"}) -public class DoorSoundInteractionTranslator implements BlockSoundInteractionTranslator { +public class OpenableSoundInteractionTranslator implements BlockSoundInteractionTranslator { @Override - public void translate(GeyserSession session, Vector3f position, String identifier) { + public void translate(GeyserSession session, Vector3f position, BlockState state) { + String identifier = state.toString(); if (identifier.contains("iron")) return; - LevelEventPacket levelEventPacket = new LevelEventPacket(); - levelEventPacket.setType(LevelEvent.SOUND_DOOR_OPEN); - levelEventPacket.setPosition(position); - levelEventPacket.setData(0); - session.sendUpstreamPacket(levelEventPacket); + SoundEvent event = getSound(identifier.contains("open=true"), identifier); + LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket(); + levelSoundEventPacket.setPosition(position.add(0.5, 0.5, 0.5)); + levelSoundEventPacket.setBabySound(false); + levelSoundEventPacket.setRelativeVolumeDisabled(false); + levelSoundEventPacket.setIdentifier(":"); + levelSoundEventPacket.setSound(event); + levelSoundEventPacket.setExtraData(session.getBlockMappings().getBedrockBlock(state).getRuntimeId()); + session.sendUpstreamPacket(levelSoundEventPacket); + } + + private SoundEvent getSound(boolean open, String identifier) { + if (identifier.contains("_door")) { + return open ? SoundEvent.DOOR_OPEN : SoundEvent.DOOR_CLOSE; + } + + if (identifier.contains("_trapdoor")) { + return open ? SoundEvent.TRAPDOOR_OPEN : SoundEvent.TRAPDOOR_CLOSE; + } + + // Fence Gate + return open ? SoundEvent.FENCE_GATE_OPEN : SoundEvent.FENCE_GATE_CLOSE; } } diff --git a/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java b/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java index 524d241db..693ce136a 100644 --- a/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java @@ -133,7 +133,7 @@ public final class SoundUtils { } if (sound == null) { session.getGeyser().getLogger().debug("[Builtin] Sound for original '" + soundIdentifier + "' to mappings '" + soundMapping.getBedrock() - + "' was not a playable level sound, or has yet to be mapped to an enum in SoundEvent."); + + "' was not a playable level sound, or has yet to be mapped to an enum in SoundEvent."); return; } @@ -144,7 +144,7 @@ public final class SoundUtils { // Minecraft Wiki: 2^(x/12) = Java pitch where x is -12 to 12 // Java sends the note value as above starting with -12 and ending at 12 // Bedrock has a number for each type of note, then proceeds up the scale by adding to that number - soundPacket.setExtraData(soundMapping.getExtraData() + (int)(Math.round((Math.log10(pitch) / Math.log10(2)) * 12)) + 12); + soundPacket.setExtraData(soundMapping.getExtraData() + (int) (Math.round((Math.log10(pitch) / Math.log10(2)) * 12)) + 12); } else if (sound == SoundEvent.PLACE && soundMapping.getExtraData() == -1) { if (!soundMapping.getIdentifier().equals(":")) { int javaId = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getOrDefault(soundMapping.getIdentifier(), Block.JAVA_AIR_ID);