From cceffe3d985ac6e1580b12bfc04b172a2d543990 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sat, 21 Jun 2025 11:27:46 -0700 Subject: [PATCH] Release ItemType and BlockType (#12708) --- .../papermc/paper/registry/RegistryKey.java | 8 +- .../main/java/org/bukkit/block/BlockType.java | 49 ++++------ .../java/org/bukkit/inventory/ItemType.java | 97 ++++++++----------- .../craftbukkit/inventory/CraftItemType.java | 5 - 4 files changed, 60 insertions(+), 99 deletions(-) diff --git a/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java b/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java index 4050f7135be..d26c40e9b84 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java @@ -76,16 +76,14 @@ public sealed interface RegistryKey extends Keyed permits RegistryKeyImpl { */ RegistryKey MOB_EFFECT = create("mob_effect"); /** - * @apiNote DO NOT USE + * Built-in registry for block types. + * @see io.papermc.paper.registry.keys.BlockTypeKeys */ - @ApiStatus.Internal RegistryKey BLOCK = create("block"); /** - * @apiNote use preferably only in the context of registry entries. - * @see io.papermc.paper.registry.data + * Built-in registry for item types. * @see io.papermc.paper.registry.keys.ItemTypeKeys */ - @ApiStatus.Experimental // Paper - already required for registry builders RegistryKey ITEM = create("item"); /** * Built-in registry for villager professions. diff --git a/paper-api/src/main/java/org/bukkit/block/BlockType.java b/paper-api/src/main/java/org/bukkit/block/BlockType.java index c12cc7a243b..849ad58f80f 100644 --- a/paper-api/src/main/java/org/bukkit/block/BlockType.java +++ b/paper-api/src/main/java/org/bukkit/block/BlockType.java @@ -2,9 +2,10 @@ package org.bukkit.block; import java.util.Collection; import java.util.function.Consumer; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.KeyPattern; import org.bukkit.Keyed; import org.bukkit.Material; -import org.bukkit.NamespacedKey; import org.bukkit.Registry; import org.bukkit.Translatable; import org.bukkit.World; @@ -82,7 +83,6 @@ import org.bukkit.block.data.type.MangrovePropagule; import org.bukkit.block.data.type.MossyCarpet; import org.bukkit.block.data.type.NoteBlock; import org.bukkit.block.data.type.Observer; -import org.bukkit.block.data.type.PinkPetals; import org.bukkit.block.data.type.Piston; import org.bukkit.block.data.type.PistonHead; import org.bukkit.block.data.type.PitcherCrop; @@ -122,18 +122,14 @@ import org.bukkit.block.data.type.WallHangingSign; import org.bukkit.block.data.type.WallSign; import org.bukkit.block.data.type.WallSkull; import org.bukkit.inventory.ItemType; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Unmodifiable; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** - * While this API is in a public interface, it is not intended for use by - * plugins until further notice. The purpose of these types is to make - * {@link Material} more maintenance friendly, but will in due time be the - * official replacement for the aforementioned enum. Entirely incompatible - * changes may occur. Do not use this API in plugins. + * Represents a block type. */ -@org.jetbrains.annotations.ApiStatus.Experimental // Paper - data component API - already required for data component API +@NullMarked public interface BlockType extends Keyed, Translatable, net.kyori.adventure.translation.Translatable, io.papermc.paper.world.flag.FeatureDependant { // Paper - add translatable & feature flag API /** @@ -150,7 +146,6 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * * @return the BlockData class of this BlockType */ - @NotNull @Override Class getBlockDataClass(); @@ -161,7 +156,6 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * @param consumer consumer to run on new instance before returning * @return new data instance */ - @NotNull B createBlockData(@Nullable Consumer consumer); /** @@ -170,7 +164,6 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * * @return new data instance */ - @NotNull @Override B createBlockData(); @@ -181,7 +174,7 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * @return new block data collection */ @Override - @Unmodifiable @NotNull Collection createBlockDataStates(); + @Unmodifiable Collection createBlockDataStates(); /** * Creates a new {@link BlockData} instance for this block type, with all @@ -192,7 +185,6 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * @return new data instance * @throws IllegalArgumentException if the specified data is not valid */ - @NotNull B createBlockData(@Nullable String data); } @@ -2411,10 +2403,10 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran // End generate - BlockType // - @NotNull - private static B getBlockType(@NotNull String key) { + @SuppressWarnings("unchecked") + private static B getBlockType(@KeyPattern.Value final String key) { // Cast instead of using BlockType#typed, since block type can be a mock during testing and would return null - return (B) Registry.BLOCK.getOrThrow(NamespacedKey.minecraft(key)); + return (B) Registry.BLOCK.getOrThrow(Key.key(Key.MINECRAFT_NAMESPACE, key)); } /** @@ -2422,7 +2414,6 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * * @return the typed block type. */ - @NotNull BlockType.Typed typed(); /** @@ -2432,8 +2423,7 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * @param the generic type of the block data to type this block type with. * @return the typed block type. */ - @NotNull - BlockType.Typed typed(@NotNull Class blockDataType); + BlockType.Typed typed(Class blockDataType); /** * Returns true if this BlockType has a corresponding {@link ItemType}. @@ -2447,12 +2437,14 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * Returns the corresponding {@link ItemType} for the given BlockType. *

* If there is no corresponding {@link ItemType} an error will be thrown. + *

This is NOT the same as the {@link ItemType} with the same key, + * but instead is the item associated with this block if this block + * can be represented with an item.

* * @return the corresponding ItemType * @see #hasItemType() * @see BlockData#getPlacementMaterial() */ - @NotNull ItemType getItemType(); /** @@ -2460,7 +2452,6 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * * @return the BlockData class of this BlockType */ - @NotNull Class getBlockDataClass(); /** @@ -2469,7 +2460,6 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * * @return new data instance */ - @NotNull BlockData createBlockData(); /** @@ -2478,7 +2468,7 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * * @return new block data collection */ - @Unmodifiable @NotNull Collection createBlockDataStates(); + @Unmodifiable Collection createBlockDataStates(); /** * Creates a new {@link BlockData} instance for this block type, with all @@ -2489,7 +2479,6 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * @return new data instance * @throws IllegalArgumentException if the specified data is not valid */ - @NotNull BlockData createBlockData(@Nullable String data); /** @@ -2607,7 +2596,7 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * @deprecated use {@link io.papermc.paper.world.flag.FeatureFlagSetHolder#isEnabled(io.papermc.paper.world.flag.FeatureDependant)} */ @Deprecated(forRemoval = true, since = "1.21.1") // Paper - boolean isEnabledByFeature(@NotNull World world); + boolean isEnabledByFeature(World world); /** * Tries to convert this BlockType into a Material @@ -2619,21 +2608,17 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran @Deprecated(since = "1.20.6") Material asMaterial(); - // Paper start - add Translatable /** * @deprecated use {@link #translationKey()} and {@link net.kyori.adventure.text.Component#translatable(net.kyori.adventure.translation.Translatable)} */ @Deprecated(forRemoval = true) @Override - @NotNull String getTranslationKey(); - // Paper end - add Translatable + String getTranslationKey(); - // Paper start - hasCollision API /** * Checks if this block type has collision. *

* @return false if this block never has collision, true if it might have collision */ boolean hasCollision(); - // Paper end - hasCollision API } diff --git a/paper-api/src/main/java/org/bukkit/inventory/ItemType.java b/paper-api/src/main/java/org/bukkit/inventory/ItemType.java index 014f0f49fa2..9fb354d2929 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/ItemType.java +++ b/paper-api/src/main/java/org/bukkit/inventory/ItemType.java @@ -1,10 +1,13 @@ package org.bukkit.inventory; import com.google.common.collect.Multimap; +import io.papermc.paper.datacomponent.DataComponentType; +import java.util.Set; import java.util.function.Consumer; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.KeyPattern; import org.bukkit.Keyed; import org.bukkit.Material; -import org.bukkit.NamespacedKey; import org.bukkit.Registry; import org.bukkit.Translatable; import org.bukkit.World; @@ -36,17 +39,14 @@ import org.bukkit.inventory.meta.SpawnEggMeta; import org.bukkit.inventory.meta.SuspiciousStewMeta; import org.bukkit.inventory.meta.TropicalFishBucketMeta; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Unmodifiable; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** - * While this API is in a public interface, it is not intended for use by - * plugins until further notice. The purpose of these types is to make - * {@link Material} more maintenance friendly, but will in due time be the - * official replacement for the aforementioned enum. Entirely incompatible - * changes may occur. Do not use this API in plugins. + * Represents an item type. */ -@ApiStatus.Experimental // Paper - already required for registry builders +@NullMarked public interface ItemType extends Keyed, Translatable, net.kyori.adventure.translation.Translatable, io.papermc.paper.world.flag.FeatureDependant { // Paper - add Translatable & feature flag API /** @@ -54,7 +54,11 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * at compile time. * * @param the generic type of the item meta that represents the item type. + * @apiNote Do not use methods exclusive to this interface unless you are + * fine with them being possibly removed in the future. */ + @ApiStatus.Experimental + @ApiStatus.NonExtendable interface Typed extends ItemType { /** @@ -63,7 +67,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * @return the ItemMeta class of this ItemType */ @Override - @NotNull + @ApiStatus.Experimental Class getItemMetaClass(); /** @@ -73,7 +77,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * May be null if no intent exists to mutate the item meta at this point. * @return the created and configured item stack. */ - @NotNull + @ApiStatus.Experimental ItemStack createItemStack(@Nullable Consumer metaConfigurator); /** @@ -84,7 +88,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * May be null if no intent exists to mutate the item meta at this point. * @return the created and configured item stack. */ - @NotNull + @ApiStatus.Experimental ItemStack createItemStack(int amount, @Nullable Consumer metaConfigurator); } @@ -2923,18 +2927,19 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans // End generate - ItemType // - @NotNull - private static M getItemType(@NotNull String key) { + @SuppressWarnings("unchecked") + private static M getItemType(@KeyPattern.Value final String key) { // Cast instead of using ItemType#typed, since item type can be a mock during testing and would return null - return (M) Registry.ITEM.getOrThrow(NamespacedKey.minecraft(key)); + return (M) Registry.ITEM.getOrThrow(Key.key(Key.MINECRAFT_NAMESPACE, key)); } /** * Yields this item type as a typed version of itself with a plain {@link ItemMeta} representing it. * * @return the typed item type. + * @apiNote The Typed interface is experimental and may be removed in future versions. */ - @NotNull + @ApiStatus.Experimental Typed typed(); /** @@ -2943,16 +2948,16 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * @param itemMetaType the class type of the {@link ItemMeta} to type this {@link ItemType} with. * @param the generic type of the item meta to type this item type with. * @return the typed item type. + * @apiNote The Typed interface is experimental and may be removed in future versions. */ - @NotNull - Typed typed(@NotNull Class itemMetaType); + @ApiStatus.Experimental + Typed typed(Class itemMetaType); /** * Constructs a new itemstack with this item type that has the amount 1. * * @return the constructed item stack. */ - @NotNull ItemStack createItemStack(); /** @@ -2961,7 +2966,6 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * @param amount the amount of the item stack. * @return the constructed item stack. */ - @NotNull ItemStack createItemStack(int amount); /** @@ -2976,11 +2980,12 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * Returns the corresponding {@link BlockType} for the given ItemType. *

* If there is no corresponding {@link BlockType} an error will be thrown. + *

This is NOT the same as the {@link BlockType} with the same key, + * but instead is the block associated with this item if this item represents a block.

* * @return the corresponding BlockType * @see #hasBlockType() */ - @NotNull BlockType getBlockType(); /** @@ -2988,7 +2993,6 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * * @return the ItemMeta class of this ItemType */ - @NotNull Class getItemMetaClass(); /** @@ -3064,20 +3068,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * * @return the item left behind when crafting, or null if nothing is. */ - @Nullable - ItemType getCraftingRemainingItem(); + @Nullable ItemType getCraftingRemainingItem(); -// /** -// * Get the best suitable slot for this item type. -// * -// * For most items this will be {@link EquipmentSlot#HAND}. -// * -// * @return the best EquipmentSlot for this item type -// */ -// @NotNull -// EquipmentSlot getEquipmentSlot(); - - // Paper start - improve default item attribute API /** * Return an immutable copy of all default {@link Attribute}s and their * {@link AttributeModifier}s. @@ -3089,8 +3081,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * @return the immutable {@link Multimap} with the respective default * Attributes and modifiers, or an empty map if no attributes are set. */ - @NotNull @org.jetbrains.annotations.Unmodifiable Multimap getDefaultAttributeModifiers(); - // Paper end - improve default item attribute API + @Unmodifiable Multimap getDefaultAttributeModifiers(); /** * Return an immutable copy of all default {@link Attribute}s and their @@ -3103,8 +3094,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * @return the immutable {@link Multimap} with the respective default * Attributes and modifiers, or an empty map if no attributes are set. */ - @NotNull - Multimap getDefaultAttributeModifiers(@NotNull EquipmentSlot slot); + @Unmodifiable Multimap getDefaultAttributeModifiers(EquipmentSlot slot); /** * Get the {@link CreativeCategory} to which this item type belongs. @@ -3112,9 +3102,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * @return the creative category. null if does not belong to a category */ - @Nullable @Deprecated(since = "1.20.6", forRemoval = true) - CreativeCategory getCreativeCategory(); + @Nullable CreativeCategory getCreativeCategory(); /** * Gets if the ItemType is enabled by the features in a world. @@ -3124,7 +3113,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * @deprecated use {@link io.papermc.paper.world.flag.FeatureFlagSetHolder#isEnabled(io.papermc.paper.world.flag.FeatureDependant)} */ @Deprecated(forRemoval = true, since = "1.21.1") // Paper - boolean isEnabledByFeature(@NotNull World world); + boolean isEnabledByFeature(World world); /** * Tries to convert this ItemType into a Material @@ -3132,38 +3121,33 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * @return the converted Material or null * @deprecated only for internal use */ - @Nullable @Deprecated(since = "1.20.6") - Material asMaterial(); + @Nullable Material asMaterial(); - // Paper start - add Translatable /** * @deprecated use {@link #translationKey()} and {@link net.kyori.adventure.text.Component#translatable(net.kyori.adventure.translation.Translatable)} */ @Deprecated(forRemoval = true) @Override - @NotNull String getTranslationKey(); - // Paper end - add Translatable + String getTranslationKey(); - // Paper start - expand ItemRarity API /** * Returns the item rarity for the item. * * @return the item rarity (or null if none is set) */ @Nullable ItemRarity getItemRarity(); - // Paper end - expand ItemRarity API - // Paper start - data component API + /** * Gets the default value of the data component type for this item type. * * @param type the data component type * @param the value type * @return the default value or {@code null} if there is none - * @see #hasDefaultData(io.papermc.paper.datacomponent.DataComponentType) for DataComponentType.NonValued + * @see #hasDefaultData(DataComponentType) for DataComponentType.NonValued */ - @org.jetbrains.annotations.ApiStatus.Experimental - @Nullable T getDefaultData(io.papermc.paper.datacomponent.DataComponentType.@NotNull Valued type); + @ApiStatus.Experimental + @Nullable T getDefaultData(DataComponentType.Valued type); /** * Checks if the data component type has a default value for this item type. @@ -3172,14 +3156,13 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * @return {@code true} if there is a default value */ @org.jetbrains.annotations.ApiStatus.Experimental - boolean hasDefaultData(io.papermc.paper.datacomponent.@NotNull DataComponentType type); + boolean hasDefaultData(DataComponentType type); /** * Gets the default data component types for this item type. * * @return an immutable set of data component types */ - @org.jetbrains.annotations.ApiStatus.Experimental - java.util.@org.jetbrains.annotations.Unmodifiable @NotNull Set getDefaultDataTypes(); - // Paper end - data component API + @ApiStatus.Experimental + @Unmodifiable Set getDefaultDataTypes(); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java index 2b55195d964..261f593aaaa 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java @@ -185,11 +185,6 @@ public class CraftItemType extends HolderableBase impl return expectedItem.isEmpty() ? null : CraftItemType.minecraftToBukkitNew(expectedItem.getItem()); } -// @Override -// public EquipmentSlot getEquipmentSlot() { -// return CraftEquipmentSlot.getSlot(EntityInsentient.getEquipmentSlotForItem(CraftItemStack.asNMSCopy(ItemStack.of(this)))); -// } - @Override public Multimap getDefaultAttributeModifiers() { return this.getDefaultAttributeModifiers(sg -> true);