diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java index ba6a5eae95..e23daadeca 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -19,6 +19,7 @@ import org.bukkit.MusicInstrument; import org.bukkit.NamespacedKey; import org.bukkit.Particle; import org.bukkit.Registry; +import org.bukkit.Sound; import org.bukkit.attribute.Attribute; import org.bukkit.block.Biome; import org.bukkit.block.BlockType; @@ -158,6 +159,9 @@ public class CraftRegistry implements Registry { if (bukkitClass == PotionEffectType.class) { return new CraftRegistry<>(PotionEffectType.class, registryHolder.lookupOrThrow(Registries.MOB_EFFECT), CraftPotionEffectType::new, FieldRename.NONE); } + if (bukkitClass == Sound.class) { + return new CraftRegistry<>(Sound.class, registryHolder.lookupOrThrow(Registries.SOUND_EVENT), CraftSound::new, FieldRename.NONE); + } if (bukkitClass == Structure.class) { return new CraftRegistry<>(Structure.class, registryHolder.lookupOrThrow(Registries.STRUCTURE), CraftStructure::new, FieldRename.NONE); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftSound.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftSound.java index db0d2acc68..7a37ec850a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftSound.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftSound.java @@ -1,32 +1,27 @@ package org.bukkit.craftbukkit; import com.google.common.base.Preconditions; +import java.util.Locale; import net.minecraft.core.Holder; import net.minecraft.core.IRegistry; import net.minecraft.core.registries.Registries; import net.minecraft.sounds.SoundEffect; +import org.bukkit.NamespacedKey; import org.bukkit.Registry; import org.bukkit.Sound; -import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.craftbukkit.util.Handleable; +import org.jetbrains.annotations.NotNull; -public class CraftSound { +public class CraftSound implements Sound, Handleable { + + private static int count = 0; public static Sound minecraftToBukkit(SoundEffect minecraft) { - Preconditions.checkArgument(minecraft != null); - - IRegistry registry = CraftRegistry.getMinecraftRegistry(Registries.SOUND_EVENT); - Sound bukkit = Registry.SOUNDS.get(CraftNamespacedKey.fromMinecraft(registry.getResourceKey(minecraft).orElseThrow().location())); - - Preconditions.checkArgument(bukkit != null); - - return bukkit; + return CraftRegistry.minecraftToBukkit(minecraft, Registries.SOUND_EVENT, Registry.SOUNDS); } public static SoundEffect bukkitToMinecraft(Sound bukkit) { - Preconditions.checkArgument(bukkit != null); - - return CraftRegistry.getMinecraftRegistry(Registries.SOUND_EVENT) - .getOptional(CraftNamespacedKey.toMinecraft(bukkit.getKey())).orElseThrow(); + return CraftRegistry.bukkitToMinecraft(bukkit); } public static Holder bukkitToMinecraftHolder(Sound bukkit) { @@ -41,4 +36,75 @@ public class CraftSound { throw new IllegalArgumentException("No Reference holder found for " + bukkit + ", this can happen if a plugin creates its own sound effect with out properly registering it."); } + + private final NamespacedKey key; + private final SoundEffect soundEffect; + private final String name; + private final int ordinal; + + public CraftSound(NamespacedKey key, SoundEffect soundEffect) { + this.key = key; + this.soundEffect = soundEffect; + // For backwards compatibility, minecraft values will stile return the uppercase name without the namespace, + // in case plugins use for example the name as key in a config file to receive sound specific values. + // Custom sounds will return the key with namespace. For a plugin this should look than like a new sound + // (which can always be added in new minecraft versions and the plugin should therefore handle it accordingly). + if (NamespacedKey.MINECRAFT.equals(key.getNamespace())) { + this.name = key.getKey().toUpperCase(Locale.ROOT).replace('.', '_'); + } else { + this.name = key.toString(); + } + this.ordinal = count++; + } + + @Override + public SoundEffect getHandle() { + return soundEffect; + } + + @NotNull + @Override + public NamespacedKey getKey() { + return key; + } + + @Override + public int compareTo(@NotNull Sound sound) { + return ordinal - sound.ordinal(); + } + + @NotNull + @Override + public String name() { + return name; + } + + @Override + public int ordinal() { + return ordinal; + } + + @Override + public String toString() { + // For backwards compatibility + return name(); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + + if (!(other instanceof CraftSound otherSound)) { + return false; + } + + return getKey().equals(otherSound.getKey()); + } + + @Override + public int hashCode() { + return getKey().hashCode(); + } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/enums/EnumEvil.java b/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/enums/EnumEvil.java index ab1b970a0e..32ba6cc36d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/enums/EnumEvil.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/enums/EnumEvil.java @@ -18,6 +18,7 @@ import java.util.stream.Collectors; import org.bukkit.Fluid; import org.bukkit.NamespacedKey; import org.bukkit.Registry; +import org.bukkit.Sound; import org.bukkit.attribute.Attribute; import org.bukkit.block.Biome; import org.bukkit.block.banner.PatternType; @@ -52,6 +53,7 @@ public class EnumEvil { REGISTRIES.put(Fluid.class, new LegacyRegistryData(Registry.FLUID, Fluid::valueOf)); REGISTRIES.put(Villager.Type.class, new LegacyRegistryData(Registry.VILLAGER_TYPE, Villager.Type::valueOf)); REGISTRIES.put(Villager.Profession.class, new LegacyRegistryData(Registry.VILLAGER_PROFESSION, Villager.Profession::valueOf)); + REGISTRIES.put(Sound.class, new LegacyRegistryData(Registry.SOUNDS, Sound::valueOf)); REGISTRIES.put(Frog.Variant.class, new LegacyRegistryData(Registry.FROG_VARIANT, Frog.Variant::valueOf)); REGISTRIES.put(Cat.Type.class, new LegacyRegistryData(Registry.CAT_VARIANT, Cat.Type::valueOf)); REGISTRIES.put(MapCursor.Type.class, new LegacyRegistryData(Registry.MAP_DECORATION_TYPE, MapCursor.Type::valueOf)); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/Commodore.java index 0d1b18a8b7..3f6a25d77a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/Commodore.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/Commodore.java @@ -80,17 +80,18 @@ public class Commodore { "org/spigotmc/event/entity/EntityDismountEvent", "org/bukkit/event/entity/EntityDismountEvent" ); - private static final Map CLASS_TO_INTERFACE = Map.of( - "org/bukkit/inventory/InventoryView", "org/bukkit/craftbukkit/inventory/CraftAbstractInventoryView", - "org/bukkit/entity/Villager$Type", "NOP", - "org/bukkit/entity/Villager$Profession", "NOP", - "org/bukkit/entity/Frog$Variant", "NOP", - "org/bukkit/entity/Cat$Type", "NOP", - "org/bukkit/map/MapCursor$Type", "NOP", - "org/bukkit/block/banner/PatternType", "NOP", - "org/bukkit/attribute/Attribute", "NOP", - "org/bukkit/block/Biome", "NOP", - "org/bukkit/Fluid", "NOP" + private static final Map CLASS_TO_INTERFACE = Map.ofEntries( + Map.entry("org/bukkit/inventory/InventoryView", "org/bukkit/craftbukkit/inventory/CraftAbstractInventoryView"), + Map.entry("org/bukkit/entity/Villager$Type", "NOP"), + Map.entry("org/bukkit/entity/Villager$Profession", "NOP"), + Map.entry("org/bukkit/entity/Frog$Variant", "NOP"), + Map.entry("org/bukkit/entity/Cat$Type", "NOP"), + Map.entry("org/bukkit/map/MapCursor$Type", "NOP"), + Map.entry("org/bukkit/block/banner/PatternType", "NOP"), + Map.entry("org/bukkit/attribute/Attribute", "NOP"), + Map.entry("org/bukkit/block/Biome", "NOP"), + Map.entry("org/bukkit/Fluid", "NOP"), + Map.entry("org/bukkit/Sound", "NOP") ); private final List reroutes = new ArrayList<>(); // only for testing diff --git a/paper-server/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java b/paper-server/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java index 90ec32cb9a..905d401a7f 100644 --- a/paper-server/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java +++ b/paper-server/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.stream.Stream; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; +import net.minecraft.sounds.SoundEffect; import net.minecraft.world.effect.MobEffectList; import net.minecraft.world.entity.ai.attributes.AttributeBase; import net.minecraft.world.entity.animal.CatVariant; @@ -22,6 +23,7 @@ import org.bukkit.Fluid; import org.bukkit.GameEvent; import org.bukkit.JukeboxSong; import org.bukkit.MusicInstrument; +import org.bukkit.Sound; import org.bukkit.attribute.Attribute; import org.bukkit.block.Biome; import org.bukkit.block.BlockType; @@ -30,6 +32,7 @@ import org.bukkit.craftbukkit.CraftFluid; import org.bukkit.craftbukkit.CraftGameEvent; import org.bukkit.craftbukkit.CraftJukeboxSong; import org.bukkit.craftbukkit.CraftMusicInstrument; +import org.bukkit.craftbukkit.CraftSound; import org.bukkit.craftbukkit.attribute.CraftAttribute; import org.bukkit.craftbukkit.block.CraftBiome; import org.bukkit.craftbukkit.block.CraftBlockType; @@ -80,6 +83,7 @@ public class RegistriesArgumentProvider implements ArgumentsProvider { register(MusicInstrument.class, Registries.INSTRUMENT, CraftMusicInstrument.class, Instrument.class); register(MenuType.class, Registries.MENU, CraftMenuType.class, Containers.class); register(PotionEffectType.class, Registries.MOB_EFFECT, CraftPotionEffectType.class, MobEffectList.class); + register(Sound.class, Registries.SOUND_EVENT, CraftSound.class, SoundEffect.class); register(Structure.class, Registries.STRUCTURE, CraftStructure.class, net.minecraft.world.level.levelgen.structure.Structure.class); register(StructureType.class, Registries.STRUCTURE_TYPE, CraftStructureType.class, net.minecraft.world.level.levelgen.structure.StructureType.class); register(Villager.Type.class, Registries.VILLAGER_TYPE, CraftVillager.CraftType.class, VillagerType.class);