diff --git a/paper-api/src/main/java/org/bukkit/Registry.java b/paper-api/src/main/java/org/bukkit/Registry.java index f1a7f3b3e2..1970b4aa02 100644 --- a/paper-api/src/main/java/org/bukkit/Registry.java +++ b/paper-api/src/main/java/org/bukkit/Registry.java @@ -134,7 +134,7 @@ public interface Registry<T extends Keyed> extends Iterable<T> { * * @see Cat.Type */ - Registry<Cat.Type> CAT_VARIANT = new SimpleRegistry<>(Cat.Type.class); + Registry<Cat.Type> CAT_VARIANT = Objects.requireNonNull(Bukkit.getRegistry(Cat.Type.class), "No registry present for Cat Type. This is a bug."); /** * Server enchantments. * @@ -248,13 +248,13 @@ public interface Registry<T extends Keyed> extends Iterable<T> { * * @see Villager.Profession */ - Registry<Villager.Profession> VILLAGER_PROFESSION = new SimpleRegistry<>(Villager.Profession.class); + Registry<Villager.Profession> VILLAGER_PROFESSION = Objects.requireNonNull(Bukkit.getRegistry(Villager.Profession.class), "No registry present for Villager Profession. This is a bug."); /** * Villager type. * * @see Villager.Type */ - Registry<Villager.Type> VILLAGER_TYPE = new SimpleRegistry<>(Villager.Type.class); + Registry<Villager.Type> VILLAGER_TYPE = Objects.requireNonNull(Bukkit.getRegistry(Villager.Type.class), "No registry present for Villager Type. This is a bug."); /** * Memory Keys. * @@ -291,7 +291,7 @@ public interface Registry<T extends Keyed> extends Iterable<T> { * * @see Frog.Variant */ - Registry<Frog.Variant> FROG_VARIANT = new SimpleRegistry<>(Frog.Variant.class); + Registry<Frog.Variant> FROG_VARIANT = Objects.requireNonNull(Bukkit.getRegistry(Frog.Variant.class), "No registry present for Frog Variant. This is a bug."); /** * Wolf variants. * @@ -304,7 +304,7 @@ public interface Registry<T extends Keyed> extends Iterable<T> { * @see MapCursor.Type */ @ApiStatus.Internal - Registry<MapCursor.Type> MAP_DECORATION_TYPE = new SimpleRegistry<>(MapCursor.Type.class); + Registry<MapCursor.Type> MAP_DECORATION_TYPE = Objects.requireNonNull(Bukkit.getRegistry(MapCursor.Type.class), "No registry present for MapCursor Type. This is a bug."); /** * Game events. * diff --git a/paper-api/src/main/java/org/bukkit/entity/Cat.java b/paper-api/src/main/java/org/bukkit/entity/Cat.java index d1327761a4..117e3e8c63 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Cat.java +++ b/paper-api/src/main/java/org/bukkit/entity/Cat.java @@ -1,8 +1,13 @@ package org.bukkit.entity; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import java.util.Locale; import org.bukkit.DyeColor; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.util.OldEnum; import org.jetbrains.annotations.NotNull; /** @@ -43,29 +48,50 @@ public interface Cat extends Tameable, Sittable { /** * Represents the various different cat types there are. */ - public enum Type implements Keyed { - TABBY("tabby"), - BLACK("black"), - RED("red"), - SIAMESE("siamese"), - BRITISH_SHORTHAIR("british_shorthair"), - CALICO("calico"), - PERSIAN("persian"), - RAGDOLL("ragdoll"), - WHITE("white"), - JELLIE("jellie"), - ALL_BLACK("all_black"); + interface Type extends OldEnum<Type>, Keyed { - private final NamespacedKey key; + Type TABBY = getType("tabby"); + Type BLACK = getType("black"); + Type RED = getType("red"); + Type SIAMESE = getType("siamese"); + Type BRITISH_SHORTHAIR = getType("british_shorthair"); + Type CALICO = getType("calico"); + Type PERSIAN = getType("persian"); + Type RAGDOLL = getType("ragdoll"); + Type WHITE = getType("white"); + Type JELLIE = getType("jellie"); + Type ALL_BLACK = getType("all_black"); - private Type(String key) { - this.key = NamespacedKey.minecraft(key); + @NotNull + private static Type getType(@NotNull String key) { + NamespacedKey namespacedKey = NamespacedKey.minecraft(key); + Type type = Registry.CAT_VARIANT.get(namespacedKey); + + Preconditions.checkNotNull(type, "No cat type found for %s. This is a bug.", namespacedKey); + return type; } - @Override + /** + * @param name of the cat type. + * @return the cat type with the given name. + * @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead. + */ @NotNull - public NamespacedKey getKey() { - return key; + @Deprecated(since = "1.21") + static Type valueOf(@NotNull String name) { + Type type = Registry.CAT_VARIANT.get(NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); + Preconditions.checkArgument(type != null, "No cat type found with the name %s", name); + return type; + } + + /** + * @return an array of all known cat types. + * @deprecated use {@link Registry#iterator()}. + */ + @NotNull + @Deprecated(since = "1.21") + static Type[] values() { + return Lists.newArrayList(Registry.CAT_VARIANT).toArray(new Type[0]); } } } diff --git a/paper-api/src/main/java/org/bukkit/entity/Frog.java b/paper-api/src/main/java/org/bukkit/entity/Frog.java index 0960bdbb32..7cf8ae63eb 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Frog.java +++ b/paper-api/src/main/java/org/bukkit/entity/Frog.java @@ -1,8 +1,12 @@ package org.bukkit.entity; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; import java.util.Locale; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.util.OldEnum; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -44,30 +48,51 @@ public interface Frog extends Animals { /** * Represents the variant of a frog - ie its color. */ - public enum Variant implements Keyed { + interface Variant extends OldEnum<Variant>, Keyed { /** * Temperate (brown-orange) frog. */ - TEMPERATE, + Variant TEMPERATE = getVariant("temperate"); /** * Warm (gray) frog. */ - WARM, + Variant WARM = getVariant("warm"); /** * Cold (green) frog. */ - COLD; - private final NamespacedKey key; - - private Variant() { - this.key = NamespacedKey.minecraft(name().toLowerCase(Locale.ROOT)); - } + Variant COLD = getVariant("cold"); @NotNull - @Override - public NamespacedKey getKey() { - return key; + private static Variant getVariant(@NotNull String key) { + NamespacedKey namespacedKey = NamespacedKey.minecraft(key); + Variant variant = Registry.FROG_VARIANT.get(namespacedKey); + + Preconditions.checkNotNull(variant, "No frog variant found for %s. This is a bug.", namespacedKey); + return variant; + } + + /** + * @param name of the frog variant. + * @return the frog variant with the given name. + * @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead. + */ + @NotNull + @Deprecated(since = "1.21") + static Variant valueOf(@NotNull String name) { + Variant variant = Registry.FROG_VARIANT.get(NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); + Preconditions.checkArgument(variant != null, "No frog variant found with the name %s", name); + return variant; + } + + /** + * @return an array of all known frog variants. + * @deprecated use {@link Registry#iterator()}. + */ + @NotNull + @Deprecated(since = "1.21") + static Variant[] values() { + return Lists.newArrayList(Registry.FROG_VARIANT).toArray(new Variant[0]); } } } diff --git a/paper-api/src/main/java/org/bukkit/entity/Villager.java b/paper-api/src/main/java/org/bukkit/entity/Villager.java index 6bf3af3ed8..45dd54afa6 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Villager.java +++ b/paper-api/src/main/java/org/bukkit/entity/Villager.java @@ -1,9 +1,13 @@ package org.bukkit.entity; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; import java.util.Locale; import org.bukkit.Keyed; import org.bukkit.Location; import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.util.OldEnum; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -118,25 +122,46 @@ public interface Villager extends AbstractVillager { * Represents Villager type, usually corresponding to what biome they spawn * in. */ - public enum Type implements Keyed { + interface Type extends OldEnum<Type>, Keyed { - DESERT, - JUNGLE, - PLAINS, - SAVANNA, - SNOW, - SWAMP, - TAIGA; - private final NamespacedKey key; - - private Type() { - this.key = NamespacedKey.minecraft(this.name().toLowerCase(Locale.ROOT)); - } + Type DESERT = getType("desert"); + Type JUNGLE = getType("jungle"); + Type PLAINS = getType("plains"); + Type SAVANNA = getType("savanna"); + Type SNOW = getType("snow"); + Type SWAMP = getType("swamp"); + Type TAIGA = getType("taiga"); @NotNull - @Override - public NamespacedKey getKey() { - return key; + private static Type getType(@NotNull String key) { + NamespacedKey namespacedKey = NamespacedKey.minecraft(key); + Type type = Registry.VILLAGER_TYPE.get(namespacedKey); + + Preconditions.checkNotNull(type, "No villager type found for %s. This is a bug.", namespacedKey); + return type; + } + + /** + * @param name of the villager type. + * @return the villager type with the given name. + * @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead. + */ + @NotNull + @Deprecated(since = "1.21") + static Type valueOf(@NotNull String name) { + Type type = Registry.VILLAGER_TYPE.get(NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); + Preconditions.checkArgument(type != null, "No villager type found with the name %s", name); + return type; + } + + /** + * @return an array of all known villager types. + * @deprecated use {@link Registry#iterator()}. + */ + @NotNull + @Deprecated(since = "1.21") + static Type[] values() { + return Lists.newArrayList(Registry.VILLAGER_TYPE).toArray(new Type[0]); } } @@ -144,88 +169,110 @@ public interface Villager extends AbstractVillager { * Represents the various different Villager professions there may be. * Villagers have different trading options depending on their profession, */ - public enum Profession implements Keyed { - NONE, + interface Profession extends OldEnum<Profession>, Keyed { + + Profession NONE = getProfession("none"); /** * Armorer profession. Wears a black apron. Armorers primarily trade for * iron armor, chainmail armor, and sometimes diamond armor. */ - ARMORER, + Profession ARMORER = getProfession("armorer"); /** * Butcher profession. Wears a white apron. Butchers primarily trade for * raw and cooked food. */ - BUTCHER, + Profession BUTCHER = getProfession("butcher"); /** * Cartographer profession. Wears a white robe. Cartographers primarily * trade for explorer maps and some paper. */ - CARTOGRAPHER, + Profession CARTOGRAPHER = getProfession("cartographer"); /** * Cleric profession. Wears a purple robe. Clerics primarily trade for * rotten flesh, gold ingot, redstone, lapis, ender pearl, glowstone, * and bottle o' enchanting. */ - CLERIC, + Profession CLERIC = getProfession("cleric"); /** * Farmer profession. Wears a brown robe. Farmers primarily trade for * food-related items. */ - FARMER, + Profession FARMER = getProfession("farmer"); /** * Fisherman profession. Wears a brown robe. Fisherman primarily trade * for fish, as well as possibly selling string and/or coal. */ - FISHERMAN, + Profession FISHERMAN = getProfession("fisherman"); /** * Fletcher profession. Wears a brown robe. Fletchers primarily trade * for string, bows, and arrows. */ - FLETCHER, + Profession FLETCHER = getProfession("fletcher"); /** * Leatherworker profession. Wears a white apron. Leatherworkers * primarily trade for leather, and leather armor, as well as saddles. */ - LEATHERWORKER, + Profession LEATHERWORKER = getProfession("leatherworker"); /** * Librarian profession. Wears a white robe. Librarians primarily trade * for paper, books, and enchanted books. */ - LIBRARIAN, + Profession LIBRARIAN = getProfession("librarian"); /** * Mason profession. */ - MASON, + Profession MASON = getProfession("mason"); /** * Nitwit profession. Wears a green apron, cannot trade. Nitwit * villagers do not do anything. They do not have any trades by default. */ - NITWIT, + Profession NITWIT = getProfession("nitwit"); /** * Sheperd profession. Wears a brown robe. Shepherds primarily trade for * wool items, and shears. */ - SHEPHERD, + Profession SHEPHERD = getProfession("shepherd"); /** * Toolsmith profession. Wears a black apron. Tool smiths primarily * trade for iron and diamond tools. */ - TOOLSMITH, + Profession TOOLSMITH = getProfession("toolsmith"); /** * Weaponsmith profession. Wears a black apron. Weapon smiths primarily * trade for iron and diamond weapons, sometimes enchanted. */ - WEAPONSMITH; - private final NamespacedKey key; - - private Profession() { - this.key = NamespacedKey.minecraft(this.name().toLowerCase(Locale.ROOT)); - } + Profession WEAPONSMITH = getProfession("weaponsmith"); @NotNull - @Override - public NamespacedKey getKey() { - return key; + private static Profession getProfession(@NotNull String key) { + NamespacedKey namespacedKey = NamespacedKey.minecraft(key); + Profession profession = Registry.VILLAGER_PROFESSION.get(namespacedKey); + + Preconditions.checkNotNull(profession, "No villager profession found for %s. This is a bug.", namespacedKey); + return profession; + } + + /** + * @param name of the villager profession. + * @return the villager profession with the given name. + * @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead. + */ + @NotNull + @Deprecated(since = "1.21") + static Profession valueOf(@NotNull String name) { + Profession profession = Registry.VILLAGER_PROFESSION.get(NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); + Preconditions.checkArgument(profession != null, "No villager profession found with the name %s", name); + return profession; + } + + /** + * @return an array of all known villager professions. + * @deprecated use {@link Registry#iterator()}. + */ + @NotNull + @Deprecated(since = "1.21") + static Profession[] values() { + return Lists.newArrayList(Registry.VILLAGER_PROFESSION).toArray(new Profession[0]); } } } diff --git a/paper-api/src/main/java/org/bukkit/map/MapCursor.java b/paper-api/src/main/java/org/bukkit/map/MapCursor.java index e645a65dbd..8250821fe7 100644 --- a/paper-api/src/main/java/org/bukkit/map/MapCursor.java +++ b/paper-api/src/main/java/org/bukkit/map/MapCursor.java @@ -1,8 +1,12 @@ package org.bukkit.map; import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import java.util.Locale; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.util.OldEnum; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -129,7 +133,7 @@ public final class MapCursor { */ @Deprecated public byte getRawType() { - return type.value; + return type.getValue(); } /** @@ -225,56 +229,51 @@ public final class MapCursor { * index in the file './assets/minecraft/textures/map/map_icons.png' from minecraft.jar or from a * resource pack. */ - public enum Type implements Keyed { - PLAYER(0, "player"), - FRAME(1, "frame"), - RED_MARKER(2, "red_marker"), - BLUE_MARKER(3, "blue_marker"), - TARGET_X(4, "target_x"), - TARGET_POINT(5, "target_point"), - PLAYER_OFF_MAP(6, "player_off_map"), - PLAYER_OFF_LIMITS(7, "player_off_limits"), - MANSION(8, "mansion"), - MONUMENT(9, "monument"), - BANNER_WHITE(10, "banner_white"), - BANNER_ORANGE(11, "banner_orange"), - BANNER_MAGENTA(12, "banner_magenta"), - BANNER_LIGHT_BLUE(13, "banner_light_blue"), - BANNER_YELLOW(14, "banner_yellow"), - BANNER_LIME(15, "banner_lime"), - BANNER_PINK(16, "banner_pink"), - BANNER_GRAY(17, "banner_gray"), - BANNER_LIGHT_GRAY(18, "banner_light_gray"), - BANNER_CYAN(19, "banner_cyan"), - BANNER_PURPLE(20, "banner_purple"), - BANNER_BLUE(21, "banner_blue"), - BANNER_BROWN(22, "banner_brown"), - BANNER_GREEN(23, "banner_green"), - BANNER_RED(24, "banner_red"), - BANNER_BLACK(25, "banner_black"), - RED_X(26, "red_x"), - VILLAGE_DESERT(27, "village_desert"), - VILLAGE_PLAINS(28, "village_plains"), - VILLAGE_SAVANNA(29, "village_savanna"), - VILLAGE_SNOWY(30, "village_snowy"), - VILLAGE_TAIGA(31, "village_taiga"), - JUNGLE_TEMPLE(32, "jungle_temple"), - SWAMP_HUT(33, "swamp_hut"), - TRIAL_CHAMBERS(34, "trial_chambers") - ; + public interface Type extends OldEnum<Type>, Keyed { - private final byte value; - private final NamespacedKey key; - - Type(int value, String key) { - this.value = (byte) value; - this.key = NamespacedKey.minecraft(key); - } + Type PLAYER = getType("player"); + Type FRAME = getType("frame"); + Type RED_MARKER = getType("red_marker"); + Type BLUE_MARKER = getType("blue_marker"); + Type TARGET_X = getType("target_x"); + Type TARGET_POINT = getType("target_point"); + Type PLAYER_OFF_MAP = getType("player_off_map"); + Type PLAYER_OFF_LIMITS = getType("player_off_limits"); + Type MANSION = getType("mansion"); + Type MONUMENT = getType("monument"); + Type BANNER_WHITE = getType("banner_white"); + Type BANNER_ORANGE = getType("banner_orange"); + Type BANNER_MAGENTA = getType("banner_magenta"); + Type BANNER_LIGHT_BLUE = getType("banner_light_blue"); + Type BANNER_YELLOW = getType("banner_yellow"); + Type BANNER_LIME = getType("banner_lime"); + Type BANNER_PINK = getType("banner_pink"); + Type BANNER_GRAY = getType("banner_gray"); + Type BANNER_LIGHT_GRAY = getType("banner_light_gray"); + Type BANNER_CYAN = getType("banner_cyan"); + Type BANNER_PURPLE = getType("banner_purple"); + Type BANNER_BLUE = getType("banner_blue"); + Type BANNER_BROWN = getType("banner_brown"); + Type BANNER_GREEN = getType("banner_green"); + Type BANNER_RED = getType("banner_red"); + Type BANNER_BLACK = getType("banner_black"); + Type RED_X = getType("red_x"); + Type VILLAGE_DESERT = getType("village_desert"); + Type VILLAGE_PLAINS = getType("village_plains"); + Type VILLAGE_SAVANNA = getType("village_savanna"); + Type VILLAGE_SNOWY = getType("village_snowy"); + Type VILLAGE_TAIGA = getType("village_taiga"); + Type JUNGLE_TEMPLE = getType("jungle_temple"); + Type SWAMP_HUT = getType("swamp_hut"); + Type TRIAL_CHAMBERS = getType("trial_chambers"); @NotNull - @Override - public NamespacedKey getKey() { - return key; + private static Type getType(@NotNull String key) { + NamespacedKey namespacedKey = NamespacedKey.minecraft(key); + Type type = Registry.MAP_DECORATION_TYPE.get(namespacedKey); + + Preconditions.checkNotNull(type, "No type found for %s. This is a bug.", namespacedKey); + return type; } /** @@ -284,9 +283,7 @@ public final class MapCursor { * @deprecated Magic value */ @Deprecated - public byte getValue() { - return value; - } + byte getValue(); /** * Get a cursor by its internal value. @@ -297,12 +294,35 @@ public final class MapCursor { */ @Deprecated @Nullable - public static Type byValue(byte value) { + static Type byValue(byte value) { for (Type t : values()) { - if (t.value == value) return t; + if (t.getValue() == value) return t; } return null; } + + /** + * @param name of the type. + * @return the type with the given name. + * @deprecated only for backwards compatibility, use {@link Registry#get(NamespacedKey)} instead. + */ + @NotNull + @Deprecated(since = "1.21") + static Type valueOf(@NotNull String name) { + Type type = Registry.MAP_DECORATION_TYPE.get(NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); + Preconditions.checkArgument(type != null, "No Type found with the name %s", name); + return type; + } + + /** + * @return an array of all known map cursor types. + * @deprecated use {@link Registry#iterator()}. + */ + @NotNull + @Deprecated(since = "1.21") + static Type[] values() { + return Lists.newArrayList(Registry.MAP_DECORATION_TYPE).toArray(new Type[0]); + } } } diff --git a/paper-api/src/main/java/org/bukkit/util/OldEnum.java b/paper-api/src/main/java/org/bukkit/util/OldEnum.java new file mode 100644 index 0000000000..ce0e5367e5 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/util/OldEnum.java @@ -0,0 +1,42 @@ +package org.bukkit.util; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +/** + * Class which holds common methods which are present in an enum. + * + * @param <T> the type of the old enum. + * @deprecated only for backwards compatibility. + */ +@ApiStatus.Internal +@Deprecated(since = "1.21") +public interface OldEnum<T extends OldEnum<T>> extends Comparable<T> { + + /** + * @param other to compare to. + * @return negative if this old enum is lower, zero if equal and positive if + * higher than the given old enum. + * @deprecated only for backwards compatibility, old enums can not be + * compared. + */ + @Deprecated(since = "1.21") + @Override + int compareTo(@NotNull T other); + + /** + * @return the name of the old enum. + * @deprecated only for backwards compatibility. + */ + @NotNull + @Deprecated(since = "1.21") + String name(); + + /** + * @return the ordinal of the old enum. + * @deprecated only for backwards compatibility, it is not guaranteed that + * an old enum always has the same ordinal. + */ + @Deprecated(since = "1.21") + int ordinal(); +} diff --git a/paper-api/src/main/javadoc/overview.html b/paper-api/src/main/javadoc/overview.html index 5d7dbc5278..68bab9bcee 100644 --- a/paper-api/src/main/javadoc/overview.html +++ b/paper-api/src/main/javadoc/overview.html @@ -31,5 +31,10 @@ <li>Implementation classes. Concrete implementation classes packaged with Bukkit (eg those beginning with Simple) are not API. You should access them via their interfaces instead.</li> + <li>The "enumness" of enums which implement {@link org.bukkit.Keyed}. + Such enums are liable to conversion to regular classes and therefore + usages deriving from their status as an enum (including, but not limited + to, use in switch statements and classes such as {@link java.util.EnumSet}) + should be avoided.</li> </ul> </body>