From 785121026435ab36d99aec2f53550c09a64a94c0 Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 2 Jul 2024 17:49:54 +0800 Subject: [PATCH] Initial Commit --- .../block/DoorSoundInteractionTranslator.java | 36 +++++++--- .../FenceGateSoundInteractionTranslator.java | 67 +++++++++++++++++++ .../org/geysermc/geyser/util/SoundUtils.java | 29 +++++--- core/src/main/resources/mappings | 2 +- 4 files changed, 115 insertions(+), 19 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/translator/sound/block/FenceGateSoundInteractionTranslator.java 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/DoorSoundInteractionTranslator.java index 8f8ab8bf6..2349dbc35 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/DoorSoundInteractionTranslator.java @@ -26,22 +26,40 @@ 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.session.GeyserSession; import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator; import org.geysermc.geyser.translator.sound.SoundTranslator; +import org.geysermc.geyser.util.SoundUtils; -@SoundTranslator(blocks = {"door", "fence_gate"}) +@SoundTranslator(blocks = {"door"}) public class DoorSoundInteractionTranslator implements BlockSoundInteractionTranslator { - @Override public void translate(GeyserSession session, Vector3f position, String identifier) { if (identifier.contains("iron")) return; - LevelEventPacket levelEventPacket = new LevelEventPacket(); - levelEventPacket.setType(LevelEvent.SOUND_DOOR_OPEN); - levelEventPacket.setPosition(position); - levelEventPacket.setData(0); - session.sendUpstreamPacket(levelEventPacket); + boolean open = identifier.contains("open=true"); + boolean trapdoor = identifier.contains("_trapdoor"); + String materialIdentifier = getMaterialIdentifier(identifier); + float volume = 1.0f; + // Sounds are quieter for wooden trapdoors and bamboo wood doors + if ((trapdoor && materialIdentifier.equals("block.wooden")) || (!trapdoor && materialIdentifier.equals("block.bamboo_wood"))) { + volume = 0.9f; + } + String doorType = trapdoor ? "_trapdoor" : "_door"; + String status = open ? ".open" : ".close"; + SoundUtils.playSound(session, "minecraft:" + materialIdentifier + doorType + status, position, volume, 1.0f); + } + + private static String getMaterialIdentifier(String identifier) { + String type = "block.wooden"; + if (identifier.contains("copper_")) { + type = "block.copper"; + } else if (identifier.contains("bamboo_")) { + type = "block.bamboo_wood"; + } else if (identifier.contains("cherry_")) { + type = "block.cherry_wood"; + } else if (identifier.contains("crimson_") || identifier.contains("warped_")) { + type = "block.nether_wood"; + } + return type; } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/sound/block/FenceGateSoundInteractionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/sound/block/FenceGateSoundInteractionTranslator.java new file mode 100644 index 000000000..63b8c4aab --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/sound/block/FenceGateSoundInteractionTranslator.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.translator.sound.block; + +import org.cloudburstmc.math.vector.Vector3f; +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.sound.BlockSoundInteractionTranslator; +import org.geysermc.geyser.translator.sound.SoundTranslator; +import org.geysermc.geyser.util.SoundUtils; + +@SoundTranslator(blocks = {"fence_gate"}) +public class FenceGateSoundInteractionTranslator implements BlockSoundInteractionTranslator { + @Override + public void translate(GeyserSession session, Vector3f position, String identifier) { + if (identifier.contains("iron")) return; + GeyserImpl.getInstance().getLogger().info(identifier); + boolean open = identifier.contains("open=true"); + String materialIdentifier = getMaterialIdentifier(identifier); + float volume = 1.0f; + float pitch = 1.0f; + // Sounds are quieter for wooden trapdoors and bamboo wood doors + if (materialIdentifier.equals("block.") || materialIdentifier.equals("block.bamboo_wood_")) { + volume = 0.9f; + } + if (materialIdentifier.equals("block.bamboo_wood_")) { + pitch = 1.1f; + } + String status = open ? "fence_gate.open" : "fence_gate.close"; + SoundUtils.playSound(session, "minecraft:" + materialIdentifier + status, position, volume, pitch); + } + + private static String getMaterialIdentifier(String identifier) { + String type = "block."; + if (identifier.contains("bamboo_")) { + type = "block.bamboo_wood_"; + } else if (identifier.contains("cherry_")) { + type = "block.cherry_wood_"; + } else if (identifier.contains("crimson_") || identifier.contains("warped_")) { + type = "block.nether_wood_"; + } + return type; + } +} 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..b74abc5c1 100644 --- a/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java @@ -84,9 +84,9 @@ public final class SoundUtils { return identifier; } - private static void playSound(GeyserSession session, String bedrockName, Vector3f position, float volume, float pitch) { + private static void sendPlaySoundPacket(GeyserSession session, String bedrockIdentifier, Vector3f position, float volume, float pitch) { PlaySoundPacket playSoundPacket = new PlaySoundPacket(); - playSoundPacket.setSound(bedrockName); + playSoundPacket.setSound(bedrockIdentifier); playSoundPacket.setPosition(position); playSoundPacket.setVolume(volume); playSoundPacket.setPitch(pitch); @@ -96,24 +96,35 @@ public final class SoundUtils { /** * Translates and plays a Java Builtin Sound for a Bedrock client * - * @param session the Bedrock client session. + * @param session the Bedrock client session. * @param javaSound the builtin sound to play - * @param position the position - * @param pitch the pitch + * @param position the position + * @param pitch the pitch */ public static void playSound(GeyserSession session, Sound javaSound, Vector3f position, float volume, float pitch) { - String soundIdentifier = removeMinecraftNamespace(javaSound.getName()); + playSound(session, javaSound.getName(), position, volume, pitch); + } + /** + * Translates and plays a Java Builtin Sound by identifier for a Bedrock client + * + * @param session the Bedrock client session. + * @param soundIdentifier the sound identifier to play + * @param position the position + * @param pitch the pitch + */ + public static void playSound(GeyserSession session, String soundIdentifier, Vector3f position, float volume, float pitch) { + soundIdentifier = removeMinecraftNamespace(soundIdentifier); SoundMapping soundMapping = Registries.SOUNDS.get(soundIdentifier); if (soundMapping == null) { session.getGeyser().getLogger().debug("[Builtin] Sound mapping for " + soundIdentifier + " not found; assuming custom."); - playSound(session, soundIdentifier, position, volume, pitch); + sendPlaySoundPacket(session, soundIdentifier, position, volume, pitch); return; } if (soundMapping.getPlaysound() != null) { // We always prefer the PlaySound mapping because we can control volume and pitch - playSound(session, soundMapping.getPlaysound(), position, volume, pitch); + sendPlaySoundPacket(session, soundMapping.getPlaysound(), position, volume, pitch); return; } @@ -144,7 +155,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); diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 23cb22f9c..014914f30 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 23cb22f9ceeb7f24b896a69a711944d7f3e756ed +Subproject commit 014914f30b9838e69330abe25f108db5744d6161