diff options
author | Lulu13022002 <[email protected]> | 2024-06-28 19:31:29 +0200 |
---|---|---|
committer | Owen1212055 <[email protected]> | 2024-11-18 14:50:38 -0500 |
commit | cab010912740af9a0ddfbd08aa08095b15ec8aa9 (patch) | |
tree | 93387cf0575e5bc1d680f319b2b3973db1a3fa11 | |
parent | e3e60ca1993e86eb13fa2059c8e4d8012a846441 (diff) | |
download | Paper-cab010912740af9a0ddfbd08aa08095b15ec8aa9.tar.gz Paper-cab010912740af9a0ddfbd08aa08095b15ec8aa9.zip |
some other changes
-rw-r--r-- | patches/api/0480-WIP-DataComponent-API.patch | 350 | ||||
-rw-r--r-- | patches/server/1026-WIP-DataComponent-API.patch | 485 |
2 files changed, 405 insertions, 430 deletions
diff --git a/patches/api/0480-WIP-DataComponent-API.patch b/patches/api/0480-WIP-DataComponent-API.patch index e7927fc859..ae09b3ddb4 100644 --- a/patches/api/0480-WIP-DataComponent-API.patch +++ b/patches/api/0480-WIP-DataComponent-API.patch @@ -6,7 +6,7 @@ Subject: [PATCH] WIP DataComponent API diff --git a/src/main/java/io/papermc/paper/block/BlockPredicate.java b/src/main/java/io/papermc/paper/block/BlockPredicate.java new file mode 100644 -index 0000000000000000000000000000000000000000..360f2b0075a478a034b1baddd1e7c70d252f84f7 +index 0000000000000000000000000000000000000000..ad7a6a260bc6903039ed3d0a961cec82b2f6fff7 --- /dev/null +++ b/src/main/java/io/papermc/paper/block/BlockPredicate.java @@ -0,0 +1,54 @@ @@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..360f2b0075a478a034b1baddd1e7c70d + + @NotNull + static Builder predicate() { -+ record BlockPredicateImpl(RegistryKeySet<BlockType> blocks) implements BlockPredicate { ++ record BlockPredicateImpl(RegistryKeySet<@NotNull BlockType> blocks) implements BlockPredicate { + + @Override + public @Nullable RegistryKeySet<@NotNull BlockType> blocks() { @@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..360f2b0075a478a034b1baddd1e7c70d + + class BuilderImpl implements Builder { + -+ private @Nullable RegistryKeySet<BlockType> blocks = null; ++ private @Nullable RegistryKeySet<@NotNull BlockType> blocks; + + @Override + public @NotNull Builder blocks(@Nullable final RegistryKeySet<@NotNull BlockType> blocks) { @@ -52,7 +52,7 @@ index 0000000000000000000000000000000000000000..360f2b0075a478a034b1baddd1e7c70d + return new BuilderImpl(); + } + -+ @Nullable RegistryKeySet<@org.jetbrains.annotations.NotNull BlockType> blocks(); ++ @Nullable RegistryKeySet<@NotNull BlockType> blocks(); + + @ApiStatus.Experimental + @ApiStatus.NonExtendable @@ -127,10 +127,10 @@ index 0000000000000000000000000000000000000000..e3fe89c9927d3b82ac7f6cadd51db565 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/DataComponentTypes.java b/src/main/java/io/papermc/paper/datacomponent/DataComponentTypes.java new file mode 100644 -index 0000000000000000000000000000000000000000..0660abc2a184a2684b4a6817590b67b38022b19f +index 0000000000000000000000000000000000000000..9529246c5f4d7b0e5a071a662850776a24b4380a --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/DataComponentTypes.java -@@ -0,0 +1,316 @@ +@@ -0,0 +1,322 @@ +package io.papermc.paper.datacomponent; + +import io.papermc.paper.datacomponent.item.BannerPatternLayers; @@ -153,7 +153,7 @@ index 0000000000000000000000000000000000000000..0660abc2a184a2684b4a6817590b67b3 +import io.papermc.paper.datacomponent.item.MapDecorations; +import io.papermc.paper.datacomponent.item.MapID; +import io.papermc.paper.datacomponent.item.MapItemColor; -+import io.papermc.paper.datacomponent.item.MapPostProcessing; ++import io.papermc.paper.item.MapPostProcessing; +import io.papermc.paper.datacomponent.item.PotDecorations; +import io.papermc.paper.datacomponent.item.PotionContents; +import io.papermc.paper.datacomponent.item.ResolvableProfile; @@ -186,36 +186,39 @@ index 0000000000000000000000000000000000000000..0660abc2a184a2684b4a6817590b67b3 + + // public static final DataComponentType.Valued<BinaryTagHolder> CUSTOM_DATA = valued("custom_data"); + /** -+ * Controls the maximum stacking size of this item ++ * Controls the maximum stacking size of this item. + * <br> -+ * Values greater than 1 are mutually exclusive with the {@link #MAX_DAMAGE} component ++ * Values greater than 1 are mutually exclusive with the {@link #MAX_DAMAGE} component. + */ + public static final DataComponentType.Valued<@IntRange(from = 1, to = 99) Integer> MAX_STACK_SIZE = valued("max_stack_size"); + /** + * Controls the maximum amount of damage than an item can take, -+ * if not present, the item cannot be damaged ++ * if not present, the item cannot be damaged. + * <br> -+ * Mutually exclusive with the {@link #MAX_STACK_SIZE} component greater than 1 ++ * Mutually exclusive with the {@link #MAX_STACK_SIZE} component greater than 1. ++ * + * @see #DAMAGE + */ + public static final DataComponentType.Valued<@Positive Integer> MAX_DAMAGE = valued("max_damage"); + /** + * The amount of durability removed from an item, -+ * for damageable items (with the {@link #MAX_DAMAGE} component), has an implicit default value of: {@code 0} ++ * for damageable items (with the {@link #MAX_DAMAGE} component), has an implicit default value of: {@code 0}. ++ * + * @see #MAX_DAMAGE + */ + public static final DataComponentType.Valued<@NonNegative Integer> DAMAGE = valued("damage"); + /** -+ * If set, the item will not lose any durability when used ++ * If set, the item will not lose any durability when used. + */ + public static final DataComponentType.Valued<Unbreakable> UNBREAKABLE = valued("unbreakable"); + /** -+ * Custom name override for an item (as set by renaming with an Anvil) ++ * Custom name override for an item (as set by renaming with an Anvil). ++ * + * @see #ITEM_NAME + */ + public static final DataComponentType.Valued<Component> CUSTOM_NAME = valued("custom_name"); + /** -+ * When present, replaces default item name with contained chat component ++ * When present, replaces default item name with contained chat component. + * <p> + * Differences from {@link #CUSTOM_NAME}: + * <ul> @@ -224,21 +227,23 @@ index 0000000000000000000000000000000000000000..0660abc2a184a2684b4a6817590b67b3 + * <li>does not show labels where applicable + * (for example: banner markers, names in item frames)</li> + * </ul> ++ * + * @see #CUSTOM_NAME + */ + public static final DataComponentType.Valued<Component> ITEM_NAME = valued("item_name"); + /** -+ * Additional lines to include in an item's tooltip ++ * Additional lines to include in an item's tooltip. + */ + public static final DataComponentType.Valued<ItemLore> LORE = valued("lore"); + /** -+ * Controls the color of the item name ++ * Controls the color of the item name. + */ + public static final DataComponentType.Valued<ItemRarity> RARITY = valued("rarity"); + /** -+ * Controls the enchantments on an item ++ * Controls the enchantments on an item. + * <br> -+ * If not present on a non-enchantment book, this item will not work in an anvil ++ * If not present on a non-enchantment book, this item will not work in an anvil. ++ * + * @see #STORED_ENCHANTMENTS + */ + public static final DataComponentType.Valued<ItemEnchantments> ENCHANTMENTS = valued("enchantments"); @@ -253,25 +258,25 @@ index 0000000000000000000000000000000000000000..0660abc2a184a2684b4a6817590b67b3 + /** + * Holds attribute modifiers applied to any item, + * if not set, has an implicit default value based on the item type's -+ * default attributes (e.g. attack damage for weapons) ++ * default attributes (e.g. attack damage for weapons). + */ + public static final DataComponentType.Valued<ItemAttributeModifiers> ATTRIBUTE_MODIFIERS = valued("attribute_modifiers"); + /** -+ * Controls the minecraft:custom_model_data property in the item model ++ * Controls the minecraft:custom_model_data property in the item model. + */ + public static final DataComponentType.Valued<CustomModelData> CUSTOM_MODEL_DATA = valued("custom_model_data"); + /** + * If set, disables 'additional' tooltip part which comes from the item type -+ * (e.g. content of a shulker) ++ * (e.g. content of a shulker). + */ + public static final DataComponentType.NonValued HIDE_ADDITIONAL_TOOLTIP = unvalued("hide_additional_tooltip"); + /** -+ * If set, it will completely hide whole item tooltip (that includes item name) ++ * If set, it will completely hide whole item tooltip (that includes item name). + */ + public static final DataComponentType.NonValued HIDE_TOOLTIP = unvalued("hide_tooltip"); + /** + * The additional experience cost required to modify an item in an Anvil. -+ * If not present, has an implicit default value of: {@code 0} ++ * If not present, has an implicit default value of: {@code 0}. + */ + public static final DataComponentType.Valued<@NonNegative Integer> REPAIR_COST = valued("repair_cost"); + /** @@ -280,24 +285,24 @@ index 0000000000000000000000000000000000000000..0660abc2a184a2684b4a6817590b67b3 + public static final DataComponentType.NonValued CREATIVE_SLOT_LOCK = unvalued("creative_slot_lock"); + /** + * Overrides the enchantment glint effect on an item. -+ * If not present, default behaviour is used ++ * If not present, default behaviour is used. + */ + public static final DataComponentType.Valued<Boolean> ENCHANTMENT_GLINT_OVERRIDE = valued("enchantment_glint_override"); + /** + * Marks that a projectile item would be intangible when fired -+ * (i.e. can only be picked up by a creative mode player) ++ * (i.e. can only be picked up by a creative mode player). + */ + public static final DataComponentType.NonValued INTANGIBLE_PROJECTILE = unvalued("intangible_projectile"); + /** -+ * When present, this item will behave as if a food (can be eaten) ++ * When present, this item will behave as if a food (can be eaten). + */ + public static final DataComponentType.Valued<FoodProperties> FOOD = valued("food"); + /** -+ * If present, this item will not burn in fire ++ * If present, this item will not burn in fire. + */ + public static final DataComponentType.NonValued FIRE_RESISTANT = unvalued("fire_resistant"); + /** -+ * Controls the behavior of the item as a tool ++ * Controls the behavior of the item as a tool. + */ + public static final DataComponentType.Valued<Tool> TOOL = valued("tool"); + /** @@ -305,59 +310,60 @@ index 0000000000000000000000000000000000000000..0660abc2a184a2684b4a6817590b67b3 + * Unlike {@link #ENCHANTMENTS}, the effects provided by enchantments + * do not apply from this component. + * <br> -+ * If not present on an Enchanted Book, it will not work in an anvil -+ * <br> ++ * If not present on an Enchanted Book, it will not work in an anvil. ++ * <p> + * Has an undefined behaviour if present on an item that is not an Enchanted Book + * (currently the presence of this component allows enchantments from {@link #ENCHANTMENTS} -+ * to be applied as if this item was an Enchanted Book) ++ * to be applied as if this item was an Enchanted Book). ++ * + * @see #ENCHANTMENTS + */ + public static final DataComponentType.Valued<ItemEnchantments> STORED_ENCHANTMENTS = valued("stored_enchantments"); + /** -+ * Represents a color applied to a dyeable item (in the {@link org.bukkit.Tag#ITEMS_DYEABLE} item tag) ++ * Represents a color applied to a dyeable item (in the {@link io.papermc.paper.registry.keys.tags.ItemTypeTagKeys#DYEABLE} item tag). + */ + public static final DataComponentType.Valued<DyedItemColor> DYED_COLOR = valued("dyed_color"); + /** -+ * Represents the tint of the decorations on the Filled Map item ++ * Represents the tint of the decorations on the Filled Map item. + */ + public static final DataComponentType.Valued<MapItemColor> MAP_COLOR = valued("map_color"); + /** -+ * References the shared map state holding map contents and markers for a Filled Map ++ * References the shared map state holding map contents and markers for a Filled Map. + */ + public static final DataComponentType.Valued<MapID> MAP_ID = valued("map_id"); + /** -+ * Holds a list of markers to be placed on a Filled Map (used for Explorer Maps) ++ * Holds a list of markers to be placed on a Filled Map (used for Explorer Maps). + */ + public static final DataComponentType.Valued<MapDecorations> MAP_DECORATIONS = valued("map_decorations"); + /** -+ * Internal map item state used in the map crafting recipe ++ * Internal map item state used in the map crafting recipe. + */ + public static final DataComponentType.Valued<MapPostProcessing> MAP_POST_PROCESSING = valued("map_post_processing"); + /** + * Holds all projectiles that have been loaded into a Crossbow. -+ * If not present, the Crossbow is not charged ++ * If not present, the Crossbow is not charged. + */ + public static final DataComponentType.Valued<ChargedProjectiles> CHARGED_PROJECTILES = valued("charged_projectiles"); + /** + * Holds all items stored inside a Bundle. -+ * If removed, items cannot be added to the Bundle ++ * If removed, items cannot be added to the Bundle. + */ + public static final DataComponentType.Valued<BundleContents> BUNDLE_CONTENTS = valued("bundle_contents"); + /** + * Holds the contents of a potion (Potion, Splash Potion, Lingering Potion), -+ * or potion applied to an item (Tipped Arrow) ++ * or potion applied to a Tipped Arrow. + */ + public static final DataComponentType.Valued<PotionContents> POTION_CONTENTS = valued("potion_contents"); + /** -+ * Holds the effects that will be applied when consuming Suspicious Stew ++ * Holds the effects that will be applied when consuming Suspicious Stew. + */ + public static final DataComponentType.Valued<SuspiciousStewEffects> SUSPICIOUS_STEW_EFFECTS = valued("suspicious_stew_effects"); + /** -+ * Holds the contents in a Book and Quill ++ * Holds the contents in a Book and Quill. + */ + public static final DataComponentType.Valued<WritableBookContent> WRITABLE_BOOK_CONTENT = valued("writable_book_content"); + /** -+ * Holds the contents and metadata of a Written Book ++ * Holds the contents and metadata of a Written Book. + */ + public static final DataComponentType.Valued<WrittenBookContent> WRITTEN_BOOK_CONTENT = valued("written_book_content"); + /** @@ -369,69 +375,69 @@ index 0000000000000000000000000000000000000000..0660abc2a184a2684b4a6817590b67b3 + // bucket_entity_data + // block_entity_data + /** -+ * Holds the instrument type used by a Goat Horn ++ * Holds the instrument type used by a Goat Horn. + */ + public static final DataComponentType.Valued<MusicInstrument> INSTRUMENT = valued("instrument"); + /** -+ * Controls the amplifier amount for an Ominous Bottle's Bad Omen effect ++ * Controls the amplifier amount for an Ominous Bottle's Bad Omen effect. + */ + public static final DataComponentType.Valued<@IntRange(from = 0, to = 4) Integer> OMINOUS_BOTTLE_AMPLIFIER = valued("ominous_bottle_amplifier"); + /** -+ * List of recipes that should be unlocked when using the Knowledge Book item ++ * List of recipes that should be unlocked when using the Knowledge Book item. + */ + public static final DataComponentType.Valued<JukeboxPlayable> JUKEBOX_PLAYABLE = valued("jukebox_playable"); + public static final DataComponentType.Valued<List<Key>> RECIPES = valued("recipes"); + /** -+ * If present, specifies that the Compass is a Lodestone Compass ++ * If present, specifies that the Compass is a Lodestone Compass. + */ + public static final DataComponentType.Valued<LodestoneTracker> LODESTONE_TRACKER = valued("lodestone_tracker"); + /** -+ * Stores the explosion crafted in a Firework Star ++ * Stores the explosion crafted in a Firework Star. + */ + public static final DataComponentType.Valued<FireworkEffect> FIREWORK_EXPLOSION = valued("firework_explosion"); + /** -+ * Stores all explosions crafted into a Firework Rocket, as well as flight duration ++ * Stores all explosions crafted into a Firework Rocket, as well as flight duration. + */ + public static final DataComponentType.Valued<Fireworks> FIREWORKS = valued("fireworks"); + /** -+ * Controls the skin displayed on a Player Head ++ * Controls the skin displayed on a Player Head. + */ + public static final DataComponentType.Valued<ResolvableProfile> PROFILE = valued("profile"); + /** -+ * Controls the sound played by a Player Head when placed on a Note Block ++ * Controls the sound played by a Player Head when placed on a Note Block. + */ + public static final DataComponentType.Valued<NamespacedKey> NOTE_BLOCK_SOUND = valued("note_block_sound"); + /** -+ * Stores the additional patterns applied to a Banner or Shield ++ * Stores the additional patterns applied to a Banner or Shield. + */ + public static final DataComponentType.Valued<BannerPatternLayers> BANNER_PATTERNS = valued("banner_patterns"); + /** -+ * Stores the base color for a Shield ++ * Stores the base color for a Shield. + */ + public static final DataComponentType.Valued<DyeColor> BASE_COLOR = valued("base_color"); + /** -+ * Stores the Sherds applied to each side of a Decorated Pot ++ * Stores the Sherds applied to each side of a Decorated Pot. + */ + public static final DataComponentType.Valued<PotDecorations> POT_DECORATIONS = valued("pot_decorations"); + /** -+ * Holds the contents of container blocks (Chests, Shulker Boxes) in item form ++ * Holds the contents of container blocks (Chests, Shulker Boxes) in item form. + */ + public static final DataComponentType.Valued<ItemContainerContents> CONTAINER = valued("container"); + /** -+ * Holds block state properties to apply when placing a block ++ * Holds block state properties to apply when placing a block. + */ + public static final DataComponentType.Valued<BlockItemDataProperties> BLOCK_DATA = valued("block_state"); + // bees + /** + * Holds the lock state of a container-like block, -+ * copied to container block when placed ++ * copied to container block when placed. + * <br> + * An item with a custom name of the same value must be used -+ * to open this container ++ * to open this container. + */ + public static final DataComponentType.Valued<LockCode> LOCK = valued("lock"); + /** -+ * Holds the unresolved loot table and seed of a container-like block ++ * Holds the unresolved loot table and seed of a container-like block. + */ + public static final DataComponentType.Valued<SeededContainerLoot> CONTAINER_LOOT = valued("container_loot"); + @@ -531,7 +537,7 @@ index 0000000000000000000000000000000000000000..270f98e95b1d0322a42bad52d492fa00 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/BundleContents.java b/src/main/java/io/papermc/paper/datacomponent/item/BundleContents.java new file mode 100644 -index 0000000000000000000000000000000000000000..07b3efef6fa502468138c3fef4a9e9d8b1f06b93 +index 0000000000000000000000000000000000000000..d5b1718ae01d6ea73f75446240d169ba9f0d7778 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/BundleContents.java @@ -0,0 +1,62 @@ @@ -582,7 +588,7 @@ index 0000000000000000000000000000000000000000..07b3efef6fa502468138c3fef4a9e9d8 + * Adds an item to this builder. + * + * @param stack item -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder add(@NonNull ItemStack stack); @@ -591,7 +597,7 @@ index 0000000000000000000000000000000000000000..07b3efef6fa502468138c3fef4a9e9d8 + * Adds items to this builder. + * + * @param stacks items -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder addAll(@NonNull List<@NonNull ItemStack> stacks); @@ -599,7 +605,7 @@ index 0000000000000000000000000000000000000000..07b3efef6fa502468138c3fef4a9e9d8 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ChargedProjectiles.java b/src/main/java/io/papermc/paper/datacomponent/item/ChargedProjectiles.java new file mode 100644 -index 0000000000000000000000000000000000000000..7c703b696cfe966a4dc400c419f97a1c9334b4fb +index 0000000000000000000000000000000000000000..b8eea6dd890bfed0462cffb0aac48ee8010636f1 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/ChargedProjectiles.java @@ -0,0 +1,62 @@ @@ -650,7 +656,7 @@ index 0000000000000000000000000000000000000000..7c703b696cfe966a4dc400c419f97a1c + * Adds a projectile to be loaded in this builder. + * + * @param stack projectile -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder add(@NonNull ItemStack stack); @@ -659,7 +665,7 @@ index 0000000000000000000000000000000000000000..7c703b696cfe966a4dc400c419f97a1c + * Adds projectiles to be loaded in this builder. + * + * @param stacks projectiles -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder addAll(@NonNull List<@NonNull ItemStack> stacks); @@ -795,7 +801,7 @@ index 0000000000000000000000000000000000000000..e93f962fc51c0f260719fccad7ccdadc +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/DyedItemColor.java b/src/main/java/io/papermc/paper/datacomponent/item/DyedItemColor.java new file mode 100644 -index 0000000000000000000000000000000000000000..3c0061339a534cf7f255fa4ba3b5687721c18616 +index 0000000000000000000000000000000000000000..93f419b8e4d9c87b3ad4fa570d3bfad484deec2c --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/DyedItemColor.java @@ -0,0 +1,45 @@ @@ -838,7 +844,7 @@ index 0000000000000000000000000000000000000000..3c0061339a534cf7f255fa4ba3b56877 + * Sets the color of this builder. + * + * @param color color -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder color(@NonNull Color color); @@ -846,10 +852,10 @@ index 0000000000000000000000000000000000000000..3c0061339a534cf7f255fa4ba3b56877 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/Fireworks.java b/src/main/java/io/papermc/paper/datacomponent/item/Fireworks.java new file mode 100644 -index 0000000000000000000000000000000000000000..feb1addc53213b2d32dc81614a7401e76a5aa38b +index 0000000000000000000000000000000000000000..c59b57eab245e7c8de1c466aa535db4a4913ff17 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/Fireworks.java -@@ -0,0 +1,75 @@ +@@ -0,0 +1,74 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.datacomponent.ComponentBuilder; @@ -891,8 +897,7 @@ index 0000000000000000000000000000000000000000..feb1addc53213b2d32dc81614a7401e7 + * @return the flight duration + */ + @Contract(pure = true) -+ @IntRange(from = 0, to = 255) -+ int flightDuration(); ++ @IntRange(from = 0, to = 255) int flightDuration(); + + @ApiStatus.NonExtendable + interface Builder extends ComponentBuilder<Fireworks> { @@ -901,7 +906,7 @@ index 0000000000000000000000000000000000000000..feb1addc53213b2d32dc81614a7401e7 + * Sets the number of gunpowder used in this builder. + * + * @param duration duration -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder flightDuration(@IntRange(from = 0, to = 255) int duration); @@ -910,7 +915,7 @@ index 0000000000000000000000000000000000000000..feb1addc53213b2d32dc81614a7401e7 + * Adds an explosion to this builder. + * + * @param effect effect -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder add(@NonNull FireworkEffect effect); @@ -919,7 +924,7 @@ index 0000000000000000000000000000000000000000..feb1addc53213b2d32dc81614a7401e7 + * Adds explosions to this builder. + * + * @param effects effects -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder addAll(@NonNull List<@NonNull FireworkEffect> effects); @@ -927,10 +932,10 @@ index 0000000000000000000000000000000000000000..feb1addc53213b2d32dc81614a7401e7 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/FoodProperties.java b/src/main/java/io/papermc/paper/datacomponent/item/FoodProperties.java new file mode 100644 -index 0000000000000000000000000000000000000000..451d9656707c61bca93193284dbf0f28a5190de8 +index 0000000000000000000000000000000000000000..9d207063f794873acb22ce1e88b072b4952aadfc --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/FoodProperties.java -@@ -0,0 +1,114 @@ +@@ -0,0 +1,113 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.datacomponent.ComponentBuilder; @@ -953,16 +958,15 @@ index 0000000000000000000000000000000000000000..451d9656707c61bca93193284dbf0f28 + } + + /** -+ * Number of food points to restore when eaten ++ * Number of food points to restore when eaten. + * -+ * @return non-negative integer ++ * @return the nutrition + */ + @Contract(pure = true) -+ @NonNegative -+ int nutrition(); ++ @NonNegative int nutrition(); + + /** -+ * Amount of saturation to restore when eaten ++ * Amount of saturation to restore when eaten. + * + * @return the saturation + */ @@ -970,7 +974,7 @@ index 0000000000000000000000000000000000000000..451d9656707c61bca93193284dbf0f28 + float saturation(); + + /** -+ * If true, this food can be eaten even if not hungry. ++ * If {@code true}, this food can be eaten even if not hungry. + * + * @return can always be eaten + */ @@ -1006,7 +1010,7 @@ index 0000000000000000000000000000000000000000..451d9656707c61bca93193284dbf0f28 + } + + /** -+ * Effect instance ++ * Effect instance. + * + * @return effect + */ @@ -1036,7 +1040,7 @@ index 0000000000000000000000000000000000000000..451d9656707c61bca93193284dbf0f28 + @NonNull Builder nutrition(int nutrition); + + @Contract(value = "_ -> this", mutates = "this") -+ @NonNull Builder usingConvertsTo(@Nullable ItemStack itemStack); ++ @NonNull Builder usingConvertsTo(@Nullable ItemStack stack); + + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder addEffect(@NonNull PossibleEffect effect); @@ -1047,7 +1051,7 @@ index 0000000000000000000000000000000000000000..451d9656707c61bca93193284dbf0f28 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ItemAdventurePredicate.java b/src/main/java/io/papermc/paper/datacomponent/item/ItemAdventurePredicate.java new file mode 100644 -index 0000000000000000000000000000000000000000..8b71f115c853241091019c612112331706849373 +index 0000000000000000000000000000000000000000..000b681492032047287a8a412142268d29e63f3a --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemAdventurePredicate.java @@ -0,0 +1,42 @@ @@ -1086,16 +1090,16 @@ index 0000000000000000000000000000000000000000..8b71f115c853241091019c6121123317 + * Adds a block predicate to this builder. + * + * @param predicate predicate -+ * @return self ++ * @return the builder for chaining + * @see #predicates() + */ -+ @Contract(value = "_, _ -> this", mutates = "this") ++ @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder addPredicate(@NonNull BlockPredicate predicate); + } +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ItemArmorTrim.java b/src/main/java/io/papermc/paper/datacomponent/item/ItemArmorTrim.java new file mode 100644 -index 0000000000000000000000000000000000000000..dc968b953f89fd3a07eb633370a95879bc369f8c +index 0000000000000000000000000000000000000000..e874f024a6a5493aad08db4a94dbfa58af78cfd4 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemArmorTrim.java @@ -0,0 +1,45 @@ @@ -1135,10 +1139,10 @@ index 0000000000000000000000000000000000000000..dc968b953f89fd3a07eb633370a95879 + interface Builder extends ShownInTooltip.Builder<Builder>, ComponentBuilder<ItemArmorTrim> { + + /** -+ * Sets the item trim for this builder. ++ * Sets the armor trim for this builder. + * + * @param armorTrim trim -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder armorTrim(@NonNull ArmorTrim armorTrim); @@ -1146,7 +1150,7 @@ index 0000000000000000000000000000000000000000..dc968b953f89fd3a07eb633370a95879 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ItemAttributeModifiers.java b/src/main/java/io/papermc/paper/datacomponent/item/ItemAttributeModifiers.java new file mode 100644 -index 0000000000000000000000000000000000000000..32432542a4c11f0f5c5c7e397ac9a3c51530376b +index 0000000000000000000000000000000000000000..852259c5ec59f1aa32261d14fbb5c7608795f9ee --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemAttributeModifiers.java @@ -0,0 +1,57 @@ @@ -1201,7 +1205,7 @@ index 0000000000000000000000000000000000000000..32432542a4c11f0f5c5c7e397ac9a3c5 + * + * @param attribute attribute + * @param attributeModifier modifier -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_, _ -> this", mutates = "this") + @NonNull Builder addModifier(@NonNull Attribute attribute, @NonNull AttributeModifier attributeModifier); @@ -1209,7 +1213,7 @@ index 0000000000000000000000000000000000000000..32432542a4c11f0f5c5c7e397ac9a3c5 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ItemContainerContents.java b/src/main/java/io/papermc/paper/datacomponent/item/ItemContainerContents.java new file mode 100644 -index 0000000000000000000000000000000000000000..a748ef9a97a3aa1bba794470cc7c2a8ca58e7ecf +index 0000000000000000000000000000000000000000..1f44eac662f975ee123305eb935e068bf916052e --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemContainerContents.java @@ -0,0 +1,42 @@ @@ -1249,15 +1253,15 @@ index 0000000000000000000000000000000000000000..a748ef9a97a3aa1bba794470cc7c2a8c + interface Builder extends ComponentBuilder<ItemContainerContents> { + + @Contract(value = "_ -> this", mutates = "this") -+ @NonNull Builder add(@NonNull ItemStack itemStack); ++ @NonNull Builder add(@NonNull ItemStack stack); + + @Contract(value = "_ -> this", mutates = "this") -+ @NonNull Builder addAll(@NonNull List<@NonNull ItemStack> itemStacks); ++ @NonNull Builder addAll(@NonNull List<@NonNull ItemStack> stacks); + } +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ItemEnchantments.java b/src/main/java/io/papermc/paper/datacomponent/item/ItemEnchantments.java new file mode 100644 -index 0000000000000000000000000000000000000000..a6420ba58822faa3cf6be130d1afc865000918dc +index 0000000000000000000000000000000000000000..3b519007fd7b7e62bcc15a1ad93fd61b954ee4c5 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemEnchantments.java @@ -0,0 +1,58 @@ @@ -1304,7 +1308,7 @@ index 0000000000000000000000000000000000000000..a6420ba58822faa3cf6be130d1afc865 + * + * @param enchantment enchantment + * @param level level -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_, _ -> this", mutates = "this") + @NonNull Builder add(@NonNull Enchantment enchantment, @IntRange(from = 1, to = 255) int level); @@ -1313,7 +1317,7 @@ index 0000000000000000000000000000000000000000..a6420ba58822faa3cf6be130d1afc865 + * Adds enchantments with the given level to this component. + * + * @param enchantments enchantments -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder addAll(@NonNull Map<@NonNull Enchantment, @NonNull @IntRange(from = 1, to = 255) Integer> enchantments); @@ -1321,7 +1325,7 @@ index 0000000000000000000000000000000000000000..a6420ba58822faa3cf6be130d1afc865 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ItemLore.java b/src/main/java/io/papermc/paper/datacomponent/item/ItemLore.java new file mode 100644 -index 0000000000000000000000000000000000000000..dafb334c6b4ab41398e1473d39e1047a8ca362b2 +index 0000000000000000000000000000000000000000..6ee7cdd943833fc72ef7260478a3fadf3496adf4 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemLore.java @@ -0,0 +1,74 @@ @@ -1375,7 +1379,7 @@ index 0000000000000000000000000000000000000000..dafb334c6b4ab41398e1473d39e1047a + * Sets the components of this lore. + * + * @param lines components -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + Builder lines(@NonNull List<@NonNull ? extends ComponentLike> lines); @@ -1384,7 +1388,7 @@ index 0000000000000000000000000000000000000000..dafb334c6b4ab41398e1473d39e1047a + * Adds a component to the lore. + * + * @param line component -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder addLine(@NonNull ComponentLike line); @@ -1393,7 +1397,7 @@ index 0000000000000000000000000000000000000000..dafb334c6b4ab41398e1473d39e1047a + * Adds components to the lore. + * + * @param lines components -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder addAllLines(@NonNull List<@NonNull ? extends ComponentLike> lines); @@ -1401,7 +1405,7 @@ index 0000000000000000000000000000000000000000..dafb334c6b4ab41398e1473d39e1047a +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/JukeboxPlayable.java b/src/main/java/io/papermc/paper/datacomponent/item/JukeboxPlayable.java new file mode 100644 -index 0000000000000000000000000000000000000000..ece9afbceb21dec772111a1e7a6813d6a7d39656 +index 0000000000000000000000000000000000000000..1d2276a6522044f06713db5ab8495d8aad863faf --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/JukeboxPlayable.java @@ -0,0 +1,26 @@ @@ -1413,6 +1417,7 @@ index 0000000000000000000000000000000000000000..ece9afbceb21dec772111a1e7a6813d6 +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; + +public interface JukeboxPlayable extends ShownInTooltip<JukeboxPlayable> { + + @Contract(value = "_ -> new", pure = true) @@ -1427,8 +1432,7 @@ index 0000000000000000000000000000000000000000..ece9afbceb21dec772111a1e7a6813d6 + interface Builder extends ShownInTooltip.Builder<JukeboxPlayable.Builder>, ComponentBuilder<JukeboxPlayable> { + + @Contract(value = "_ -> this", mutates = "this") -+ @NonNull -+ Builder jukeboxSong(@NonNull JukeboxSong song); ++ @NonNull Builder jukeboxSong(@NonNull JukeboxSong song); + } +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/LockCode.java b/src/main/java/io/papermc/paper/datacomponent/item/LockCode.java @@ -1466,7 +1470,7 @@ index 0000000000000000000000000000000000000000..cf6a2e8e6640deeae05283b3cb5755a4 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/LodestoneTracker.java b/src/main/java/io/papermc/paper/datacomponent/item/LodestoneTracker.java new file mode 100644 -index 0000000000000000000000000000000000000000..e5c6feb0267b05aab99d90e351ae2e848711a79b +index 0000000000000000000000000000000000000000..7b195f3cea91446fa75c1c0982b0ac7070edb9e5 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/LodestoneTracker.java @@ -0,0 +1,63 @@ @@ -1504,7 +1508,7 @@ index 0000000000000000000000000000000000000000..e5c6feb0267b05aab99d90e351ae2e84 + @Nullable Location location(); + + /** -+ * If true, when the Lodestone at the target position is removed, the component will be removed. ++ * If {@code true}, when the Lodestone at the target position is removed, the component will be removed. + * + * @return tracked + */ @@ -1518,7 +1522,7 @@ index 0000000000000000000000000000000000000000..e5c6feb0267b05aab99d90e351ae2e84 + * Sets the location to point towards for this builder. + * + * @param location location to point towards -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder location(@Nullable Location location); @@ -1527,7 +1531,7 @@ index 0000000000000000000000000000000000000000..e5c6feb0267b05aab99d90e351ae2e84 + * Sets if this location lodestone is tracked for this builder. + * + * @param tracked is tracked -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder tracked(boolean tracked); @@ -1535,7 +1539,7 @@ index 0000000000000000000000000000000000000000..e5c6feb0267b05aab99d90e351ae2e84 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/MapDecorations.java b/src/main/java/io/papermc/paper/datacomponent/item/MapDecorations.java new file mode 100644 -index 0000000000000000000000000000000000000000..83b6d7b8675fc924c6129d4090ee863a7dc64e3f +index 0000000000000000000000000000000000000000..3cf5e994ce00dcd1823b9fff5f0359316bbb647d --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/MapDecorations.java @@ -0,0 +1,105 @@ @@ -1550,7 +1554,7 @@ index 0000000000000000000000000000000000000000..83b6d7b8675fc924c6129d4090ee863a +import org.jetbrains.annotations.Contract; + +/** -+ * Holds a list of markers to be placed on a Filled Map (used for Explorer Maps) ++ * Holds a list of markers to be placed on a Filled Map (used for Explorer Maps). + */ +public interface MapDecorations { @@ -1599,7 +1603,7 @@ index 0000000000000000000000000000000000000000..83b6d7b8675fc924c6129d4090ee863a + /** + * X world coordinate of the decoration. + * -+ * @return x ++ * @return x coordinate + */ + @Contract(pure = true) + double x(); @@ -1607,7 +1611,7 @@ index 0000000000000000000000000000000000000000..83b6d7b8675fc924c6129d4090ee863a + /** + * Z world coordinate of the decoration. + * -+ * @return z ++ * @return z coordinate + */ + @Contract(pure = true) + double z(); @@ -1629,7 +1633,7 @@ index 0000000000000000000000000000000000000000..83b6d7b8675fc924c6129d4090ee863a + * + * @param id id + * @param entry decoration -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_, _ -> this", mutates = "this") + MapDecorations.@NonNull Builder put(@NonNull String id, @NonNull DecorationEntry entry); @@ -1638,7 +1642,7 @@ index 0000000000000000000000000000000000000000..83b6d7b8675fc924c6129d4090ee863a + * Puts all the decoration with the given id in this builder. + * + * @param entries decorations -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + MapDecorations.@NonNull Builder putAll(@NonNull Map<@NonNull String, @NonNull DecorationEntry> entries); @@ -1646,7 +1650,7 @@ index 0000000000000000000000000000000000000000..83b6d7b8675fc924c6129d4090ee863a +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/MapID.java b/src/main/java/io/papermc/paper/datacomponent/item/MapID.java new file mode 100644 -index 0000000000000000000000000000000000000000..74d70614f00391136ff797f900024d13bc9d34b9 +index 0000000000000000000000000000000000000000..89e3f32ef74e7a2018cf76ebe51f31a1037bb701 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/MapID.java @@ -0,0 +1,41 @@ @@ -1679,10 +1683,10 @@ index 0000000000000000000000000000000000000000..74d70614f00391136ff797f900024d13 + interface Builder { + + /** -+ * Sets the map id of this builder ++ * Sets the map id of this builder. + * + * @param id id -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder mapId(int id); @@ -1693,7 +1697,7 @@ index 0000000000000000000000000000000000000000..74d70614f00391136ff797f900024d13 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/MapItemColor.java b/src/main/java/io/papermc/paper/datacomponent/item/MapItemColor.java new file mode 100644 -index 0000000000000000000000000000000000000000..38d09482166323e8d06b82977e8bb7a95486afaf +index 0000000000000000000000000000000000000000..776a9f554519a0737b363a494e628e64a40bfe66 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/MapItemColor.java @@ -0,0 +1,41 @@ @@ -1726,10 +1730,10 @@ index 0000000000000000000000000000000000000000..38d09482166323e8d06b82977e8bb7a9 + interface Builder { + + /** -+ * Sets the map color of this builder. ++ * Sets the tint color of this map. + * -+ * @param color color -+ * @return self ++ * @param color tint color ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder mapColor(@NonNull Color color); @@ -1738,18 +1742,6 @@ index 0000000000000000000000000000000000000000..38d09482166323e8d06b82977e8bb7a9 + @NonNull MapItemColor build(); + } +} -diff --git a/src/main/java/io/papermc/paper/datacomponent/item/MapPostProcessing.java b/src/main/java/io/papermc/paper/datacomponent/item/MapPostProcessing.java -new file mode 100644 -index 0000000000000000000000000000000000000000..acdede37bf2625698e9a6c0521e7e98a5fd9c377 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/datacomponent/item/MapPostProcessing.java -@@ -0,0 +1,6 @@ -+package io.papermc.paper.datacomponent.item; -+ -+public enum MapPostProcessing { -+ LOCK, -+ SCALE -+} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PotDecorations.java b/src/main/java/io/papermc/paper/datacomponent/item/PotDecorations.java new file mode 100644 index 0000000000000000000000000000000000000000..abd94c0c900f7c2bf936e0c5c28ec92847db39ec @@ -1808,7 +1800,7 @@ index 0000000000000000000000000000000000000000..abd94c0c900f7c2bf936e0c5c28ec928 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PotionContents.java b/src/main/java/io/papermc/paper/datacomponent/item/PotionContents.java new file mode 100644 -index 0000000000000000000000000000000000000000..e6779fb88cbb8d7166eecd161aab8620d05485f7 +index 0000000000000000000000000000000000000000..586f32d0198ec0f17006066c72fad8c5e7af6120 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PotionContents.java @@ -0,0 +1,92 @@ @@ -1826,7 +1818,7 @@ index 0000000000000000000000000000000000000000..e6779fb88cbb8d7166eecd161aab8620 +import org.jetbrains.annotations.Unmodifiable; + +/** -+ * Holds the contents of a potion (Potion, Splash Potion, Lingering Potion), or potion applied to an item (Tipped Arrow) ++ * Holds the contents of a potion (Potion, Splash Potion, Lingering Potion), or potion applied to a Tipped Arrow. + */ +public interface PotionContents { @@ -1845,7 +1837,7 @@ index 0000000000000000000000000000000000000000..e6779fb88cbb8d7166eecd161aab8620 + @Nullable PotionType potion(); + + /** -+ * Overrides the visual color of the potion ++ * Overrides the visual color of the potion. + * + * @return color override, or {@code null} if not present + */ @@ -1864,11 +1856,11 @@ index 0000000000000000000000000000000000000000..e6779fb88cbb8d7166eecd161aab8620 + interface Builder extends ComponentBuilder<PotionContents> { + + /** -+ * Sets the potion type for this builder ++ * Sets the potion type for this builder. + * + * @param potionType builder + * @see #potion() -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder potion(@Nullable PotionType potionType); @@ -1878,7 +1870,7 @@ index 0000000000000000000000000000000000000000..e6779fb88cbb8d7166eecd161aab8620 + * + * @param color color + * @see #customColor() -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder customColor(@Nullable Color color); @@ -1888,7 +1880,7 @@ index 0000000000000000000000000000000000000000..e6779fb88cbb8d7166eecd161aab8620 + * + * @param potionEffect effect + * @see #customEffects() -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder add(@NonNull PotionEffect potionEffect); @@ -1898,7 +1890,7 @@ index 0000000000000000000000000000000000000000..e6779fb88cbb8d7166eecd161aab8620 + * + * @param potionEffects effects + * @see #customEffects() -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder addAll(@NonNull List<@NonNull PotionEffect> potionEffects); @@ -2033,7 +2025,7 @@ index 0000000000000000000000000000000000000000..1e39fc6779e324030fb2890a4568376f +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/SuspiciousStewEffects.java b/src/main/java/io/papermc/paper/datacomponent/item/SuspiciousStewEffects.java new file mode 100644 -index 0000000000000000000000000000000000000000..0b82b863fd130d41a95ed758cdd50364a0bff8f2 +index 0000000000000000000000000000000000000000..64d99c69d17ca1bc5be5c2e21b6ae423048f1d87 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/SuspiciousStewEffects.java @@ -0,0 +1,62 @@ @@ -2049,7 +2041,7 @@ index 0000000000000000000000000000000000000000..0b82b863fd130d41a95ed758cdd50364 +import org.jetbrains.annotations.Unmodifiable; + +/** -+ * Holds the effects that will be applied when consuming Suspicious Stew ++ * Holds the effects that will be applied when consuming Suspicious Stew. + */ +public interface SuspiciousStewEffects { @@ -2084,7 +2076,7 @@ index 0000000000000000000000000000000000000000..0b82b863fd130d41a95ed758cdd50364 + * Adds an effect applied to this builder. + * + * @param entry effect -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder add(@NonNull SuspiciousEffectEntry entry); @@ -2093,7 +2085,7 @@ index 0000000000000000000000000000000000000000..0b82b863fd130d41a95ed758cdd50364 + * Adds effects applied to this builder. + * + * @param entries effect -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder addAll(@NonNull List<@NonNull SuspiciousEffectEntry> entries); @@ -2101,13 +2093,12 @@ index 0000000000000000000000000000000000000000..0b82b863fd130d41a95ed758cdd50364 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/Tool.java b/src/main/java/io/papermc/paper/datacomponent/item/Tool.java new file mode 100644 -index 0000000000000000000000000000000000000000..3195077207827439a57e007ee5719fc88c92ed86 +index 0000000000000000000000000000000000000000..914fd3144dd81dd2209489671d1a1df5231b9167 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/Tool.java -@@ -0,0 +1,133 @@ +@@ -0,0 +1,132 @@ +package io.papermc.paper.datacomponent.item; + -+import com.google.common.base.Preconditions; +import io.papermc.paper.datacomponent.ComponentBuilder; +import java.util.List; +import io.papermc.paper.registry.set.RegistryKeySet; @@ -2132,7 +2123,7 @@ index 0000000000000000000000000000000000000000..3195077207827439a57e007ee5719fc8 + } + + /** -+ * Mining speed to use if no rules match and don't override mining speed ++ * Mining speed to use if no rules match and don't override mining speed. + * + * @return default mining speed + */ @@ -2140,7 +2131,7 @@ index 0000000000000000000000000000000000000000..3195077207827439a57e007ee5719fc8 + float defaultMiningSpeed(); + + /** -+ * Amount of durability to remove each time a block is mined with this tool ++ * Amount of durability to remove each time a block is mined with this tool. + * + * @return durability + */ @@ -2148,7 +2139,7 @@ index 0000000000000000000000000000000000000000..3195077207827439a57e007ee5719fc8 + @NonNegative int damagePerBlock(); + + /** -+ * List of rule entries ++ * List of rule entries. + * + * @return rules + */ @@ -2205,7 +2196,7 @@ index 0000000000000000000000000000000000000000..3195077207827439a57e007ee5719fc8 + * Controls the amount of durability to remove each time a block is mined with this tool. + * + * @param damage durability to remove -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder damagePerBlock(int damage); @@ -2214,7 +2205,7 @@ index 0000000000000000000000000000000000000000..3195077207827439a57e007ee5719fc8 + * Controls mining speed to use if no rules match and don't override mining speed. + * + * @param speed mining speed -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder defaultMiningSpeed(float speed); @@ -2223,7 +2214,7 @@ index 0000000000000000000000000000000000000000..3195077207827439a57e007ee5719fc8 + * Adds a rule to the tool that controls the breaking speed / damage per block if matched. + * + * @param rule rule -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder addRule(@NonNull Rule rule); @@ -2232,7 +2223,7 @@ index 0000000000000000000000000000000000000000..3195077207827439a57e007ee5719fc8 + * Adds rules to the tool that control the breaking speed / damage per block if matched. + * + * @param rules rules -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder addRules(@NonNull List<@NonNull Rule> rules); @@ -2273,7 +2264,7 @@ index 0000000000000000000000000000000000000000..ecd1130152d0bac324cfd1feeb38b86e +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/WritableBookContent.java b/src/main/java/io/papermc/paper/datacomponent/item/WritableBookContent.java new file mode 100644 -index 0000000000000000000000000000000000000000..a0c78a0bff8512792797d2268cdd9c4e774abf89 +index 0000000000000000000000000000000000000000..9e448331e8855143ebdad2ea6419bcf2bc61389c --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/WritableBookContent.java @@ -0,0 +1,67 @@ @@ -2311,7 +2302,7 @@ index 0000000000000000000000000000000000000000..a0c78a0bff8512792797d2268cdd9c4e + * Adds a page that can be written to for this builder. + * + * @param page page -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder addPage(@NonNull String page); @@ -2320,7 +2311,7 @@ index 0000000000000000000000000000000000000000..a0c78a0bff8512792797d2268cdd9c4e + * Adds pages that can be written to for this builder. + * + * @param pages pages -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder addPages(@NonNull Collection<@NonNull String> pages); @@ -2329,24 +2320,24 @@ index 0000000000000000000000000000000000000000..a0c78a0bff8512792797d2268cdd9c4e + * Adds a filterable page that can be written to for this builder. + * + * @param page page -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") -+ @NonNull Builder addPageFiltered(@NonNull Filtered<@NonNull String> page); ++ @NonNull Builder addFilteredPage(@NonNull Filtered<@NonNull String> page); + + /** + * Adds filterable pages that can be written to for this builder. + * + * @param pages pages -+ * @return self ++ * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") -+ @NonNull Builder addPagesFiltered(@NonNull Collection<@NonNull Filtered<@NonNull String>> pages); ++ @NonNull Builder addFilteredPages(@NonNull Collection<@NonNull Filtered<@NonNull String>> pages); + } +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/WrittenBookContent.java b/src/main/java/io/papermc/paper/datacomponent/item/WrittenBookContent.java new file mode 100644 -index 0000000000000000000000000000000000000000..07d5d7b5e281790e108a0a3acfd007782d175461 +index 0000000000000000000000000000000000000000..95e2323c875a36fb383b41fd3d58722ad304b829 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/WrittenBookContent.java @@ -0,0 +1,96 @@ @@ -2407,8 +2398,8 @@ index 0000000000000000000000000000000000000000..07d5d7b5e281790e108a0a3acfd00778 + @NonNull @Unmodifiable List<@NonNull Filtered<@NonNull Component>> pages(); + + /** -+ * If the chat components in this book have already been resolved (entity selectors, scores substituted) -+ * If false, will be resolved when opened by a player ++ * If the chat components in this book have already been resolved (entity selectors, scores substituted). ++ * If {@code false}, will be resolved when opened by a player. + * + * @return resolved + */ @@ -2422,7 +2413,7 @@ index 0000000000000000000000000000000000000000..07d5d7b5e281790e108a0a3acfd00778 + @NonNull Builder title(@NonNull String title); + + @Contract(value = "_ -> this", mutates = "this") -+ @NonNull Builder titleFiltered(@NonNull Filtered<@NonNull String> title); ++ @NonNull Builder filteredTitle(@NonNull Filtered<@NonNull String> title); + + @Contract(value = "_ -> this", mutates = "this") + @NonNull Builder author(@NonNull String author); @@ -2457,6 +2448,18 @@ index 0000000000000000000000000000000000000000..3ddd1f787e97c22eee3e32bb2a9660a8 + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; +diff --git a/src/main/java/io/papermc/paper/item/MapPostProcessing.java b/src/main/java/io/papermc/paper/item/MapPostProcessing.java +new file mode 100644 +index 0000000000000000000000000000000000000000..5843768d0be2ae4a0219636ed7640727808da567 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/item/MapPostProcessing.java +@@ -0,0 +1,6 @@ ++package io.papermc.paper.item; ++ ++public enum MapPostProcessing { ++ LOCK, ++ SCALE ++} diff --git a/src/main/java/io/papermc/paper/registry/RegistryKey.java b/src/main/java/io/papermc/paper/registry/RegistryKey.java index 2945dde566682f977e84fde5d473a6c69be24df1..6ab6e9d3a1fcb5fcb370e507164da70012e61e88 100644 --- a/src/main/java/io/papermc/paper/registry/RegistryKey.java @@ -2597,10 +2600,10 @@ index 9725580b6458e5d37fbc6059869604f9883bd6d1..966bbc686280a1b7f479a2ff755e4776 /** * Get the object by its key. diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index f603b5b6ba80af919f415322583a8345a5b1358a..26cb1e31a8169283f11b5a7af8a4fd52754095ae 100644 +index f603b5b6ba80af919f415322583a8345a5b1358a..22035e8cc586ca454fab6b494928d6d610574615 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -1031,4 +1031,123 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -1031,4 +1031,124 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat return Bukkit.getUnsafe().computeTooltipLines(this, tooltipContext, player); } // Paper end - expose itemstack tooltip lines @@ -2660,7 +2663,7 @@ index f603b5b6ba80af919f415322583a8345a5b1358a..26cb1e31a8169283f11b5a7af8a4fd52 + * Sets the value of the data component type for this itemstack. To + * reset the value to the default for the {@link #getType() item type}, use + * {@link #resetData(io.papermc.paper.datacomponent.DataComponentType)}. To mark the data component type -+ * as removed, use {@link #unsetData(io.papermc.paper.datacomponent.DataComponentType)} ++ * as removed, use {@link #unsetData(io.papermc.paper.datacomponent.DataComponentType)}. + * + * @param type component type + * @param valueBuilder value builder @@ -2675,7 +2678,7 @@ index f603b5b6ba80af919f415322583a8345a5b1358a..26cb1e31a8169283f11b5a7af8a4fd52 + * Sets the value of the data component type for this itemstack. To + * reset the value to the default for the {@link #getType() item type}, use + * {@link #resetData(io.papermc.paper.datacomponent.DataComponentType)}. To mark the data component type -+ * as removed, use {@link #unsetData(io.papermc.paper.datacomponent.DataComponentType)} ++ * as removed, use {@link #unsetData(io.papermc.paper.datacomponent.DataComponentType)}. + * + * @param type component type + * @param value value to set @@ -2705,7 +2708,8 @@ index f603b5b6ba80af919f415322583a8345a5b1358a..26cb1e31a8169283f11b5a7af8a4fd52 + + /** + * Resets the value of this component to be the default -+ * value for the item type from {@link Material#getDefaultData(io.papermc.paper.datacomponent.DataComponentType.Valued)} ++ * value for the item type from {@link Material#getDefaultData(io.papermc.paper.datacomponent.DataComponentType.Valued)}. ++ * + * @param type data component type to reset + */ + public void resetData(final io.papermc.paper.datacomponent.@NotNull DataComponentType type) { @@ -2717,7 +2721,7 @@ index f603b5b6ba80af919f415322583a8345a5b1358a..26cb1e31a8169283f11b5a7af8a4fd52 + * item type. + * + * @param type the data component type -+ * @return true if the data type is overridden ++ * @return {@code true} if the data type is overridden + */ + public boolean isOverridden(final io.papermc.paper.datacomponent.@NotNull DataComponentType type) { + return this.craftDelegate.isOverridden(type); diff --git a/patches/server/1026-WIP-DataComponent-API.patch b/patches/server/1026-WIP-DataComponent-API.patch index f482a04dc3..13a5043d4a 100644 --- a/patches/server/1026-WIP-DataComponent-API.patch +++ b/patches/server/1026-WIP-DataComponent-API.patch @@ -9,20 +9,24 @@ public net/minecraft/world/item/component/ItemContainerContents items diff --git a/src/main/java/io/papermc/paper/datacomponent/ComponentAdapter.java b/src/main/java/io/papermc/paper/datacomponent/ComponentAdapter.java new file mode 100644 -index 0000000000000000000000000000000000000000..2e6860c991b7484996897c3432d85f6df8cb1022 +index 0000000000000000000000000000000000000000..2ce01dbcbd205625bae879af14e2c1a7d919b200 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/ComponentAdapter.java -@@ -0,0 +1,25 @@ +@@ -0,0 +1,36 @@ +package io.papermc.paper.datacomponent; + +import java.util.function.Function; ++import com.mojang.serialization.JavaOps; +import net.minecraft.core.component.DataComponentType; ++import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.util.Unit; ++import org.bukkit.craftbukkit.CraftRegistry; + +public record ComponentAdapter<NMS, API>( + DataComponentType<NMS> type, + Function<API, NMS> apiToVanilla, -+ Function<NMS, API> vanillaToApi ++ Function<NMS, API> vanillaToApi, ++ boolean codecValidation +) { + static final Function<Void, Unit> API_TO_UNIT_CONVERTER = $ -> Unit.INSTANCE; + @@ -31,7 +35,14 @@ index 0000000000000000000000000000000000000000..2e6860c991b7484996897c3432d85f6d + } + + public NMS toVanilla(final API value) { -+ return this.apiToVanilla.apply(value); ++ NMS nms = this.apiToVanilla.apply(value); ++ if (this.codecValidation) { ++ this.type().codec().encodeStart(CraftRegistry.getMinecraftRegistry().createSerializationContext(JavaOps.INSTANCE), nms).error().ifPresent(error -> { ++ throw new IllegalArgumentException("Failed to encode data component %s (%s)".formatted(BuiltInRegistries.DATA_COMPONENT_TYPE.getKey(this.type), error.message())); ++ }); ++ } ++ ++ return nms; + } + + public API fromVanilla(final NMS value) { @@ -40,13 +51,14 @@ index 0000000000000000000000000000000000000000..2e6860c991b7484996897c3432d85f6d +} diff --git a/src/main/java/io/papermc/paper/datacomponent/ComponentAdapters.java b/src/main/java/io/papermc/paper/datacomponent/ComponentAdapters.java new file mode 100644 -index 0000000000000000000000000000000000000000..7aa48de3f2c02f8d4f775b23f563d6c4d47d5b64 +index 0000000000000000000000000000000000000000..852f456048940e07189810b4591b2a566b63a5f2 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/ComponentAdapters.java -@@ -0,0 +1,185 @@ +@@ -0,0 +1,186 @@ +package io.papermc.paper.datacomponent; + +import com.mojang.brigadier.exceptions.CommandSyntaxException; ++import com.mojang.serialization.JavaOps; +import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.datacomponent.item.PaperBannerPatternLayers; +import io.papermc.paper.datacomponent.item.PaperBlockItemDataProperties; @@ -153,7 +165,7 @@ index 0000000000000000000000000000000000000000..7aa48de3f2c02f8d4f775b23f563d6c4 + register(DataComponents.MAP_COLOR, PaperMapItemColor::new); + register(DataComponents.MAP_ID, PaperMapID::new); + register(DataComponents.MAP_DECORATIONS, PaperMapDecorations::new); -+ register(DataComponents.MAP_POST_PROCESSING, nms -> io.papermc.paper.datacomponent.item.MapPostProcessing.valueOf(nms.name()), api -> MapPostProcessing.valueOf(api.name())); ++ register(DataComponents.MAP_POST_PROCESSING, nms -> io.papermc.paper.item.MapPostProcessing.valueOf(nms.name()), api -> MapPostProcessing.valueOf(api.name())); + register(DataComponents.CHARGED_PROJECTILES, PaperChargedProjectiles::new); + register(DataComponents.BUNDLE_CONTENTS, PaperBundleContents::new); + register(DataComponents.POTION_CONTENTS, PaperPotionContents::new); @@ -206,38 +218,76 @@ index 0000000000000000000000000000000000000000..7aa48de3f2c02f8d4f775b23f563d6c4 + } + + public static void registerUntyped(final DataComponentType<Unit> type) { -+ registerInternal(type, UNIT_TO_API_CONVERTER, ComponentAdapter.API_TO_UNIT_CONVERTER); ++ registerInternal(type, UNIT_TO_API_CONVERTER, ComponentAdapter.API_TO_UNIT_CONVERTER, false); + } + + private static <COMMON> void registerIdentity(final DataComponentType<COMMON> type) { -+ registerInternal(type, Function.identity(), Function.identity()); ++ registerInternal(type, Function.identity(), Function.identity(), true); + } + + private static <NMS, API extends Handleable<NMS>> void register(final DataComponentType<NMS> type, final Function<NMS, API> vanillaToApi) { -+ register(type, vanillaToApi, Handleable::getHandle); ++ registerInternal(type, vanillaToApi, Handleable::getHandle, false); + } + + private static <NMS, API> void register(final DataComponentType<NMS> type, final Function<NMS, API> vanillaToApi, final Function<API, NMS> apiToVanilla) { -+ registerInternal(type, vanillaToApi, apiToVanilla); ++ registerInternal(type, vanillaToApi, apiToVanilla, true); + } + -+ private static <NMS, API> void registerInternal(final DataComponentType<NMS> type, final Function<NMS, API> vanillaToApi, final Function<API, NMS> apiToVanilla) { ++ private static <NMS, API> void registerInternal(final DataComponentType<NMS> type, final Function<NMS, API> vanillaToApi, final Function<API, NMS> apiToVanilla, final boolean codecValidation) { + final ResourceKey<DataComponentType<?>> key = BuiltInRegistries.DATA_COMPONENT_TYPE.getResourceKey(type).orElseThrow(); + if (ADAPTERS.containsKey(key)) { + throw new IllegalStateException("Duplicate adapter registration for " + key); + } -+ ADAPTERS.put(key, new ComponentAdapter<>(type, apiToVanilla, vanillaToApi)); ++ ADAPTERS.put(key, new ComponentAdapter<>(type, apiToVanilla, vanillaToApi, codecValidation && !type.isTransient())); ++ } ++} +diff --git a/src/main/java/io/papermc/paper/datacomponent/ComponentUtils.java b/src/main/java/io/papermc/paper/datacomponent/ComponentUtils.java +new file mode 100644 +index 0000000000000000000000000000000000000000..07e268941d95c315592e3464c3ea08023205813e +--- /dev/null ++++ b/src/main/java/io/papermc/paper/datacomponent/ComponentUtils.java +@@ -0,0 +1,31 @@ ++package io.papermc.paper.datacomponent; ++ ++import com.google.common.collect.Collections2; ++import com.google.common.collect.Lists; ++import java.util.Collection; ++import java.util.Collections; ++import java.util.List; ++import java.util.function.Function; ++import org.checkerframework.checker.nullness.qual.NonNull; ++import org.checkerframework.framework.qual.DefaultQualifier; ++ ++@DefaultQualifier(NonNull.class) ++public final class ComponentUtils { ++ ++ private ComponentUtils() { ++ } ++ ++ public static <A, M> List<A> transform(final List<? extends M> nms, final Function<? super M, ? extends A> converter) { ++ return Collections.unmodifiableList(Lists.transform(nms, converter::apply)); ++ } ++ ++ public static <A, M> Collection<A> transform(final Collection<? extends M> nms, final Function<? super M, ? extends A> converter) { ++ return Collections.unmodifiableCollection(Collections2.transform(nms, converter::apply)); ++ } ++ ++ public static <A, M, C extends Collection<M>> void addAndConvert(final C target, final Collection<A> toAdd, final Function<? super A, ? extends M> converter) { ++ for (final A value : toAdd) { ++ target.add(converter.apply(value)); ++ } + } +} diff --git a/src/main/java/io/papermc/paper/datacomponent/PaperComponentType.java b/src/main/java/io/papermc/paper/datacomponent/PaperComponentType.java new file mode 100644 -index 0000000000000000000000000000000000000000..b5db510f1e641bba6d6a70c920921a774dc411a0 +index 0000000000000000000000000000000000000000..60bb87cc071d21e58615210e6b0b4dfe0dc9ea71 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/PaperComponentType.java -@@ -0,0 +1,118 @@ +@@ -0,0 +1,119 @@ +package io.papermc.paper.datacomponent; + +import java.util.Collections; ++import java.util.HashSet; +import java.util.Set; +import net.kyori.adventure.key.Key; +import net.minecraft.core.component.DataComponentMap; @@ -268,7 +318,7 @@ index 0000000000000000000000000000000000000000..b5db510f1e641bba6d6a70c920921a77 + } + + public static Set<DataComponentType> minecraftToBukkit(final Set<net.minecraft.core.component.DataComponentType<?>> nmsTypes) { -+ final Set<DataComponentType> types = new java.util.HashSet<>(); ++ final Set<DataComponentType> types = new HashSet<>(nmsTypes.size()); + for (final net.minecraft.core.component.DataComponentType<?> nmsType : nmsTypes) { + types.add(PaperComponentType.minecraftToBukkit(nmsType)); + } @@ -355,10 +405,10 @@ index 0000000000000000000000000000000000000000..b5db510f1e641bba6d6a70c920921a77 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ComponentTypesBridgesImpl.java b/src/main/java/io/papermc/paper/datacomponent/item/ComponentTypesBridgesImpl.java new file mode 100644 -index 0000000000000000000000000000000000000000..c0d3af2b26390d48c3c5d825c31bc9fc07cdd778 +index 0000000000000000000000000000000000000000..c21519941b82788733d541bd114e8b0ea12024bc --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/ComponentTypesBridgesImpl.java -@@ -0,0 +1,179 @@ +@@ -0,0 +1,178 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.registry.set.RegistryKeySet; @@ -473,7 +523,7 @@ index 0000000000000000000000000000000000000000..c0d3af2b26390d48c3c5d825c31bc9fc + } + + @Override -+ public JukeboxPlayable.Builder jukeboxPlayable(JukeboxSong song) { ++ public JukeboxPlayable.Builder jukeboxPlayable(final JukeboxSong song) { + return new PaperJukeboxPlayable.BuilderImpl(song); + } + @@ -484,8 +534,7 @@ index 0000000000000000000000000000000000000000..c0d3af2b26390d48c3c5d825c31bc9fc + + @Override + public Tool.Rule rule(final RegistryKeySet<BlockType> blockTypes, final @Nullable Float speed, final TriState correctForDrops) { -+ //Preconditions.checkArgument(speed == null || speed > 0, "Speed must be positive"); -+ return new PaperItemTool.PaperRule(blockTypes, speed, correctForDrops); ++ return PaperItemTool.PaperRule.fromUnsafe(blockTypes, speed, correctForDrops); + } + + @Override @@ -538,53 +587,9 @@ index 0000000000000000000000000000000000000000..c0d3af2b26390d48c3c5d825c31bc9fc + return new PaperLockCode.BuilderImpl(); + } +} -diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ComponentUtils.java b/src/main/java/io/papermc/paper/datacomponent/item/ComponentUtils.java -new file mode 100644 -index 0000000000000000000000000000000000000000..d91a8b1e903ebb01b7da7e4d0150af5cc9ef68e4 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/datacomponent/item/ComponentUtils.java -@@ -0,0 +1,38 @@ -+package io.papermc.paper.datacomponent.item; -+ -+import com.google.common.collect.Collections2; -+import com.google.common.collect.ImmutableList; -+import com.google.common.collect.Iterables; -+import com.google.common.collect.Lists; -+import java.util.Collection; -+import java.util.Collections; -+import java.util.List; -+import java.util.function.Function; -+import org.checkerframework.checker.nullness.qual.NonNull; -+import org.checkerframework.framework.qual.DefaultQualifier; -+ -+@DefaultQualifier(NonNull.class) -+final class ComponentUtils { -+ -+ private ComponentUtils() { -+ } -+ -+ static <A, M> List<A> transform(final List<? extends M> nms, final Function<? super M, ? extends A> converter) { -+ return Collections.unmodifiableList(Lists.transform(nms, converter::apply)); -+ } -+ -+ static <A, M> Collection<A> transform(final Collection<? extends M> nms, final Function<? super M, ? extends A> converter) { -+ return Collections.unmodifiableCollection(Collections2.transform(nms, converter::apply)); -+ } -+ -+ @Deprecated -+ static <A, M> List<A> transform(final Iterable<? extends M> nms, final Function<? super M, ? extends A> converter) { -+ return ImmutableList.copyOf(Iterables.transform(nms, converter::apply)); -+ } -+ -+ static <A, M, C extends Collection<M>> void addAndConvert(final C target, final Collection<A> toAdd, final Function<? super A, ? extends M> converter) { -+ for (final A value : toAdd) { -+ target.add(converter.apply(value)); -+ } -+ } -+} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperBannerPatternLayers.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperBannerPatternLayers.java new file mode 100644 -index 0000000000000000000000000000000000000000..a624e3fe2721ef55399b2d4bccf6ddf3917c756b +index 0000000000000000000000000000000000000000..e8e602f99c718c8939ce71aa2aad57a06f373c94 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperBannerPatternLayers.java @@ -0,0 +1,62 @@ @@ -601,7 +606,7 @@ index 0000000000000000000000000000000000000000..a624e3fe2721ef55399b2d4bccf6ddf3 +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; + -+import static io.papermc.paper.datacomponent.item.ComponentUtils.transform; ++import static io.papermc.paper.datacomponent.ComponentUtils.transform; + +@DefaultQualifier(NonNull.class) +public record PaperBannerPatternLayers( @@ -616,7 +621,7 @@ index 0000000000000000000000000000000000000000..a624e3fe2721ef55399b2d4bccf6ddf3 + private static List<Pattern> convert(final net.minecraft.world.level.block.entity.BannerPatternLayers nmsPatterns) { + return transform(nmsPatterns.layers(), input -> { + final Optional<PatternType> type = CraftRegistry.unwrapAndConvertHolder(org.bukkit.Registry.BANNER_PATTERN, input.pattern()); -+ return new Pattern(DyeColor.getByWoolData((byte) input.color().getId()), type.orElseThrow()); ++ return new Pattern(DyeColor.getByWoolData((byte) input.color().getId()), type.orElseThrow(() -> new IllegalStateException("Custom banner are not supported yet in the API!"))); + }); + } + @@ -713,10 +718,10 @@ index 0000000000000000000000000000000000000000..09335d46724831478fe396905a0f8d21 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperBundleContents.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperBundleContents.java new file mode 100644 -index 0000000000000000000000000000000000000000..4865acd021f1d00b0f8fcecc6b2836e68a1d622c +index 0000000000000000000000000000000000000000..7eb80089785a8c28db046402d52326ffab695e4d --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperBundleContents.java -@@ -0,0 +1,52 @@ +@@ -0,0 +1,51 @@ +package io.papermc.paper.datacomponent.item; + +import java.util.ArrayList; @@ -728,7 +733,7 @@ index 0000000000000000000000000000000000000000..4865acd021f1d00b0f8fcecc6b2836e6 +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; + -+import static io.papermc.paper.datacomponent.item.ComponentUtils.transform; ++import static io.papermc.paper.datacomponent.ComponentUtils.transform; + +@DefaultQualifier(NonNull.class) +public record PaperBundleContents( @@ -742,8 +747,7 @@ index 0000000000000000000000000000000000000000..4865acd021f1d00b0f8fcecc6b2836e6 + + @Override + public List<ItemStack> contents() { -+ // TODO anyway to make this lazy? the nms itemsCopy returns an Iterable not a list so its a tad annoying. Can just change the nms impl maybe? -+ return transform(this.impl.itemsCopy() /*makes copies internally*/, CraftItemStack::asCraftMirror); ++ return transform((List<net.minecraft.world.item.ItemStack>) this.impl.itemsCopy(), CraftItemStack::asCraftMirror); + } + + static final class BuilderImpl implements BundleContents.Builder { @@ -771,7 +775,7 @@ index 0000000000000000000000000000000000000000..4865acd021f1d00b0f8fcecc6b2836e6 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperChargedProjectiles.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperChargedProjectiles.java new file mode 100644 -index 0000000000000000000000000000000000000000..c81b13d88f19ac272ab27986722543490ce38bec +index 0000000000000000000000000000000000000000..080281b2feb577b0d9c9b342dda81352dd0fb922 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperChargedProjectiles.java @@ -0,0 +1,51 @@ @@ -786,7 +790,7 @@ index 0000000000000000000000000000000000000000..c81b13d88f19ac272ab2798672254349 +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; + -+import static io.papermc.paper.datacomponent.item.ComponentUtils.transform; ++import static io.papermc.paper.datacomponent.ComponentUtils.transform; + +@DefaultQualifier(NonNull.class) +public record PaperChargedProjectiles( @@ -871,7 +875,7 @@ index 0000000000000000000000000000000000000000..88f9697d3beda288c3e02b571753c124 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperDyedItemColor.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperDyedItemColor.java new file mode 100644 -index 0000000000000000000000000000000000000000..da22c58bcbf3e03686961f5a5127edeff700a545 +index 0000000000000000000000000000000000000000..ff2a81366fcd554451e9b2aa438e9277fa70248b --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperDyedItemColor.java @@ -0,0 +1,55 @@ @@ -894,7 +898,7 @@ index 0000000000000000000000000000000000000000..da22c58bcbf3e03686961f5a5127edef + + @Override + public Color color() { -+ return Color.fromRGB(this.impl.rgb()); ++ return Color.fromRGB(this.impl.rgb() & 0x00FFFFFF); // skip alpha channel + } + + @Override @@ -932,7 +936,7 @@ index 0000000000000000000000000000000000000000..da22c58bcbf3e03686961f5a5127edef +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperFireworks.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperFireworks.java new file mode 100644 -index 0000000000000000000000000000000000000000..34ff8431ae588c1bfe0f6c7aa621de7357f084b7 +index 0000000000000000000000000000000000000000..605728447636c2a721d6e7c340900c8a8f4eaeb0 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperFireworks.java @@ -0,0 +1,80 @@ @@ -948,8 +952,8 @@ index 0000000000000000000000000000000000000000..34ff8431ae588c1bfe0f6c7aa621de73 +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; + -+import static io.papermc.paper.datacomponent.item.ComponentUtils.addAndConvert; -+import static io.papermc.paper.datacomponent.item.ComponentUtils.transform; ++import static io.papermc.paper.datacomponent.ComponentUtils.addAndConvert; ++import static io.papermc.paper.datacomponent.ComponentUtils.transform; + +@DefaultQualifier(NonNull.class) +public record PaperFireworks( @@ -1018,10 +1022,10 @@ index 0000000000000000000000000000000000000000..34ff8431ae588c1bfe0f6c7aa621de73 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperFoodProperties.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperFoodProperties.java new file mode 100644 -index 0000000000000000000000000000000000000000..1404f97914767e57c59e33cb0b0cdffa9c4b50c0 +index 0000000000000000000000000000000000000000..7b210b4172fbc78adaae52602045eef40701a98d --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperFoodProperties.java -@@ -0,0 +1,152 @@ +@@ -0,0 +1,153 @@ +package io.papermc.paper.datacomponent.item; + +import com.google.common.base.Preconditions; @@ -1037,8 +1041,8 @@ index 0000000000000000000000000000000000000000..1404f97914767e57c59e33cb0b0cdffa +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.framework.qual.DefaultQualifier; + -+import static io.papermc.paper.datacomponent.item.ComponentUtils.addAndConvert; -+import static io.papermc.paper.datacomponent.item.ComponentUtils.transform; ++import static io.papermc.paper.datacomponent.ComponentUtils.addAndConvert; ++import static io.papermc.paper.datacomponent.ComponentUtils.transform; + +@DefaultQualifier(NonNull.class) +public record PaperFoodProperties( @@ -1144,8 +1148,9 @@ index 0000000000000000000000000000000000000000..1404f97914767e57c59e33cb0b0cdffa + } + + @Override -+ public FoodProperties.Builder usingConvertsTo(final @Nullable ItemStack itemStack) { -+ this.convertedStack = itemStack; ++ public FoodProperties.Builder usingConvertsTo(final @Nullable ItemStack stack) { ++ Preconditions.checkArgument(stack == null || !stack.isEmpty(), "Item stack cannot be empty!"); ++ this.convertedStack = stack; + return this; + } + @@ -1157,7 +1162,7 @@ index 0000000000000000000000000000000000000000..1404f97914767e57c59e33cb0b0cdffa + + @Override + public FoodProperties.Builder addAllEffects(final List<PossibleEffect> effects) { -+ addAndConvert(this.possibleEffects, effects, ef -> ((PossibleEffectImpl) ef).possibleEffect()); ++ addAndConvert(this.possibleEffects, effects, effect -> ((PossibleEffectImpl) effect).possibleEffect()); + return this; + } + @@ -1176,10 +1181,10 @@ index 0000000000000000000000000000000000000000..1404f97914767e57c59e33cb0b0cdffa +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperItemAdventurePredicate.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemAdventurePredicate.java new file mode 100644 -index 0000000000000000000000000000000000000000..a6368dc4288b5a4cb60c0cb006f8a5072afc1e2f +index 0000000000000000000000000000000000000000..2bf2540e1ef88d8e20c0182bd794a09f5819aa53 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemAdventurePredicate.java -@@ -0,0 +1,78 @@ +@@ -0,0 +1,77 @@ +package io.papermc.paper.datacomponent.item; + +import java.util.ArrayList; @@ -1194,9 +1199,8 @@ index 0000000000000000000000000000000000000000..a6368dc4288b5a4cb60c0cb006f8a507 +import org.bukkit.craftbukkit.util.Handleable; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; -+import org.jetbrains.annotations.Unmodifiable; + -+import static io.papermc.paper.datacomponent.item.ComponentUtils.transform; ++import static io.papermc.paper.datacomponent.ComponentUtils.transform; + +@DefaultQualifier(NonNull.class) +public record PaperItemAdventurePredicate( @@ -1229,17 +1233,17 @@ index 0000000000000000000000000000000000000000..a6368dc4288b5a4cb60c0cb006f8a507 + } + + @Override -+ public @NonNull @Unmodifiable List<@NonNull BlockPredicate> predicates() { ++ public List<BlockPredicate> predicates() { + return this.predicates; + } + -+ static final class BuilderImpl implements Builder { ++ static final class BuilderImpl implements ItemAdventurePredicate.Builder { + + private final List<net.minecraft.advancements.critereon.BlockPredicate> predicates = new ArrayList<>(); + private boolean showInTooltip = net.minecraft.world.item.component.ItemAttributeModifiers.EMPTY.showInTooltip(); + + @Override -+ public @NonNull Builder addPredicate(@NonNull final BlockPredicate predicate) { ++ public ItemAdventurePredicate.Builder addPredicate(final BlockPredicate predicate) { + this.predicates.add(new net.minecraft.advancements.critereon.BlockPredicate(Optional.ofNullable(predicate.blocks()).map( + blocks -> PaperRegistrySets.convertToNms(Registries.BLOCK, BuiltInRegistries.BUILT_IN_CONVERSIONS.lookup(), blocks) + ), Optional.empty(), Optional.empty())); @@ -1247,23 +1251,23 @@ index 0000000000000000000000000000000000000000..a6368dc4288b5a4cb60c0cb006f8a507 + } + + @Override -+ public Builder showInTooltip(final boolean showInTooltip) { ++ public ItemAdventurePredicate.Builder showInTooltip(final boolean showInTooltip) { + this.showInTooltip = showInTooltip; + return this; + } + + @Override -+ public @NonNull ItemAdventurePredicate build() { ++ public ItemAdventurePredicate build() { + return new PaperItemAdventurePredicate(new net.minecraft.world.item.AdventureModePredicate(Collections.unmodifiableList(this.predicates), this.showInTooltip)); + } + } +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperItemArmorTrim.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemArmorTrim.java new file mode 100644 -index 0000000000000000000000000000000000000000..d96be0ea89094d080ab81722d36af99a4be7808f +index 0000000000000000000000000000000000000000..861de65b528844756d2c1cea085768858bc50328 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemArmorTrim.java -@@ -0,0 +1,68 @@ +@@ -0,0 +1,65 @@ +package io.papermc.paper.datacomponent.item; + +import org.bukkit.craftbukkit.inventory.trim.CraftTrimMaterial; @@ -1300,18 +1304,11 @@ index 0000000000000000000000000000000000000000..d96be0ea89094d080ab81722d36af99a + + static final class BuilderImpl implements ItemArmorTrim.Builder { + -+ private net.minecraft.world.item.armortrim.ArmorTrim armorTrim; ++ private ArmorTrim armorTrim; + private boolean showInTooltip = true; + + BuilderImpl(final ArmorTrim armorTrim) { -+ this.armorTrim = convert(armorTrim); -+ } -+ -+ private static net.minecraft.world.item.armortrim.ArmorTrim convert(final ArmorTrim armorTrim) { -+ return new net.minecraft.world.item.armortrim.ArmorTrim( -+ CraftTrimMaterial.bukkitToMinecraftHolder(armorTrim.getMaterial()), -+ CraftTrimPattern.bukkitToMinecraftHolder(armorTrim.getPattern()) -+ ); ++ this.armorTrim = armorTrim; + } + + @Override @@ -1322,19 +1319,23 @@ index 0000000000000000000000000000000000000000..d96be0ea89094d080ab81722d36af99a + + @Override + public ItemArmorTrim.Builder armorTrim(final ArmorTrim armorTrim) { -+ this.armorTrim = convert(armorTrim); ++ this.armorTrim = armorTrim; + return this; + } + + @Override + public ItemArmorTrim build() { -+ return new PaperItemArmorTrim(this.armorTrim.withTooltip(this.showInTooltip)); ++ return new PaperItemArmorTrim( ++ new net.minecraft.world.item.armortrim.ArmorTrim( ++ CraftTrimMaterial.bukkitToMinecraftHolder(this.armorTrim.getMaterial()), ++ CraftTrimPattern.bukkitToMinecraftHolder(this.armorTrim.getPattern()) ++ ).withTooltip(this.showInTooltip)); + } + } +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperItemAttributeModifiers.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemAttributeModifiers.java new file mode 100644 -index 0000000000000000000000000000000000000000..11cdc84f9d64e0c38d116eff0ca767e9de421990 +index 0000000000000000000000000000000000000000..78867991f5075005725307d16ed2c8487e0e7b7e --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemAttributeModifiers.java @@ -0,0 +1,96 @@ @@ -1353,7 +1354,7 @@ index 0000000000000000000000000000000000000000..11cdc84f9d64e0c38d116eff0ca767e9 +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; + -+import static io.papermc.paper.datacomponent.item.ComponentUtils.transform; ++import static io.papermc.paper.datacomponent.ComponentUtils.transform; + +@DefaultQualifier(NonNull.class) +public record PaperItemAttributeModifiers( @@ -1436,7 +1437,7 @@ index 0000000000000000000000000000000000000000..11cdc84f9d64e0c38d116eff0ca767e9 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperItemContainerContents.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemContainerContents.java new file mode 100644 -index 0000000000000000000000000000000000000000..eb86427206b7f5d38c40bfe26358dc6a051ac87f +index 0000000000000000000000000000000000000000..967da68950438b489a6e816eab94e58ffd316da7 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemContainerContents.java @@ -0,0 +1,63 @@ @@ -1451,8 +1452,8 @@ index 0000000000000000000000000000000000000000..eb86427206b7f5d38c40bfe26358dc6a +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; + -+import static io.papermc.paper.datacomponent.item.ComponentUtils.addAndConvert; -+import static io.papermc.paper.datacomponent.item.ComponentUtils.transform; ++import static io.papermc.paper.datacomponent.ComponentUtils.addAndConvert; ++import static io.papermc.paper.datacomponent.ComponentUtils.transform; + +@DefaultQualifier(NonNull.class) +public record PaperItemContainerContents( @@ -1474,47 +1475,48 @@ index 0000000000000000000000000000000000000000..eb86427206b7f5d38c40bfe26358dc6a + private final List<net.minecraft.world.item.ItemStack> items = new ArrayList<>(); + + @Override -+ public ItemContainerContents.Builder add(final ItemStack itemStack) { ++ public ItemContainerContents.Builder add(final ItemStack stack) { + Preconditions.checkArgument( + this.items.size() + 1 <= net.minecraft.world.item.component.ItemContainerContents.MAX_SIZE, + "Cannot have more than %s items, had %s", + net.minecraft.world.item.component.ItemContainerContents.MAX_SIZE, + this.items.size() + 1 + ); -+ this.items.add(CraftItemStack.asNMSCopy(itemStack)); ++ this.items.add(CraftItemStack.asNMSCopy(stack)); + return this; + } + + @Override -+ public ItemContainerContents.Builder addAll(final List<ItemStack> itemStacks) { ++ public ItemContainerContents.Builder addAll(final List<ItemStack> stacks) { + Preconditions.checkArgument( -+ this.items.size() + itemStacks.size() <= net.minecraft.world.item.component.ItemContainerContents.MAX_SIZE, ++ this.items.size() + stacks.size() <= net.minecraft.world.item.component.ItemContainerContents.MAX_SIZE, + "Cannot have more than %s items, had %s", + net.minecraft.world.item.component.ItemContainerContents.MAX_SIZE, -+ this.items.size() + itemStacks.size() ++ this.items.size() + stacks.size() + ); -+ addAndConvert(this.items, itemStacks, CraftItemStack::asNMSCopy); ++ addAndConvert(this.items, stacks, CraftItemStack::asNMSCopy); + return this; + } + + @Override + public ItemContainerContents build() { -+ return new PaperItemContainerContents(net.minecraft.world.item.component.ItemContainerContents.fromItems(this.items)); ++ return new PaperItemContainerContents(net.minecraft.world.item.component.ItemContainerContents.fromItems(this.items)); // todo expose container slot? + } + } +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperItemEnchantments.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemEnchantments.java new file mode 100644 -index 0000000000000000000000000000000000000000..1f1ae514250c586479da5d2bc45f39447679879d +index 0000000000000000000000000000000000000000..47793f7b41850b982646e16485568dc7bdad0d9c --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemEnchantments.java -@@ -0,0 +1,92 @@ +@@ -0,0 +1,93 @@ +package io.papermc.paper.datacomponent.item; + +import com.google.common.base.Preconditions; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; ++import it.unimi.dsi.fastutil.objects.Object2IntMap; +import net.minecraft.core.Holder; +import org.bukkit.craftbukkit.enchantments.CraftEnchantment; +import org.bukkit.craftbukkit.util.Handleable; @@ -1536,9 +1538,9 @@ index 0000000000000000000000000000000000000000..1f1ae514250c586479da5d2bc45f3944 + if (itemEnchantments.isEmpty()) { + return Collections.emptyMap(); + } -+ final Map<Enchantment, Integer> map = new HashMap<>(); -+ for (final Holder<net.minecraft.world.item.enchantment.Enchantment> nmsEnchantment : itemEnchantments.keySet()) { -+ map.put(CraftEnchantment.minecraftHolderToBukkit(nmsEnchantment), itemEnchantments.getLevel(nmsEnchantment)); ++ final Map<Enchantment, Integer> map = new HashMap<>(itemEnchantments.size()); ++ for (final Object2IntMap.Entry<Holder<net.minecraft.world.item.enchantment.Enchantment>> entry : itemEnchantments.entrySet()) { ++ map.put(CraftEnchantment.minecraftHolderToBukkit(entry.getKey()), entry.getIntValue()); + } + return Collections.unmodifiableMap(map); // TODO look into making a "transforming" map + } @@ -1603,7 +1605,7 @@ index 0000000000000000000000000000000000000000..1f1ae514250c586479da5d2bc45f3944 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperItemLore.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemLore.java new file mode 100644 -index 0000000000000000000000000000000000000000..a7374010c21d87a225805d2c7dce2c5d04cc2e19 +index 0000000000000000000000000000000000000000..041eb21f9d5a3549ce6f27cbfe7cdf2e32c4671e --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemLore.java @@ -0,0 +1,85 @@ @@ -1620,7 +1622,7 @@ index 0000000000000000000000000000000000000000..a7374010c21d87a225805d2c7dce2c5d +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; + -+import static io.papermc.paper.datacomponent.item.ComponentUtils.transform; ++import static io.papermc.paper.datacomponent.ComponentUtils.transform; + +@DefaultQualifier(NonNull.class) +public record PaperItemLore( @@ -1694,15 +1696,16 @@ index 0000000000000000000000000000000000000000..a7374010c21d87a225805d2c7dce2c5d +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperItemTool.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemTool.java new file mode 100644 -index 0000000000000000000000000000000000000000..02cf3613bb93266c19988f3af47ecf992e573a36 +index 0000000000000000000000000000000000000000..35f12ebb9cb7dc222405de917b232a46a1afcade --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemTool.java -@@ -0,0 +1,97 @@ +@@ -0,0 +1,103 @@ +package io.papermc.paper.datacomponent.item; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; ++import com.google.common.base.Preconditions; +import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.set.PaperRegistrySets; +import io.papermc.paper.registry.set.RegistryKeySet; @@ -1715,7 +1718,7 @@ index 0000000000000000000000000000000000000000..02cf3613bb93266c19988f3af47ecf99 +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.framework.qual.DefaultQualifier; + -+import static io.papermc.paper.datacomponent.item.ComponentUtils.transform; ++import static io.papermc.paper.datacomponent.ComponentUtils.transform; + +@DefaultQualifier(NonNull.class) +public record PaperItemTool( @@ -1752,7 +1755,12 @@ index 0000000000000000000000000000000000000000..02cf3613bb93266c19988f3af47ecf99 + + + // TODO maybe move to API as package-private so they can create Entry objects? not sure if needed -+ public record PaperRule(RegistryKeySet<BlockType> blockTypes, @Nullable Float speed, @NonNull TriState correctForDrops) implements Rule { ++ record PaperRule(RegistryKeySet<BlockType> blockTypes, @Nullable Float speed, TriState correctForDrops) implements Rule { ++ ++ public static PaperRule fromUnsafe(RegistryKeySet<BlockType> blockTypes, @Nullable Float speed, TriState correctForDrops) { ++ Preconditions.checkArgument(speed == null || speed > 0, "Speed must be positive"); ++ return new PaperRule(blockTypes, speed, correctForDrops); ++ } + } + + static final class BuilderImpl implements Builder { @@ -1762,19 +1770,19 @@ index 0000000000000000000000000000000000000000..02cf3613bb93266c19988f3af47ecf99 + private float miningSpeed = 1.0F; + + @Override -+ public @NonNull Builder damagePerBlock(final int damage) { ++ public Builder damagePerBlock(final int damage) { + this.damage = damage; + return this; + } + + @Override -+ public @NonNull Builder defaultMiningSpeed(final float speed) { ++ public Builder defaultMiningSpeed(final float speed) { + this.miningSpeed = speed; + return this; + } + + @Override -+ public @NonNull Builder addRule(@NonNull final Rule rule) { ++ public Builder addRule(final Rule rule) { + this.rules.add(new net.minecraft.world.item.component.Tool.Rule( + PaperRegistrySets.convertToNms(Registries.BLOCK, BuiltInRegistries.BUILT_IN_CONVERSIONS.lookup(), rule.blockTypes()), + Optional.ofNullable(rule.speed()), @@ -1784,20 +1792,20 @@ index 0000000000000000000000000000000000000000..02cf3613bb93266c19988f3af47ecf99 + } + + @Override -+ public @NonNull Builder addRules(@NonNull final List<@NonNull Rule> rules) { ++ public Builder addRules(final List<Rule> rules) { + rules.forEach(this::addRule); + return this; + } + + @Override -+ public @NonNull Tool build() { ++ public Tool build() { + return new PaperItemTool(new net.minecraft.world.item.component.Tool(this.rules, this.miningSpeed, this.damage)); + } + } +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperJukeboxPlayable.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperJukeboxPlayable.java new file mode 100644 -index 0000000000000000000000000000000000000000..4eedbfc337fc3c937845268546dcd2f58ca0d789 +index 0000000000000000000000000000000000000000..2abd5f1a78fb0335bc4ed2651c53eb1290f213f2 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperJukeboxPlayable.java @@ -0,0 +1,61 @@ @@ -1831,11 +1839,11 @@ index 0000000000000000000000000000000000000000..4eedbfc337fc3c937845268546dcd2f5 + } + + @Override -+ public @NonNull JukeboxSong jukeboxSong() { ++ public JukeboxSong jukeboxSong() { + return this.impl.song().holder().map(CraftJukeboxSong::minecraftHolderToBukkit).orElseThrow(); + } + -+ static final class BuilderImpl implements Builder { ++ static final class BuilderImpl implements JukeboxPlayable.Builder { + + private JukeboxSong song; + private boolean showInTooltip = true; @@ -1845,19 +1853,19 @@ index 0000000000000000000000000000000000000000..4eedbfc337fc3c937845268546dcd2f5 + } + + @Override -+ public Builder showInTooltip(final boolean showInTooltip) { ++ public JukeboxPlayable.Builder showInTooltip(final boolean showInTooltip) { + this.showInTooltip = showInTooltip; + return this; + } + + @Override -+ public @NonNull Builder jukeboxSong(@NonNull final JukeboxSong song) { ++ public JukeboxPlayable.Builder jukeboxSong(final JukeboxSong song) { + this.song = song; + return this; + } + + @Override -+ public @NonNull JukeboxPlayable build() { ++ public JukeboxPlayable build() { + return new PaperJukeboxPlayable(new net.minecraft.world.item.JukeboxPlayable(new EitherHolder<>(CraftJukeboxSong.bukkitToMinecraftHolder(this.song)), this.showInTooltip)); + } + } @@ -1910,7 +1918,7 @@ index 0000000000000000000000000000000000000000..0737a3d3ed9a325f0cf232278de0098d +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperLodestoneTracker.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperLodestoneTracker.java new file mode 100644 -index 0000000000000000000000000000000000000000..fea818b24e2833033ef70c1ca825de814eccaf61 +index 0000000000000000000000000000000000000000..7f3a2929203a1c681f89d7f8aab8e574c4059921 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperLodestoneTracker.java @@ -0,0 +1,58 @@ @@ -1946,12 +1954,12 @@ index 0000000000000000000000000000000000000000..fea818b24e2833033ef70c1ca825de81 + + static final class BuilderImpl implements LodestoneTracker.Builder { + -+ private @Nullable Location pos; ++ private @Nullable Location location; + private boolean tracked = true; + + @Override + public LodestoneTracker.Builder location(final @Nullable Location location) { -+ this.pos = location; ++ this.location = location; + return this; + } + @@ -1965,7 +1973,7 @@ index 0000000000000000000000000000000000000000..fea818b24e2833033ef70c1ca825de81 + public LodestoneTracker build() { + return new PaperLodestoneTracker( + new net.minecraft.world.item.component.LodestoneTracker( -+ Optional.ofNullable(this.pos).map(CraftLocation::toGlobalPos), ++ Optional.ofNullable(this.location).map(CraftLocation::toGlobalPos), + this.tracked + ) + ); @@ -2251,7 +2259,7 @@ index 0000000000000000000000000000000000000000..3bf2538dff070f48b735bafe88a23e6e +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperPotionContents.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperPotionContents.java new file mode 100644 -index 0000000000000000000000000000000000000000..a18cbe16298ad944e1fff4f4c5576ae377f9a00f +index 0000000000000000000000000000000000000000..ac8973d7f558bb1391e7f7eb665bfdfe0e6d1ca1 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperPotionContents.java @@ -0,0 +1,90 @@ @@ -2271,7 +2279,7 @@ index 0000000000000000000000000000000000000000..a18cbe16298ad944e1fff4f4c5576ae3 +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.framework.qual.DefaultQualifier; + -+import static io.papermc.paper.datacomponent.item.ComponentUtils.transform; ++import static io.papermc.paper.datacomponent.ComponentUtils.transform; + +@DefaultQualifier(NonNull.class) +public record PaperPotionContents( @@ -2347,10 +2355,10 @@ index 0000000000000000000000000000000000000000..a18cbe16298ad944e1fff4f4c5576ae3 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperResolvableProfile.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperResolvableProfile.java new file mode 100644 -index 0000000000000000000000000000000000000000..d469fd6e0cd853c275ad263c832623f3b0b24cf5 +index 0000000000000000000000000000000000000000..96f91e0b7718eda002eaf8714c21516aa6ffe5bf --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperResolvableProfile.java -@@ -0,0 +1,105 @@ +@@ -0,0 +1,106 @@ +package io.papermc.paper.datacomponent.item; + +import com.destroystokyo.paper.profile.CraftPlayerProfile; @@ -2370,7 +2378,7 @@ index 0000000000000000000000000000000000000000..d469fd6e0cd853c275ad263c832623f3 +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.framework.qual.DefaultQualifier; + -+import static io.papermc.paper.datacomponent.item.ComponentUtils.transform; ++import static io.papermc.paper.datacomponent.ComponentUtils.transform; + +@DefaultQualifier(NonNull.class) +public record PaperResolvableProfile( @@ -2413,9 +2421,10 @@ index 0000000000000000000000000000000000000000..d469fd6e0cd853c275ad263c832623f3 + + @Override + public ResolvableProfile.Builder name(final @Nullable String name) { -+ final int length = name == null ? 0 : name.length(); -+ Preconditions.checkArgument(name == null || length <= 16, "name cannot be more than 16 characters, was %s", length); -+ Preconditions.checkArgument(name == null || StringUtil.isValidPlayerName(name), "name cannot include invalid characters, was %s", name); ++ if (name != null) { ++ Preconditions.checkArgument(name.length() <= 16, "name cannot be more than 16 characters, was %s", name.length()); ++ Preconditions.checkArgument(StringUtil.isValidPlayerName(name), "name cannot include invalid characters, was %s", name); ++ } + this.name = name; + return this; + } @@ -2429,7 +2438,7 @@ index 0000000000000000000000000000000000000000..d469fd6e0cd853c275ad263c832623f3 + @Override + public ResolvableProfile.Builder addProperty(final ProfileProperty property) { + // ProfileProperty constructor already has specific validations -+ final int newSize = this.propertyMap.size() + 1; ++ final int newSize = this.propertyMap.size() + 1; // todo see below notice + Preconditions.checkArgument(newSize <= 16, "Cannot have more than 16 properties, was %s", newSize); + this.propertyMap.put(property.getName(), new Property(property.getName(), property.getValue(), property.getSignature())); + return this; @@ -2437,7 +2446,7 @@ index 0000000000000000000000000000000000000000..d469fd6e0cd853c275ad263c832623f3 + + @Override + public ResolvableProfile.Builder addAllProperties(final List<ProfileProperty> properties) { -+ final int newSize = this.propertyMap.size() + properties.size(); ++ final int newSize = this.propertyMap.size() + properties.size(); // todo this check is wrong for duplicate property key since this is a map not a list + Preconditions.checkArgument(newSize <= 16, "Cannot have more than 16 properties, was %s", newSize); + for (final ProfileProperty property : properties) { + this.propertyMap.put(property.getName(), new Property(property.getName(), property.getValue(), property.getSignature())); @@ -2525,7 +2534,7 @@ index 0000000000000000000000000000000000000000..c6a11cbe924926ec6d7ac1d69b5dacfb +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperSuspiciousStewEffects.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperSuspiciousStewEffects.java new file mode 100644 -index 0000000000000000000000000000000000000000..19827c8b88f9a9b882633c5aff0561df4cbf2f48 +index 0000000000000000000000000000000000000000..5113d65c36c64710b0d1668baa986a755a215d5a --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperSuspiciousStewEffects.java @@ -0,0 +1,59 @@ @@ -2539,7 +2548,7 @@ index 0000000000000000000000000000000000000000..19827c8b88f9a9b882633c5aff0561df +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; + -+import static io.papermc.paper.datacomponent.item.ComponentUtils.transform; ++import static io.papermc.paper.datacomponent.ComponentUtils.transform; +import static io.papermc.paper.potion.SuspiciousEffectEntry.create; + +@DefaultQualifier(NonNull.class) @@ -2565,17 +2574,17 @@ index 0000000000000000000000000000000000000000..19827c8b88f9a9b882633c5aff0561df + private final List<net.minecraft.world.item.component.SuspiciousStewEffects.Entry> effects = new ArrayList<>(); + + @Override -+ public Builder add(final SuspiciousEffectEntry itemStack) { ++ public Builder add(final SuspiciousEffectEntry entry) { + this.effects.add(new net.minecraft.world.item.component.SuspiciousStewEffects.Entry( -+ org.bukkit.craftbukkit.potion.CraftPotionEffectType.bukkitToMinecraftHolder(itemStack.effect()), -+ itemStack.duration() ++ org.bukkit.craftbukkit.potion.CraftPotionEffectType.bukkitToMinecraftHolder(entry.effect()), ++ entry.duration() + )); + return this; + } + + @Override -+ public Builder addAll(final List<SuspiciousEffectEntry> itemStack) { -+ itemStack.forEach(this::add); ++ public Builder addAll(final List<SuspiciousEffectEntry> entries) { ++ entries.forEach(this::add); + return this; + } + @@ -2638,7 +2647,7 @@ index 0000000000000000000000000000000000000000..f95ceec3e154772f0af9e51eac99dcd7 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperWritableBookContent.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperWritableBookContent.java new file mode 100644 -index 0000000000000000000000000000000000000000..5c8249525613bfb2ddca470f27947fbe7f8cac86 +index 0000000000000000000000000000000000000000..e6336a7fd93c8bd6f9c3d63d48ce3c7d154a0d4b --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperWritableBookContent.java @@ -0,0 +1,107 @@ @@ -2655,7 +2664,7 @@ index 0000000000000000000000000000000000000000..5c8249525613bfb2ddca470f27947fbe +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; + -+import static io.papermc.paper.datacomponent.item.ComponentUtils.transform; ++import static io.papermc.paper.datacomponent.ComponentUtils.transform; +import static io.papermc.paper.util.Filtered.create; + +@DefaultQualifier(NonNull.class) @@ -2718,7 +2727,7 @@ index 0000000000000000000000000000000000000000..5c8249525613bfb2ddca470f27947fbe + } + + @Override -+ public WritableBookContent.Builder addPageFiltered(final Filtered<String> page) { ++ public WritableBookContent.Builder addFilteredPage(final Filtered<String> page) { + validatePageLength(page.raw()); + if (page.filtered() != null) { + validatePageLength(page.filtered()); @@ -2729,7 +2738,7 @@ index 0000000000000000000000000000000000000000..5c8249525613bfb2ddca470f27947fbe + } + + @Override -+ public WritableBookContent.Builder addPagesFiltered(final Collection<Filtered<String>> pages) { ++ public WritableBookContent.Builder addFilteredPages(final Collection<Filtered<String>> pages) { + validatePageCount(this.pages.size(), pages.size()); + for (final Filtered<String> page : pages) { + validatePageLength(page.raw()); @@ -2751,7 +2760,7 @@ index 0000000000000000000000000000000000000000..5c8249525613bfb2ddca470f27947fbe +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperWrittenBookContent.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperWrittenBookContent.java new file mode 100644 -index 0000000000000000000000000000000000000000..afb79f06d38fe0eeacfb5473b2f6d4e8cc869e83 +index 0000000000000000000000000000000000000000..c4de9165c341d9aa860ddb13c3c2d743a2680e81 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperWrittenBookContent.java @@ -0,0 +1,190 @@ @@ -2776,7 +2785,7 @@ index 0000000000000000000000000000000000000000..afb79f06d38fe0eeacfb5473b2f6d4e8 + +import static io.papermc.paper.adventure.PaperAdventure.asAdventure; +import static io.papermc.paper.adventure.PaperAdventure.asVanilla; -+import static io.papermc.paper.datacomponent.item.ComponentUtils.transform; ++import static io.papermc.paper.datacomponent.ComponentUtils.transform; + +@DefaultQualifier(NonNull.class) +public record PaperWrittenBookContent( @@ -2863,7 +2872,7 @@ index 0000000000000000000000000000000000000000..afb79f06d38fe0eeacfb5473b2f6d4e8 + } + + @Override -+ public WrittenBookContent.Builder titleFiltered(final Filtered<String> title) { ++ public WrittenBookContent.Builder filteredTitle(final Filtered<String> title) { + validateTitle(title.raw()); + if (title.filtered() != null) { + validateTitle(title.filtered()); @@ -2905,7 +2914,7 @@ index 0000000000000000000000000000000000000000..afb79f06d38fe0eeacfb5473b2f6d4e8 + } + + @Override -+ public WrittenBookContent.Builder addPages(final @NonNull Collection<? extends ComponentLike> pages) { ++ public WrittenBookContent.Builder addPages(final Collection<? extends ComponentLike> pages) { + for (final ComponentLike page : pages) { + final Component component = page.asComponent(); + validatePageLength(component); @@ -2980,7 +2989,7 @@ index 8ac485d82c2d2b32f4d54e02c18c2cb2c3df4fa4..4f15ec26c7512a6f2b9c14e108d582d3 ItemEnchantments(Object2IntAVLTreeMap<Holder<Enchantment>> enchantments, boolean showInTooltip) { // Paper diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index 32a41c8b324aad67b9dcf74387aef299e6478a64..30cca598bdec443ffe4f8a38ae8c10c4b20d1027 100644 +index 32a41c8b324aad67b9dcf74387aef299e6478a64..8bc572919dfd04f477a5b6aa62ee6bd7710c8039 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -192,7 +192,7 @@ public final class CraftItemStack extends ItemStack { @@ -3019,7 +3028,7 @@ index 32a41c8b324aad67b9dcf74387aef299e6478a64..30cca598bdec443ffe4f8a38ae8c10c4 item.set(DataComponents.PROFILE, new net.minecraft.world.item.component.ResolvableProfile(gameProfile)); } }; -@@ -539,4 +539,90 @@ public final class CraftItemStack extends ItemStack { +@@ -539,4 +539,84 @@ public final class CraftItemStack extends ItemStack { return this.pdcView; } // Paper end - pdc @@ -3066,13 +3075,7 @@ index 32a41c8b324aad67b9dcf74387aef299e6478a64..30cca598bdec443ffe4f8a38ae8c10c4 + } + + private <A, V> void setDataInternal(final io.papermc.paper.datacomponent.PaperComponentType<A, V> type, final A value) { -+ final io.papermc.paper.datacomponent.ComponentAdapter<V, A> adapter = type.getAdapter(); -+ if (adapter.isValued()) { -+ Preconditions.checkArgument(value != null, "value cannot be null"); -+ this.handle.set(type.getHandle(), adapter.toVanilla(value)); -+ } else { -+ this.handle.set(type.getHandle(), adapter.toVanilla(value)); -+ } ++ this.handle.set(type.getHandle(), type.getAdapter().toVanilla(value)); + } + + @Override @@ -3106,7 +3109,7 @@ index 32a41c8b324aad67b9dcf74387aef299e6478a64..30cca598bdec443ffe4f8a38ae8c10c4 + } + final net.minecraft.core.component.DataComponentType<?> nms = io.papermc.paper.datacomponent.PaperComponentType.bukkitToMinecraft(type); + // maybe a more efficient way is to expose the "patch" map in PatchedDataComponentMap and just check if the type exists as a key -+ return java.util.Objects.equals(this.handle.get(nms), this.handle.getPrototype().get(nms)); ++ return !java.util.Objects.equals(this.handle.get(nms), this.handle.getPrototype().get(nms)); + } + // Paper end - data component API } @@ -3159,7 +3162,7 @@ index 7277e7ee566aabf6e01937072d949ed67c3e8e38..24ff8b4ed2a70d02b850c3701d3295fd IntList fadeColors = CraftMetaFirework.addColors(effect.getFadeColors()); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index 4d97024bb05ab815409fc25c5924903868cc3945..a1839baaef752f54efeebb982b160396a690fc2e 100644 +index 4d97024bb05ab815409fc25c5924903868cc3945..c3e2cf55768a28824764fee387e8c1b2c0863744 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -136,7 +136,7 @@ import org.bukkit.persistence.PersistentDataContainer; @@ -3171,35 +3174,6 @@ index 4d97024bb05ab815409fc25c5924903868cc3945..a1839baaef752f54efeebb982b160396 static class ItemMetaKey { -@@ -182,10 +182,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - } - } - -- static abstract class Applicator { // Paper - support updating profile after resolving it -+ public static abstract class Applicator { // Paper - support updating profile after resolving it - -- final DataComponentPatch.Builder builder = DataComponentPatch.builder(); // Paper - private -> package-private -- void skullCallback(com.mojang.authlib.GameProfile gameProfile) {} // Paper - support updating profile after resolving it -+ public final DataComponentPatch.Builder builder = DataComponentPatch.builder(); // Paper -+ public void skullCallback(com.mojang.authlib.GameProfile gameProfile) {} // Paper - support updating profile after resolving it - - <T> Applicator put(ItemMetaKeyType<T> key, T value) { - this.builder.set(key.TYPE, value); -@@ -840,8 +840,13 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - return result; - } - -+ // Paper -+ public void applyToItemPublic(CraftMetaItem.Applicator itemTag) { -+ this.applyToItem(itemTag); -+ } -+ // Paper end - @Overridden -- void applyToItem(CraftMetaItem.Applicator itemTag) { -+ void applyToItem(CraftMetaItem.Applicator itemTag) { // Paper - if (this.hasDisplayName()) { - itemTag.put(CraftMetaItem.NAME, this.displayName); - } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftLocation.java b/src/main/java/org/bukkit/craftbukkit/util/CraftLocation.java index 097996d3955ab5126b71f7bff1dd2c62becb5ffd..0797ef29b76564491351042ce47e3d4500490bef 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftLocation.java @@ -3230,13 +3204,12 @@ index 0000000000000000000000000000000000000000..1c1fcbbacc3881e088d64a7a840b3f3e +io.papermc.paper.datacomponent.item.ComponentTypesBridgesImpl diff --git a/src/test/java/io/papermc/paper/item/ItemStackDataComponentTest.java b/src/test/java/io/papermc/paper/item/ItemStackDataComponentTest.java new file mode 100644 -index 0000000000000000000000000000000000000000..eab92494238fc6664ba7d551a2b9d8b33e59e188 +index 0000000000000000000000000000000000000000..49e18cffd75bbd9c28e75807d303759f552819dd --- /dev/null +++ b/src/test/java/io/papermc/paper/item/ItemStackDataComponentTest.java -@@ -0,0 +1,392 @@ +@@ -0,0 +1,389 @@ +package io.papermc.paper.item; + -+import com.google.common.collect.Iterators; +import io.papermc.paper.datacomponent.DataComponentType; +import io.papermc.paper.datacomponent.DataComponentTypes; +import io.papermc.paper.datacomponent.item.ChargedProjectiles; @@ -3248,6 +3221,7 @@ index 0000000000000000000000000000000000000000..eab92494238fc6664ba7d551a2b9d8b3 +import io.papermc.paper.datacomponent.item.ItemAttributeModifiers; +import io.papermc.paper.datacomponent.item.ItemEnchantments; +import io.papermc.paper.datacomponent.item.ItemLore; ++import io.papermc.paper.datacomponent.item.JukeboxPlayable; +import io.papermc.paper.datacomponent.item.MapID; +import io.papermc.paper.datacomponent.item.MapItemColor; +import io.papermc.paper.datacomponent.item.PotDecorations; @@ -3261,6 +3235,7 @@ index 0000000000000000000000000000000000000000..eab92494238fc6664ba7d551a2b9d8b3 +import net.kyori.adventure.util.TriState; +import org.bukkit.Color; +import org.bukkit.FireworkEffect; ++import org.bukkit.JukeboxSong; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; @@ -3284,6 +3259,7 @@ index 0000000000000000000000000000000000000000..eab92494238fc6664ba7d551a2b9d8b3 +import org.bukkit.inventory.meta.MapMeta; +import org.bukkit.inventory.meta.Repairable; +import org.bukkit.inventory.meta.components.FoodComponent; ++import org.bukkit.inventory.meta.components.JukeboxPlayableComponent; +import org.bukkit.inventory.meta.components.ToolComponent; +import org.bukkit.inventory.meta.trim.ArmorTrim; +import org.bukkit.inventory.meta.trim.TrimMaterial; @@ -3302,20 +3278,17 @@ index 0000000000000000000000000000000000000000..eab92494238fc6664ba7d551a2b9d8b3 + + @Test + void testMaxStackSize() { -+ final ItemStack stack = new ItemStack(Material.STONE); -+ testWithMeta(stack, DataComponentTypes.MAX_STACK_SIZE, 32, ItemMeta.class, ItemMeta::getMaxStackSize, ItemMeta::setMaxStackSize); ++ testWithMeta(new ItemStack(Material.STONE), DataComponentTypes.MAX_STACK_SIZE, 32, ItemMeta.class, ItemMeta::getMaxStackSize, ItemMeta::setMaxStackSize); + } + + @Test + void testMaxDamage() { -+ final ItemStack stack = new ItemStack(Material.STONE); -+ testWithMeta(stack, DataComponentTypes.MAX_DAMAGE, 120, Damageable.class, Damageable::getMaxDamage, Damageable::setMaxDamage); ++ testWithMeta(new ItemStack(Material.STONE), DataComponentTypes.MAX_DAMAGE, 120, Damageable.class, Damageable::getMaxDamage, Damageable::setMaxDamage); + } + + @Test + void testDamage() { -+ final ItemStack stack = new ItemStack(Material.STONE); -+ testWithMeta(stack, DataComponentTypes.DAMAGE, 120, Damageable.class, Damageable::getDamage, Damageable::setDamage); ++ testWithMeta(new ItemStack(Material.STONE), DataComponentTypes.DAMAGE, 120, Damageable.class, Damageable::getDamage, Damageable::setDamage); + } + + @Test @@ -3402,14 +3375,12 @@ index 0000000000000000000000000000000000000000..eab92494238fc6664ba7d551a2b9d8b3 + AttributeModifier modifier = new AttributeModifier(NamespacedKey.minecraft("test"), 5, AttributeModifier.Operation.ADD_NUMBER, EquipmentSlotGroup.ANY); + stack.setData(DataComponentTypes.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.itemAttributes().showInTooltip(false).addModifier(Attribute.GENERIC_ATTACK_DAMAGE, modifier).build()); + -+ + Assertions.assertTrue(stack.getItemMeta().hasItemFlag(ItemFlag.HIDE_ATTRIBUTES)); -+ Assertions.assertEquals(modifier, Iterators.get(stack.getItemMeta().getAttributeModifiers(Attribute.GENERIC_ATTACK_DAMAGE).iterator(), 0)); ++ Assertions.assertEquals(modifier, ((List<AttributeModifier>) stack.getItemMeta().getAttributeModifiers(Attribute.GENERIC_ATTACK_DAMAGE)).getFirst()); + stack.unsetData(DataComponentTypes.ATTRIBUTE_MODIFIERS); + Assertions.assertNull(stack.getItemMeta().getAttributeModifiers()); + } + -+ + @Test + void testCustomModelData() { + testWithMeta(new ItemStack(Material.STONE), DataComponentTypes.CUSTOM_MODEL_DATA, CustomModelData.customModelData().customModelData(1).build(), CustomModelData::data, ItemMeta.class, ItemMeta::getCustomModelData, ItemMeta::setCustomModelData); @@ -3449,7 +3420,7 @@ index 0000000000000000000000000000000000000000..eab92494238fc6664ba7d551a2b9d8b3 + + + stack.unsetData(DataComponentTypes.FOOD); -+ meta = (CrossbowMeta) stack.getItemMeta(); ++ meta = stack.getItemMeta(); + Assertions.assertFalse(meta.hasFood()); + } + @@ -3463,16 +3434,12 @@ index 0000000000000000000000000000000000000000..eab92494238fc6664ba7d551a2b9d8b3 + RegistrySet.keySetFromValues(RegistryKey.BLOCK, List.of(BlockType.STONE, BlockType.GRAVEL)), + 2F, + TriState.TRUE -+ + ), + Tool.Rule.of( + RegistryAccess.registryAccess().getRegistry(RegistryKey.BLOCK).getTag(TagKey.create(RegistryKey.BLOCK, NamespacedKey.minecraft("bamboo_blocks"))), + 2F, + TriState.TRUE -+ + ) -+ -+ + )) + .build(); + @@ -3492,12 +3459,26 @@ index 0000000000000000000000000000000000000000..eab92494238fc6664ba7d551a2b9d8b3 + idx++; + } + -+ + stack.unsetData(DataComponentTypes.TOOL); + meta = stack.getItemMeta(); + Assertions.assertFalse(meta.hasTool()); + } + ++ @Test ++ void testJukeboxPlayable() { ++ JukeboxPlayable properties = JukeboxPlayable.jukeboxPlayable(JukeboxSong.MALL).build(); ++ ++ final ItemStack stack = new ItemStack(Material.BEEF); ++ stack.setData(DataComponentTypes.JUKEBOX_PLAYABLE, properties); ++ ++ ItemMeta meta = stack.getItemMeta(); ++ JukeboxPlayableComponent component = meta.getJukeboxPlayable(); ++ Assertions.assertEquals(properties.jukeboxSong(), component.getSong()); ++ ++ stack.unsetData(DataComponentTypes.JUKEBOX_PLAYABLE); ++ meta = stack.getItemMeta(); ++ Assertions.assertFalse(meta.hasJukeboxPlayable()); ++ } + + @Test + void testFireResistant() { @@ -3528,9 +3509,9 @@ index 0000000000000000000000000000000000000000..eab92494238fc6664ba7d551a2b9d8b3 + + @Test + void testFireworks() { -+ testWithMeta(new ItemStack(Material.FIREWORK_ROCKET), DataComponentTypes.FIREWORKS, Fireworks.fireworks(List.of(FireworkEffect.builder().build()), 1), Fireworks::effects, FireworkMeta.class, FireworkMeta::getEffects, (fireworkMeta, o) -> { ++ testWithMeta(new ItemStack(Material.FIREWORK_ROCKET), DataComponentTypes.FIREWORKS, Fireworks.fireworks(List.of(FireworkEffect.builder().build()), 1), Fireworks::effects, FireworkMeta.class, FireworkMeta::getEffects, (fireworkMeta, effects) -> { + fireworkMeta.clearEffects(); -+ fireworkMeta.addEffects(o); ++ fireworkMeta.addEffects(effects); + }); + + testWithMeta(new ItemStack(Material.FIREWORK_ROCKET), DataComponentTypes.FIREWORKS, Fireworks.fireworks(List.of(FireworkEffect.builder().build()), 1), Fireworks::flightDuration, FireworkMeta.class, FireworkMeta::getPower, FireworkMeta::setPower); @@ -3578,25 +3559,10 @@ index 0000000000000000000000000000000000000000..eab92494238fc6664ba7d551a2b9d8b3 + Assertions.assertTrue(decoratedPot.getSherds().values().stream().allMatch((m) -> m == Material.BRICK)); + } + -+ @SuppressWarnings("unchecked") + private static <T, M extends ItemMeta> void testWithMeta(final ItemStack stack, final DataComponentType.Valued<T> type, final T value, final Class<M> metaType, final Function<M, T> metaGetter, final BiConsumer<M, T> metaSetter) { -+ ItemStack original = stack.clone(); -+ stack.setData(type, value); -+ -+ Assertions.assertEquals(value, stack.getData(type)); -+ -+ final ItemMeta meta = stack.getItemMeta(); -+ final M typedMeta = Assertions.assertInstanceOf(metaType, meta); -+ -+ Assertions.assertEquals(metaGetter.apply(typedMeta), value); -+ -+ // SETTING -+ metaSetter.accept(typedMeta, value); -+ original.setItemMeta(typedMeta); -+ Assertions.assertEquals(value, original.getData(type)); ++ testWithMeta(stack, type, value, Function.identity(), metaType, metaGetter, metaSetter); + } + -+ @SuppressWarnings("unchecked") + private static <T, M extends ItemMeta, R> void testWithMeta(final ItemStack stack, final DataComponentType.Valued<T> type, final T value, Function<T, R> mapper, final Class<M> metaType, final Function<M, R> metaGetter, final BiConsumer<M, R> metaSetter) { + ItemStack original = stack.clone(); + stack.setData(type, value); @@ -3614,8 +3580,8 @@ index 0000000000000000000000000000000000000000..eab92494238fc6664ba7d551a2b9d8b3 + Assertions.assertEquals(value, original.getData(type)); + } + -+ @SuppressWarnings("unchecked") -+ private static <M> void testWithMeta(final ItemStack stack, final DataComponentType.NonValued type, final boolean value, final Class<M> metaType, final Function<M, Boolean> metaGetter, final BiConsumer<M, Boolean> metaSetter) { ++ private static <M extends ItemMeta> void testWithMeta(final ItemStack stack, final DataComponentType.NonValued type, final boolean value, final Class<M> metaType, final Function<M, Boolean> metaGetter, final BiConsumer<M, Boolean> metaSetter) { ++ ItemStack original = stack.clone(); + stack.setData(type); + + Assertions.assertEquals(value, stack.hasData(type)); @@ -3624,11 +3590,16 @@ index 0000000000000000000000000000000000000000..eab92494238fc6664ba7d551a2b9d8b3 + final M typedMeta = Assertions.assertInstanceOf(metaType, meta); + + Assertions.assertEquals(metaGetter.apply(typedMeta), value); ++ ++ // SETTING ++ metaSetter.accept(typedMeta, value); ++ original.setItemMeta(typedMeta); ++ Assertions.assertEquals(value, original.hasData(type)); + } +} diff --git a/src/test/java/io/papermc/paper/item/MetaComparisonTest.java b/src/test/java/io/papermc/paper/item/MetaComparisonTest.java new file mode 100644 -index 0000000000000000000000000000000000000000..03aeb992c274d762c1b3475458851671d3045ffc +index 0000000000000000000000000000000000000000..6a5e874854a803c132de2fe638b89789af0f185a --- /dev/null +++ b/src/test/java/io/papermc/paper/item/MetaComparisonTest.java @@ -0,0 +1,284 @@ @@ -3655,11 +3626,12 @@ index 0000000000000000000000000000000000000000..03aeb992c274d762c1b3475458851671 +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.support.AbstractTestingBase; -+import org.bukkit.util.Consumer; +import org.junit.jupiter.api.Assertions; ++import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import java.util.UUID; ++import java.util.function.Consumer; + +// TODO: This should technically be used to compare legacy meta vs the newly implemented +public class MetaComparisonTest extends AbstractTestingBase { @@ -3710,12 +3682,11 @@ index 0000000000000000000000000000000000000000..03aeb992c274d762c1b3475458851671 + Assertions.assertNull(downgraded.getColor()); + } + -+ + @Test + public void testNullMeta() { + ItemStack itemStack = new ItemStack(Material.AIR); + -+ //Assertions.assertFalse(itemStack.hasItemMeta()); ++ Assertions.assertFalse(itemStack.hasItemMeta()); + Assertions.assertNull(itemStack.getItemMeta()); + } + @@ -3726,7 +3697,7 @@ index 0000000000000000000000000000000000000000..03aeb992c274d762c1b3475458851671 + + testSetAndGet(nmsItemStack, + (meta) -> ((PotionMeta) meta).addCustomEffect(potionEffect, true), -+ (meta) -> Assertions.assertEquals(potionEffect, ((PotionMeta) meta).getCustomEffects().get(0)) ++ (meta) -> Assertions.assertEquals(potionEffect, ((PotionMeta) meta).getCustomEffects().getFirst()) + ); + } + @@ -3741,7 +3712,8 @@ index 0000000000000000000000000000000000000000..03aeb992c274d762c1b3475458851671 + } + + -+ //@Test ++ @Test ++ @Disabled + public void testPlayerHead() { + PlayerProfile profile = new CraftPlayerProfile(UUID.randomUUID(), "Owen1212055"); + ItemStack stack = new ItemStack(Material.PLAYER_HEAD, 1); @@ -3914,7 +3886,6 @@ index 0000000000000000000000000000000000000000..03aeb992c274d762c1b3475458851671 + set.accept(paperMeta); + get.accept(paperMeta); + } -+ +} diff --git a/src/test/java/org/bukkit/PerMaterialTest.java b/src/test/java/org/bukkit/PerMaterialTest.java index c28386c3114ce85d67832e55ab44e2ab8f6e04d7..c1fca209e67e2f7bfa6f9efdef52264253ef8d58 100644 |