diff --git a/paper-api/src/main/java/org/bukkit/Registry.java b/paper-api/src/main/java/org/bukkit/Registry.java index d55c33ca14..52b3a105b4 100644 --- a/paper-api/src/main/java/org/bukkit/Registry.java +++ b/paper-api/src/main/java/org/bukkit/Registry.java @@ -3,13 +3,21 @@ package org.bukkit; import com.google.common.base.Preconditions; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableMap; +import io.papermc.paper.datacomponent.DataComponentType; +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.tag.Tag; +import io.papermc.paper.registry.tag.TagKey; import java.util.Iterator; import java.util.Locale; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Objects; import java.util.function.Predicate; import java.util.stream.Stream; import java.util.stream.StreamSupport; +import net.kyori.adventure.key.Key; import org.bukkit.advancement.Advancement; import org.bukkit.attribute.Attribute; import org.bukkit.block.Biome; @@ -35,8 +43,8 @@ import org.bukkit.map.MapCursor; import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionType; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** * Represents a registry of Bukkit objects that may be retrieved by @@ -44,39 +52,34 @@ import org.jetbrains.annotations.Nullable; * * @param type of item in the registry */ +@NullMarked public interface Registry extends Iterable { + private static Registry registryFor(final RegistryKey registryKey) { + return RegistryAccess.registryAccess().getRegistry(registryKey); + } + + @SuppressWarnings("removal") + @Deprecated(forRemoval = true, since = "1.21.4") + private static Registry legacyRegistryFor(final Class clazz) { + return Objects.requireNonNull(RegistryAccess.registryAccess().getRegistry(clazz), "No registry present for " + clazz.getSimpleName() + ". This is a bug."); + } + /** * Server advancements. * - * @see Bukkit#getAdvancement(org.bukkit.NamespacedKey) + * @see Bukkit#getAdvancement(NamespacedKey) * @see Bukkit#advancementIterator() + * @deprecated use {@link Bukkit#getAdvancement(NamespacedKey)} and {@link Bukkit#advancementIterator()} */ - Registry ADVANCEMENT = new Registry() { + @Deprecated(since = "1.21.4", forRemoval = true) + Registry ADVANCEMENT = new NotARegistry<>() { - @Nullable @Override - public Advancement get(@NotNull NamespacedKey key) { + public @Nullable Advancement get(final NamespacedKey key) { return Bukkit.getAdvancement(key); } - @NotNull - @Override - public Advancement getOrThrow(@NotNull NamespacedKey key) { - Advancement advancement = get(key); - - Preconditions.checkArgument(advancement != null, "No Advancement registry entry found for key %s.", key); - - return advancement; - } - - @NotNull - @Override - public Stream stream() { - return StreamSupport.stream(spliterator(), false); - } - - @NotNull @Override public Iterator iterator() { return Bukkit.advancementIterator(); @@ -86,71 +89,54 @@ public interface Registry extends Iterable { * Server art. * * @see Art - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#PAINTING_VARIANT} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#PAINTING_VARIANT} */ @Deprecated(since = "1.21.3") // Paper - Registry ART = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Art.class), "No registry present for Art. This is a bug."); + Registry ART = legacyRegistryFor(Art.class); /** * Attribute. * * @see Attribute */ - Registry ATTRIBUTE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.ATTRIBUTE); // Paper + Registry ATTRIBUTE = registryFor(RegistryKey.ATTRIBUTE); /** * Server banner patterns. * * @see PatternType - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#BANNER_PATTERN} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#BANNER_PATTERN} */ @Deprecated(since = "1.21") // Paper - Registry BANNER_PATTERN = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(PatternType.class), "No registry present for PatternType. This is a bug."); // Paper + Registry BANNER_PATTERN = legacyRegistryFor(PatternType.class); /** * Server biomes. * * @see Biome - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#BIOME} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#BIOME} */ @Deprecated(since = "1.21.3") // Paper - Registry BIOME = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Biome.class), "No registry present for Biome. This is a bug."); + Registry BIOME = legacyRegistryFor(Biome.class); /** * Server block types. * * @see BlockType - * @apiNote BlockType is not ready for public usage yet */ - @ApiStatus.Internal - Registry BLOCK = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.BLOCK); // Paper + @ApiStatus.Experimental + Registry BLOCK = registryFor(RegistryKey.BLOCK); /** * Custom boss bars. * * @see Bukkit#getBossBar(org.bukkit.NamespacedKey) * @see Bukkit#getBossBars() + * @deprecated use {@link Bukkit#getBossBar(NamespacedKey)} and {@link Bukkit#getBossBars()} */ - Registry BOSS_BARS = new Registry() { + @Deprecated(since = "1.21.4", forRemoval = true) + Registry BOSS_BARS = new NotARegistry<>() { - @Nullable @Override - public KeyedBossBar get(@NotNull NamespacedKey key) { + public @Nullable KeyedBossBar get(final NamespacedKey key) { return Bukkit.getBossBar(key); } - @NotNull - @Override - public KeyedBossBar getOrThrow(@NotNull NamespacedKey key) { - KeyedBossBar keyedBossBar = get(key); - - Preconditions.checkArgument(keyedBossBar != null, "No KeyedBossBar registry entry found for key %s.", key); - - return keyedBossBar; - } - - @NotNull - @Override - public Stream stream() { - return StreamSupport.stream(spliterator(), false); - } - - @NotNull @Override public Iterator iterator() { return Bukkit.getBossBars(); @@ -161,37 +147,36 @@ public interface Registry extends Iterable { * * @see Cat.Type */ - Registry CAT_VARIANT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.CAT_VARIANT); // Paper + Registry CAT_VARIANT = registryFor(RegistryKey.CAT_VARIANT); /** * Server enchantments. * * @see Enchantment - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#ENCHANTMENT} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#ENCHANTMENT} */ @Deprecated(since = "1.21") - Registry ENCHANTMENT = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Enchantment.class), "No registry present for Enchantment. This is a bug."); // Paper + Registry ENCHANTMENT = legacyRegistryFor(Enchantment.class); /** * Server entity types. * * @see EntityType */ - Registry ENTITY_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.ENTITY_TYPE); // Paper + Registry ENTITY_TYPE = registryFor(RegistryKey.ENTITY_TYPE); /** * Server instruments. * * @see MusicInstrument - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#INSTRUMENT} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#INSTRUMENT} */ @Deprecated(since = "1.21.2") - Registry INSTRUMENT = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(MusicInstrument.class), "No registry present for Instruments. This is a bug."); // Paper + Registry INSTRUMENT = legacyRegistryFor(MusicInstrument.class); /** * Server item types. * * @see ItemType - * @apiNote ItemType is not ready for public usage yet */ - @ApiStatus.Internal - Registry ITEM = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.ITEM); // Paper + @ApiStatus.Experimental + Registry ITEM = registryFor(RegistryKey.ITEM); /** * Default server loot tables. * @@ -210,25 +195,26 @@ public interface Registry extends Iterable { * @see MenuType */ @ApiStatus.Experimental - Registry MENU = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.MENU); // Paper + Registry MENU = registryFor(RegistryKey.MENU); /** * Server mob effects. * * @see PotionEffectType */ - Registry EFFECT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.MOB_EFFECT); // Paper + @ApiStatus.Obsolete(since = "1.21.4") + Registry MOB_EFFECT = registryFor(RegistryKey.MOB_EFFECT); /** * Server particles. * * @see Particle */ - Registry PARTICLE_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.PARTICLE_TYPE); // Paper + Registry PARTICLE_TYPE = RegistryAccess.registryAccess().getRegistry(RegistryKey.PARTICLE_TYPE); // Paper /** * Server potions. * * @see PotionType */ - Registry POTION = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.POTION); // Paper + Registry POTION = RegistryAccess.registryAccess().getRegistry(RegistryKey.POTION); // Paper /** * Server statistics. * @@ -239,160 +225,158 @@ public interface Registry extends Iterable { * Server structures. * * @see Structure - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#STRUCTURE} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#STRUCTURE} */ @Deprecated(since = "1.20.6") // Paper - Registry STRUCTURE = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Structure.class), "No registry present for Structure. This is a bug."); // Paper + Registry STRUCTURE = legacyRegistryFor(Structure.class); /** * Server structure types. * * @see StructureType */ - Registry STRUCTURE_TYPE = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.STRUCTURE_TYPE), "No registry present for StructureType. This is a bug."); // Paper + Registry STRUCTURE_TYPE = Objects.requireNonNull(RegistryAccess.registryAccess().getRegistry(RegistryKey.STRUCTURE_TYPE), "No registry present for StructureType. This is a bug."); // Paper /** - * Sound keys. + * Sound events. * * @see Sound */ - Registry SOUNDS = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.SOUND_EVENT); // Paper + Registry SOUND_EVENT = registryFor(RegistryKey.SOUND_EVENT); /** * Trim materials. * * @see TrimMaterial - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#TRIM_MATERIAL} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#TRIM_MATERIAL} */ @Deprecated(since = "1.20.6") // Paper - Registry TRIM_MATERIAL = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(TrimMaterial.class), "No registry present for TrimMaterial. This is a bug."); // Paper + Registry TRIM_MATERIAL = legacyRegistryFor(TrimMaterial.class); /** * Trim patterns. * * @see TrimPattern - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#TRIM_PATTERN} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#TRIM_PATTERN} */ @Deprecated(since = "1.20.6") - Registry TRIM_PATTERN = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(TrimPattern.class), "No registry present for TrimPattern. This is a bug."); // Paper + Registry TRIM_PATTERN = legacyRegistryFor(TrimPattern.class); /** * Damage types. * * @see DamageType - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#DAMAGE_TYPE} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#DAMAGE_TYPE} */ @Deprecated(since = "1.20.6") - Registry DAMAGE_TYPE = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(DamageType.class), "No registry present for DamageType. This is a bug."); // Paper + Registry DAMAGE_TYPE = legacyRegistryFor(DamageType.class); /** * Jukebox songs. * * @see JukeboxSong - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#JUKEBOX_SONG} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#JUKEBOX_SONG} */ @ApiStatus.Experimental @Deprecated(since = "1.21") - Registry JUKEBOX_SONG = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(JukeboxSong.class), "No registry present for JukeboxSong. This is a bug."); // Paper + Registry JUKEBOX_SONG = legacyRegistryFor(JukeboxSong.class); /** * Villager profession. * * @see Villager.Profession */ - Registry VILLAGER_PROFESSION = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.VILLAGER_PROFESSION); // Paper + Registry VILLAGER_PROFESSION = registryFor(RegistryKey.VILLAGER_PROFESSION); /** * Villager type. * * @see Villager.Type */ - Registry VILLAGER_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.VILLAGER_TYPE); // Paper + Registry VILLAGER_TYPE = registryFor(RegistryKey.VILLAGER_TYPE); /** * Memory Keys. * * @see MemoryKey */ - Registry MEMORY_MODULE_TYPE = new Registry() { + Registry MEMORY_MODULE_TYPE = new NotARegistry<>() { - @NotNull @Override public Iterator iterator() { return MemoryKey.values().iterator(); } - @Nullable @Override - public MemoryKey get(@NotNull NamespacedKey key) { + public @Nullable MemoryKey get(final NamespacedKey key) { return MemoryKey.getByKey(key); } - - @NotNull - @Override - public MemoryKey getOrThrow(@NotNull NamespacedKey key) { - MemoryKey memoryKey = get(key); - - Preconditions.checkArgument(memoryKey != null, "No MemoryKey registry entry found for key %s.", key); - - return memoryKey; - } - - @NotNull - @Override - public Stream stream() { - return StreamSupport.stream(spliterator(), false); - } }; /** * Server fluids. * * @see Fluid */ - Registry FLUID = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.FLUID); // Paper + Registry FLUID = registryFor(RegistryKey.FLUID); /** * Frog variants. * * @see Frog.Variant */ - Registry FROG_VARIANT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.FROG_VARIANT); // Paper + Registry FROG_VARIANT = registryFor(RegistryKey.FROG_VARIANT); /** * Wolf variants. * * @see Wolf.Variant - * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#WOLF_VARIANT} + * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#WOLF_VARIANT} */ @Deprecated(since = "1.20.6") - Registry WOLF_VARIANT = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Wolf.Variant.class), "No registry present for Wolf$Variant. This is a bug."); // Paper + Registry WOLF_VARIANT = legacyRegistryFor(Wolf.Variant.class); /** * Map cursor types. * * @see MapCursor.Type */ - Registry MAP_DECORATION_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.MAP_DECORATION_TYPE); // Paper + Registry MAP_DECORATION_TYPE = registryFor(RegistryKey.MAP_DECORATION_TYPE); /** * Game events. * * @see GameEvent + * @see io.papermc.paper.registry.event.RegistryEvents#GAME_EVENT */ - Registry GAME_EVENT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.GAME_EVENT); // Paper + Registry GAME_EVENT = registryFor(RegistryKey.GAME_EVENT); + /** + * Data component types. + * + * @see DataComponentType + */ + Registry DATA_COMPONENT_TYPE = registryFor(RegistryKey.DATA_COMPONENT_TYPE); // Paper - // Paper start - potion effect type registry + // /** - * Potion effect types. - * - * @see org.bukkit.potion.PotionEffectType + * @apiNote use {@link #MOB_EFFECT} instead */ + @ApiStatus.Obsolete(since = "1.21.4") + Registry EFFECT = MOB_EFFECT; + /** + * @apiNote use {@link #MOB_EFFECT} instead + */ + @ApiStatus.Obsolete(since = "1.21.4") Registry POTION_EFFECT_TYPE = EFFECT; - // Paper end - potion effect type registry - Registry DATA_COMPONENT_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.DATA_COMPONENT_TYPE); // Paper /** - * Get the object by its key. - * - * @param key non-null key - * @return item or null if does not exist + * @apiNote use {@link #SOUND_EVENT} */ - @Nullable - T get(@NotNull NamespacedKey key); - // Paper start + @ApiStatus.Obsolete(since = "1.21.4") + Registry SOUNDS = registryFor(RegistryKey.SOUND_EVENT); + // + /** * Get the object by its key. * * @param key non-null key * @return item or null if it does not exist */ - default @Nullable T get(final net.kyori.adventure.key.@NotNull Key key) { + @Nullable T get(NamespacedKey key); + // Paper start + + /** + * Get the object by its key. + * + * @param key non-null key + * @return item or null if it does not exist + */ + default @Nullable T get(final Key key) { return key instanceof final NamespacedKey nsKey ? this.get(nsKey) : this.get(new NamespacedKey(key.namespace(), key.value())); } @@ -402,23 +386,26 @@ public interface Registry extends Iterable { * @param typedKey non-null typed key * @return item or null if it does not exist */ - default @Nullable T get(final io.papermc.paper.registry.@NotNull TypedKey typedKey) { + default @Nullable T get(final TypedKey typedKey) { + Preconditions.checkArgument(typedKey != null, "typedKey cannot be null"); return this.get(typedKey.key()); } // Paper end // Paper start - improve Registry + /** * Gets the object by its key or throws if it doesn't exist. * * @param key the key to get the object of in this registry * @return the object for the key - * @throws java.util.NoSuchElementException if the key doesn't point to an object in the registry + * @throws NoSuchElementException if the key doesn't point to an object in the registry */ - default @NotNull T getOrThrow(final net.kyori.adventure.key.@NotNull Key key) { + default T getOrThrow(final net.kyori.adventure.key.Key key) { + Preconditions.checkArgument(key != null, "key cannot be null"); final T value = this.get(key); if (value == null) { - throw new java.util.NoSuchElementException("No value for " + key + " in " + this); + throw new NoSuchElementException("No value for " + key + " in " + this); } return value; } @@ -428,12 +415,12 @@ public interface Registry extends Iterable { * * @param key the key to get the object of in this registry * @return the object for the key - * @throws java.util.NoSuchElementException if the key doesn't point to an object in the registry + * @throws NoSuchElementException if the key doesn't point to an object in the registry */ - default @NotNull T getOrThrow(final io.papermc.paper.registry.@NotNull TypedKey key) { + default T getOrThrow(final TypedKey key) { final T value = this.get(key); if (value == null) { - throw new java.util.NoSuchElementException("No value for " + key + " in " + this); + throw new NoSuchElementException("No value for " + key + " in " + this); } return value; } @@ -447,14 +434,13 @@ public interface Registry extends Iterable { * * @param value the value to get the key of in this registry * @return the key for the value - * @throws java.util.NoSuchElementException if the value doesn't exist in this registry + * @throws NoSuchElementException if the value doesn't exist in this registry * @see #getKey(Keyed) */ - default @NotNull NamespacedKey getKeyOrThrow(final @NotNull T value) { - Preconditions.checkArgument(value != null, "value cannot be null"); + default NamespacedKey getKeyOrThrow(final T value) { final NamespacedKey key = this.getKey(value); if (key == null) { - throw new java.util.NoSuchElementException(value + " has no key in " + this); + throw new NoSuchElementException(value + " has no key in " + this); } return key; } @@ -470,14 +456,7 @@ public interface Registry extends Iterable { * @return the key for the value or null if not in the registry * @see #getKeyOrThrow(Keyed) */ - default @Nullable NamespacedKey getKey(final @NotNull T value) { - Preconditions.checkArgument(value != null, "value cannot be null"); - //noinspection ConstantValue (it might not be in the future...) - if (value instanceof Keyed) { - return value.getKey(); - } - return null; - } + @Nullable NamespacedKey getKey(T value); // Paper end - improve Registry // Paper start - RegistrySet API @@ -486,46 +465,52 @@ public interface Registry extends Iterable { * * @param key the key to check for * @return true if this registry has a tag with the given key, false otherwise - * @see #getTag(io.papermc.paper.registry.tag.TagKey) + * @throws UnsupportedOperationException if this registry doesn't have or support tags + * @see #getTag(TagKey) */ @ApiStatus.Experimental - default boolean hasTag(final io.papermc.paper.registry.tag.@NotNull TagKey key) { - throw new UnsupportedOperationException(this + " doesn't have tags"); - } + boolean hasTag(TagKey key); /** * Gets the named registry set (tag) for the given key. * * @param key the key to get the tag for * @return the tag for the key - * @throws java.util.NoSuchElementException if no tag with the given key is found - * @throws UnsupportedOperationException if this registry doesn't have or support tags - * @see #hasTag(io.papermc.paper.registry.tag.TagKey) + * @throws NoSuchElementException if no tag with the given key is found + * @throws UnsupportedOperationException if this registry doesn't have or support tags + * @see #hasTag(TagKey) */ @ApiStatus.Experimental - default @NotNull io.papermc.paper.registry.tag.Tag getTag(final io.papermc.paper.registry.tag.@NotNull TagKey key) { - throw new UnsupportedOperationException(this + " doesn't have tags"); - } + Tag getTag(TagKey key); + + /** + * Gets all the tags in this registry. + * + * @return a stream of all tags in this registry + * @throws UnsupportedOperationException if this registry doesn't have or support tags + */ + @ApiStatus.Experimental + Stream> getTags(); // Paper end - RegistrySet API /** * Get the object by its key. - * + *

* If there is no object with the given key, an exception will be thrown. * * @param key to get the object from * @return object with the given key - * @throws IllegalArgumentException if there is no object with the given key + * @throws NoSuchElementException if there is no object with the given key */ - @NotNull - T getOrThrow(@NotNull NamespacedKey key); + default T getOrThrow(final NamespacedKey key) { + return this.getOrThrow((Key) key); + } /** * Returns a new stream, which contains all registry items, which are registered to the registry. * * @return a stream of all registry items */ - @NotNull Stream stream(); /** @@ -539,64 +524,47 @@ public interface Registry extends Iterable { * @deprecated this method's behavior is broken and not useful. If you want to get an object * based on its vanilla name, or a key, wrap it in a {@link NamespacedKey} object and use {@link #get(NamespacedKey)} */ - @Nullable - @Deprecated(forRemoval = true) // Paper - default T match(@NotNull String input) { + // Paper + @Deprecated(forRemoval = true) + default @Nullable T match(final String input) { Preconditions.checkArgument(input != null, "input must not be null"); - String filtered = input.toLowerCase(Locale.ROOT).replaceAll("\\s+", "_"); - NamespacedKey namespacedKey = NamespacedKey.fromString(filtered); - return (namespacedKey != null) ? get(namespacedKey) : null; + final String filtered = input.toLowerCase(Locale.ROOT).replaceAll("\\s+", "_"); + final NamespacedKey namespacedKey = NamespacedKey.fromString(filtered); + return (namespacedKey != null) ? this.get(namespacedKey) : null; } - class SimpleRegistry & Keyed> implements Registry { // Paper - remove final + @ApiStatus.Internal + class SimpleRegistry & Keyed> extends NotARegistry { // Paper - remove final private final Class type; private final Map map; - protected SimpleRegistry(@NotNull Class type) { - this(type, Predicates.alwaysTrue()); + protected SimpleRegistry(final Class type) { + this(type, Predicates.alwaysTrue()); } - protected SimpleRegistry(@NotNull Class type, @NotNull Predicate predicate) { - ImmutableMap.Builder builder = ImmutableMap.builder(); + protected SimpleRegistry(final Class type, final Predicate predicate) { + final ImmutableMap.Builder builder = ImmutableMap.builder(); - for (T entry : type.getEnumConstants()) { + for (final T entry : type.getEnumConstants()) { if (predicate.test(entry)) { builder.put(entry.getKey(), entry); } } - map = builder.build(); + this.map = builder.build(); this.type = type; } - @Nullable @Override - public T get(@NotNull NamespacedKey key) { - return map.get(key); + public @Nullable T get(final NamespacedKey key) { + return this.map.get(key); } - @NotNull - @Override - public T getOrThrow(@NotNull NamespacedKey key) { - T object = get(key); - - Preconditions.checkArgument(object != null, "No %s registry entry found for key %s.", type, key); - - return object; - } - - @NotNull - @Override - public Stream stream() { - return StreamSupport.stream(spliterator(), false); - } - - @NotNull @Override public Iterator iterator() { - return map.values().iterator(); + return this.map.values().iterator(); } @ApiStatus.Internal @@ -604,12 +572,34 @@ public interface Registry extends Iterable { public Class getType() { return this.type; } + } + + @ApiStatus.Internal + abstract class NotARegistry implements Registry { - // Paper start - improve Registry @Override - public @NotNull NamespacedKey getKey(final @NotNull T value) { + public Stream stream() { + return StreamSupport.stream(this.spliterator(), false); + } + + @Override + public NamespacedKey getKey(final A value) { return value.getKey(); } - // Paper end - improve Registry + + @Override + public boolean hasTag(final TagKey key) { + throw new UnsupportedOperationException("This is not a real registry and therefore cannot support tags"); + } + + @Override + public Tag getTag(final TagKey key) { + throw new UnsupportedOperationException("This is not a real registry and therefore cannot support tags"); + } + + @Override + public Stream> getTags() { + throw new UnsupportedOperationException("This is not a real registry and therefore cannot support tags"); + } } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/PaperSimpleRegistry.java b/paper-server/src/main/java/io/papermc/paper/registry/PaperSimpleRegistry.java index cc39bc68d2..a07f8a8c6f 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/PaperSimpleRegistry.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/PaperSimpleRegistry.java @@ -4,6 +4,7 @@ import io.papermc.paper.registry.set.NamedRegistryKeySetImpl; import io.papermc.paper.registry.tag.Tag; import io.papermc.paper.registry.tag.TagKey; import java.util.function.Predicate; +import java.util.stream.Stream; import net.minecraft.core.HolderSet; import net.minecraft.core.registries.BuiltInRegistries; import org.bukkit.Keyed; @@ -51,4 +52,9 @@ public class PaperSimpleRegistry & Keyed, M> extends Registry. final HolderSet.Named namedHolderSet = this.nmsRegistry.get(PaperRegistries.toNms(key)).orElseThrow(); return new NamedRegistryKeySetImpl<>(key, namedHolderSet); } + + @Override + public Stream> getTags() { + return this.nmsRegistry.getTags().map(NamedRegistryKeySetImpl::new); + } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java b/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java index fdc475f2b1..395448b36e 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java @@ -38,11 +38,6 @@ public final class DelayedRegistry> imple return this.delegate().get(key); } - @Override - public T getOrThrow(final NamespacedKey key) { - return this.delegate().getOrThrow(key); - } - @Override public Iterator iterator() { return this.delegate().iterator(); @@ -67,4 +62,9 @@ public final class DelayedRegistry> imple public @NonNull Tag getTag(final TagKey key) { return this.delegate().getTag(key); } + + @Override + public Stream> getTags() { + return this.delegate().getTags(); + } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/set/NamedRegistryKeySetImpl.java b/paper-server/src/main/java/io/papermc/paper/registry/set/NamedRegistryKeySetImpl.java index 7b15640c2f..79499fa902 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/set/NamedRegistryKeySetImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/set/NamedRegistryKeySetImpl.java @@ -26,6 +26,10 @@ public record NamedRegistryKeySetImpl( // TODO remove Keyed HolderSet.Named namedSet ) implements Tag, org.bukkit.Tag { + public NamedRegistryKeySetImpl(final HolderSet.Named namedSet) { + this(PaperRegistries.fromNms(namedSet.key()), namedSet); + } + @Override public @Unmodifiable Collection> values() { final ImmutableList.Builder> builder = ImmutableList.builder(); 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 332215f8b4..3955f5e40b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -2,6 +2,8 @@ package org.bukkit.craftbukkit; import com.google.common.base.Preconditions; import io.papermc.paper.registry.entry.RegistryEntryMeta; +import io.papermc.paper.registry.set.NamedRegistryKeySetImpl; +import io.papermc.paper.registry.tag.Tag; import io.papermc.paper.util.Holderable; import java.util.HashMap; import java.util.Iterator; @@ -304,7 +306,7 @@ public class CraftRegistry implements Registry { if (value instanceof Holderable holderable) { return holderable.getKeyOrNull(); } - return Registry.super.getKey(value); + return value.getKey(); } // Paper end - improve Registry @@ -319,5 +321,10 @@ public class CraftRegistry implements Registry { final net.minecraft.core.HolderSet.Named namedHolderSet = this.minecraftRegistry.get(io.papermc.paper.registry.PaperRegistries.toNms(key)).orElseThrow(); return new io.papermc.paper.registry.set.NamedRegistryKeySetImpl<>(key, namedHolderSet); } + + @Override + public Stream> getTags() { + return this.minecraftRegistry.getTags().map(NamedRegistryKeySetImpl::new); + } // Paper end - RegistrySet API }