From 3e6855aa9e7418b00d2b72bb9de819a6d8ee5f73 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 1 Aug 2025 01:57:36 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8D=E7=A8=B3=E5=AE=9A=E5=A3=B0=E9=9F=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/sound/BukkitSoundManager.java | 42 ++++++++++++++++--- .../core/sound/AbstractSoundManager.java | 5 +++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/sound/BukkitSoundManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/sound/BukkitSoundManager.java index dce7ca633..099653115 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/sound/BukkitSoundManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/sound/BukkitSoundManager.java @@ -7,11 +7,13 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries import net.momirealms.craftengine.bukkit.util.ComponentUtils; import net.momirealms.craftengine.bukkit.util.KeyUtils; import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.sound.AbstractSoundManager; import net.momirealms.craftengine.core.sound.JukeboxSong; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.VersionHelper; +import java.util.Collection; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -26,6 +28,37 @@ public class BukkitSoundManager extends AbstractSoundManager { } } + @Override + protected void registerSounds(Collection sounds) { + if (sounds.isEmpty()) return; + Object registry = MBuiltInRegistries.SOUND_EVENT; + try { + CoreReflections.field$MappedRegistry$frozen.set(registry, false); + for (Key soundEventId : sounds) { + Object resourceLocation = KeyUtils.toResourceLocation(soundEventId); + // 检查之前有没有注册过了 + Object soundEvent = FastNMS.INSTANCE.method$Registry$getValue(registry, resourceLocation); + // 只有没注册才注册,否则会报错 + if (soundEvent == null) { + soundEvent = VersionHelper.isOrAbove1_21_2() ? + CoreReflections.constructor$SoundEvent.newInstance(resourceLocation, Optional.of(0)) : + CoreReflections.constructor$SoundEvent.newInstance(resourceLocation, 0, false); + Object holder = CoreReflections.method$Registry$registerForHolder.invoke(null, registry, resourceLocation, soundEvent); + CoreReflections.method$Holder$Reference$bindValue.invoke(holder, soundEvent); + CoreReflections.field$Holder$Reference$tags.set(holder, Set.of()); + int id = FastNMS.INSTANCE.method$Registry$getId(registry, soundEvent); + super.customSoundsInRegistry.put(id, soundEventId); + } + } + } catch (Exception e) { + this.plugin.logger().warn("Failed to register jukebox songs.", e); + } finally { + try { + CoreReflections.field$MappedRegistry$frozen.set(registry, true); + } catch (ReflectiveOperationException ignored) {} + } + } + @Override protected void registerSongs(Map songs) { if (songs.isEmpty()) return; @@ -40,13 +73,12 @@ public class BukkitSoundManager extends AbstractSoundManager { Object soundId = KeyUtils.toResourceLocation(jukeboxSong.sound()); // 检查之前有没有注册过了 Object song = FastNMS.INSTANCE.method$Registry$getValue(registry, resourceLocation); - - Object soundEvent = VersionHelper.isOrAbove1_21_2() ? - CoreReflections.constructor$SoundEvent.newInstance(soundId, Optional.of(jukeboxSong.range())) : - CoreReflections.constructor$SoundEvent.newInstance(soundId, jukeboxSong.range(), false); - Object soundHolder = CoreReflections.method$Holder$direct.invoke(null, soundEvent); // 只有没注册才注册,否则会报错 if (song == null) { + Object soundEvent = VersionHelper.isOrAbove1_21_2() ? + CoreReflections.constructor$SoundEvent.newInstance(soundId, Optional.of(jukeboxSong.range())) : + CoreReflections.constructor$SoundEvent.newInstance(soundId, jukeboxSong.range(), false); + Object soundHolder = CoreReflections.method$Holder$direct.invoke(null, soundEvent); song = CoreReflections.constructor$JukeboxSong.newInstance(soundHolder, ComponentUtils.adventureToMinecraft(jukeboxSong.description()), jukeboxSong.lengthInSeconds(), jukeboxSong.comparatorOutput()); Object holder = CoreReflections.method$Registry$registerForHolder.invoke(null, registry, resourceLocation, song); CoreReflections.method$Holder$Reference$bindValue.invoke(holder, song); diff --git a/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java b/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java index eaa7df2ba..a0892da26 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java @@ -19,6 +19,7 @@ public abstract class AbstractSoundManager implements SoundManager { protected final Map songs = new HashMap<>(); protected final SoundParser soundParser; protected final SongParser songParser; + protected final Map customSoundsInRegistry = new HashMap<>(); public AbstractSoundManager(CraftEngine plugin) { this.plugin = plugin; @@ -46,6 +47,8 @@ public abstract class AbstractSoundManager implements SoundManager { @Override public void runDelayedSyncTasks() { if (!VersionHelper.isOrAbove1_21()) return; + // 问题是会踢客户端 + // this.registerSounds(this.byId.keySet()); this.registerSongs(this.songs); } @@ -60,6 +63,8 @@ public abstract class AbstractSoundManager implements SoundManager { protected abstract void registerSongs(Map songs); + protected abstract void registerSounds(Collection sounds); + public class SongParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] {"jukebox_songs", "jukebox_song", "jukebox-songs", "jukebox-song"};