diff --git a/patches/api/0004-Code-Generation.patch b/patches/api/0004-Code-Generation.patch index 93ed7b062d..b5b2313958 100644 --- a/patches/api/0004-Code-Generation.patch +++ b/patches/api/0004-Code-Generation.patch @@ -319,7 +319,7 @@ index 0000000000000000000000000000000000000000..80e3e64f47ac55a4978c9e5b430e2f2d +} diff --git a/src/main/java/io/papermc/paper/registry/TypedKey.java b/src/main/java/io/papermc/paper/registry/TypedKey.java new file mode 100644 -index 0000000000000000000000000000000000000000..cb2e1a4a6d583787573eeefab24e3188c43d148f +index 0000000000000000000000000000000000000000..81bee5224196008662ddda528b5dcb8dd7cb9f21 --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/TypedKey.java @@ -0,0 +1,45 @@ @@ -337,7 +337,7 @@ index 0000000000000000000000000000000000000000..cb2e1a4a6d583787573eeefab24e3188 + */ +@ApiStatus.Experimental +@NullMarked -+public sealed interface TypedKey extends Keyed permits TypedKeyImpl { ++public sealed interface TypedKey extends Key permits TypedKeyImpl { + + /** + * Gets the key for the value in the registry. @@ -370,10 +370,10 @@ index 0000000000000000000000000000000000000000..cb2e1a4a6d583787573eeefab24e3188 +} diff --git a/src/main/java/io/papermc/paper/registry/TypedKeyImpl.java b/src/main/java/io/papermc/paper/registry/TypedKeyImpl.java new file mode 100644 -index 0000000000000000000000000000000000000000..99375deaa6b90b33cd6a77e0df651236d304874e +index 0000000000000000000000000000000000000000..3e29f7007500582cdc3f84b91f11ebeb58f68bbf --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/TypedKeyImpl.java -@@ -0,0 +1,8 @@ +@@ -0,0 +1,23 @@ +package io.papermc.paper.registry; + +import net.kyori.adventure.key.Key; @@ -381,6 +381,21 @@ index 0000000000000000000000000000000000000000..99375deaa6b90b33cd6a77e0df651236 + +@NullMarked +record TypedKeyImpl(Key key, RegistryKey registryKey) implements TypedKey { ++ // Wrap key methods to make this easier to use ++ @Override ++ public String namespace() { ++ return this.key.namespace(); ++ } ++ ++ @Override ++ public String value() { ++ return this.key.value(); ++ } ++ ++ @Override ++ public String asString() { ++ return this.key.asString(); ++ } +} diff --git a/src/main/java/org/bukkit/MinecraftExperimental.java b/src/main/java/org/bukkit/MinecraftExperimental.java index b7845523e8587e13b86516c0012fe097d904846c..d92a75f610cb2a95203b3f22dc67bdbfb5c3405a 100644 diff --git a/patches/api/0236-Add-RegistryAccess-for-managing-registries.patch b/patches/api/0236-Add-RegistryAccess-for-managing-registries.patch index 9150b77592..06d8e6d23f 100644 --- a/patches/api/0236-Add-RegistryAccess-for-managing-registries.patch +++ b/patches/api/0236-Add-RegistryAccess-for-managing-registries.patch @@ -206,8 +206,45 @@ index 3470755c65a2db38e679adc35d3d43f7fef5468d..1fe3a5e2f5c15fddfbcd503a061ebf75 public static Registry getRegistry(@NotNull Class tClass) { return server.getRegistry(tClass); } +diff --git a/src/main/java/org/bukkit/Particle.java b/src/main/java/org/bukkit/Particle.java +index 37e7862be843da4f48ac061fb1625854fd671b2a..cdc09d18088af3100cb731702edb7e6bffdeb502 100644 +--- a/src/main/java/org/bukkit/Particle.java ++++ b/src/main/java/org/bukkit/Particle.java +@@ -162,28 +162,23 @@ public enum Particle implements Keyed { + + private final NamespacedKey key; + private final Class dataType; +- final boolean register; ++ // Paper - all particles are registered + + Particle(String key) { + this(key, Void.class); + } + +- Particle(String key, boolean register) { +- this(key, Void.class, register); +- } ++ // Paper - all particles are registered + + Particle(String key, /*@NotNull*/ Class data) { +- this(key, data, true); +- } +- +- Particle(String key, /*@NotNull*/ Class data, boolean register) { ++ // Paper - all particles are registered + if (key != null) { + this.key = NamespacedKey.minecraft(key); + } else { + this.key = null; + } + dataType = data; +- this.register = register; ++ // Paper - all particles are registered + } + + /** diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java -index b4f297f90e3c1deaa1fc3f4418418588ab19b6c5..46dce7c2a543f6b165975565ea9d40654a132b9b 100644 +index b4f297f90e3c1deaa1fc3f4418418588ab19b6c5..d03bdf6617ce66950e335f0afb52c19b2e2a14e2 100644 --- a/src/main/java/org/bukkit/Registry.java +++ b/src/main/java/org/bukkit/Registry.java @@ -86,26 +86,32 @@ public interface Registry extends Iterable { @@ -256,7 +293,7 @@ index b4f297f90e3c1deaa1fc3f4418418588ab19b6c5..46dce7c2a543f6b165975565ea9d4065 /** * Custom boss bars. * -@@ -155,13 +161,15 @@ public interface Registry extends Iterable { +@@ -155,25 +161,29 @@ public interface Registry extends Iterable { * * @see Cat.Type */ @@ -274,7 +311,11 @@ index b4f297f90e3c1deaa1fc3f4418418588ab19b6c5..46dce7c2a543f6b165975565ea9d4065 /** * Server entity types. * -@@ -172,8 +180,10 @@ public interface Registry extends Iterable { + * @see EntityType + */ +- Registry ENTITY_TYPE = new SimpleRegistry<>(EntityType.class, (entity) -> entity != EntityType.UNKNOWN); ++ Registry ENTITY_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.ENTITY_TYPE); // Paper + /** * Server instruments. * * @see MusicInstrument @@ -295,7 +336,7 @@ index b4f297f90e3c1deaa1fc3f4418418588ab19b6c5..46dce7c2a543f6b165975565ea9d4065 /** * Default server loot tables. * -@@ -200,13 +210,13 @@ public interface Registry extends Iterable { +@@ -200,25 +210,25 @@ public interface Registry extends Iterable { * @see MenuType */ @ApiStatus.Experimental @@ -311,6 +352,20 @@ index b4f297f90e3c1deaa1fc3f4418418588ab19b6c5..46dce7c2a543f6b165975565ea9d4065 /** * Server particles. * + * @see Particle + */ +- Registry PARTICLE_TYPE = new SimpleRegistry<>(Particle.class, (par) -> par.register); ++ Registry PARTICLE_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.PARTICLE_TYPE); // Paper + /** + * Server potions. + * + * @see PotionType + */ +- Registry POTION = new SimpleRegistry<>(PotionType.class); ++ Registry POTION = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.POTION); // Paper + /** + * Server statistics. + * @@ -229,58 +239,67 @@ public interface Registry extends Iterable { * Server structures. * @@ -428,6 +483,15 @@ index b4f297f90e3c1deaa1fc3f4418418588ab19b6c5..46dce7c2a543f6b165975565ea9d4065 /** * Get the object by its key. * +@@ -396,7 +417,7 @@ public interface Registry extends Iterable { + return (namespacedKey != null) ? get(namespacedKey) : null; + } + +- static final class SimpleRegistry & Keyed> implements Registry { ++ class SimpleRegistry & Keyed> implements Registry { // Paper - remove final + + private final Class type; + private final Map map; diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java index 6bc43f3a5748a1b83aa4c4d462df3cbc9220c267..cad9c18dbe56ffcef377f0b1162bc880fc56aa6c 100644 --- a/src/main/java/org/bukkit/Server.java diff --git a/patches/api/0471-Registry-Modification-API.patch b/patches/api/0471-Registry-Modification-API.patch index 68aa633997..74474eb752 100644 --- a/patches/api/0471-Registry-Modification-API.patch +++ b/patches/api/0471-Registry-Modification-API.patch @@ -809,7 +809,7 @@ index 0000000000000000000000000000000000000000..bf49125acc8a0508bf59674bba3ed350 + } +} diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java -index 67b9ab322baecf5b2453df4795106514cb073108..7cf7c6d05aa6cbf3f0c8612831404552c6a7b84a 100644 +index c3d49f9c640eb390f507f9521a389cb7c172983a..87907918c42b11780b285b6d82e7297628a07376 100644 --- a/src/main/java/org/bukkit/Registry.java +++ b/src/main/java/org/bukkit/Registry.java @@ -384,6 +384,27 @@ public interface Registry extends Iterable { @@ -875,38 +875,3 @@ index 67b9ab322baecf5b2453df4795106514cb073108..7cf7c6d05aa6cbf3f0c8612831404552 /** * Get the object by its key. * -@@ -561,5 +610,23 @@ public interface Registry extends Iterable { - return value.getKey(); - } - // Paper end - improve Registry -+ -+ // Paper start - RegistrySet API -+ @SuppressWarnings("deprecation") -+ @Override -+ public boolean hasTag(final io.papermc.paper.registry.tag.@NotNull TagKey key) { -+ return Bukkit.getUnsafe().getTag(key) != null; -+ } -+ -+ @SuppressWarnings("deprecation") -+ @Override -+ public io.papermc.paper.registry.tag.@NotNull Tag getTag(final io.papermc.paper.registry.tag.@NotNull TagKey key) { -+ final io.papermc.paper.registry.tag.Tag tag = Bukkit.getUnsafe().getTag(key); -+ if (tag == null) { -+ throw new java.util.NoSuchElementException("No tag " + key + " found"); -+ } -+ return tag; -+ } -+ // Paper end - RegistrySet API - } - } -diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index b503b5e13c51580367d53939ad4c19a7718c22ce..5b13617e497e847ef66214f9140aea0cd41f4c4f 100644 ---- a/src/main/java/org/bukkit/UnsafeValues.java -+++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -281,4 +281,6 @@ public interface UnsafeValues { - // Paper end - lifecycle event API - - @NotNull java.util.List computeTooltipLines(@NotNull ItemStack itemStack, @NotNull io.papermc.paper.inventory.tooltip.TooltipContext tooltipContext, @Nullable org.bukkit.entity.Player player); // Paper - expose itemstack tooltip lines -+ -+ io.papermc.paper.registry.tag.@Nullable Tag getTag(io.papermc.paper.registry.tag.@NotNull TagKey tagKey); // Paper - hack to get tags for non-server backed registries - } diff --git a/patches/api/0472-Introduce-registry-entry-and-builders.patch b/patches/api/0472-Introduce-registry-entry-and-builders.patch index 0a25fd735e..631eaf3f55 100644 --- a/patches/api/0472-Introduce-registry-entry-and-builders.patch +++ b/patches/api/0472-Introduce-registry-entry-and-builders.patch @@ -3,6 +3,7 @@ From: Bjarne Koll Date: Thu, 13 Jun 2024 22:35:05 +0200 Subject: [PATCH] Introduce registry entry and builders +Co-authored-by: kokiriglade diff --git a/src/main/java/io/papermc/paper/registry/RegistryKey.java b/src/main/java/io/papermc/paper/registry/RegistryKey.java index 647f6a1ec1f9d3c203b41f90a99bfd415bf67366..9b39e33514b15a9d07104e2ad826d0da11f569d6 100644 @@ -414,6 +415,147 @@ index 0000000000000000000000000000000000000000..980fe12b75258b51cc2498590cadb9de + Builder range(@Range(from = 0, to = Integer.MAX_VALUE) int range); + } +} +diff --git a/src/main/java/io/papermc/paper/registry/data/PaintingVariantRegistryEntry.java b/src/main/java/io/papermc/paper/registry/data/PaintingVariantRegistryEntry.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b8d133afa82da1b5b9e7a18e1c332ae3aefea50d +--- /dev/null ++++ b/src/main/java/io/papermc/paper/registry/data/PaintingVariantRegistryEntry.java +@@ -0,0 +1,135 @@ ++package io.papermc.paper.registry.data; ++ ++import io.papermc.paper.registry.RegistryBuilder; ++import java.util.Optional; ++import net.kyori.adventure.key.Key; ++import net.kyori.adventure.text.Component; ++import org.bukkit.Art; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.Range; ++import org.jspecify.annotations.NullMarked; ++import org.jspecify.annotations.Nullable; ++ ++/** ++ * A data-centric version-specific registry entry for the {@link Art} type. ++ */ ++@ApiStatus.Experimental ++@NullMarked ++@ApiStatus.NonExtendable ++public interface PaintingVariantRegistryEntry { ++ ++ /** ++ * Provides the width of this variant in blocks. ++ * ++ * @return the width ++ * @see Art#getBlockWidth() ++ */ ++ @Range(from = 1, to = 16) ++ int width(); ++ ++ /** ++ * Provides the height of this variant in blocks. ++ * ++ * @return the height ++ * @see Art#getBlockHeight() ++ */ ++ @Range(from = 1, to = 16) ++ int height(); ++ ++ /** ++ * Provides the title of the painting visible in the creative inventory. ++ * ++ * @return the title ++ * @see Art#title() ++ */ ++ @Nullable Component title(); ++ ++ /** ++ * Provides the author of the painting visible in the creative inventory. ++ * ++ * @return the author ++ * @see Art#author() ++ */ ++ @Nullable Component author(); ++ ++ /** ++ * Provides the assetId of the variant, which is the location of the sprite to use. ++ * ++ * @return the asset id ++ * @see Art#assetId() ++ */ ++ Key assetId(); ++ ++ /** ++ * A mutable builder for the {@link PaintingVariantRegistryEntry} plugins may change in applicable registry events. ++ *

++ * The following values are required for each builder: ++ *

    ++ *
  • {@link #width(int)}
  • ++ *
  • {@link #height(int)}
  • ++ *
  • {@link #assetId(Key)}
  • ++ *
++ */ ++ @ApiStatus.Experimental ++ @ApiStatus.NonExtendable ++ interface Builder extends PaintingVariantRegistryEntry, RegistryBuilder { ++ ++ /** ++ * Sets the width of the painting in blocks. ++ * ++ * @param width the width in blocks ++ * @return this builder instance ++ * @see PaintingVariantRegistryEntry#width() ++ * @see Art#getBlockWidth() ++ */ ++ @Contract(value = "_ -> this", mutates = "this") ++ Builder width(@Range(from = 0, to = 16) int width); ++ ++ /** ++ * Sets the height of the painting in blocks. ++ * ++ * @param height the height in blocks ++ * @return this builder instance ++ * @see PaintingVariantRegistryEntry#height() ++ * @see Art#getBlockHeight() ++ */ ++ @Contract(value = "_ -> this", mutates = "this") ++ Builder height(@Range(from = 0, to = 16) int height); ++ ++ /** ++ * Sets the title of the painting. ++ * ++ * @param title the title ++ * @return this builder instance ++ * @see PaintingVariantRegistryEntry#title() ++ * @see Art#title() ++ */ ++ @Contract(value = "_ -> this", mutates = "this") ++ Builder title(@Nullable Component title); ++ ++ /** ++ * Sets the author of the painting. ++ * ++ * @param author the author ++ * @return this builder instance ++ * @see PaintingVariantRegistryEntry#author() ++ * @see Art#author() ++ */ ++ @Contract(value = "_ -> this", mutates = "this") ++ Builder author(@Nullable Component author); ++ ++ /** ++ * Sets the assetId of the variant, which is the location of the sprite to use. ++ * ++ * @param assetId the asset id ++ * @return this builder instance ++ * @see PaintingVariantRegistryEntry#assetId() ++ * @see Art#assetId() ++ */ ++ @Contract(value = "_ -> this", mutates = "this") ++ Builder assetId(Key assetId); ++ ++ } ++ ++} diff --git a/src/main/java/io/papermc/paper/registry/data/package-info.java b/src/main/java/io/papermc/paper/registry/data/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..4f8f536f437c5f483ac7bce393e664fd7bc38477 @@ -430,15 +572,17 @@ index 0000000000000000000000000000000000000000..4f8f536f437c5f483ac7bce393e664fd + */ +package io.papermc.paper.registry.data; diff --git a/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java b/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java -index 91ae9c0d3ec55ce417d4b447bf3d1b0d0c174b5e..1c8e77c7243cfedef6c4d1491cf98e6ec8f1690f 100644 +index 91ae9c0d3ec55ce417d4b447bf3d1b0d0c174b5e..40deffbd0930508bb04e9aedfd62ad2144855198 100644 --- a/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java +++ b/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java -@@ -1,8 +1,15 @@ +@@ -1,8 +1,17 @@ package io.papermc.paper.registry.event; +import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.data.EnchantmentRegistryEntry; +import io.papermc.paper.registry.data.GameEventRegistryEntry; ++import io.papermc.paper.registry.data.PaintingVariantRegistryEntry; ++import org.bukkit.Art; +import org.bukkit.GameEvent; +import org.bukkit.enchantments.Enchantment; import org.jetbrains.annotations.ApiStatus; @@ -449,12 +593,13 @@ index 91ae9c0d3ec55ce417d4b447bf3d1b0d0c174b5e..1c8e77c7243cfedef6c4d1491cf98e6e /** * Holds providers for {@link RegistryEntryAddEvent} and {@link RegistryFreezeEvent} * handlers for each applicable registry. -@@ -11,6 +18,9 @@ import org.jspecify.annotations.NullMarked; +@@ -11,6 +20,10 @@ import org.jspecify.annotations.NullMarked; @NullMarked public final class RegistryEvents { + public static final RegistryEventProvider GAME_EVENT = create(RegistryKey.GAME_EVENT); + public static final RegistryEventProvider ENCHANTMENT = create(RegistryKey.ENCHANTMENT); ++ public static final RegistryEventProvider PAINTING_VARIANT = create(RegistryKey.PAINTING_VARIANT); + private RegistryEvents() { } diff --git a/patches/api/0473-Proxy-ItemStack-to-CraftItemStack.patch b/patches/api/0473-Proxy-ItemStack-to-CraftItemStack.patch index 927052f343..1608d48862 100644 --- a/patches/api/0473-Proxy-ItemStack-to-CraftItemStack.patch +++ b/patches/api/0473-Proxy-ItemStack-to-CraftItemStack.patch @@ -5,13 +5,13 @@ Subject: [PATCH] Proxy ItemStack to CraftItemStack diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 5b13617e497e847ef66214f9140aea0cd41f4c4f..56d16c887b7663aab7db2f7be532d9912aeb3570 100644 +index b503b5e13c51580367d53939ad4c19a7718c22ce..307439827b401acb96f0df1cf4ef31835bd1d513 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -283,4 +283,6 @@ public interface UnsafeValues { - @NotNull java.util.List computeTooltipLines(@NotNull ItemStack itemStack, @NotNull io.papermc.paper.inventory.tooltip.TooltipContext tooltipContext, @Nullable org.bukkit.entity.Player player); // Paper - expose itemstack tooltip lines +@@ -281,4 +281,6 @@ public interface UnsafeValues { + // Paper end - lifecycle event API -
io.papermc.paper.registry.tag.@Nullable Tag getTag(io.papermc.paper.registry.tag.@NotNull TagKey tagKey); // Paper - hack to get tags for non-server backed registries + @NotNull java.util.List computeTooltipLines(@NotNull ItemStack itemStack, @NotNull io.papermc.paper.inventory.tooltip.TooltipContext tooltipContext, @Nullable org.bukkit.entity.Player player); // Paper - expose itemstack tooltip lines + + ItemStack createEmptyStack(); // Paper - proxy ItemStack } diff --git a/patches/api/0478-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch b/patches/api/0478-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch index 9ee5f867c6..61318cd604 100644 --- a/patches/api/0478-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch +++ b/patches/api/0478-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch @@ -228,7 +228,7 @@ index 7ff6d60deb129e23b2a4d772aee123eb6c0b6433..52a2763773b234c581b2dcc6f0584f8d return key; } diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java -index fc089b796f5a0f2e1ab081cc710e4bb5c3f5ee7b..2a86e599175549a3021a63a837f8cc9d8da5697d 100644 +index 3fdba38fd5e75ddcbfca9cee70a606bfa4a539bf..66219e3855aef885341132a7456af54cf315475f 100644 --- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java @@ -1010,4 +1010,98 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste diff --git a/patches/api/0484-Add-FeatureFlag-API.patch b/patches/api/0484-Add-FeatureFlag-API.patch index 9a535e20f5..008c2d793c 100644 --- a/patches/api/0484-Add-FeatureFlag-API.patch +++ b/patches/api/0484-Add-FeatureFlag-API.patch @@ -247,7 +247,7 @@ index eb33e8e671972aa308ad75a7ce9aa9ac526f470f..05ecf3cb38ff42c8b52405d900197e6b /** * Gets the {@link Biome} at the given {@link Location}. diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 56d16c887b7663aab7db2f7be532d9912aeb3570..2dd4c16ac107f58752c725540ab414ff79c46ff4 100644 +index 307439827b401acb96f0df1cf4ef31835bd1d513..e8dc8a6abebf6c31cb095ca3646eb4909e42f105 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java @@ -111,8 +111,7 @@ public interface UnsafeValues { diff --git a/patches/api/0486-Item-serialization-as-json.patch b/patches/api/0486-Item-serialization-as-json.patch index e7d391dc20..eae7e05be8 100644 --- a/patches/api/0486-Item-serialization-as-json.patch +++ b/patches/api/0486-Item-serialization-as-json.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Item serialization as json diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 2dd4c16ac107f58752c725540ab414ff79c46ff4..79312bdda8ef0799e2d46decc52cfdac95b97d37 100644 +index e8dc8a6abebf6c31cb095ca3646eb4909e42f105..a491dc40093e19b8d1900443ad613223fd7f3119 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java @@ -168,6 +168,36 @@ public interface UnsafeValues { diff --git a/patches/api/0492-Void-damage-configuration-API.patch b/patches/api/0492-Void-damage-configuration-API.patch index 26cbd83b18..6863ef168c 100644 --- a/patches/api/0492-Void-damage-configuration-API.patch +++ b/patches/api/0492-Void-damage-configuration-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Void damage configuration API diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index adcd8161846b06fd1a7895750f98b629204a8406..ef32a937e6faf1e8a5d6b1207986715bae5a246c 100644 +index b462f2a9f7b6acbdc826d093b1de826ca682f25b..7a439c99fc4c5ee17d674460c8e58a9fe0c64e02 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -52,6 +52,54 @@ import org.jetbrains.annotations.Nullable; diff --git a/patches/api/0495-DataComponent-API.patch b/patches/api/0495-DataComponent-API.patch index 9284c1e00b..5f86c0b8e6 100644 --- a/patches/api/0495-DataComponent-API.patch +++ b/patches/api/0495-DataComponent-API.patch @@ -158,7 +158,7 @@ index 0000000000000000000000000000000000000000..e2266d86a4dd1bf20346e48c428f8baf +} 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..e79737ae012179fc7c89b14af8801b8b09fa042b +index 0000000000000000000000000000000000000000..68284abd5c4358617ee7766101e942f81a001e2c --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/DataComponentTypes.java @@ -0,0 +1,344 @@ @@ -322,9 +322,9 @@ index 0000000000000000000000000000000000000000..e79737ae012179fc7c89b14af8801b8b + * If not present, has an implicit default value of: {@code 0}. + */ + public static final DataComponentType.Valued<@NonNegative Integer> REPAIR_COST = valued("repair_cost"); -+ /** -+ * Causes an item to not be pickable in the creative menu, currently not very useful. -+ */ ++ // /** ++ // * Causes an item to not be pickable in the creative menu, currently not very useful. ++ // */ + // public static final DataComponentType.NonValued CREATIVE_SLOT_LOCK = unvalued("creative_slot_lock"); + /** + * Overrides the enchantment glint effect on an item. @@ -508,14 +508,13 @@ index 0000000000000000000000000000000000000000..e79737ae012179fc7c89b14af8801b8b +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/BannerPatternLayers.java b/src/main/java/io/papermc/paper/datacomponent/item/BannerPatternLayers.java new file mode 100644 -index 0000000000000000000000000000000000000000..12cfae82234b8c4cb231ab91e72ad82d28b85183 +index 0000000000000000000000000000000000000000..785b5db96bb5a0584647f2ed41fcd882ab6b3250 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/BannerPatternLayers.java -@@ -0,0 +1,66 @@ +@@ -0,0 +1,65 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.datacomponent.DataComponentBuilder; -+import java.util.Arrays; +import java.util.List; +import org.bukkit.block.banner.Pattern; +import org.jetbrains.annotations.ApiStatus; @@ -637,14 +636,13 @@ index 0000000000000000000000000000000000000000..65f1bc8d1bea0042dca9683c43956113 +} 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..c0f671aef8225c87632d2368d1b28fc8b1bce686 +index 0000000000000000000000000000000000000000..d47a78a6f51db66950ee67c60cfef1e21f4a4d40 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/BundleContents.java -@@ -0,0 +1,66 @@ +@@ -0,0 +1,65 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.datacomponent.DataComponentBuilder; -+import java.util.Arrays; +import java.util.List; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; @@ -709,14 +707,13 @@ index 0000000000000000000000000000000000000000..c0f671aef8225c87632d2368d1b28fc8 +} 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..d0a6e7db06f540e13ac00e8da3acabd9f7838f1f +index 0000000000000000000000000000000000000000..aac079e1d8056ec02741386a1bf2e7adf592e5bd --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/ChargedProjectiles.java -@@ -0,0 +1,66 @@ +@@ -0,0 +1,65 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.datacomponent.DataComponentBuilder; -+import java.util.Arrays; +import java.util.List; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; @@ -781,17 +778,16 @@ index 0000000000000000000000000000000000000000..d0a6e7db06f540e13ac00e8da3acabd9 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/Consumable.java b/src/main/java/io/papermc/paper/datacomponent/item/Consumable.java new file mode 100644 -index 0000000000000000000000000000000000000000..a448fedb63ffce18b9f6a1bd0fecfc5cd90224a6 +index 0000000000000000000000000000000000000000..8c88bbbeef179e6c6666d07c8b28157ee1e84a2b --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/Consumable.java -@@ -0,0 +1,70 @@ +@@ -0,0 +1,69 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.datacomponent.BuildableDataComponent; +import io.papermc.paper.datacomponent.DataComponentBuilder; +import io.papermc.paper.datacomponent.item.consumable.ConsumeEffect; +import io.papermc.paper.datacomponent.item.consumable.ItemUseAnimation; -+import java.util.Collection; +import java.util.List; +import net.kyori.adventure.key.Key; +import org.checkerframework.checker.index.qual.NonNegative; @@ -927,16 +923,14 @@ index 0000000000000000000000000000000000000000..6cbd73cb2a11f4858b44a2f57d2fe0ac +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/DeathProtection.java b/src/main/java/io/papermc/paper/datacomponent/item/DeathProtection.java new file mode 100644 -index 0000000000000000000000000000000000000000..87c2220708af7db06348994ad5940c7cecd9f691 +index 0000000000000000000000000000000000000000..8a42550bb52d00d9b5df1a64e997e0762bffde59 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/DeathProtection.java -@@ -0,0 +1,48 @@ +@@ -0,0 +1,46 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.datacomponent.DataComponentBuilder; +import io.papermc.paper.datacomponent.item.consumable.ConsumeEffect; -+import java.util.Arrays; -+import java.util.Collection; +import java.util.List; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; @@ -1040,7 +1034,7 @@ index 0000000000000000000000000000000000000000..d80581fc8b894cc4d4af9741244b1bb0 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/Enchantable.java b/src/main/java/io/papermc/paper/datacomponent/item/Enchantable.java new file mode 100644 -index 0000000000000000000000000000000000000000..5169b9cd73dc0ffc8297f8d5f63d3d707a47d279 +index 0000000000000000000000000000000000000000..a128348247d8845321d3fecebaa09a5175a923cc --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/Enchantable.java @@ -0,0 +1,31 @@ @@ -1069,18 +1063,18 @@ index 0000000000000000000000000000000000000000..5169b9cd73dc0ffc8297f8d5f63d3d70 + * Gets the current enchantment value level allowed, + * a higher value allows enchantments with a higher cost to be picked. + * -+ * @see Minecraft Wiki + * @return the value ++ * @see Minecraft Wiki + */ + @Contract(pure = true) + @Positive int value(); +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/Equippable.java b/src/main/java/io/papermc/paper/datacomponent/item/Equippable.java new file mode 100644 -index 0000000000000000000000000000000000000000..7d84217814bba4ce826e33755fee0d5c3b280009 +index 0000000000000000000000000000000000000000..826bb860bd55ff18f91d9bc7a5dde4d638b39f98 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/Equippable.java -@@ -0,0 +1,170 @@ +@@ -0,0 +1,169 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.datacomponent.BuildableDataComponent; @@ -1094,7 +1088,6 @@ index 0000000000000000000000000000000000000000..7d84217814bba4ce826e33755fee0d5c +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + -+ +/** + * Holds the equippable properties of an item. + * @see io.papermc.paper.datacomponent.DataComponentTypes#EQUIPPABLE @@ -1106,8 +1099,8 @@ index 0000000000000000000000000000000000000000..7d84217814bba4ce826e33755fee0d5c + + /** + * Creates a new {@link Equippable.Builder} instance. -+ * @param slot The slot for the new equippable to be equippable in. + * ++ * @param slot The slot for the new equippable to be equippable in. + * @return a new builder + */ + @Contract(value = "_ -> new", pure = true) @@ -1190,11 +1183,11 @@ index 0000000000000000000000000000000000000000..7d84217814bba4ce826e33755fee0d5c + /** + * Sets the equip sound key for this item. + * -+ * @param equipSound the equip sound key ++ * @param sound the equip sound key + * @return the builder for chaining + */ + @Contract(value = "_ -> this", mutates = "this") -+ Builder equipSound(Key equipSound); ++ Builder equipSound(Key sound); + + /** + * Sets the model key for this item. @@ -1343,10 +1336,10 @@ index 0000000000000000000000000000000000000000..72aa1b4bda2693e0cd78d93449dda23b +} 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..369208e15a0e7fc91a9505fef2097c4283445e4a +index 0000000000000000000000000000000000000000..2b94017d0310d023556bdd7b9ab1eae0261669c6 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/FoodProperties.java -@@ -0,0 +1,87 @@ +@@ -0,0 +1,86 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.datacomponent.BuildableDataComponent; @@ -1431,7 +1424,6 @@ index 0000000000000000000000000000000000000000..369208e15a0e7fc91a9505fef2097c42 + */ + @Contract(value = "_ -> this", mutates = "this") + Builder nutrition(@NonNegative int nutrition); -+ + } +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ItemAdventurePredicate.java b/src/main/java/io/papermc/paper/datacomponent/item/ItemAdventurePredicate.java @@ -1566,10 +1558,10 @@ index 0000000000000000000000000000000000000000..0309ae59ab7945ddfb5410930d161e2c +} 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..948505d38121d54df62e6a67d4597bc7d42c356f +index 0000000000000000000000000000000000000000..56a3e678c6658dd617da4974d9392006875aef0c --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemAttributeModifiers.java -@@ -0,0 +1,98 @@ +@@ -0,0 +1,97 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.datacomponent.DataComponentBuilder; @@ -1584,7 +1576,6 @@ index 0000000000000000000000000000000000000000..948505d38121d54df62e6a67d4597bc7 + +/** + * Holds attribute modifiers applied to any item. -+ * + * @see io.papermc.paper.datacomponent.DataComponentTypes#ATTRIBUTE_MODIFIERS + */ +@NullMarked @@ -1652,7 +1643,7 @@ index 0000000000000000000000000000000000000000..948505d38121d54df62e6a67d4597bc7 + * @return the builder for chaining + * @see #modifiers() + */ -+ @Contract(value = "_, _, _ -> this", mutates = "this") ++ @Contract(value = "_, _ -> this", mutates = "this") + Builder addModifier(Attribute attribute, AttributeModifier modifier); + + /** @@ -1788,14 +1779,13 @@ index 0000000000000000000000000000000000000000..1ce34642371a65590ce1ac74b402ccfc +} 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..7d1c973ba566752d7a85496327b1352d973f2218 +index 0000000000000000000000000000000000000000..3b00e34a1d6aeec694c712d7a3a323da938f270b --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemContainerContents.java -@@ -0,0 +1,63 @@ +@@ -0,0 +1,62 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.datacomponent.DataComponentBuilder; -+import java.util.Arrays; +import java.util.List; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; @@ -2393,10 +2383,10 @@ index 0000000000000000000000000000000000000000..4f16e08f04c2cea24f3cb132ff21f4bd +} 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..6da78b8735a6cadd1282fa2fafd8b0f74f087fb4 +index 0000000000000000000000000000000000000000..15154d7f9f861991134eb5a5210f7244db3216eb --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PotDecorations.java -@@ -0,0 +1,109 @@ +@@ -0,0 +1,108 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.datacomponent.DataComponentBuilder; @@ -2406,7 +2396,6 @@ index 0000000000000000000000000000000000000000..6da78b8735a6cadd1282fa2fafd8b0f7 +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + -+// CONTRIBUTORS: LEAVE THIS AS ITEM TYPE!!! +/** + * Holds the item types for the decorations on a flower pot. + * @see io.papermc.paper.datacomponent.DataComponentTypes#POT_DECORATIONS @@ -2508,10 +2497,10 @@ index 0000000000000000000000000000000000000000..6da78b8735a6cadd1282fa2fafd8b0f7 +} 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..7cf05b382319064d45433a7e2678f65c25d11b14 +index 0000000000000000000000000000000000000000..1583d408336aec5d0c6eb7124b2cecc32c4fda56 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PotionContents.java -@@ -0,0 +1,120 @@ +@@ -0,0 +1,118 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.datacomponent.DataComponentBuilder; @@ -2593,8 +2582,8 @@ index 0000000000000000000000000000000000000000..7cf05b382319064d45433a7e2678f65c + * + * @param color color + * @return the builder for chaining -+ * @see #customColor() + * @apiNote alpha channel of the color is supported only for Tipped Arrow ++ * @see #customColor() + */ + @Contract(value = "_ -> this", mutates = "this") + Builder customColor(@Nullable Color color); @@ -2613,7 +2602,6 @@ index 0000000000000000000000000000000000000000..7cf05b382319064d45433a7e2678f65c + * Adds a custom effect instance to this builder. + * + * @param effect effect -+ * @see #customEffects() + * @return the builder for chaining + * @see #customEffects() + */ @@ -2624,7 +2612,6 @@ index 0000000000000000000000000000000000000000..7cf05b382319064d45433a7e2678f65c + * Adds custom effect instances to this builder. + * + * @param effects effects -+ * @see #customEffects() + * @return the builder for chaining + * @see #customEffects() + */ @@ -2876,10 +2863,10 @@ index 0000000000000000000000000000000000000000..f79af65e8f3f8ffbb9be1cf1c6b537cd +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ShownInTooltip.java b/src/main/java/io/papermc/paper/datacomponent/item/ShownInTooltip.java new file mode 100644 -index 0000000000000000000000000000000000000000..7e058aebcbd768517f6db51540598721cdae4425 +index 0000000000000000000000000000000000000000..1307221216d2b38ec5daee4d798d7fcabef7a2e2 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/ShownInTooltip.java -@@ -0,0 +1,52 @@ +@@ -0,0 +1,55 @@ +package io.papermc.paper.datacomponent.item; + +import org.jetbrains.annotations.ApiStatus; @@ -2889,6 +2876,7 @@ index 0000000000000000000000000000000000000000..7e058aebcbd768517f6db51540598721 +/** + * Holds the state of whether a data component should be shown + * in an item's tooltip. ++ * + * @param the data component type + */ +@NullMarked @@ -2907,6 +2895,7 @@ index 0000000000000000000000000000000000000000..7e058aebcbd768517f6db51540598721 + /** + * Returns a copy of this data component with the specified + * show-in-tooltip state. ++ * + * @param showInTooltip {@code true} to show in the tooltip + * @return the new data component + */ @@ -2915,6 +2904,7 @@ index 0000000000000000000000000000000000000000..7e058aebcbd768517f6db51540598721 + + /** + * A builder for creating a {@link ShownInTooltip} data component. ++ * + * @param builder type + */ + @ApiStatus.Experimental @@ -2934,15 +2924,14 @@ index 0000000000000000000000000000000000000000..7e058aebcbd768517f6db51540598721 +} 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..422bb5ccc42b94b60fba6714e9e6fb8aced6eb0c +index 0000000000000000000000000000000000000000..9a740ef7da967e865a801367cf179eead0632d66 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/SuspiciousStewEffects.java -@@ -0,0 +1,67 @@ +@@ -0,0 +1,66 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.datacomponent.DataComponentBuilder; +import io.papermc.paper.potion.SuspiciousEffectEntry; -+import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import org.jetbrains.annotations.ApiStatus; @@ -3273,13 +3262,12 @@ index 0000000000000000000000000000000000000000..57fc55ad1def2bb14fc0a95ee3c0c157 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/UseRemainder.java b/src/main/java/io/papermc/paper/datacomponent/item/UseRemainder.java new file mode 100644 -index 0000000000000000000000000000000000000000..50e42e073311332142980828d0beec1828570512 +index 0000000000000000000000000000000000000000..aaecc3c954ea7c6b70c1effea65a34901e1a0924 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/UseRemainder.java -@@ -0,0 +1,31 @@ +@@ -0,0 +1,29 @@ +package io.papermc.paper.datacomponent.item; + -+import io.papermc.paper.datacomponent.DataComponentBuilder; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; @@ -3306,7 +3294,6 @@ index 0000000000000000000000000000000000000000..50e42e073311332142980828d0beec18 + */ + @Contract(value = "-> new", pure = true) + ItemStack transformInto(); -+ +} 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 @@ -3612,20 +3599,20 @@ index 0000000000000000000000000000000000000000..a845ccfc21f101f0632249745bbd8b33 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumeEffect.java b/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumeEffect.java new file mode 100644 -index 0000000000000000000000000000000000000000..ff1a14e19c21dd22f249503a0b738f190a75aca0 +index 0000000000000000000000000000000000000000..87537e431e505e498f9c5f86cc3401d39ebdb2ac --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumeEffect.java -@@ -0,0 +1,150 @@ +@@ -0,0 +1,147 @@ +package io.papermc.paper.datacomponent.item.consumable; + +import io.papermc.paper.registry.set.RegistryKeySet; ++import java.util.List; +import net.kyori.adventure.key.Key; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jspecify.annotations.NullMarked; -+import java.util.List; + +/** + * Effect that occurs when consuming an item. @@ -3690,7 +3677,6 @@ index 0000000000000000000000000000000000000000..ff1a14e19c21dd22f249503a0b738f19 + return ConsumableTypesBridge.bridge().applyStatusEffects(effects, probability); + } + -+ @NullMarked + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface TeleportRandomly extends ConsumeEffect { @@ -3706,7 +3692,6 @@ index 0000000000000000000000000000000000000000..ff1a14e19c21dd22f249503a0b738f19 + /** + * Represents a consumable effect that removes status effects on consumption + */ -+ @NullMarked + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface RemoveStatusEffects extends ConsumeEffect { @@ -3722,7 +3707,6 @@ index 0000000000000000000000000000000000000000..ff1a14e19c21dd22f249503a0b738f19 + /** + * Represents a consumable effect that plays a sound on consumption. + */ -+ @NullMarked + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface PlaySound extends ConsumeEffect { @@ -3738,7 +3722,8 @@ index 0000000000000000000000000000000000000000..ff1a14e19c21dd22f249503a0b738f19 + /** + * Represents a consumable effect that clears all effects on consumption. + */ -+ @NullMarked ++ @ApiStatus.Experimental ++ @ApiStatus.NonExtendable + interface ClearAllStatusEffects extends ConsumeEffect { + + } @@ -3746,7 +3731,6 @@ index 0000000000000000000000000000000000000000..ff1a14e19c21dd22f249503a0b738f19 + /** + * Represents a consumable effect that applies effects based on a probability on consumption. + */ -+ @NullMarked + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface ApplyStatusEffects extends ConsumeEffect { @@ -3932,7 +3916,7 @@ index 615eb24ffdd8f6d55ccd4f21760b809c1098bc68..c7ce8fa1ff9feda66d5a4e497112a24f + // Paper end - data component API } diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java -index 7cf7c6d05aa6cbf3f0c8612831404552c6a7b84a..c60e31425efd7b863941f5538faef6c0552290ae 100644 +index 87907918c42b11780b285b6d82e7297628a07376..d55c33ca14257be5005520e18e465da87a58dbaf 100644 --- a/src/main/java/org/bukkit/Registry.java +++ b/src/main/java/org/bukkit/Registry.java @@ -376,6 +376,7 @@ public interface Registry extends Iterable { diff --git a/patches/api/0500-Expanded-Art-API.patch b/patches/api/0500-Expanded-Art-API.patch new file mode 100644 index 0000000000..171995d80b --- /dev/null +++ b/patches/api/0500-Expanded-Art-API.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: kokiriglade <60290002+celerry@users.noreply.github.com> +Date: Sat, 23 Nov 2024 18:08:13 +0000 +Subject: [PATCH] Expanded Art API + + +diff --git a/src/main/java/org/bukkit/Art.java b/src/main/java/org/bukkit/Art.java +index 00a290f1bf58cdc2238c13fd5a6048a26b7871da..ed2263450e98460250e431d2ee6debd03204c175 100644 +--- a/src/main/java/org/bukkit/Art.java ++++ b/src/main/java/org/bukkit/Art.java +@@ -107,6 +107,29 @@ public interface Art extends OldEnum, Keyed { + @NotNull NamespacedKey getKey(); + // Paper end - deprecate getKey + ++ // Paper start - name and author components, assetId key ++ /** ++ * Get the painting's title. ++ * ++ * @return the title ++ */ ++ net.kyori.adventure.text.@Nullable Component title(); ++ ++ /** ++ * Get the painting's author. ++ * ++ * @return the author ++ */ ++ net.kyori.adventure.text.@Nullable Component author(); ++ ++ /** ++ * Get the painting's asset id ++ * ++ * @return the asset id ++ */ ++ net.kyori.adventure.key.@NotNull Key assetId(); ++ // Paper end - name and author components, assetId key ++ + /** + * Get a painting by its numeric ID + * diff --git a/patches/server/0005-Paper-config-files.patch b/patches/server/0005-Paper-config-files.patch index 8115fc2d48..d5545fac61 100644 --- a/patches/server/0005-Paper-config-files.patch +++ b/patches/server/0005-Paper-config-files.patch @@ -121,10 +121,10 @@ index 0000000000000000000000000000000000000000..042478cf7ce150f1f1bc5cddd7fa40f8 +} diff --git a/src/main/java/io/papermc/paper/configuration/Configurations.java b/src/main/java/io/papermc/paper/configuration/Configurations.java new file mode 100644 -index 0000000000000000000000000000000000000000..d9502ba028a96f9cc846f9ed428bd8066b857ca3 +index 0000000000000000000000000000000000000000..007e01d329a31acf7f4ed4c6dc4de7ad54ccad04 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/Configurations.java -@@ -0,0 +1,360 @@ +@@ -0,0 +1,358 @@ +package io.papermc.paper.configuration; + +import com.google.common.base.Preconditions; @@ -132,23 +132,6 @@ index 0000000000000000000000000000000000000000..d9502ba028a96f9cc846f9ed428bd806 +import io.leangen.geantyref.TypeToken; +import io.papermc.paper.configuration.constraint.Constraint; +import io.papermc.paper.configuration.constraint.Constraints; -+import net.minecraft.core.RegistryAccess; -+import net.minecraft.resources.ResourceLocation; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.GameRules; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.jetbrains.annotations.MustBeInvokedByOverriders; -+import org.slf4j.Logger; -+import org.spongepowered.configurate.CommentedConfigurationNode; -+import org.spongepowered.configurate.ConfigurateException; -+import org.spongepowered.configurate.ConfigurationNode; -+import org.spongepowered.configurate.ConfigurationOptions; -+import org.spongepowered.configurate.NodePath; -+import org.spongepowered.configurate.objectmapping.ObjectMapper; -+import org.spongepowered.configurate.serialize.SerializationException; -+import org.spongepowered.configurate.util.CheckedFunction; -+import org.spongepowered.configurate.yaml.YamlConfigurationLoader; -+ +import java.io.IOException; +import java.lang.reflect.Type; +import java.nio.file.AccessDeniedException; @@ -159,6 +142,21 @@ index 0000000000000000000000000000000000000000..d9502ba028a96f9cc846f9ed428bd806 +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.function.UnaryOperator; ++import net.minecraft.core.RegistryAccess; ++import net.minecraft.resources.ResourceLocation; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.world.level.GameRules; ++import org.jetbrains.annotations.MustBeInvokedByOverriders; ++import org.jspecify.annotations.Nullable; ++import org.slf4j.Logger; ++import org.spongepowered.configurate.CommentedConfigurationNode; ++import org.spongepowered.configurate.ConfigurateException; ++import org.spongepowered.configurate.ConfigurationNode; ++import org.spongepowered.configurate.ConfigurationOptions; ++import org.spongepowered.configurate.objectmapping.ObjectMapper; ++import org.spongepowered.configurate.serialize.SerializationException; ++import org.spongepowered.configurate.util.CheckedFunction; ++import org.spongepowered.configurate.yaml.YamlConfigurationLoader; + +public abstract class Configurations { + @@ -487,7 +485,7 @@ index 0000000000000000000000000000000000000000..d9502ba028a96f9cc846f9ed428bd806 +} diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java new file mode 100644 -index 0000000000000000000000000000000000000000..f0d470d7770e119f734b9e72021c806d0ea8ecbd +index 0000000000000000000000000000000000000000..0ea9eba1367858dfa5284524a8dd2f79daf6fc69 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -0,0 +1,330 @@ @@ -501,7 +499,7 @@ index 0000000000000000000000000000000000000000..f0d470d7770e119f734b9e72021c806d +import net.kyori.adventure.text.format.NamedTextColor; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ServerboundPlaceRecipePacket; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.slf4j.Logger; +import org.spongepowered.configurate.objectmapping.ConfigSerializable; +import org.spongepowered.configurate.objectmapping.meta.Comment; @@ -823,21 +821,20 @@ index 0000000000000000000000000000000000000000..f0d470d7770e119f734b9e72021c806d +} diff --git a/src/main/java/io/papermc/paper/configuration/NestedSetting.java b/src/main/java/io/papermc/paper/configuration/NestedSetting.java new file mode 100644 -index 0000000000000000000000000000000000000000..69add4a7f1147015806bc9b63a8340d1893356c1 +index 0000000000000000000000000000000000000000..b8c42cc2624f325dc8725ebab68bbff0addb3855 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/NestedSetting.java -@@ -0,0 +1,32 @@ +@@ -0,0 +1,31 @@ +package io.papermc.paper.configuration; + -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.spongepowered.configurate.objectmapping.meta.NodeResolver; -+ +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.AnnotatedElement; ++import org.jspecify.annotations.Nullable; ++import org.spongepowered.configurate.objectmapping.meta.NodeResolver; + +@Documented +@Retention(RetentionPolicy.RUNTIME) @@ -861,10 +858,10 @@ index 0000000000000000000000000000000000000000..69add4a7f1147015806bc9b63a8340d1 +} diff --git a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java new file mode 100644 -index 0000000000000000000000000000000000000000..1029b6de6f36b08bf634b4056ef5701383f6f258 +index 0000000000000000000000000000000000000000..c5644d8d64f12073e39bc6ed79c8714f4560ff89 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java -@@ -0,0 +1,467 @@ +@@ -0,0 +1,470 @@ +package io.papermc.paper.configuration; + +import com.google.common.base.Suppliers; @@ -903,6 +900,8 @@ index 0000000000000000000000000000000000000000..1029b6de6f36b08bf634b4056ef57013 +import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.Reference2LongMap; +import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap; ++import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; ++import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Type; @@ -925,8 +924,8 @@ index 0000000000000000000000000000000000000000..1029b6de6f36b08bf634b4056ef57013 +import org.apache.commons.lang3.RandomStringUtils; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; -+import org.checkerframework.checker.nullness.qual.Nullable; +import org.jetbrains.annotations.VisibleForTesting; ++import org.jspecify.annotations.Nullable; +import org.slf4j.Logger; +import org.spigotmc.SpigotConfig; +import org.spigotmc.SpigotWorldConfig; @@ -1108,6 +1107,7 @@ index 0000000000000000000000000000000000000000..1029b6de6f36b08bf634b4056ef57013 + .serializers(serializers -> serializers + .register(new TypeToken>() {}, new FastutilMapSerializer.SomethingToPrimitive>(Reference2IntOpenHashMap::new, Integer.TYPE)) + .register(new TypeToken>() {}, new FastutilMapSerializer.SomethingToPrimitive>(Reference2LongOpenHashMap::new, Long.TYPE)) ++ .register(new TypeToken>() {}, new FastutilMapSerializer.SomethingToSomething>(Reference2ObjectOpenHashMap::new)) + .register(new TypeToken>() {}, new TableSerializer()) + .register(DespawnRange.class, DespawnRange.SERIALIZER) + .register(StringRepresentableSerializer::isValidFor, new StringRepresentableSerializer()) @@ -1423,10 +1423,10 @@ index 0000000000000000000000000000000000000000..279b24c689b9979884b65df7eb1f0590 +} diff --git a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java new file mode 100644 -index 0000000000000000000000000000000000000000..dad3fcc689ec806f985122a7cbd501a7d0fd0d36 +index 0000000000000000000000000000000000000000..b1c917d65076a3805e5b78cb946753f0c101e214 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java -@@ -0,0 +1,581 @@ +@@ -0,0 +1,590 @@ +package io.papermc.paper.configuration; + +import com.google.common.collect.HashBasedTable; @@ -1436,6 +1436,7 @@ index 0000000000000000000000000000000000000000..dad3fcc689ec806f985122a7cbd501a7 +import io.papermc.paper.configuration.legacy.RequiresSpigotInitialization; +import io.papermc.paper.configuration.mapping.MergeMap; +import io.papermc.paper.configuration.serializer.NbtPathSerializer; ++import io.papermc.paper.configuration.serializer.collections.MapSerializer; +import io.papermc.paper.configuration.transformation.world.FeatureSeedsGeneration; +import io.papermc.paper.configuration.type.BooleanOrDefault; +import io.papermc.paper.configuration.type.DespawnRange; @@ -1451,6 +1452,8 @@ index 0000000000000000000000000000000000000000..dad3fcc689ec806f985122a7cbd501a7 +import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.Reference2LongMap; +import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap; ++import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; ++import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; +import java.util.Arrays; +import java.util.IdentityHashMap; +import java.util.List; @@ -1628,6 +1631,12 @@ index 0000000000000000000000000000000000000000..dad3fcc689ec806f985122a7cbd501a7 + } + } + ++ @MapSerializer.ThrowExceptions ++ public Reference2ObjectMap, IntOr.Disabled> despawnTime = Util.make(new Reference2ObjectOpenHashMap<>(), map -> { ++ map.put(EntityType.SNOWBALL, IntOr.Disabled.DISABLED); ++ map.put(EntityType.LLAMA_SPIT, IntOr.Disabled.DISABLED); ++ }); ++ + @PostProcess + public void precomputeDespawnDistances() throws SerializationException { + for (Map.Entry entry : this.despawnRanges.entrySet()) { @@ -2046,7 +2055,7 @@ index 0000000000000000000000000000000000000000..514be9a11e2ca368ea72dd2bac1b84bf +} diff --git a/src/main/java/io/papermc/paper/configuration/constraint/Constraints.java b/src/main/java/io/papermc/paper/configuration/constraint/Constraints.java new file mode 100644 -index 0000000000000000000000000000000000000000..2d8c91007d5ebc051623bb308cf973bdad3f3273 +index 0000000000000000000000000000000000000000..9cab83a5b47b29d394bdf6e5c5f8e2c9952d9156 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/constraint/Constraints.java @@ -0,0 +1,43 @@ @@ -2058,7 +2067,7 @@ index 0000000000000000000000000000000000000000..2d8c91007d5ebc051623bb308cf973bd +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Type; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.objectmapping.meta.Constraint; +import org.spongepowered.configurate.serialize.SerializationException; + @@ -2095,13 +2104,13 @@ index 0000000000000000000000000000000000000000..2d8c91007d5ebc051623bb308cf973bd +} diff --git a/src/main/java/io/papermc/paper/configuration/legacy/MaxEntityCollisionsInitializer.java b/src/main/java/io/papermc/paper/configuration/legacy/MaxEntityCollisionsInitializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..62b43280f59163f7910f79cc901b50d05cdd024e +index 0000000000000000000000000000000000000000..ddef1ed3ff6fef52a70ee8bbf0b7607f6588ae6d --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/legacy/MaxEntityCollisionsInitializer.java @@ -0,0 +1,29 @@ +package io.papermc.paper.configuration.legacy; + -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spigotmc.SpigotWorldConfig; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.objectmapping.meta.NodeResolver; @@ -2130,18 +2139,14 @@ index 0000000000000000000000000000000000000000..62b43280f59163f7910f79cc901b50d0 +} diff --git a/src/main/java/io/papermc/paper/configuration/legacy/RequiresSpigotInitialization.java b/src/main/java/io/papermc/paper/configuration/legacy/RequiresSpigotInitialization.java new file mode 100644 -index 0000000000000000000000000000000000000000..611bdbcef3d52e09179aa8b1677ab1e198c70b02 +index 0000000000000000000000000000000000000000..81c64a2ffad4bcd69f0012f04567a7d15f2d6dd5 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/legacy/RequiresSpigotInitialization.java -@@ -0,0 +1,51 @@ +@@ -0,0 +1,48 @@ +package io.papermc.paper.configuration.legacy; + +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.spigotmc.SpigotWorldConfig; -+import org.spongepowered.configurate.objectmapping.meta.NodeResolver; -+ +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; @@ -2149,8 +2154,9 @@ index 0000000000000000000000000000000000000000..611bdbcef3d52e09179aa8b1677ab1e1 +import java.lang.annotation.Target; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Constructor; -+import java.util.Map; -+import java.util.concurrent.ConcurrentHashMap; ++import org.jspecify.annotations.Nullable; ++import org.spigotmc.SpigotWorldConfig; ++import org.spongepowered.configurate.objectmapping.meta.NodeResolver; + +@Documented +@Retention(RetentionPolicy.RUNTIME) @@ -2220,21 +2226,19 @@ index 0000000000000000000000000000000000000000..fe5cc1c097f8d8c135e6ead6f458426b +} diff --git a/src/main/java/io/papermc/paper/configuration/mapping/InnerClassFieldDiscoverer.java b/src/main/java/io/papermc/paper/configuration/mapping/InnerClassFieldDiscoverer.java new file mode 100644 -index 0000000000000000000000000000000000000000..8f23276796037d048eb114952891a01a40971b3e +index 0000000000000000000000000000000000000000..05339a176083af667c16f77d76dc1878dafce3f0 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/mapping/InnerClassFieldDiscoverer.java -@@ -0,0 +1,54 @@ +@@ -0,0 +1,52 @@ +package io.papermc.paper.configuration.mapping; + +import io.papermc.paper.configuration.ConfigurationPart; -+import io.papermc.paper.configuration.Configurations; -+import io.papermc.paper.configuration.PaperConfigurations; +import io.papermc.paper.configuration.WorldConfiguration; +import java.lang.reflect.AnnotatedType; +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.Map; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.objectmapping.FieldDiscoverer; +import org.spongepowered.configurate.serialize.SerializationException; + @@ -2280,10 +2284,10 @@ index 0000000000000000000000000000000000000000..8f23276796037d048eb114952891a01a +} diff --git a/src/main/java/io/papermc/paper/configuration/mapping/InnerClassInstanceFactory.java b/src/main/java/io/papermc/paper/configuration/mapping/InnerClassInstanceFactory.java new file mode 100644 -index 0000000000000000000000000000000000000000..cec678ae24a7d99a46fa672be907f4c28fe4da96 +index 0000000000000000000000000000000000000000..25e3152c3307175da734a1cad7f7a4166e233021 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/mapping/InnerClassInstanceFactory.java -@@ -0,0 +1,65 @@ +@@ -0,0 +1,64 @@ +package io.papermc.paper.configuration.mapping; + +import java.lang.reflect.AnnotatedType; @@ -2291,7 +2295,6 @@ index 0000000000000000000000000000000000000000..cec678ae24a7d99a46fa672be907f4c2 +import java.util.Iterator; +import java.util.Map; +import java.util.Objects; -+import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.configurate.objectmapping.FieldDiscoverer; +import org.spongepowered.configurate.serialize.SerializationException; + @@ -2323,7 +2326,7 @@ index 0000000000000000000000000000000000000000..cec678ae24a7d99a46fa672be907f4c2 + Map.Entry entry = iter.next(); + if (entry.getKey().isAnnotationPresent(MergeMap.class) && Map.class.isAssignableFrom(entry.getKey().getType()) && intermediate.get(entry.getKey()) instanceof Map map) { + iter.remove(); -+ @Nullable Map existingMap = (Map) entry.getKey().get(instance); ++ Map existingMap = (Map) entry.getKey().get(instance); + if (existingMap != null) { + existingMap.putAll(map); + } else { @@ -2351,7 +2354,7 @@ index 0000000000000000000000000000000000000000..cec678ae24a7d99a46fa672be907f4c2 +} diff --git a/src/main/java/io/papermc/paper/configuration/mapping/InnerClassInstanceSupplier.java b/src/main/java/io/papermc/paper/configuration/mapping/InnerClassInstanceSupplier.java new file mode 100644 -index 0000000000000000000000000000000000000000..8d8bc050441c02cf65dfcb6400978363d6b8ef10 +index 0000000000000000000000000000000000000000..3778c47f563fd0011659234fc8394e3d59325782 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/mapping/InnerClassInstanceSupplier.java @@ -0,0 +1,72 @@ @@ -2364,7 +2367,7 @@ index 0000000000000000000000000000000000000000..8d8bc050441c02cf65dfcb6400978363 +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.serialize.SerializationException; +import org.spongepowered.configurate.util.CheckedFunction; +import org.spongepowered.configurate.util.CheckedSupplier; @@ -2400,7 +2403,7 @@ index 0000000000000000000000000000000000000000..8d8bc050441c02cf65dfcb6400978363 + final Constructor constructor; + final CheckedSupplier instanceSupplier; + if (type.getEnclosingClass() != null && !Modifier.isStatic(type.getModifiers())) { -+ final @Nullable Object instance = this.instanceMap.get(type.getEnclosingClass()); ++ final Object instance = this.instanceMap.get(type.getEnclosingClass()); + if (instance == null) { + throw new SerializationException("Cannot create a new instance of an inner class " + type.getName() + " without an instance of its enclosing class " + type.getEnclosingClass().getName()); + } @@ -2453,18 +2456,26 @@ index 0000000000000000000000000000000000000000..471b161ac51900672434c6608595bb73 +@Retention(RetentionPolicy.RUNTIME) +public @interface MergeMap { +} +diff --git a/src/main/java/io/papermc/paper/configuration/mapping/package-info.java b/src/main/java/io/papermc/paper/configuration/mapping/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..454e6ec7ebf9c54a38d6ba3a73e7c197c67c2c00 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/mapping/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.mapping; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/package-info.java b/src/main/java/io/papermc/paper/configuration/package-info.java new file mode 100644 -index 0000000000000000000000000000000000000000..4e3bcd7c478096384fcc643d48771ab94318deb3 +index 0000000000000000000000000000000000000000..11bf7bb357305cf90c201444be08dc71c14b7505 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/package-info.java -@@ -0,0 +1,5 @@ -+@DefaultQualifier(NonNull.class) +@@ -0,0 +1,4 @@ ++@NullMarked +package io.papermc.paper.configuration; + -+import org.checkerframework.checker.nullness.qual.NonNull; -+import org.checkerframework.framework.qual.DefaultQualifier; -\ No newline at end of file ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/serializer/ComponentSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/ComponentSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..9c339ef178ebc3b0251095f320e4a7a3656d3521 @@ -2538,24 +2549,23 @@ index 0000000000000000000000000000000000000000..27c0679d376bb31ab52131dfea74b3b5 +} diff --git a/src/main/java/io/papermc/paper/configuration/serializer/EnumValueSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/EnumValueSerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..8535c748a5e355362e77e6c5103e11c4c318a138 +index 0000000000000000000000000000000000000000..d24d1480e3ee7e5004c2dcbe826823aa427f787a --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/EnumValueSerializer.java -@@ -0,0 +1,50 @@ +@@ -0,0 +1,49 @@ +package io.papermc.paper.configuration.serializer; + +import com.mojang.logging.LogUtils; +import io.leangen.geantyref.TypeToken; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.slf4j.Logger; -+import org.spongepowered.configurate.serialize.ScalarSerializer; -+import org.spongepowered.configurate.serialize.SerializationException; -+import org.spongepowered.configurate.util.EnumLookup; -+ +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; ++import org.jspecify.annotations.Nullable; ++import org.slf4j.Logger; ++import org.spongepowered.configurate.serialize.ScalarSerializer; ++import org.spongepowered.configurate.serialize.SerializationException; ++import org.spongepowered.configurate.util.EnumLookup; + +import static io.leangen.geantyref.GenericTypeReflector.erase; + @@ -2575,14 +2585,14 @@ index 0000000000000000000000000000000000000000..8535c748a5e355362e77e6c5103e11c4 + public @Nullable Enum deserialize(final Type type, final Object obj) throws SerializationException { + final String enumConstant = obj.toString(); + final Class typeClass = erase(type).asSubclass(Enum.class); -+ @Nullable Enum ret = EnumLookup.lookupEnum(typeClass, enumConstant); ++ Enum ret = EnumLookup.lookupEnum(typeClass, enumConstant); + if (ret == null) { + ret = EnumLookup.lookupEnum(typeClass, enumConstant.replace("-", "_")); + } + if (ret == null) { + boolean longer = typeClass.getEnumConstants().length > 10; + List options = Arrays.stream(typeClass.getEnumConstants()).limit(10L).map(Enum::name).toList(); -+ LOGGER.error("Invalid enum constant provided, expected one of [" + String.join(", " ,options) + (longer ? ", ..." : "") + "], but got " + enumConstant); ++ LOGGER.error("Invalid enum constant provided, expected one of [{}{}], but got {}", String.join(", ", options), longer ? ", ..." : "", enumConstant); + } + return ret; + } @@ -2652,10 +2662,10 @@ index 0000000000000000000000000000000000000000..b44b2dc28f619594e302417848e95c00 +} diff --git a/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..893ad5e7c2d32ccd64962d95d146bbd317c28ab8 +index 0000000000000000000000000000000000000000..b61935052154e76b1b8cb49868c96c52f34a41d1 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java -@@ -0,0 +1,86 @@ +@@ -0,0 +1,85 @@ +package io.papermc.paper.configuration.serializer; + +import com.google.common.collect.BiMap; @@ -2664,16 +2674,15 @@ index 0000000000000000000000000000000000000000..893ad5e7c2d32ccd64962d95d146bbd3 +import io.leangen.geantyref.TypeToken; +import io.papermc.paper.configuration.serializer.collections.MapSerializer; +import io.papermc.paper.util.ObfHelper; -+import net.minecraft.network.protocol.Packet; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.slf4j.Logger; -+import org.spongepowered.configurate.serialize.ScalarSerializer; -+import org.spongepowered.configurate.serialize.SerializationException; -+ +import java.lang.reflect.Type; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; ++import net.minecraft.network.protocol.Packet; ++import org.jspecify.annotations.Nullable; ++import org.slf4j.Logger; ++import org.spongepowered.configurate.serialize.ScalarSerializer; ++import org.spongepowered.configurate.serialize.SerializationException; + +@SuppressWarnings("Convert2Diamond") +public final class PacketClassSerializer extends ScalarSerializer>> implements MapSerializer.WriteBack { @@ -2703,14 +2712,14 @@ index 0000000000000000000000000000000000000000..893ad5e7c2d32ccd64962d95d146bbd3 + @SuppressWarnings("unchecked") + @Override + public Class> deserialize(final Type type, final Object obj) throws SerializationException { -+ @Nullable Class packetClass = null; ++ Class packetClass = null; + for (final String subpackage : SUBPACKAGES) { + final String fullClassName = "net.minecraft.network.protocol." + subpackage + "." + obj; + try { + packetClass = Class.forName(fullClassName); + break; + } catch (final ClassNotFoundException ex) { -+ final @Nullable String spigotClassName = MOJANG_TO_OBF.get(fullClassName); ++ final String spigotClassName = MOJANG_TO_OBF.get(fullClassName); + if (spigotClassName != null) { + try { + packetClass = Class.forName(spigotClassName); @@ -2744,23 +2753,22 @@ index 0000000000000000000000000000000000000000..893ad5e7c2d32ccd64962d95d146bbd3 +} diff --git a/src/main/java/io/papermc/paper/configuration/serializer/StringRepresentableSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/StringRepresentableSerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..7fc0905fc6b8f5df762b4cea573f935dc00b8bc1 +index 0000000000000000000000000000000000000000..629012cb8ea8d8d81f99033794226bef19ee6c80 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/StringRepresentableSerializer.java -@@ -0,0 +1,52 @@ +@@ -0,0 +1,51 @@ +package io.papermc.paper.configuration.serializer; + -+import net.minecraft.util.StringRepresentable; -+import net.minecraft.world.entity.MobCategory; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.spongepowered.configurate.serialize.ScalarSerializer; -+import org.spongepowered.configurate.serialize.SerializationException; -+ +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.Map; +import java.util.function.Function; +import java.util.function.Predicate; ++import net.minecraft.util.StringRepresentable; ++import net.minecraft.world.entity.MobCategory; ++import org.jspecify.annotations.Nullable; ++import org.spongepowered.configurate.serialize.ScalarSerializer; ++import org.spongepowered.configurate.serialize.SerializationException; + +public final class StringRepresentableSerializer extends ScalarSerializer { + private static final Map> TYPES = Collections.synchronizedMap(Map.ofEntries( @@ -2802,52 +2810,61 @@ index 0000000000000000000000000000000000000000..7fc0905fc6b8f5df762b4cea573f935d +} diff --git a/src/main/java/io/papermc/paper/configuration/serializer/collections/FastutilMapSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/collections/FastutilMapSerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..4af710e144b70933d750c22edfe484c18e4a3540 +index 0000000000000000000000000000000000000000..68ed5ad7b6f28a9fdda35e25c12a13a2619e1449 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/collections/FastutilMapSerializer.java -@@ -0,0 +1,69 @@ +@@ -0,0 +1,91 @@ +package io.papermc.paper.configuration.serializer.collections; + +import io.leangen.geantyref.GenericTypeReflector; +import io.leangen.geantyref.TypeFactory; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.spongepowered.configurate.ConfigurationNode; -+import org.spongepowered.configurate.serialize.SerializationException; -+import org.spongepowered.configurate.serialize.TypeSerializer; -+ ++import java.lang.annotation.Annotation; ++import java.lang.reflect.AnnotatedParameterizedType; ++import java.lang.reflect.AnnotatedType; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.Map; +import java.util.function.Function; ++import org.jspecify.annotations.Nullable; ++import org.spongepowered.configurate.ConfigurationNode; ++import org.spongepowered.configurate.serialize.SerializationException; ++import org.spongepowered.configurate.serialize.TypeSerializer; + +@SuppressWarnings("rawtypes") -+public abstract class FastutilMapSerializer> implements TypeSerializer { -+ private final Function factory; ++public abstract class FastutilMapSerializer> implements TypeSerializer.Annotated { + -+ protected FastutilMapSerializer(final Function factory) { ++ private final Function factory; ++ ++ protected FastutilMapSerializer(final Function factory) { + this.factory = factory; + } + + @Override -+ public M deserialize(final Type type, final ConfigurationNode node) throws SerializationException { -+ @Nullable final Map map = (Map) node.get(this.createBaseMapType((ParameterizedType) type)); ++ public M deserialize(final AnnotatedType annotatedType, final ConfigurationNode node) throws SerializationException { ++ final Map map = (Map) node.get(this.createAnnotatedMapType((AnnotatedParameterizedType) annotatedType)); + return this.factory.apply(map == null ? Collections.emptyMap() : map); + } + + @Override -+ public void serialize(final Type type, @Nullable final M obj, final ConfigurationNode node) throws SerializationException { ++ public void serialize(final AnnotatedType annotatedType, final @Nullable M obj, final ConfigurationNode node) throws SerializationException { + if (obj == null || obj.isEmpty()) { + node.raw(null); + } else { -+ final Type baseMapType = this.createBaseMapType((ParameterizedType) type); ++ final AnnotatedType baseMapType = this.createAnnotatedMapType((AnnotatedParameterizedType) annotatedType); + node.set(baseMapType, obj); + } + } + ++ private AnnotatedType createAnnotatedMapType(final AnnotatedParameterizedType type) { ++ final Type baseType = this.createBaseMapType((ParameterizedType) type.getType()); ++ return GenericTypeReflector.annotate(baseType, type.getAnnotations()); ++ } ++ + protected abstract Type createBaseMapType(final ParameterizedType type); + + public static final class SomethingToPrimitive> extends FastutilMapSerializer { ++ + private final Type primitiveType; + + public SomethingToPrimitive(final Function factory, final Type primitiveType) { @@ -2862,6 +2879,7 @@ index 0000000000000000000000000000000000000000..4af710e144b70933d750c22edfe484c1 + } + + public static final class PrimitiveToSomething> extends FastutilMapSerializer { ++ + private final Type primitiveType; + + public PrimitiveToSomething(final Function factory, final Type primitiveType) { @@ -2874,26 +2892,32 @@ index 0000000000000000000000000000000000000000..4af710e144b70933d750c22edfe484c1 + return TypeFactory.parameterizedClass(Map.class, GenericTypeReflector.box(this.primitiveType), type.getActualTypeArguments()[0]); + } + } ++ ++ public static final class SomethingToSomething> extends FastutilMapSerializer { ++ ++ public SomethingToSomething(final Function factory) { ++ super(factory); ++ } ++ ++ @Override ++ protected Type createBaseMapType(final ParameterizedType type) { ++ return TypeFactory.parameterizedClass(Map.class, type.getActualTypeArguments()[0], type.getActualTypeArguments()[1]); ++ } ++ } +} diff --git a/src/main/java/io/papermc/paper/configuration/serializer/collections/MapSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/collections/MapSerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..e7e997796ec47c742cc1f98e61db75a4231e6f98 +index 0000000000000000000000000000000000000000..6bb8304b9d98bf2ba53274a3808e607e08f0787f --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/collections/MapSerializer.java -@@ -0,0 +1,162 @@ +@@ -0,0 +1,182 @@ +package io.papermc.paper.configuration.serializer.collections; + +import com.mojang.logging.LogUtils; +import io.leangen.geantyref.TypeToken; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.slf4j.Logger; -+import org.spongepowered.configurate.BasicConfigurationNode; -+import org.spongepowered.configurate.ConfigurationNode; -+import org.spongepowered.configurate.ConfigurationOptions; -+import org.spongepowered.configurate.NodePath; -+import org.spongepowered.configurate.serialize.SerializationException; -+import org.spongepowered.configurate.serialize.TypeSerializer; -+ ++import java.lang.annotation.Retention; ++import java.lang.annotation.RetentionPolicy; ++import java.lang.reflect.AnnotatedType; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Collections; @@ -2901,27 +2925,45 @@ index 0000000000000000000000000000000000000000..e7e997796ec47c742cc1f98e61db75a4 +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; ++import org.jspecify.annotations.Nullable; ++import org.slf4j.Logger; ++import org.spongepowered.configurate.BasicConfigurationNode; ++import org.spongepowered.configurate.ConfigurationNode; ++import org.spongepowered.configurate.ConfigurationOptions; ++import org.spongepowered.configurate.NodePath; ++import org.spongepowered.configurate.serialize.SerializationException; ++import org.spongepowered.configurate.serialize.TypeSerializer; ++import org.spongepowered.configurate.serialize.TypeSerializerCollection; + +import static java.util.Objects.requireNonNull; + +/** + * Map serializer that does not throw errors on individual entry serialization failures. + */ -+public class MapSerializer implements TypeSerializer> { ++public class MapSerializer implements TypeSerializer.Annotated> { + + public static final TypeToken> TYPE = new TypeToken>() {}; + + private static final Logger LOGGER = LogUtils.getClassLogger(); + + private final boolean clearInvalids; ++ private final TypeSerializer> fallback; + + public MapSerializer(boolean clearInvalids) { + this.clearInvalids = clearInvalids; ++ this.fallback = requireNonNull(TypeSerializerCollection.defaults().get(TYPE), "Could not find default Map serializer"); + } + ++ @Retention(RetentionPolicy.RUNTIME) ++ public @interface ThrowExceptions {} ++ + @Override -+ public Map deserialize(Type type, ConfigurationNode node) throws SerializationException { ++ public Map deserialize(AnnotatedType annotatedType, ConfigurationNode node) throws SerializationException { ++ if (annotatedType.isAnnotationPresent(ThrowExceptions.class)) { ++ return this.fallback.deserialize(annotatedType, node); ++ } + final Map map = new LinkedHashMap<>(); ++ final Type type = annotatedType.getType(); + if (node.isMap()) { + if (!(type instanceof ParameterizedType parameterizedType)) { + throw new SerializationException(type, "Raw types are not supported for collections"); @@ -2975,7 +3017,12 @@ index 0000000000000000000000000000000000000000..e7e997796ec47c742cc1f98e61db75a4 + } + + @Override -+ public void serialize(Type type, @Nullable Map obj, ConfigurationNode node) throws SerializationException { ++ public void serialize(AnnotatedType annotatedType, @Nullable Map obj, ConfigurationNode node) throws SerializationException { ++ if (annotatedType.isAnnotationPresent(ThrowExceptions.class)) { ++ this.fallback.serialize(annotatedType, obj, node); ++ return; ++ } ++ final Type type = annotatedType.getType(); + if (!(type instanceof ParameterizedType parameterizedType)) { + throw new SerializationException(type, "Raw types are not supported for collections"); + } @@ -3036,7 +3083,10 @@ index 0000000000000000000000000000000000000000..e7e997796ec47c742cc1f98e61db75a4 + } + + @Override -+ public @Nullable Map emptyValue(Type specificType, ConfigurationOptions options) { ++ public @Nullable Map emptyValue(AnnotatedType specificType, ConfigurationOptions options) { ++ if (specificType.isAnnotationPresent(ThrowExceptions.class)) { ++ return this.fallback.emptyValue(specificType, options); ++ } + return new LinkedHashMap<>(); + } + @@ -3045,28 +3095,27 @@ index 0000000000000000000000000000000000000000..e7e997796ec47c742cc1f98e61db75a4 +} diff --git a/src/main/java/io/papermc/paper/configuration/serializer/collections/TableSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/collections/TableSerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..36ca88b677e1b55b41c52750948d5b6de7ecd007 +index 0000000000000000000000000000000000000000..c02b2aa2565645d64c2709310d2aba9e32fd536d --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/collections/TableSerializer.java -@@ -0,0 +1,89 @@ +@@ -0,0 +1,88 @@ +package io.papermc.paper.configuration.serializer.collections; + +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.ImmutableTable; +import com.google.common.collect.Table; +import io.leangen.geantyref.TypeFactory; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import java.lang.reflect.ParameterizedType; ++import java.lang.reflect.Type; ++import java.util.Map; ++import java.util.Objects; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.BasicConfigurationNode; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.ConfigurationOptions; +import org.spongepowered.configurate.serialize.SerializationException; +import org.spongepowered.configurate.serialize.TypeSerializer; + -+import java.lang.reflect.ParameterizedType; -+import java.lang.reflect.Type; -+import java.util.Map; -+import java.util.Objects; -+ +public class TableSerializer implements TypeSerializer> { + private static final int ROW_TYPE_ARGUMENT_INDEX = 0; + private static final int COLUMN_TYPE_ARGUMENT_INDEX = 1; @@ -3087,13 +3136,13 @@ index 0000000000000000000000000000000000000000..36ca88b677e1b55b41c52750948d5b6d + final Type columnType = type.getActualTypeArguments()[COLUMN_TYPE_ARGUMENT_INDEX]; + final Type valueType = type.getActualTypeArguments()[VALUE_TYPE_ARGUMENT_INDEX]; + -+ final @Nullable TypeSerializer rowKeySerializer = (TypeSerializer) node.options().serializers().get(rowType); ++ final TypeSerializer rowKeySerializer = (TypeSerializer) node.options().serializers().get(rowType); + if (rowKeySerializer == null) { + throw new SerializationException("Could not find serializer for table row type " + rowType); + } + + final Type mapType = TypeFactory.parameterizedClass(Map.class, columnType, valueType); -+ final @Nullable TypeSerializer> columnValueSerializer = (TypeSerializer>) node.options().serializers().get(mapType); ++ final TypeSerializer> columnValueSerializer = (TypeSerializer>) node.options().serializers().get(mapType); + if (columnValueSerializer == null) { + throw new SerializationException("Could not find serializer for table column-value map " + type); + } @@ -3108,7 +3157,7 @@ index 0000000000000000000000000000000000000000..36ca88b677e1b55b41c52750948d5b6d + } + + @Override -+ public void serialize(final Type type, @Nullable final Table table, final ConfigurationNode node) throws SerializationException { ++ public void serialize(final Type type, final @Nullable Table table, final ConfigurationNode node) throws SerializationException { + if (table != null) { + this.serialize0(table, (ParameterizedType) type, node); + } @@ -3120,7 +3169,7 @@ index 0000000000000000000000000000000000000000..36ca88b677e1b55b41c52750948d5b6d + final Type columnType = type.getActualTypeArguments()[COLUMN_TYPE_ARGUMENT_INDEX]; + final Type valueType = type.getActualTypeArguments()[VALUE_TYPE_ARGUMENT_INDEX]; + -+ final @Nullable TypeSerializer rowKeySerializer = node.options().serializers().get(rowType); ++ final TypeSerializer rowKeySerializer = node.options().serializers().get(rowType); + if (rowKeySerializer == null) { + throw new SerializationException("Could not find a serializer for table row type " + rowType); + } @@ -3138,12 +3187,32 @@ index 0000000000000000000000000000000000000000..36ca88b677e1b55b41c52750948d5b6d + return ImmutableTable.of(); + } +} +diff --git a/src/main/java/io/papermc/paper/configuration/serializer/collections/package-info.java b/src/main/java/io/papermc/paper/configuration/serializer/collections/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..78899dc1357626f993119efabf29c52396e15b2b +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/serializer/collections/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.serializer.collections; ++ ++import org.jspecify.annotations.NullMarked; +diff --git a/src/main/java/io/papermc/paper/configuration/serializer/package-info.java b/src/main/java/io/papermc/paper/configuration/serializer/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..757de4562e038a2d62f276e18e86ecab7c7332bf +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/serializer/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.serializer; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryEntrySerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryEntrySerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..cb0de1a639578320fd38177a915bfa5d1e9a73bd +index 0000000000000000000000000000000000000000..6b600a133f0689a70d1619c684c5e3c0f313b42d --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryEntrySerializer.java -@@ -0,0 +1,64 @@ +@@ -0,0 +1,63 @@ +package io.papermc.paper.configuration.serializer.registry; + +import io.leangen.geantyref.TypeToken; @@ -3153,7 +3222,6 @@ index 0000000000000000000000000000000000000000..cb0de1a639578320fd38177a915bfa5d +import net.minecraft.core.RegistryAccess; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; -+import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.configurate.serialize.ScalarSerializer; +import org.spongepowered.configurate.serialize.SerializationException; + @@ -3201,7 +3269,7 @@ index 0000000000000000000000000000000000000000..cb0de1a639578320fd38177a915bfa5d + } + + private ResourceKey deserializeKey(final Object input) throws SerializationException { -+ final @Nullable ResourceLocation key = ResourceLocation.tryParse(input.toString()); ++ final ResourceLocation key = ResourceLocation.tryParse(input.toString()); + if (key == null) { + throw new SerializationException("Could not create a key from " + input); + } @@ -3289,6 +3357,16 @@ index 0000000000000000000000000000000000000000..6831b7b72c5e1f79eff36019ca2ff565 + return this.registry().getResourceKey(value).orElseThrow(); + } +} +diff --git a/src/main/java/io/papermc/paper/configuration/serializer/registry/package-info.java b/src/main/java/io/papermc/paper/configuration/serializer/registry/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..5185a314b555dffb6dea355dc9e2b005e5808843 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/serializer/registry/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.serializer.registry; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/transformation/Transformations.java b/src/main/java/io/papermc/paper/configuration/transformation/Transformations.java new file mode 100644 index 0000000000000000000000000000000000000000..96e8d03bd4a4d43633a94bb251054610ac07315a @@ -3338,14 +3416,15 @@ index 0000000000000000000000000000000000000000..96e8d03bd4a4d43633a94bb251054610 +} diff --git a/src/main/java/io/papermc/paper/configuration/transformation/global/LegacyPaperConfig.java b/src/main/java/io/papermc/paper/configuration/transformation/global/LegacyPaperConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799733d66d9 +index 0000000000000000000000000000000000000000..7b984ec88a72a5e2581cb717d1f228b01cffbcda --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/transformation/global/LegacyPaperConfig.java -@@ -0,0 +1,223 @@ +@@ -0,0 +1,221 @@ +package io.papermc.paper.configuration.transformation.global; + +import com.mojang.logging.LogUtils; +import io.papermc.paper.configuration.Configuration; ++import java.util.function.Predicate; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.minimessage.MiniMessage; @@ -3353,14 +3432,11 @@ index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799 +import net.minecraft.network.protocol.game.ServerboundPlaceRecipePacket; +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.YamlConfiguration; -+import org.checkerframework.checker.nullness.qual.Nullable; +import org.slf4j.Logger; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.transformation.ConfigurationTransformation; +import org.spongepowered.configurate.transformation.TransformAction; + -+import java.util.function.Predicate; -+ +import static org.spongepowered.configurate.NodePath.path; + +public final class LegacyPaperConfig { @@ -3425,7 +3501,7 @@ index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799 + .addAction(path("allow-perm-block-break-exploits"), (path, value) -> new Object[]{"settings", "unsupported-settings", "allow-permanent-block-break-exploits"}) + .addAction(path("settings", "unsupported-settings", "allow-tnt-duplication"), TransformAction.rename("allow-piston-duplication")) + .addAction(path("settings", "save-player-data"), (path, value) -> { -+ final @Nullable Object val = value.raw(); ++ final Object val = value.raw(); + if (val instanceof Boolean bool) { + spigotConfiguration.set("players.disable-saving", !bool); + } @@ -3433,7 +3509,7 @@ index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799 + return null; + }) + .addAction(path("settings", "log-named-entity-deaths"), (path, value) -> { -+ final @Nullable Object val = value.raw(); ++ final Object val = value.raw(); + if (val instanceof Boolean bool && !bool) { + spigotConfiguration.set("settings.log-named-deaths", false); + } @@ -3461,7 +3537,7 @@ index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799 + .addAction(path("packet-limiter", "limits", "all"), (path, value) -> new Object[]{"packet-limiter", "all-packets"}) + .addAction(path("packet-limiter", "limits"), (path, value) -> new Object[]{"packet-limiter", "overrides"}) + .addAction(path("packet-limiter", "overrides", ConfigurationTransformation.WILDCARD_OBJECT), (path, value) -> { -+ final @Nullable Object keyValue = value.key(); ++ final Object keyValue = value.key(); + if (keyValue != null && keyValue.toString().equals("PacketPlayInAutoRecipe")) { // add special cast to handle the default for moj-mapped servers that upgrade the config + return path.with(path.size() - 1, ServerboundPlaceRecipePacket.class.getSimpleName()).array(); + } @@ -3520,7 +3596,7 @@ index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799 + } + private static void miniMessageWithTranslatable(final ConfigurationTransformation.Builder builder, final Predicate englishCheck, final Component component, final String... strPath) { + builder.addAction(path((Object[]) strPath), (path, value) -> { -+ final @Nullable Object val = value.raw(); ++ final Object val = value.raw(); + if (val != null) { + final String strVal = val.toString(); + if (!englishCheck.test(strVal)) { @@ -3535,7 +3611,7 @@ index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799 + + private static void miniMessage(final ConfigurationTransformation.Builder builder, final String... strPath) { + builder.addAction(path((Object[]) strPath), (path, value) -> { -+ final @Nullable Object val = value.raw(); ++ final Object val = value.raw(); + if (val != null) { + value.set(miniMessage(val.toString())); + } @@ -3565,9 +3641,19 @@ index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799 + }); + } +} +diff --git a/src/main/java/io/papermc/paper/configuration/transformation/global/package-info.java b/src/main/java/io/papermc/paper/configuration/transformation/global/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..241101a25821d3e506308ef9d7edb36aecd76232 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/transformation/global/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.transformation.global; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/V29_LogIPs.java b/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/V29_LogIPs.java new file mode 100644 -index 0000000000000000000000000000000000000000..66073f7a6a96405348cc4044ad1e6922158b13ba +index 0000000000000000000000000000000000000000..bf5de965d26a59f7b4ba5ade3cdab35c37f42be2 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/V29_LogIPs.java @@ -0,0 +1,44 @@ @@ -3576,7 +3662,7 @@ index 0000000000000000000000000000000000000000..66073f7a6a96405348cc4044ad1e6922 +import java.util.Properties; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.dedicated.DedicatedServer; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.NodePath; @@ -3615,9 +3701,29 @@ index 0000000000000000000000000000000000000000..66073f7a6a96405348cc4044ad1e6922 + } + +} +diff --git a/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/package-info.java b/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d9f90a01e88fb402b796a354bb3419193566b4b5 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.transformation.global.versioned; ++ ++import org.jspecify.annotations.NullMarked; +diff --git a/src/main/java/io/papermc/paper/configuration/transformation/package-info.java b/src/main/java/io/papermc/paper/configuration/transformation/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7a1220c80c3eb4d365dd317958bdca0a6c8321aa +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/transformation/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.transformation; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/FeatureSeedsGeneration.java b/src/main/java/io/papermc/paper/configuration/transformation/world/FeatureSeedsGeneration.java new file mode 100644 -index 0000000000000000000000000000000000000000..cb1f5f65c098470dc8553b015d0f0f29f28ed956 +index 0000000000000000000000000000000000000000..d670865dc9bf75ccc5309222e8af7fc10325c5fb --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/transformation/world/FeatureSeedsGeneration.java @@ -0,0 +1,71 @@ @@ -3633,7 +3739,7 @@ index 0000000000000000000000000000000000000000..cb1f5f65c098470dc8553b015d0f0f29 +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.slf4j.Logger; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.ConfigurationNode; @@ -3694,14 +3800,19 @@ index 0000000000000000000000000000000000000000..cb1f5f65c098470dc8553b015d0f0f29 +} diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/LegacyPaperWorldConfig.java b/src/main/java/io/papermc/paper/configuration/transformation/world/LegacyPaperWorldConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..77e530830dc8ebc861b2e70f787f9b71524a54d2 +index 0000000000000000000000000000000000000000..7af8f613ac63f04f01e373ec80747336f744baa4 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/transformation/world/LegacyPaperWorldConfig.java -@@ -0,0 +1,322 @@ +@@ -0,0 +1,320 @@ +package io.papermc.paper.configuration.transformation.world; + +import io.papermc.paper.configuration.Configuration; +import io.papermc.paper.configuration.WorldConfiguration; ++import java.util.HashMap; ++import java.util.List; ++import java.util.Locale; ++import java.util.Map; ++import java.util.Optional; +import net.minecraft.core.Holder; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; @@ -3710,16 +3821,9 @@ index 0000000000000000000000000000000000000000..77e530830dc8ebc861b2e70f787f9b71 +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.item.Item; +import org.bukkit.Material; -+import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.configurate.transformation.ConfigurationTransformation; +import org.spongepowered.configurate.transformation.TransformAction; + -+import java.util.HashMap; -+import java.util.List; -+import java.util.Locale; -+import java.util.Map; -+import java.util.Optional; -+ +import static io.papermc.paper.configuration.transformation.Transformations.moveFromRoot; +import static io.papermc.paper.configuration.transformation.Transformations.moveFromRootAndRename; +import static org.spongepowered.configurate.NodePath.path; @@ -3758,14 +3862,14 @@ index 0000000000000000000000000000000000000000..77e530830dc8ebc861b2e70f787f9b71 + }).build()) + .addVersion(19, ConfigurationTransformation.builder() + .addAction(path("anti-xray", "hidden-blocks"), (path, value) -> { -+ @Nullable final List hiddenBlocks = value.getList(String.class); ++ final List hiddenBlocks = value.getList(String.class); + if (hiddenBlocks != null) { + hiddenBlocks.remove("lit_redstone_ore"); + } + return null; + }) + .addAction(path("anti-xray", "replacement-blocks"), (path, value) -> { -+ @Nullable final List replacementBlocks = value.getList(String.class); ++ final List replacementBlocks = value.getList(String.class); + if (replacementBlocks != null) { + final int index = replacementBlocks.indexOf("planks"); + if (index != -1) { @@ -3838,9 +3942,9 @@ index 0000000000000000000000000000000000000000..77e530830dc8ebc861b2e70f787f9b71 + value.childrenMap().forEach((key, node) -> { + String itemName = key.toString(); + final Optional> itemHolder = BuiltInRegistries.ITEM.get(ResourceKey.create(Registries.ITEM, ResourceLocation.parse(itemName.toLowerCase(Locale.ROOT)))); -+ final @Nullable String item; ++ final String item; + if (itemHolder.isEmpty()) { -+ final @Nullable Material bukkitMat = Material.matchMaterial(itemName); ++ final Material bukkitMat = Material.matchMaterial(itemName); + item = bukkitMat != null ? bukkitMat.getKey().getKey() : null; + } else { + item = itemHolder.get().unwrapKey().orElseThrow().location().getPath(); @@ -3976,7 +4080,7 @@ index 0000000000000000000000000000000000000000..77e530830dc8ebc861b2e70f787f9b71 + + builder.addAction(path("feature-seeds", ConfigurationTransformation.WILDCARD_OBJECT), (path, value) -> { + final String key = path.array()[path.size() - 1].toString(); -+ if (!key.equals("generate-random-seeds-for-all")) { ++ if (!"generate-random-seeds-for-all".equals(key)) { + return new Object[]{"feature-seeds", "features", key}; + } + return null; @@ -3994,7 +4098,7 @@ index 0000000000000000000000000000000000000000..77e530830dc8ebc861b2e70f787f9b71 + }); + + builder.addAction(path("redstone-implementation"), (path, value) -> { -+ if (value.require(String.class).equalsIgnoreCase("alternate-current")) { ++ if ("alternate-current".equalsIgnoreCase(value.require(String.class))) { + value.set("alternate_current"); + } + return new Object[]{"misc", "redstone-implementation"}; @@ -4020,16 +4124,26 @@ index 0000000000000000000000000000000000000000..77e530830dc8ebc861b2e70f787f9b71 + moveFromRootAndRename(builder, path("game-mechanics", oldKey), newKey, parents); + } +} +diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/package-info.java b/src/main/java/io/papermc/paper/configuration/transformation/world/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0db4d187f780a0cf90c9c2936d1f33415d004137 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/transformation/world/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.transformation.world; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/V29_ZeroWorldHeight.java b/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/V29_ZeroWorldHeight.java new file mode 100644 -index 0000000000000000000000000000000000000000..6e481d509d091e65a4909d79014ac94ea63c8455 +index 0000000000000000000000000000000000000000..a1e8ce5407f2c5f188b2ce2d768512d3d42ad64b --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/V29_ZeroWorldHeight.java @@ -0,0 +1,49 @@ +package io.papermc.paper.configuration.transformation.world.versioned; + +import io.papermc.paper.configuration.type.number.IntOr; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.NodePath; @@ -4108,7 +4222,7 @@ index 0000000000000000000000000000000000000000..d08b65234192d5b639cead675114f64b +} diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/V31_SpawnLoadedRangeToGameRule.java b/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/V31_SpawnLoadedRangeToGameRule.java new file mode 100644 -index 0000000000000000000000000000000000000000..d872b1948df52759fed9c3d892aed6abfdfc8068 +index 0000000000000000000000000000000000000000..cb05980256f20df7b3c30e33eaa2c3185f2a38f8 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/V31_SpawnLoadedRangeToGameRule.java @@ -0,0 +1,55 @@ @@ -4116,7 +4230,7 @@ index 0000000000000000000000000000000000000000..d872b1948df52759fed9c3d892aed6ab + +import io.papermc.paper.configuration.Configurations; +import net.minecraft.world.level.GameRules; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.NodePath; +import org.spongepowered.configurate.transformation.ConfigurationTransformation; @@ -4167,22 +4281,31 @@ index 0000000000000000000000000000000000000000..d872b1948df52759fed9c3d892aed6ab + } + } +} +diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/package-info.java b/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..087aa63ae612aaabf4c161c56c78d47ef5b591d3 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.transformation.world.versioned; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/type/BooleanOrDefault.java b/src/main/java/io/papermc/paper/configuration/type/BooleanOrDefault.java new file mode 100644 -index 0000000000000000000000000000000000000000..a3eaa47cfcfc4fd2a607f9b375230fada35620d3 +index 0000000000000000000000000000000000000000..1e73f51b7f6d06a1e86b150b001f90dd179b8ec8 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/type/BooleanOrDefault.java -@@ -0,0 +1,53 @@ +@@ -0,0 +1,52 @@ +package io.papermc.paper.configuration.type; + -+import org.apache.commons.lang3.BooleanUtils; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.spongepowered.configurate.serialize.ScalarSerializer; -+import org.spongepowered.configurate.serialize.SerializationException; -+ +import java.lang.reflect.Type; +import java.util.Locale; +import java.util.function.Predicate; ++import org.apache.commons.lang3.BooleanUtils; ++import org.jspecify.annotations.Nullable; ++import org.spongepowered.configurate.serialize.ScalarSerializer; ++import org.spongepowered.configurate.serialize.SerializationException; + +public record BooleanOrDefault(@Nullable Boolean value) { + private static final String DEFAULT_VALUE = "default"; @@ -4217,7 +4340,7 @@ index 0000000000000000000000000000000000000000..a3eaa47cfcfc4fd2a607f9b375230fad + + @Override + protected Object serialize(BooleanOrDefault item, Predicate> typeSupported) { -+ final @Nullable Boolean value = item.value; ++ final Boolean value = item.value; + if (value != null) { + return value.toString(); + } else { @@ -4228,7 +4351,7 @@ index 0000000000000000000000000000000000000000..a3eaa47cfcfc4fd2a607f9b375230fad +} diff --git a/src/main/java/io/papermc/paper/configuration/type/DespawnRange.java b/src/main/java/io/papermc/paper/configuration/type/DespawnRange.java new file mode 100644 -index 0000000000000000000000000000000000000000..8a792a000e924b3ddc572edc788598811e9ef71c +index 0000000000000000000000000000000000000000..7779edcbbce36d7da177a92807dac73fbe24c9fa --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/type/DespawnRange.java @@ -0,0 +1,109 @@ @@ -4236,7 +4359,7 @@ index 0000000000000000000000000000000000000000..8a792a000e924b3ddc572edc78859881 + +import io.papermc.paper.configuration.type.number.IntOr; +import java.lang.reflect.Type; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.serialize.SerializationException; +import org.spongepowered.configurate.serialize.TypeSerializer; @@ -4343,26 +4466,25 @@ index 0000000000000000000000000000000000000000..8a792a000e924b3ddc572edc78859881 +} diff --git a/src/main/java/io/papermc/paper/configuration/type/Duration.java b/src/main/java/io/papermc/paper/configuration/type/Duration.java new file mode 100644 -index 0000000000000000000000000000000000000000..422ccb0b332b3e94be228b9b94f379467d6461a5 +index 0000000000000000000000000000000000000000..ad1c77388da868b61d99dd8d7ab272bf6f7142a9 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/type/Duration.java -@@ -0,0 +1,97 @@ +@@ -0,0 +1,96 @@ +package io.papermc.paper.configuration.type; + -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.spongepowered.configurate.serialize.ScalarSerializer; -+import org.spongepowered.configurate.serialize.SerializationException; -+ +import java.lang.reflect.Type; +import java.util.Objects; +import java.util.function.Predicate; +import java.util.regex.Pattern; ++import org.jspecify.annotations.Nullable; ++import org.spongepowered.configurate.serialize.ScalarSerializer; ++import org.spongepowered.configurate.serialize.SerializationException; + +public final class Duration { + + private static final Pattern SPACE = Pattern.compile(" "); + private static final Pattern NOT_NUMERIC = Pattern.compile("[^-\\d.]"); -+ public static final Serializer SERIALIZER = new Serializer(); ++ public static final ScalarSerializer SERIALIZER = new Serializer(); + + private final long seconds; + private final String value; @@ -4746,23 +4868,21 @@ index 0000000000000000000000000000000000000000..a3a1d398d783c37914fb6d646e11361a +} diff --git a/src/main/java/io/papermc/paper/configuration/type/fallback/FallbackValueSerializer.java b/src/main/java/io/papermc/paper/configuration/type/fallback/FallbackValueSerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..8d0fcd038e12c70a3a5aaf2669452589d9055255 +index 0000000000000000000000000000000000000000..8def3c63b146905df287779cbe2502ff89ecd4bd --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/type/fallback/FallbackValueSerializer.java -@@ -0,0 +1,55 @@ +@@ -0,0 +1,53 @@ +package io.papermc.paper.configuration.type.fallback; + -+import net.minecraft.server.MinecraftServer; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.spigotmc.SpigotWorldConfig; -+import org.spongepowered.configurate.serialize.ScalarSerializer; -+import org.spongepowered.configurate.serialize.SerializationException; -+ +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Predicate; +import java.util.function.Supplier; ++import net.minecraft.server.MinecraftServer; ++import org.spigotmc.SpigotWorldConfig; ++import org.spongepowered.configurate.serialize.ScalarSerializer; ++import org.spongepowered.configurate.serialize.SerializationException; + +import static io.leangen.geantyref.GenericTypeReflector.erase; + @@ -4789,7 +4909,7 @@ index 0000000000000000000000000000000000000000..8d0fcd038e12c70a3a5aaf2669452589 + + @Override + public FallbackValue deserialize(Type type, Object obj) throws SerializationException { -+ final @Nullable FallbackCreator creator = REGISTRY.get(erase(type)); ++ final FallbackCreator creator = REGISTRY.get(erase(type)); + if (creator == null) { + throw new SerializationException(type + " does not have a FallbackCreator registered"); + } @@ -4821,6 +4941,16 @@ index 0000000000000000000000000000000000000000..70cc7b45e7355f6c8476a74a070f1266 + return value < 0 ? OptionalInt.empty() : OptionalInt.of(value); + } +} +diff --git a/src/main/java/io/papermc/paper/configuration/type/fallback/package-info.java b/src/main/java/io/papermc/paper/configuration/type/fallback/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7daf9e0ec8f35b68373d4f025ec2366ab110e22e +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/type/fallback/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.type.fallback; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/type/number/BelowZeroToEmpty.java b/src/main/java/io/papermc/paper/configuration/type/number/BelowZeroToEmpty.java new file mode 100644 index 0000000000000000000000000000000000000000..31068170086aeac51a2adb952b19672e875ba528 @@ -5073,6 +5203,26 @@ index 0000000000000000000000000000000000000000..614aba60bb07946a144650fd3aedb316 + + protected abstract boolean belowZero(O value); +} +diff --git a/src/main/java/io/papermc/paper/configuration/type/number/package-info.java b/src/main/java/io/papermc/paper/configuration/type/number/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a1e8c3a3922aea672bc75c810496718ea3acfe0a +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/type/number/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.type.number; ++ ++import org.jspecify.annotations.NullMarked; +diff --git a/src/main/java/io/papermc/paper/configuration/type/package-info.java b/src/main/java/io/papermc/paper/configuration/type/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..af8bcae3fb6aeb75350d0783599582d0d0cd3912 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/type/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.type; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java index fc5c42e77a76b0ca946b13435144584b9c4bfafa..9bd6056bba6ba48bada7e9cd5883b0a171b0bbc4 100644 --- a/src/main/java/net/minecraft/server/Main.java @@ -5226,7 +5376,7 @@ index 9cf0c141fefe67893828e300cba4f8a8545ba25f..c8e49c1904c80c4ede40ca5c26efad9b this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 60805f6a2badca9b9cdfa54a9273ceba6311b16c..6c8a69b7c1b45549b2c388a8df2258184c587309 100644 +index 46b067fdfbbdeb3c0005b37d24ae248ec2d6bb90..d5451cb1976ca3675dd19b07bd8a2d363f82db86 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -967,6 +967,7 @@ public final class CraftServer implements Server { @@ -5238,7 +5388,7 @@ index 60805f6a2badca9b9cdfa54a9273ceba6311b16c..6c8a69b7c1b45549b2c388a8df225818 world.serverLevelData.setDifficulty(config.difficulty); world.setSpawnSettings(config.spawnMonsters); diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 17e10c4373b4281cc74b748c4a1e173e36eb9196..755b1d77418ecae0dc9ec5197275d0cd914e7bee 100644 +index 5e75839c0620f94e5b58942c984938e564d3b936..3ee69736494467aa6a1450baf868e73c94733e5b 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -142,6 +142,19 @@ public class Main { diff --git a/patches/server/0009-MC-Utils.patch b/patches/server/0009-MC-Utils.patch index 5e156e9126..1912c615e2 100644 --- a/patches/server/0009-MC-Utils.patch +++ b/patches/server/0009-MC-Utils.patch @@ -4691,16 +4691,15 @@ index 0000000000000000000000000000000000000000..197224e31175252d8438a8df585bbb65 +} diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java new file mode 100644 -index 0000000000000000000000000000000000000000..e85e544506b4c762503a1cb490e6c0f5b1d563f4 +index 0000000000000000000000000000000000000000..9d97c9afa31bed6d2e6b7778bfe4cc41cea31c4d --- /dev/null +++ b/src/main/java/io/papermc/paper/util/MCUtil.java -@@ -0,0 +1,220 @@ +@@ -0,0 +1,209 @@ +package io.papermc.paper.util; + +import com.google.common.collect.Collections2; +import com.google.common.collect.Lists; +import com.google.common.util.concurrent.ThreadFactoryBuilder; -+import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.math.BlockPosition; +import io.papermc.paper.math.FinePosition; +import io.papermc.paper.math.Position; @@ -4716,15 +4715,10 @@ index 0000000000000000000000000000000000000000..e85e544506b4c762503a1cb490e6c0f5 +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; -+import net.kyori.adventure.key.Key; +import net.minecraft.core.BlockPos; -+import net.minecraft.core.Holder; +import net.minecraft.core.Vec3i; -+import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceKey; -+import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; -+import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; @@ -4896,11 +4890,6 @@ index 0000000000000000000000000000000000000000..e85e544506b4c762503a1cb490e6c0f5 + return CraftNamespacedKey.fromMinecraft(key.location()); + } + -+ public static Holder keyToSound(Key key) { -+ ResourceLocation soundId = PaperAdventure.asVanilla(key); -+ return BuiltInRegistries.SOUND_EVENT.wrapAsHolder(BuiltInRegistries.SOUND_EVENT.getOptional(soundId).orElse(SoundEvent.createVariableRangeEvent(soundId))); -+ } -+ + public static List transformUnmodifiable(final List nms, final Function converter) { + return Collections.unmodifiableList(Lists.transform(nms, converter::apply)); + } diff --git a/patches/server/0010-Adventure.patch b/patches/server/0010-Adventure.patch index 5fc337c1e3..07b2834d8e 100644 --- a/patches/server/0010-Adventure.patch +++ b/patches/server/0010-Adventure.patch @@ -1161,16 +1161,15 @@ index 0000000000000000000000000000000000000000..2fd6c3e65354071af71c7d8ebb97b559 +} diff --git a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java new file mode 100644 -index 0000000000000000000000000000000000000000..610003a668c4a7fe53e3477accc6bafb8479b936 +index 0000000000000000000000000000000000000000..8ec506a1ae40f2e4b01af9b34a0b98be8653b460 --- /dev/null +++ b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java -@@ -0,0 +1,483 @@ +@@ -0,0 +1,505 @@ +package io.papermc.paper.adventure; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.serialization.JavaOps; -+import com.mojang.serialization.JsonOps; +import io.netty.util.AttributeKey; +import java.io.IOException; +import java.util.ArrayList; @@ -1223,6 +1222,7 @@ index 0000000000000000000000000000000000000000..610003a668c4a7fe53e3477accc6bafb +import net.minecraft.network.protocol.game.ClientboundSoundEntityPacket; +import net.minecraft.network.protocol.game.ClientboundSoundPacket; +import net.minecraft.resources.RegistryOps; ++import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.network.Filterable; +import net.minecraft.sounds.SoundEvent; @@ -1322,13 +1322,35 @@ index 0000000000000000000000000000000000000000..610003a668c4a7fe53e3477accc6bafb + return ResourceLocation.fromNamespaceAndPath(key.namespace(), key.value()); + } + -+ public static ResourceLocation asVanillaNullable(final Key key) { ++ public static ResourceKey asVanilla( ++ final ResourceKey> registry, ++ final Key key ++ ) { ++ return ResourceKey.create(registry, asVanilla(key)); ++ } ++ ++ public static Key asAdventureKey(final ResourceKey key) { ++ return asAdventure(key.location()); ++ } ++ ++ public static @Nullable ResourceLocation asVanillaNullable(final Key key) { + if (key == null) { + return null; + } + return asVanilla(key); + } + ++ public static Holder resolveSound(final Key key) { ++ ResourceLocation id = asVanilla(key); ++ Optional> vanilla = BuiltInRegistries.SOUND_EVENT.get(id); ++ if (vanilla.isPresent()) { ++ return vanilla.get(); ++ } ++ ++ // sound is not known so not in the registry but might be used by the client with a resource pack ++ return Holder.direct(SoundEvent.createVariableRangeEvent(id)); ++ } ++ + // Component + + public static @NotNull Component asAdventure(@Nullable final net.minecraft.network.chat.Component component) { diff --git a/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch b/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch index 5163963488..9eaddf3d66 100644 --- a/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch +++ b/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch @@ -222,10 +222,10 @@ index 0000000000000000000000000000000000000000..8f07539a82f449ad217e316a7513a170 + +} diff --git a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java -index 161bc8c577643094d824ea96fb6974c76e5e77f0..cfcaf215c4a901dd2938c7ce41db502c57b42bbf 100644 +index 8ec506a1ae40f2e4b01af9b34a0b98be8653b460..f466bfdf5557c94ebee3ad609d9b6f18f86aefef 100644 --- a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java +++ b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java -@@ -32,6 +32,7 @@ import net.kyori.adventure.text.flattener.ComponentFlattener; +@@ -31,6 +31,7 @@ import net.kyori.adventure.text.flattener.ComponentFlattener; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.serializer.ComponentSerializer; diff --git a/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch b/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch index 047ec2d29f..d04608c8b2 100644 --- a/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch +++ b/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Remap reflection calls in plugins using internals Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com> diff --git a/build.gradle.kts b/build.gradle.kts -index 24f3d0c96fe9d70b1a7cf528e09ebfc4366577ed..7aee6d9849f0a9c64db0368d2faa03c0633a72a4 100644 +index 8678e5bd59a7e085cb1b4e38f29e06ce36d2c1de..8d05216e246bfaec5945cdd55d08b6a388a769e8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -62,6 +62,12 @@ dependencies { @@ -23,7 +23,7 @@ index 24f3d0c96fe9d70b1a7cf528e09ebfc4366577ed..7aee6d9849f0a9c64db0368d2faa03c0 paperweight { diff --git a/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java -index 893ad5e7c2d32ccd64962d95d146bbd317c28ab8..3d73ea0e63c97b2b08e719b7be7af3894fb2d4e8 100644 +index b61935052154e76b1b8cb49868c96c52f34a41d1..a2fe12513b93ded71517955ef3e52c925f56f7d1 100644 --- a/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java +++ b/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java @@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableBiMap; @@ -32,9 +32,9 @@ index 893ad5e7c2d32ccd64962d95d146bbd317c28ab8..3d73ea0e63c97b2b08e719b7be7af389 import io.papermc.paper.configuration.serializer.collections.MapSerializer; +import io.papermc.paper.util.MappingEnvironment; import io.papermc.paper.util.ObfHelper; - import net.minecraft.network.protocol.Packet; - import org.checkerframework.checker.nullness.qual.Nullable; -@@ -69,7 +70,7 @@ public final class PacketClassSerializer extends ScalarSerializer> packetClass, final Predicate> typeSupported) { final String name = packetClass.getName(); diff --git a/patches/server/0466-Add-RegistryAccess-for-managing-Registries.patch b/patches/server/0466-Add-RegistryAccess-for-managing-Registries.patch index 55351393f7..24764d91ee 100644 --- a/patches/server/0466-Add-RegistryAccess-for-managing-Registries.patch +++ b/patches/server/0466-Add-RegistryAccess-for-managing-Registries.patch @@ -12,12 +12,13 @@ public net.minecraft.server.RegistryLayer STATIC_ACCESS diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/src/main/java/io/papermc/paper/registry/PaperRegistries.java new file mode 100644 -index 0000000000000000000000000000000000000000..c6969f968b45eff2aeb44e647712abda10c7c113 +index 0000000000000000000000000000000000000000..2f22f46f80b80be43a2cc1cd8afb51f4d1fd0e91 --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/PaperRegistries.java -@@ -0,0 +1,156 @@ +@@ -0,0 +1,157 @@ +package io.papermc.paper.registry; + ++import com.google.common.base.Preconditions; +import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.registry.entry.RegistryEntry; +import java.util.Collections; @@ -125,16 +126,16 @@ index 0000000000000000000000000000000000000000..c6969f968b45eff2aeb44e647712abda + entry(Registries.INSTRUMENT, RegistryKey.INSTRUMENT, MusicInstrument.class, CraftMusicInstrument::new).delayed(), + + // api-only -+ apiOnly(Registries.ENTITY_TYPE, RegistryKey.ENTITY_TYPE, () -> org.bukkit.Registry.ENTITY_TYPE), -+ apiOnly(Registries.PARTICLE_TYPE, RegistryKey.PARTICLE_TYPE, () -> org.bukkit.Registry.PARTICLE_TYPE), -+ apiOnly(Registries.POTION, RegistryKey.POTION, () -> org.bukkit.Registry.POTION), ++ apiOnly(Registries.ENTITY_TYPE, RegistryKey.ENTITY_TYPE, PaperSimpleRegistry::entityType), ++ apiOnly(Registries.PARTICLE_TYPE, RegistryKey.PARTICLE_TYPE, PaperSimpleRegistry::particleType), ++ apiOnly(Registries.POTION, RegistryKey.POTION, PaperSimpleRegistry::potion), + apiOnly(Registries.MEMORY_MODULE_TYPE, RegistryKey.MEMORY_MODULE_TYPE, () -> (org.bukkit.Registry>) (org.bukkit.Registry) org.bukkit.Registry.MEMORY_MODULE_TYPE) + ); + final Map, RegistryEntry> byRegistryKey = new IdentityHashMap<>(REGISTRY_ENTRIES.size()); + final Map, RegistryEntry> byResourceKey = new IdentityHashMap<>(REGISTRY_ENTRIES.size()); + for (final RegistryEntry entry : REGISTRY_ENTRIES) { -+ byRegistryKey.put(entry.apiKey(), entry); -+ byResourceKey.put(entry.mcKey(), entry); ++ Preconditions.checkState(byRegistryKey.put(entry.apiKey(), entry) == null, "Duplicate api registry key: %s", entry.apiKey()); ++ Preconditions.checkState(byResourceKey.put(entry.mcKey(), entry) == null, "Duplicate mc registry key: %s", entry.mcKey()); + } + BY_REGISTRY_KEY = Collections.unmodifiableMap(byRegistryKey); + BY_RESOURCE_KEY = Collections.unmodifiableMap(byResourceKey); @@ -305,6 +306,50 @@ index 0000000000000000000000000000000000000000..35b6a7c5bac9640332a833bd3627f2bc + return (RegistryKey) LegacyRegistryIdentifiers.CLASS_TO_KEY_MAP.get(type); + } +} +diff --git a/src/main/java/io/papermc/paper/registry/PaperSimpleRegistry.java b/src/main/java/io/papermc/paper/registry/PaperSimpleRegistry.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6d134ace042758da722960cbcb48e52508dafd61 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/registry/PaperSimpleRegistry.java +@@ -0,0 +1,38 @@ ++package io.papermc.paper.registry; ++ ++import java.util.function.Predicate; ++import net.minecraft.core.registries.BuiltInRegistries; ++import org.bukkit.Keyed; ++import org.bukkit.Particle; ++import org.bukkit.Registry; ++import org.bukkit.entity.EntityType; ++import org.bukkit.potion.PotionType; ++import org.jspecify.annotations.NullMarked; ++ ++@NullMarked ++public class PaperSimpleRegistry & Keyed, M> extends Registry.SimpleRegistry { ++ ++ static Registry entityType() { ++ return new PaperSimpleRegistry<>(EntityType.class, entity -> entity != EntityType.UNKNOWN, BuiltInRegistries.ENTITY_TYPE); ++ } ++ ++ static Registry particleType() { ++ return new PaperSimpleRegistry<>(Particle.class, BuiltInRegistries.PARTICLE_TYPE); ++ } ++ ++ static Registry potion() { ++ return new PaperSimpleRegistry<>(PotionType.class, BuiltInRegistries.POTION); ++ } ++ ++ private final net.minecraft.core.Registry nmsRegistry; ++ ++ protected PaperSimpleRegistry(final Class type, final net.minecraft.core.Registry nmsRegistry) { ++ super(type); ++ this.nmsRegistry = nmsRegistry; ++ } ++ ++ public PaperSimpleRegistry(final Class type, final Predicate predicate, final net.minecraft.core.Registry nmsRegistry) { ++ super(type, predicate); ++ this.nmsRegistry = nmsRegistry; ++ } ++} diff --git a/src/main/java/io/papermc/paper/registry/RegistryHolder.java b/src/main/java/io/papermc/paper/registry/RegistryHolder.java new file mode 100644 index 0000000000000000000000000000000000000000..a31bdd9f02fe75a87fceb2ebe8c36b3232a561cc diff --git a/patches/server/0928-Add-onboarding-message-for-initial-server-start.patch b/patches/server/0928-Add-onboarding-message-for-initial-server-start.patch index 64a7380197..b9d8134356 100644 --- a/patches/server/0928-Add-onboarding-message-for-initial-server-start.patch +++ b/patches/server/0928-Add-onboarding-message-for-initial-server-start.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add onboarding message for initial server start diff --git a/src/main/java/io/papermc/paper/configuration/Configurations.java b/src/main/java/io/papermc/paper/configuration/Configurations.java -index d9502ba028a96f9cc846f9ed428bd8066b857ca3..87e5f614ba988547a827486740db217e28585773 100644 +index 007e01d329a31acf7f4ed4c6dc4de7ad54ccad04..8cf720f08514e8e4f62f4ad196f1277bd761c6b2 100644 --- a/src/main/java/io/papermc/paper/configuration/Configurations.java +++ b/src/main/java/io/papermc/paper/configuration/Configurations.java -@@ -129,6 +129,7 @@ public abstract class Configurations { +@@ -127,6 +127,7 @@ public abstract class Configurations { if (Files.notExists(configFile)) { node = CommentedConfigurationNode.root(loader.defaultOptions()); node.node(Configuration.VERSION_FIELD).raw(this.globalConfigVersion()); @@ -17,7 +17,7 @@ index d9502ba028a96f9cc846f9ed428bd8066b857ca3..87e5f614ba988547a827486740db217e node = loader.load(); this.verifyGlobalConfigVersion(node); diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 56798215644d8bca1695856b3a941e8089f49e48..46c37c8db8ecf3cc808fcf59f6bee5fe6ca49b75 100644 +index e0cef37664b64f5db95943c5c118424436163e06..5e9c471ab20b0391e7e41351c65d96745fc8ce4a 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -25,6 +25,7 @@ public class GlobalConfiguration extends ConfigurationPart { diff --git a/patches/server/0948-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch b/patches/server/0948-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch index 811e5396d1..1c00cb4a33 100644 --- a/patches/server/0948-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch +++ b/patches/server/0948-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch @@ -48,3 +48,16 @@ index d08eec460a67fbd0b2ed2e0dd6d557dc629f4dfe..555d1b05ef6278567de598488b9486db } public CombatTracker getCombatTracker() { +diff --git a/src/main/java/net/minecraft/world/entity/animal/Wolf.java b/src/main/java/net/minecraft/world/entity/animal/Wolf.java +index fc19bd326f00d1e8bd08ef6cc430c555337a6e3d..fb84ee1225cd762ef306d1fc3e1baed42c034a3c 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/Wolf.java ++++ b/src/main/java/net/minecraft/world/entity/animal/Wolf.java +@@ -388,7 +388,7 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder>) PaperRegistries.registryToNms(typedKey.registryKey()), PaperAdventure.asVanilla(typedKey.key())); } @@ -286,6 +286,38 @@ index 0000000000000000000000000000000000000000..69e946173407eb05b18a2b19b0d45cbb + return this.freezeEventTypes.getOrCreate(type.registryKey(), RegistryLifecycleEventType::new); + } +} +diff --git a/src/main/java/io/papermc/paper/registry/PaperSimpleRegistry.java b/src/main/java/io/papermc/paper/registry/PaperSimpleRegistry.java +index 6d134ace042758da722960cbcb48e52508dafd61..cc39bc68d29055ef6429f08f975412bd9fe68dbc 100644 +--- a/src/main/java/io/papermc/paper/registry/PaperSimpleRegistry.java ++++ b/src/main/java/io/papermc/paper/registry/PaperSimpleRegistry.java +@@ -1,6 +1,10 @@ + package io.papermc.paper.registry; + ++import io.papermc.paper.registry.set.NamedRegistryKeySetImpl; ++import io.papermc.paper.registry.tag.Tag; ++import io.papermc.paper.registry.tag.TagKey; + import java.util.function.Predicate; ++import net.minecraft.core.HolderSet; + import net.minecraft.core.registries.BuiltInRegistries; + import org.bukkit.Keyed; + import org.bukkit.Particle; +@@ -35,4 +39,16 @@ public class PaperSimpleRegistry & Keyed, M> extends Registry. + super(type, predicate); + this.nmsRegistry = nmsRegistry; + } ++ ++ @Override ++ public boolean hasTag(final TagKey key) { ++ final net.minecraft.tags.TagKey nmsKey = PaperRegistries.toNms(key); ++ return this.nmsRegistry.get(nmsKey).isPresent(); ++ } ++ ++ @Override ++ public Tag getTag(final TagKey key) { ++ final HolderSet.Named namedHolderSet = this.nmsRegistry.get(PaperRegistries.toNms(key)).orElseThrow(); ++ return new NamedRegistryKeySetImpl<>(key, namedHolderSet); ++ } + } diff --git a/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java b/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java new file mode 100644 index 0000000000000000000000000000000000000000..78317c7ab42a666f19634593a8f3b696700764c8 @@ -1174,7 +1206,7 @@ index 4638ba98dbbdb0f880337347be85a6e0fbed2191..bc448f8511c629d1f13d4baf717a11e6 } } diff --git a/src/main/java/net/minecraft/resources/RegistryDataLoader.java b/src/main/java/net/minecraft/resources/RegistryDataLoader.java -index 61774165a25209ee6d26cf8d80149b220c3874e6..fdc88e52235a152dbe3cca273990b4b68f8daaf8 100644 +index 61774165a25209ee6d26cf8d80149b220c3874e6..c5e279216f6cb880397ea2768ee6e99a8798e3e1 100644 --- a/src/main/java/net/minecraft/resources/RegistryDataLoader.java +++ b/src/main/java/net/minecraft/resources/RegistryDataLoader.java @@ -130,7 +130,7 @@ public class RegistryDataLoader { @@ -1195,7 +1227,7 @@ index 61774165a25209ee6d26cf8d80149b220c3874e6..fdc88e52235a152dbe3cca273990b4b6 } private static RegistryAccess.Frozen load( -@@ -148,9 +148,11 @@ public class RegistryDataLoader { +@@ -148,7 +148,8 @@ public class RegistryDataLoader { Map, Exception> map = new HashMap<>(); List> list = entries.stream().map(entry -> entry.create(Lifecycle.stable(), map)).collect(Collectors.toUnmodifiableList()); RegistryOps.RegistryInfoLookup registryInfoLookup = createContext(registries, list); @@ -1204,11 +1236,8 @@ index 61774165a25209ee6d26cf8d80149b220c3874e6..fdc88e52235a152dbe3cca273990b4b6 + list.forEach(loader -> loadable.apply((RegistryDataLoader.Loader)loader, registryInfoLookup, conversions)); list.forEach(loader -> { Registry registry = loader.registry(); -+ io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(loader.registry.key(), conversions); // Paper - run pre-freeze listeners - try { - registry.freeze(); -@@ -238,13 +240,13 @@ public class RegistryDataLoader { +@@ -238,13 +239,13 @@ public class RegistryDataLoader { } private static void loadElementFromResource( @@ -1224,7 +1253,7 @@ index 61774165a25209ee6d26cf8d80149b220c3874e6..fdc88e52235a152dbe3cca273990b4b6 } } -@@ -253,7 +255,8 @@ public class RegistryDataLoader { +@@ -253,7 +254,8 @@ public class RegistryDataLoader { RegistryOps.RegistryInfoLookup infoGetter, WritableRegistry registry, Decoder elementDecoder, @@ -1234,7 +1263,7 @@ index 61774165a25209ee6d26cf8d80149b220c3874e6..fdc88e52235a152dbe3cca273990b4b6 ) { String string = Registries.elementsDirPath(registry.key()); FileToIdConverter fileToIdConverter = FileToIdConverter.json(string); -@@ -266,7 +269,7 @@ public class RegistryDataLoader { +@@ -266,7 +268,7 @@ public class RegistryDataLoader { RegistrationInfo registrationInfo = REGISTRATION_INFO_CACHE.apply(resource.knownPackInfo()); try { @@ -1243,6 +1272,14 @@ index 61774165a25209ee6d26cf8d80149b220c3874e6..fdc88e52235a152dbe3cca273990b4b6 } catch (Exception var15) { errors.put( resourceKey, +@@ -275,6 +277,7 @@ public class RegistryDataLoader { + } + } + ++ io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), conversions); // Paper - run pre-freeze listeners + TagLoader.loadTagsForRegistry(resourceManager, registry); + } + @@ -284,7 +287,8 @@ public class RegistryDataLoader { RegistryOps.RegistryInfoLookup infoGetter, WritableRegistry registry, @@ -1360,32 +1397,6 @@ index 45c78c113e881b277e1216293ad918ee40b44325..8314059455d91f01b986c5c0a239f418 + } + // Paper end - RegistrySet API } -diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index f0556a207f6d9d1766ef0d9753355f7fa5052dc1..f55733b7a56ac21cb297971b9e854ef54001ca26 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -666,6 +666,21 @@ public final class CraftMagicNumbers implements UnsafeValues { - } - // Paper end - lifecycle event API - -+ // Paper start - hack to get tags for non server-backed registries -+ @Override -+ public io.papermc.paper.registry.tag.Tag getTag(final io.papermc.paper.registry.tag.TagKey tagKey) { // TODO remove Keyed -+ if (tagKey.registryKey() != io.papermc.paper.registry.RegistryKey.ENTITY_TYPE && tagKey.registryKey() != io.papermc.paper.registry.RegistryKey.FLUID) { -+ throw new UnsupportedOperationException(tagKey.registryKey() + " doesn't have tags"); -+ } -+ final net.minecraft.resources.ResourceKey> nmsKey = io.papermc.paper.registry.PaperRegistries.registryToNms(tagKey.registryKey()); -+ final net.minecraft.core.Registry nmsRegistry = org.bukkit.craftbukkit.CraftRegistry.getMinecraftRegistry().lookupOrThrow(nmsKey); -+ return nmsRegistry -+ .get(io.papermc.paper.registry.PaperRegistries.toNms(tagKey)) -+ .map(named -> new io.papermc.paper.registry.set.NamedRegistryKeySetImpl<>(tagKey, named)) -+ .orElse(null); -+ } -+ // Paper end - hack to get tags for non server-backed registries -+ - /** - * This helper class represents the different NBT Tags. - *

diff --git a/src/main/resources/META-INF/services/io.papermc.paper.registry.event.RegistryEventTypeProvider b/src/main/resources/META-INF/services/io.papermc.paper.registry.event.RegistryEventTypeProvider new file mode 100644 index 0000000000000000000000000000000000000000..8bee1a5ed877a04e4d027593df1f42cefdd824e7 diff --git a/patches/server/0993-Add-registry-entry-and-builders.patch b/patches/server/0993-Add-registry-entry-and-builders.patch index 37f4a6a8c0..4c2d2a81a2 100644 --- a/patches/server/0993-Add-registry-entry-and-builders.patch +++ b/patches/server/0993-Add-registry-entry-and-builders.patch @@ -6,19 +6,20 @@ Subject: [PATCH] Add registry entry and builders Feature patch diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/src/main/java/io/papermc/paper/registry/PaperRegistries.java -index d34ffad8a36abbb215491d74ae8d9b490a0bc64f..f8c6da955e4bd0e480c7b581d2a4325738f9dd6f 100644 +index 3ec2aa5da045b62809afd2c13fc9ae74189dbdad..31d660bbbe62cd2c26715e8d90fef58b8e024e34 100644 --- a/src/main/java/io/papermc/paper/registry/PaperRegistries.java +++ b/src/main/java/io/papermc/paper/registry/PaperRegistries.java -@@ -1,6 +1,8 @@ - package io.papermc.paper.registry; +@@ -2,6 +2,9 @@ package io.papermc.paper.registry; + import com.google.common.base.Preconditions; import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.registry.data.PaperEnchantmentRegistryEntry; +import io.papermc.paper.registry.data.PaperGameEventRegistryEntry; ++import io.papermc.paper.registry.data.PaperPaintingVariantRegistryEntry; import io.papermc.paper.registry.entry.RegistryEntry; import io.papermc.paper.registry.tag.TagKey; import java.util.Collections; -@@ -80,7 +82,7 @@ public final class PaperRegistries { +@@ -81,7 +84,7 @@ public final class PaperRegistries { static { REGISTRY_ENTRIES = List.of( // built-ins @@ -27,7 +28,7 @@ index d34ffad8a36abbb215491d74ae8d9b490a0bc64f..f8c6da955e4bd0e480c7b581d2a43257 entry(Registries.STRUCTURE_TYPE, RegistryKey.STRUCTURE_TYPE, StructureType.class, CraftStructureType::new), entry(Registries.MOB_EFFECT, RegistryKey.MOB_EFFECT, PotionEffectType.class, CraftPotionEffectType::new), entry(Registries.BLOCK, RegistryKey.BLOCK, BlockType.class, CraftBlockType::new), -@@ -102,7 +104,7 @@ public final class PaperRegistries { +@@ -103,10 +106,10 @@ public final class PaperRegistries { entry(Registries.TRIM_PATTERN, RegistryKey.TRIM_PATTERN, TrimPattern.class, CraftTrimPattern::new).delayed(), entry(Registries.DAMAGE_TYPE, RegistryKey.DAMAGE_TYPE, DamageType.class, CraftDamageType::new).delayed(), entry(Registries.WOLF_VARIANT, RegistryKey.WOLF_VARIANT, Wolf.Variant.class, CraftWolf.CraftVariant::new).delayed(), @@ -35,7 +36,11 @@ index d34ffad8a36abbb215491d74ae8d9b490a0bc64f..f8c6da955e4bd0e480c7b581d2a43257 + writable(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT, Enchantment.class, CraftEnchantment::new, PaperEnchantmentRegistryEntry.PaperBuilder::new).withSerializationUpdater(FieldRename.ENCHANTMENT_RENAME).delayed(), entry(Registries.JUKEBOX_SONG, RegistryKey.JUKEBOX_SONG, JukeboxSong.class, CraftJukeboxSong::new).delayed(), entry(Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN, PatternType.class, CraftPatternType::new).delayed(), - entry(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT, Art.class, CraftArt::new).delayed(), +- entry(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT, Art.class, CraftArt::new).delayed(), ++ writable(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT, Art.class, CraftArt::new, PaperPaintingVariantRegistryEntry.PaperBuilder::new).delayed(), + entry(Registries.INSTRUMENT, RegistryKey.INSTRUMENT, MusicInstrument.class, CraftMusicInstrument::new).delayed(), + + // api-only diff --git a/src/main/java/io/papermc/paper/registry/data/PaperEnchantmentRegistryEntry.java b/src/main/java/io/papermc/paper/registry/data/PaperEnchantmentRegistryEntry.java new file mode 100644 index 0000000000000000000000000000000000000000..481f5f0cfae1fada3bc3f873fb7e04c3086ea9bf @@ -339,6 +344,132 @@ index 0000000000000000000000000000000000000000..18f9463ae23ba2d9c65ffb7531a87c92 + } + } +} +diff --git a/src/main/java/io/papermc/paper/registry/data/PaperPaintingVariantRegistryEntry.java b/src/main/java/io/papermc/paper/registry/data/PaperPaintingVariantRegistryEntry.java +new file mode 100644 +index 0000000000000000000000000000000000000000..21cb8c28c0027b4b2446279f6cf9dbedfc8945d5 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/registry/data/PaperPaintingVariantRegistryEntry.java +@@ -0,0 +1,120 @@ ++package io.papermc.paper.registry.data; ++ ++import io.papermc.paper.adventure.PaperAdventure; ++import io.papermc.paper.registry.PaperRegistryBuilder; ++import io.papermc.paper.registry.TypedKey; ++import io.papermc.paper.registry.data.util.Conversions; ++import java.util.Optional; ++import java.util.OptionalInt; ++import net.kyori.adventure.key.Key; ++import net.minecraft.network.chat.Component; ++import net.minecraft.resources.ResourceLocation; ++import net.minecraft.world.entity.decoration.PaintingVariant; ++import org.bukkit.Art; ++import org.jetbrains.annotations.Range; ++import org.jspecify.annotations.NullMarked; ++import org.jspecify.annotations.Nullable; ++ ++import static io.papermc.paper.registry.data.util.Checks.asArgument; ++import static io.papermc.paper.registry.data.util.Checks.asArgumentRange; ++import static io.papermc.paper.registry.data.util.Checks.asConfigured; ++ ++@NullMarked ++public class PaperPaintingVariantRegistryEntry implements PaintingVariantRegistryEntry { ++ ++ protected OptionalInt width = OptionalInt.empty(); ++ protected OptionalInt height = OptionalInt.empty(); ++ protected @Nullable Component title; ++ protected @Nullable Component author; ++ protected @Nullable ResourceLocation assetId; ++ ++ protected final Conversions conversions; ++ ++ public PaperPaintingVariantRegistryEntry( ++ final Conversions conversions, ++ final TypedKey ignoredKey, ++ final @Nullable PaintingVariant nms ++ ) { ++ this.conversions = conversions; ++ if(nms == null) return; ++ ++ this.width = OptionalInt.of(nms.width()); ++ this.height = OptionalInt.of(nms.height()); ++ this.title = nms.title().orElse(null); ++ this.author = nms.title().orElse(null); ++ this.assetId = nms.assetId(); ++ } ++ ++ @Override ++ public @Range(from = 1, to = 16) int width() { ++ return asConfigured(this.width, "width"); ++ } ++ ++ @Override ++ public @Range(from = 1, to = 16) int height() { ++ return asConfigured(this.height, "height"); ++ } ++ ++ @Override ++ public net.kyori.adventure.text.@Nullable Component title() { ++ return this.title == null ? null : this.conversions.asAdventure(this.title); ++ } ++ ++ @Override ++ public net.kyori.adventure.text.@Nullable Component author() { ++ return this.author == null ? null : this.conversions.asAdventure(this.author); ++ } ++ ++ @Override ++ public Key assetId() { ++ return PaperAdventure.asAdventure(asConfigured(this.assetId, "assetId")); ++ } ++ ++ public static final class PaperBuilder extends PaperPaintingVariantRegistryEntry implements PaintingVariantRegistryEntry.Builder, PaperRegistryBuilder { ++ ++ public PaperBuilder(final Conversions conversions, final TypedKey key, final @Nullable PaintingVariant nms) { ++ super(conversions, key, nms); ++ } ++ ++ @Override ++ public Builder width(@Range(from = 0, to = 16) final int width) { ++ this.width = OptionalInt.of(asArgumentRange(width, "width", 1, 16)); ++ return this; ++ } ++ ++ @Override ++ public Builder height(@Range(from = 0, to = 16) final int height) { ++ this.height = OptionalInt.of(asArgumentRange(height, "height", 1, 16)); ++ return this; ++ } ++ ++ @Override ++ public Builder title(final net.kyori.adventure.text.@Nullable Component title) { ++ this.title = this.conversions.asVanilla(title); ++ return this; ++ } ++ ++ @Override ++ public Builder author(final net.kyori.adventure.text.@Nullable Component author) { ++ this.author = this.conversions.asVanilla(author); ++ return this; ++ } ++ ++ @Override ++ public Builder assetId(final Key assetId) { ++ this.assetId = PaperAdventure.asVanilla(asArgument(assetId, "assetId")); ++ return this; ++ } ++ ++ @Override ++ public PaintingVariant build() { ++ return new PaintingVariant( ++ this.width(), ++ this.height(), ++ asConfigured(this.assetId, "assetId"), ++ Optional.ofNullable(this.title), ++ Optional.ofNullable(this.author) ++ ); ++ } ++ } ++} diff --git a/src/main/java/io/papermc/paper/registry/data/util/Checks.java b/src/main/java/io/papermc/paper/registry/data/util/Checks.java new file mode 100644 index 0000000000000000000000000000000000000000..3241a94731fe8163876614efdcf30f8b551535af diff --git a/patches/server/0994-Proxy-ItemStack-to-CraftItemStack.patch b/patches/server/0994-Proxy-ItemStack-to-CraftItemStack.patch index c7dfc54b2e..a321d37f33 100644 --- a/patches/server/0994-Proxy-ItemStack-to-CraftItemStack.patch +++ b/patches/server/0994-Proxy-ItemStack-to-CraftItemStack.patch @@ -205,12 +205,12 @@ index 6cc9d7a9e6d4bfdc27e52fc581b2bb832616f121..6930d0afb230a88aa813b02e4d55c95d + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index f55733b7a56ac21cb297971b9e854ef54001ca26..8af9ac9e22a15457da12f0746d0e411942c278fb 100644 +index f0556a207f6d9d1766ef0d9753355f7fa5052dc1..2539802c0a02b6a564bdbd58e93ffe5685e775b9 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -681,6 +681,13 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -666,6 +666,13 @@ public final class CraftMagicNumbers implements UnsafeValues { } - // Paper end - hack to get tags for non server-backed registries + // Paper end - lifecycle event API + // Paper start - proxy ItemStack + @Override diff --git a/patches/server/1019-Add-FeatureFlag-API.patch b/patches/server/1019-Add-FeatureFlag-API.patch index ed2a09b0c6..15ab16d841 100644 --- a/patches/server/1019-Add-FeatureFlag-API.patch +++ b/patches/server/1019-Add-FeatureFlag-API.patch @@ -284,7 +284,7 @@ index 6cf790c9fa23ea313423fdaeb7c181bf530828c6..0bcb9df1103050441f8922a688b163dc public static PotionEffectType minecraftHolderToBukkit(Holder minecraft) { return CraftPotionEffectType.minecraftToBukkit(minecraft.value()); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 8af9ac9e22a15457da12f0746d0e411942c278fb..f4ccdd848dd64e97796ef952d2aeacb3219da1bd 100644 +index 2539802c0a02b6a564bdbd58e93ffe5685e775b9..44c9127c71402afd6f98215b9e66fe5b848db50b 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -48,7 +48,7 @@ import org.bukkit.attribute.Attribute; diff --git a/patches/server/1020-Tag-Lifecycle-Events.patch b/patches/server/1020-Tag-Lifecycle-Events.patch index 6b65432932..593b77a3f1 100644 --- a/patches/server/1020-Tag-Lifecycle-Events.patch +++ b/patches/server/1020-Tag-Lifecycle-Events.patch @@ -461,13 +461,13 @@ index 0000000000000000000000000000000000000000..d6d4bfc6f45d646afeace422a038c670 +) { +} diff --git a/src/main/java/net/minecraft/resources/RegistryDataLoader.java b/src/main/java/net/minecraft/resources/RegistryDataLoader.java -index fdc88e52235a152dbe3cca273990b4b68f8daaf8..13797035494a1e010e1da529fb46040f8a6e859f 100644 +index c5e279216f6cb880397ea2768ee6e99a8798e3e1..46bf2b95658ca3bbd3048df5f8adf1bdcc2d3571 100644 --- a/src/main/java/net/minecraft/resources/RegistryDataLoader.java +++ b/src/main/java/net/minecraft/resources/RegistryDataLoader.java @@ -278,7 +278,7 @@ public class RegistryDataLoader { - } } + io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), conversions); // Paper - run pre-freeze listeners - TagLoader.loadTagsForRegistry(resourceManager, registry); + TagLoader.loadTagsForRegistry(resourceManager, registry, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL); // Paper - tag lifecycle - add cause } diff --git a/patches/server/1021-Item-serialization-as-json.patch b/patches/server/1021-Item-serialization-as-json.patch index ea3fc2b9a6..1e422d7da9 100644 --- a/patches/server/1021-Item-serialization-as-json.patch +++ b/patches/server/1021-Item-serialization-as-json.patch @@ -28,7 +28,7 @@ index c80fd4960dfbb0fde37363e7df25b0a5411bdb11..ff7f6916f65466c25a7bde35d64682c1 public static final Codec CODEC_WITH_ID = CODEC.validate( component -> component.getUnsafe().contains("id", 8) ? DataResult.success(component) : DataResult.error(() -> "Missing id for entity in: " + component) diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index f4ccdd848dd64e97796ef952d2aeacb3219da1bd..29d5fa49730d2161bb1b024995a533a08c57939b 100644 +index 44c9127c71402afd6f98215b9e66fe5b848db50b..4c82dae4c2d764c8310832b1a209846d4352bae9 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -527,6 +527,39 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/1035-DataComponent-API.patch b/patches/server/1035-DataComponent-API.patch index 744404bca8..1b469c83f7 100644 --- a/patches/server/1035-DataComponent-API.patch +++ b/patches/server/1035-DataComponent-API.patch @@ -57,10 +57,10 @@ index 0000000000000000000000000000000000000000..4a49f65cae1354afbcd4afda07581790 +} 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..c11de1f077c51483c61af6492f998781df866b88 +index 0000000000000000000000000000000000000000..ee7adf16febfb508b14ff1453e73c75a42be7d26 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/ComponentAdapters.java -@@ -0,0 +1,168 @@ +@@ -0,0 +1,171 @@ +package io.papermc.paper.datacomponent; + +import io.papermc.paper.adventure.PaperAdventure; @@ -101,13 +101,13 @@ index 0000000000000000000000000000000000000000..c11de1f077c51483c61af6492f998781 +import io.papermc.paper.datacomponent.item.PaperUseRemainder; +import io.papermc.paper.datacomponent.item.PaperWritableBookContent; +import io.papermc.paper.datacomponent.item.PaperWrittenBookContent; -+import io.papermc.paper.registry.PaperRegistries; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.BuiltInRegistries; ++import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.util.Unit; +import net.minecraft.world.item.Rarity; @@ -119,7 +119,7 @@ index 0000000000000000000000000000000000000000..c11de1f077c51483c61af6492f998781 +import org.bukkit.craftbukkit.util.Handleable; +import org.bukkit.inventory.ItemRarity; + -+import static io.papermc.paper.datacomponent.ComponentUtils.transform; ++import static io.papermc.paper.util.MCUtil.transformUnmodifiable; + +public final class ComponentAdapters { + @@ -182,7 +182,10 @@ index 0000000000000000000000000000000000000000..c11de1f077c51483c61af6492f998781 + register(DataComponents.INSTRUMENT, CraftMusicInstrument::minecraftHolderToBukkit, CraftMusicInstrument::bukkitToMinecraftHolder); + register(DataComponents.OMINOUS_BOTTLE_AMPLIFIER, PaperOminousBottleAmplifier::new); + register(DataComponents.JUKEBOX_PLAYABLE, PaperJukeboxPlayable::new); -+ register(DataComponents.RECIPES, nms -> transform(nms, PaperRegistries::fromNms), api -> transform(api, PaperRegistries::toNms)); ++ register(DataComponents.RECIPES, ++ nms -> transformUnmodifiable(nms, PaperAdventure::asAdventureKey), ++ api -> transformUnmodifiable(api, key -> PaperAdventure.asVanilla(Registries.RECIPE, key)) ++ ); + register(DataComponents.LODESTONE_TRACKER, PaperLodestoneTracker::new); + register(DataComponents.FIREWORK_EXPLOSION, CraftMetaFirework::getEffect, CraftMetaFirework::getExplosion); + register(DataComponents.FIREWORKS, PaperFireworks::new); @@ -229,51 +232,6 @@ index 0000000000000000000000000000000000000000..c11de1f077c51483c61af6492f998781 + 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..c95ffef54d7149cd8bb220533dddade515e48c8c ---- /dev/null -+++ b/src/main/java/io/papermc/paper/datacomponent/ComponentUtils.java -@@ -0,0 +1,39 @@ -+package io.papermc.paper.datacomponent; -+ -+import com.google.common.collect.Collections2; -+import com.google.common.collect.Lists; -+import io.papermc.paper.adventure.PaperAdventure; -+import java.util.Collection; -+import java.util.Collections; -+import java.util.List; -+import java.util.function.Function; -+import net.kyori.adventure.key.Key; -+import net.minecraft.core.Holder; -+import net.minecraft.core.registries.BuiltInRegistries; -+import net.minecraft.resources.ResourceLocation; -+import net.minecraft.sounds.SoundEvent; -+ -+public final class ComponentUtils { -+ -+ private ComponentUtils() { -+ } -+ -+ public static Holder keyToSound(Key key) { -+ ResourceLocation soundId = PaperAdventure.asVanilla(key); -+ return BuiltInRegistries.SOUND_EVENT.wrapAsHolder(BuiltInRegistries.SOUND_EVENT.getOptional(soundId).orElse(SoundEvent.createVariableRangeEvent(soundId))); -+ } -+ -+ public static List transform(final List nms, final Function converter) { -+ return Collections.unmodifiableList(Lists.transform(nms, converter::apply)); -+ } -+ -+ public static Collection transform(final Collection nms, final Function converter) { -+ return Collections.unmodifiableCollection(Collections2.transform(nms, converter::apply)); -+ } -+ -+ public static > void addAndConvert(final C target, final Collection toAdd, final Function 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..f0d4ec462eee47840e91bac888ae46045b493f07 @@ -391,7 +349,7 @@ index 0000000000000000000000000000000000000000..f0d4ec462eee47840e91bac888ae4604 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ItemComponentTypesBridgesImpl.java b/src/main/java/io/papermc/paper/datacomponent/item/ItemComponentTypesBridgesImpl.java new file mode 100644 -index 0000000000000000000000000000000000000000..14d039995a16a2c85569ca09e7f825c7de42fd6b +index 0000000000000000000000000000000000000000..9111c3095986bea43d5eb06763cbe287f6853434 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemComponentTypesBridgesImpl.java @@ -0,0 +1,239 @@ @@ -574,7 +532,7 @@ index 0000000000000000000000000000000000000000..14d039995a16a2c85569ca09e7f825c7 + + @Override + public UseRemainder useRemainder(final ItemStack itemStack) { -+ Preconditions.checkNotNull(itemStack); ++ Preconditions.checkArgument(itemStack != null, "Item cannot be null"); + Preconditions.checkArgument(!itemStack.isEmpty(), "Remaining item cannot be empty!"); + return new PaperUseRemainder( + new net.minecraft.world.item.component.UseRemainder(CraftItemStack.asNMSCopy(itemStack)) @@ -636,7 +594,7 @@ index 0000000000000000000000000000000000000000..14d039995a16a2c85569ca09e7f825c7 +} 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..9fde759d57bb9f54e32ce2e7ac36876079013c2b +index 0000000000000000000000000000000000000000..ca49c2d2e1edcf6c4f7a5ca6c9ba96920aa385f4 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperBannerPatternLayers.java @@ -0,0 +1,62 @@ @@ -663,7 +621,7 @@ index 0000000000000000000000000000000000000000..9fde759d57bb9f54e32ce2e7ac368760 + private static List convert(final net.minecraft.world.level.block.entity.BannerPatternLayers nmsPatterns) { + return MCUtil.transformUnmodifiable(nmsPatterns.layers(), input -> { + final Optional type = CraftRegistry.unwrapAndConvertHolder(RegistryAccess.registryAccess().getRegistry(RegistryKey.BANNER_PATTERN), input.pattern()); -+ return new Pattern(Objects.requireNonNull(DyeColor.getByWoolData((byte) input.color().getId())), type.orElseThrow(() -> new IllegalStateException("Inline banner patterns are not supported yet in the API!"))); ++ return new Pattern(Objects.requireNonNull(DyeColor.getByWoolData((byte) input.color().getId())), type.orElseThrow(() -> new IllegalStateException("Inlined banner patterns are not supported yet in the API!"))); + }); + } + @@ -760,7 +718,7 @@ index 0000000000000000000000000000000000000000..5757e16c5948a6897bc61005ea726094 +} 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..a59a98bdb15d2f4595d5ea651bfdf62542d80b2b +index 0000000000000000000000000000000000000000..ba95ce77dbddb90fd2616c9112fd74051dddc3ee --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperBundleContents.java @@ -0,0 +1,51 @@ @@ -794,7 +752,7 @@ index 0000000000000000000000000000000000000000..a59a98bdb15d2f4595d5ea651bfdf625 + + @Override + public BundleContents.Builder add(final ItemStack stack) { -+ Preconditions.checkNotNull(stack, "stack cannot be null"); ++ Preconditions.checkArgument(stack != null, "stack cannot be null"); + Preconditions.checkArgument(!stack.isEmpty(), "stack cannot be empty"); + this.items.add(CraftItemStack.asNMSCopy(stack)); + return this; @@ -817,7 +775,7 @@ index 0000000000000000000000000000000000000000..a59a98bdb15d2f4595d5ea651bfdf625 +} 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..3aa8b905748f2b82e1c464272d4b9da0c20086ad +index 0000000000000000000000000000000000000000..2129dd67fd02a13f6e6fbdfb07505dc64307a3f0 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperChargedProjectiles.java @@ -0,0 +1,51 @@ @@ -851,7 +809,7 @@ index 0000000000000000000000000000000000000000..3aa8b905748f2b82e1c464272d4b9da0 + + @Override + public ChargedProjectiles.Builder add(final ItemStack stack) { -+ Preconditions.checkNotNull(stack, "stack cannot be null"); ++ Preconditions.checkArgument(stack != null, "stack cannot be null"); + Preconditions.checkArgument(!stack.isEmpty(), "stack cannot be empty"); + this.items.add(CraftItemStack.asNMSCopy(stack)); + return this; @@ -874,10 +832,10 @@ index 0000000000000000000000000000000000000000..3aa8b905748f2b82e1c464272d4b9da0 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperConsumable.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperConsumable.java new file mode 100644 -index 0000000000000000000000000000000000000000..9badd3859745c0090c782fdccdd6fe8830f36b49 +index 0000000000000000000000000000000000000000..0bc2bad71d6945ca24f37008effc903a84466004 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperConsumable.java -@@ -0,0 +1,134 @@ +@@ -0,0 +1,126 @@ +package io.papermc.paper.datacomponent.item; + +import com.google.common.base.Preconditions; @@ -890,8 +848,6 @@ index 0000000000000000000000000000000000000000..9badd3859745c0090c782fdccdd6fe88 +import java.util.List; +import net.kyori.adventure.key.Key; +import net.minecraft.core.Holder; -+import net.minecraft.core.registries.BuiltInRegistries; -+import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import org.bukkit.craftbukkit.util.Handleable; @@ -931,7 +887,7 @@ index 0000000000000000000000000000000000000000..9badd3859745c0090c782fdccdd6fe88 + + @Override + public @Unmodifiable List consumeEffects() { -+ return MCUtil.transformUnmodifiable(impl.onConsumeEffects(), PaperConsumableEffects::fromNms); ++ return MCUtil.transformUnmodifiable(this.impl.onConsumeEffects(), PaperConsumableEffects::fromNms); + } + + @Override @@ -968,13 +924,7 @@ index 0000000000000000000000000000000000000000..9badd3859745c0090c782fdccdd6fe88 + + @Override + public Builder sound(final Key sound) { -+ final ResourceLocation keySound = PaperAdventure.asVanilla(sound); -+ this.eatSound = BuiltInRegistries.SOUND_EVENT.wrapAsHolder( -+ BuiltInRegistries.SOUND_EVENT.getOptional(keySound).orElse( -+ SoundEvent.createVariableRangeEvent(keySound) -+ ) -+ ); -+ ++ this.eatSound = PaperAdventure.resolveSound(sound); + return this; + } + @@ -1065,7 +1015,7 @@ index 0000000000000000000000000000000000000000..adc986c8b3d65e3fb91a8951048194bb +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperDeathProtection.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperDeathProtection.java new file mode 100644 -index 0000000000000000000000000000000000000000..6184acced73d8e99c0fa8b0df03680ad9b84f689 +index 0000000000000000000000000000000000000000..798e45d3b3e895f8b3abb9db1c9d58348bcd22d3 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperDeathProtection.java @@ -0,0 +1,50 @@ @@ -1090,7 +1040,7 @@ index 0000000000000000000000000000000000000000..6184acced73d8e99c0fa8b0df03680ad + + @Override + public @Unmodifiable List deathEffects() { -+ return MCUtil.transformUnmodifiable(impl.deathEffects(), PaperConsumableEffects::fromNms); ++ return MCUtil.transformUnmodifiable(this.impl.deathEffects(), PaperConsumableEffects::fromNms); + } + + static final class BuilderImpl implements Builder { @@ -1203,17 +1153,16 @@ index 0000000000000000000000000000000000000000..422e1a4d606481f0dc68843fbbc8126c +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PaperEquippable.java b/src/main/java/io/papermc/paper/datacomponent/item/PaperEquippable.java new file mode 100644 -index 0000000000000000000000000000000000000000..dbf8d060ab20b9cf31f209f26a8ad4d0cf05d6db +index 0000000000000000000000000000000000000000..ab7947bddfad12d8ae7abcda34f17c3335082a01 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperEquippable.java -@@ -0,0 +1,169 @@ +@@ -0,0 +1,168 @@ +package io.papermc.paper.datacomponent.item; + +import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.set.PaperRegistrySets; +import io.papermc.paper.registry.set.RegistryKeySet; -+import io.papermc.paper.util.MCUtil; +import java.util.Optional; +import net.kyori.adventure.key.Key; +import net.minecraft.core.Holder; @@ -1313,8 +1262,8 @@ index 0000000000000000000000000000000000000000..dbf8d060ab20b9cf31f209f26a8ad4d0 + } + + @Override -+ public Builder equipSound(final Key equipSound) { -+ this.equipSound = MCUtil.keyToSound(equipSound); ++ public Builder equipSound(final Key sound) { ++ this.equipSound = PaperAdventure.resolveSound(sound); + return this; + } + @@ -1378,7 +1327,7 @@ index 0000000000000000000000000000000000000000..dbf8d060ab20b9cf31f209f26a8ad4d0 +} 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..d7002c97086b55af851faaf8c65ad05c75381b02 +index 0000000000000000000000000000000000000000..80189eb5054a044a76f19200eb0e5f316c30de92 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperFireworks.java @@ -0,0 +1,73 @@ @@ -1405,7 +1354,7 @@ index 0000000000000000000000000000000000000000..d7002c97086b55af851faaf8c65ad05c + + @Override + public @Unmodifiable List effects() { -+ return MCUtil.transformUnmodifiable(impl.explosions(), CraftMetaFirework::getEffect); ++ return MCUtil.transformUnmodifiable(this.impl.explosions(), CraftMetaFirework::getEffect); + } + + @Override @@ -1787,7 +1736,7 @@ index 0000000000000000000000000000000000000000..47ca2b8eb1c1483b6049cf18c7d8a40d +} 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..e65603e711ecd08039361d291a0aac761a2f9349 +index 0000000000000000000000000000000000000000..2c4ecc2d5fc925f245c691facde9c96f3b5eef85 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemContainerContents.java @@ -0,0 +1,65 @@ @@ -1821,7 +1770,7 @@ index 0000000000000000000000000000000000000000..e65603e711ecd08039361d291a0aac76 + + @Override + public ItemContainerContents.Builder add(final ItemStack stack) { -+ Preconditions.checkNotNull(stack); ++ Preconditions.checkArgument(stack != null, "Item cannot be null"); + Preconditions.checkArgument( + this.items.size() + 1 <= net.minecraft.world.item.component.ItemContainerContents.MAX_SIZE, + "Cannot have more than %s items, had %s", @@ -1840,9 +1789,9 @@ index 0000000000000000000000000000000000000000..e65603e711ecd08039361d291a0aac76 + net.minecraft.world.item.component.ItemContainerContents.MAX_SIZE, + this.items.size() + stacks.size() + ); -+ MCUtil.addAndConvert(this.items, stacks, itemStack -> { -+ Preconditions.checkNotNull(itemStack, "Cannot pass null itemstacks!"); -+ return CraftItemStack.asNMSCopy(itemStack); ++ MCUtil.addAndConvert(this.items, stacks, stack -> { ++ Preconditions.checkArgument(stack != null, "Cannot pass null itemstacks!"); ++ return CraftItemStack.asNMSCopy(stack); + }); + return this; + } @@ -1956,7 +1905,7 @@ index 0000000000000000000000000000000000000000..3cfb18f6a4868ff32e2b118c5833b1b9 +} 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..8f58b6869bb79428288a4be05424ace4d77c3845 +index 0000000000000000000000000000000000000000..3bb0c1aebb03c8dfd6a76ab60c26cbb104586975 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperItemLore.java @@ -0,0 +1,77 @@ @@ -1984,12 +1933,12 @@ index 0000000000000000000000000000000000000000..8f58b6869bb79428288a4be05424ace4 + + @Override + public @Unmodifiable List lines() { -+ return MCUtil.transformUnmodifiable(impl.lines(), PaperAdventure::asAdventure); ++ return MCUtil.transformUnmodifiable(this.impl.lines(), PaperAdventure::asAdventure); + } + + @Override + public @Unmodifiable List styledLines() { -+ return MCUtil.transformUnmodifiable(impl.styledLines(), PaperAdventure::asAdventure); ++ return MCUtil.transformUnmodifiable(this.impl.styledLines(), PaperAdventure::asAdventure); + } + + static final class BuilderImpl implements ItemLore.Builder { @@ -2145,15 +2094,16 @@ index 0000000000000000000000000000000000000000..538a61eaa02c029b4d92f938e0ffde8a +} 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..eb7209d42e7c44ae7c9b31663aa94ed6cc77f592 +index 0000000000000000000000000000000000000000..c43ccf7ccc6157389fce9f9746d5297f0eab1b6e --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperJukeboxPlayable.java -@@ -0,0 +1,58 @@ +@@ -0,0 +1,62 @@ +package io.papermc.paper.datacomponent.item; + +import net.minecraft.world.item.EitherHolder; +import org.bukkit.JukeboxSong; +import org.bukkit.craftbukkit.CraftJukeboxSong; ++import org.bukkit.craftbukkit.CraftRegistry; +import org.bukkit.craftbukkit.util.Handleable; + +public record PaperJukeboxPlayable( @@ -2177,7 +2127,10 @@ index 0000000000000000000000000000000000000000..eb7209d42e7c44ae7c9b31663aa94ed6 + + @Override + public JukeboxSong jukeboxSong() { -+ return this.impl.song().holder().map(CraftJukeboxSong::minecraftHolderToBukkit).orElseThrow(); ++ return this.impl.song() ++ .unwrap(CraftRegistry.getMinecraftRegistry()) ++ .map(CraftJukeboxSong::minecraftHolderToBukkit) ++ .orElseThrow(); + } + + static final class BuilderImpl implements JukeboxPlayable.Builder { @@ -2550,7 +2503,7 @@ index 0000000000000000000000000000000000000000..bde757b51d0ae6a36870c789d416ec0e +} 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..196297175610644a5a4cad8e619303b4517df274 +index 0000000000000000000000000000000000000000..4712f8bbaa9f00ede895651472d7975ffa30c88d --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperPotionContents.java @@ -0,0 +1,103 @@ @@ -2582,7 +2535,7 @@ index 0000000000000000000000000000000000000000..196297175610644a5a4cad8e619303b4 + + @Override + public @Unmodifiable List customEffects() { -+ return MCUtil.transformUnmodifiable(impl.customEffects(), CraftPotionUtil::toBukkit); ++ return MCUtil.transformUnmodifiable(this.impl.customEffects(), CraftPotionUtil::toBukkit); + } + + @Override @@ -2687,7 +2640,7 @@ index 0000000000000000000000000000000000000000..96345e051c4aa77820e857a02768b684 +} 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..2c59b17f58502402c3234289b38da28672244cbb +index 0000000000000000000000000000000000000000..7583a7efb4bfdb0157ee27a1b7cfb661eeccb02a --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperResolvableProfile.java @@ -0,0 +1,105 @@ @@ -2734,7 +2687,7 @@ index 0000000000000000000000000000000000000000..2c59b17f58502402c3234289b38da286 + + @Override + public @Unmodifiable Collection properties() { -+ return MCUtil.transformUnmodifiable(impl.properties().values(), input -> new ProfileProperty(input.name(), input.value(), input.signature())); ++ return MCUtil.transformUnmodifiable(this.impl.properties().values(), input -> new ProfileProperty(input.name(), input.value(), input.signature())); + } + + @Override @@ -2863,7 +2816,7 @@ index 0000000000000000000000000000000000000000..1ee469b3b690a877e066dbca79706678 +} 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..69801d8f22945b9818299d8e770fe80a28da7018 +index 0000000000000000000000000000000000000000..41df23c7e7e713e88eef757fda347381e151b0fc --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperSuspiciousStewEffects.java @@ -0,0 +1,58 @@ @@ -2891,7 +2844,7 @@ index 0000000000000000000000000000000000000000..69801d8f22945b9818299d8e770fe80a + + @Override + public @Unmodifiable List effects() { -+ return MCUtil.transformUnmodifiable(impl.effects(), entry -> create(CraftPotionEffectType.minecraftHolderToBukkit(entry.effect()), entry.duration())); ++ return MCUtil.transformUnmodifiable(this.impl.effects(), entry -> create(CraftPotionEffectType.minecraftHolderToBukkit(entry.effect()), entry.duration())); + } + + static final class BuilderImpl implements Builder { @@ -3060,10 +3013,10 @@ index 0000000000000000000000000000000000000000..c2c04506940704c2ec9a5e6bb469c477 +} 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..563ac5345efe68cfe223853df13d5f07cc48e850 +index 0000000000000000000000000000000000000000..559343a33bada475cc5bbcd431cd88b537c8cef7 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperWritableBookContent.java -@@ -0,0 +1,105 @@ +@@ -0,0 +1,103 @@ +package io.papermc.paper.datacomponent.item; + +import com.google.common.base.Preconditions; @@ -3076,8 +3029,6 @@ index 0000000000000000000000000000000000000000..563ac5345efe68cfe223853df13d5f07 +import org.bukkit.craftbukkit.util.Handleable; +import org.jetbrains.annotations.Unmodifiable; + -+import static io.papermc.paper.text.Filtered.of; -+ +public record PaperWritableBookContent( + net.minecraft.world.item.component.WritableBookContent impl +) implements WritableBookContent, Handleable { @@ -3089,7 +3040,7 @@ index 0000000000000000000000000000000000000000..563ac5345efe68cfe223853df13d5f07 + + @Override + public @Unmodifiable List> pages() { -+ return MCUtil.transformUnmodifiable(impl.pages(), input -> of(input.raw(), input.filtered().orElse(null))); ++ return MCUtil.transformUnmodifiable(this.impl.pages(), input -> Filtered.of(input.raw(), input.filtered().orElse(null))); + } + + static final class BuilderImpl implements WritableBookContent.Builder { @@ -3171,7 +3122,7 @@ index 0000000000000000000000000000000000000000..563ac5345efe68cfe223853df13d5f07 +} 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..e6ce137806cd789586108fef5a5da508b19b7131 +index 0000000000000000000000000000000000000000..037a6695bdb8ee6e3c119fa79000c4ea28e1bef8 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/PaperWrittenBookContent.java @@ -0,0 +1,183 @@ @@ -3222,7 +3173,7 @@ index 0000000000000000000000000000000000000000..e6ce137806cd789586108fef5a5da508 + @Override + public @Unmodifiable List> pages() { + return MCUtil.transformUnmodifiable( -+ impl.pages(), ++ this.impl.pages(), + page -> Filtered.of(asAdventure(page.raw()), page.filtered().map(PaperAdventure::asAdventure).orElse(null)) + ); + } @@ -3360,19 +3311,19 @@ index 0000000000000000000000000000000000000000..e6ce137806cd789586108fef5a5da508 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumableTypesBridgeImpl.java b/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumableTypesBridgeImpl.java new file mode 100644 -index 0000000000000000000000000000000000000000..c96cb39cf21ebe33d09733affc3cb031d94213f2 +index 0000000000000000000000000000000000000000..e11e7b36c0b0b499a6149c44ca2ad9f331d1b863 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumableTypesBridgeImpl.java -@@ -0,0 +1,66 @@ +@@ -0,0 +1,64 @@ +package io.papermc.paper.datacomponent.item.consumable; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; ++import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.registry.set.PaperRegistrySets; +import io.papermc.paper.registry.set.RegistryKeySet; +import java.util.ArrayList; +import java.util.List; -+import io.papermc.paper.util.MCUtil; +import net.kyori.adventure.key.Key; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; @@ -3416,9 +3367,7 @@ index 0000000000000000000000000000000000000000..c96cb39cf21ebe33d09733affc3cb031 + @Override + public ConsumeEffect.PlaySound playSoundEffect(final Key sound) { + return new PaperPlaySound( -+ new net.minecraft.world.item.consume_effects.PlaySoundConsumeEffect( -+ MCUtil.keyToSound(sound) -+ ) ++ new net.minecraft.world.item.consume_effects.PlaySoundConsumeEffect(PaperAdventure.resolveSound(sound)) + ); + } + @@ -3432,7 +3381,7 @@ index 0000000000000000000000000000000000000000..c96cb39cf21ebe33d09733affc3cb031 +} diff --git a/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperApplyStatusEffects.java b/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperApplyStatusEffects.java new file mode 100644 -index 0000000000000000000000000000000000000000..465bec185aad849f283aae39bc23e9ba7a052371 +index 0000000000000000000000000000000000000000..0d2a4ba560f5a34139517ac2e17667c94a3c56f6 --- /dev/null +++ b/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperApplyStatusEffects.java @@ -0,0 +1,28 @@ @@ -3443,7 +3392,7 @@ index 0000000000000000000000000000000000000000..465bec185aad849f283aae39bc23e9ba +import org.bukkit.craftbukkit.potion.CraftPotionUtil; +import org.bukkit.potion.PotionEffect; + -+import static io.papermc.paper.datacomponent.ComponentUtils.transform; ++import static io.papermc.paper.util.MCUtil.transformUnmodifiable; + +public record PaperApplyStatusEffects( + ApplyStatusEffectsConsumeEffect impl @@ -3451,7 +3400,7 @@ index 0000000000000000000000000000000000000000..465bec185aad849f283aae39bc23e9ba + + @Override + public List effects() { -+ return transform(this.impl().effects(), CraftPotionUtil::toBukkit); ++ return transformUnmodifiable(this.impl().effects(), CraftPotionUtil::toBukkit); + } + + @Override @@ -3640,19 +3589,19 @@ index 0000000000000000000000000000000000000000..62aa1061c35d5358e6dec16a52574b42 + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/src/main/java/io/papermc/paper/registry/PaperRegistries.java -index f8c6da955e4bd0e480c7b581d2a4325738f9dd6f..ee1fce58c6e57dd93a30ee66e7488a92f9da2fe3 100644 +index 31d660bbbe62cd2c26715e8d90fef58b8e024e34..7e5d1d4f563dfd4beef9cd73b3670714c96bacaf 100644 --- a/src/main/java/io/papermc/paper/registry/PaperRegistries.java +++ b/src/main/java/io/papermc/paper/registry/PaperRegistries.java -@@ -1,6 +1,8 @@ - package io.papermc.paper.registry; +@@ -2,6 +2,8 @@ package io.papermc.paper.registry; + import com.google.common.base.Preconditions; import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.datacomponent.DataComponentType; +import io.papermc.paper.datacomponent.PaperComponentType; import io.papermc.paper.registry.data.PaperEnchantmentRegistryEntry; import io.papermc.paper.registry.data.PaperGameEventRegistryEntry; - import io.papermc.paper.registry.entry.RegistryEntry; -@@ -96,6 +98,7 @@ public final class PaperRegistries { + import io.papermc.paper.registry.data.PaperPaintingVariantRegistryEntry; +@@ -98,6 +100,7 @@ public final class PaperRegistries { entry(Registries.ATTRIBUTE, RegistryKey.ATTRIBUTE, Attribute.class, CraftAttribute::new), entry(Registries.FLUID, RegistryKey.FLUID, Fluid.class, CraftFluid::new), entry(Registries.SOUND_EVENT, RegistryKey.SOUND_EVENT, Sound.class, CraftSound::new), @@ -3661,7 +3610,7 @@ index f8c6da955e4bd0e480c7b581d2a4325738f9dd6f..ee1fce58c6e57dd93a30ee66e7488a92 // data-drivens entry(Registries.BIOME, RegistryKey.BIOME, Biome.class, CraftBiome::new).delayed(), diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index 756c73a401437566258813946fa10c7caa8f2469..bfddaa146c1bcb6a3fdd43773ec06f91a259b200 100644 +index 756c73a401437566258813946fa10c7caa8f2469..ccad5a7018f6eaacb011818e9da990c75e0d06df 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -206,7 +206,7 @@ public final class CraftItemStack extends ItemStack { @@ -3678,7 +3627,7 @@ index 756c73a401437566258813946fa10c7caa8f2469..bfddaa146c1bcb6a3fdd43773ec06f91 @Override public int getMaxStackSize() { - return (this.handle == null) ? Material.AIR.getMaxStackSize() : this.handle.getMaxStackSize(); -+ return (this.handle == null) ? 64 : this.handle.getMaxStackSize(); // Paper - air stacks to 64 ++ return (this.handle == null) ? Item.DEFAULT_MAX_STACK_SIZE : this.handle.getMaxStackSize(); // Paper - air stacks to 64 } // Paper start @@ -3876,9 +3825,18 @@ index 756c73a401437566258813946fa10c7caa8f2469..bfddaa146c1bcb6a3fdd43773ec06f91 + // Paper end - data component API } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java -index 1b57649d0d3db24ed32c78cf3d5ce1d9fb1353e0..ce1287edd7db00279ec8569d767ab6272c8ae3fb 100644 +index 1b57649d0d3db24ed32c78cf3d5ce1d9fb1353e0..674ec11b77f41905e3744c22b2ee2d828b0693ad 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java +@@ -150,7 +150,7 @@ public class CraftItemType implements ItemType.Typed, Han + public int getMaxStackSize() { + // Based of the material enum air is only 0, in PerMaterialTest it is also set as special case + // the item info itself would return 64 +- if (this == AIR) { ++ if (false && this == AIR) { // Paper - air stacks to 64 + return 0; + } + return this.item.components().getOrDefault(DataComponents.MAX_STACK_SIZE, 64); @@ -270,4 +270,20 @@ public class CraftItemType implements ItemType.Typed, Han return rarity == null ? null : org.bukkit.inventory.ItemRarity.valueOf(rarity.name()); } @@ -4100,10 +4058,10 @@ index 0000000000000000000000000000000000000000..4ee0491763341232844a99aa528310a3 +} 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..5825be69af0b949ce28d6bde28bef68935db0d45 +index 0000000000000000000000000000000000000000..06597cc8ba23e0e1e439af5b6cbc2a7fac3c4022 --- /dev/null +++ b/src/test/java/io/papermc/paper/item/ItemStackDataComponentTest.java -@@ -0,0 +1,371 @@ +@@ -0,0 +1,416 @@ +package io.papermc.paper.item; + +import io.papermc.paper.datacomponent.DataComponentType; @@ -4127,8 +4085,18 @@ index 0000000000000000000000000000000000000000..5825be69af0b949ce28d6bde28bef689 +import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.set.RegistrySet; +import io.papermc.paper.registry.tag.TagKey; ++import java.util.List; ++import java.util.Map; ++import java.util.function.BiConsumer; ++import java.util.function.Function; ++import net.kyori.adventure.key.Key; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.util.TriState; ++import net.minecraft.core.component.DataComponents; ++import net.minecraft.core.registries.Registries; ++import net.minecraft.world.item.EitherHolder; ++import net.minecraft.world.item.Items; ++import net.minecraft.world.item.JukeboxSongs; +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.JukeboxSong; @@ -4140,6 +4108,7 @@ index 0000000000000000000000000000000000000000..5825be69af0b949ce28d6bde28bef689 +import org.bukkit.block.BlockState; +import org.bukkit.block.BlockType; +import org.bukkit.block.DecoratedPot; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.EquipmentSlotGroup; +import org.bukkit.inventory.ItemFlag; @@ -4152,6 +4121,7 @@ index 0000000000000000000000000000000000000000..5825be69af0b949ce28d6bde28bef689 +import org.bukkit.inventory.meta.Damageable; +import org.bukkit.inventory.meta.FireworkMeta; +import org.bukkit.inventory.meta.ItemMeta; ++import org.bukkit.inventory.meta.KnowledgeBookMeta; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.bukkit.inventory.meta.MapMeta; +import org.bukkit.inventory.meta.Repairable; @@ -4161,13 +4131,10 @@ index 0000000000000000000000000000000000000000..5825be69af0b949ce28d6bde28bef689 +import org.bukkit.inventory.meta.trim.ArmorTrim; +import org.bukkit.inventory.meta.trim.TrimMaterial; +import org.bukkit.inventory.meta.trim.TrimPattern; ++import org.bukkit.support.RegistryHelper; +import org.bukkit.support.environment.AllFeatures; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; -+import java.util.List; -+import java.util.Map; -+import java.util.function.BiConsumer; -+import java.util.function.Function; + +@AllFeatures +class ItemStackDataComponentTest { @@ -4437,6 +4404,42 @@ index 0000000000000000000000000000000000000000..5825be69af0b949ce28d6bde28bef689 + Assertions.assertTrue(decoratedPot.getSherds().values().stream().allMatch((m) -> m.asItemType() == ItemType.BRICK)); + } + ++ @Test ++ void testRecipes() { ++ final ItemStack stack = new ItemStack(Material.KNOWLEDGE_BOOK); ++ stack.setData(DataComponentTypes.RECIPES, List.of(Key.key("paper:fun_recipe"))); ++ ++ final ItemMeta itemMeta = stack.getItemMeta(); ++ Assertions.assertInstanceOf(KnowledgeBookMeta.class, itemMeta); ++ ++ final List recipes = ((KnowledgeBookMeta) itemMeta).getRecipes(); ++ Assertions.assertEquals(recipes, List.of(new NamespacedKey("paper", "fun_recipe"))); ++ } ++ ++ @Test ++ void testJukeboxWithEitherKey() { ++ final ItemStack apiStack = CraftItemStack.asBukkitCopy(new net.minecraft.world.item.ItemStack(Items.MUSIC_DISC_5)); ++ final JukeboxPlayable data = apiStack.getData(DataComponentTypes.JUKEBOX_PLAYABLE); ++ ++ Assertions.assertNotNull(data); ++ Assertions.assertEquals(JukeboxSong.FIVE, data.jukeboxSong()); ++ } ++ ++ @Test ++ void testJukeboxWithEitherHolder() { ++ final net.minecraft.world.item.ItemStack internalStack = new net.minecraft.world.item.ItemStack(Items.STONE); ++ internalStack.set(DataComponents.JUKEBOX_PLAYABLE, new net.minecraft.world.item.JukeboxPlayable( ++ new EitherHolder<>(RegistryHelper.getRegistry().lookupOrThrow(Registries.JUKEBOX_SONG).getOrThrow(JukeboxSongs.FIVE)), ++ true ++ )); ++ ++ final ItemStack apiStack = CraftItemStack.asBukkitCopy(internalStack); ++ final JukeboxPlayable data = apiStack.getData(DataComponentTypes.JUKEBOX_PLAYABLE); ++ ++ Assertions.assertNotNull(data); ++ Assertions.assertEquals(JukeboxSong.FIVE, data.jukeboxSong()); ++ } ++ + private static void testWithMeta(final ItemStack stack, final DataComponentType.Valued type, final T value, final Class metaType, final Function metaGetter, final BiConsumer metaSetter) { + testWithMeta(stack, type, value, Function.identity(), metaType, metaGetter, metaSetter); + } @@ -4477,14 +4480,16 @@ index 0000000000000000000000000000000000000000..5825be69af0b949ce28d6bde28bef689 +} 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..1225ad95a204434ef6af5e6e92593cbbafc31b4a +index 0000000000000000000000000000000000000000..7cda79980729770695451adcd03b1886f60d86e3 --- /dev/null +++ b/src/test/java/io/papermc/paper/item/MetaComparisonTest.java -@@ -0,0 +1,284 @@ +@@ -0,0 +1,281 @@ +package io.papermc.paper.item; + +import com.destroystokyo.paper.profile.CraftPlayerProfile; +import com.destroystokyo.paper.profile.PlayerProfile; ++import java.util.UUID; ++import java.util.function.Consumer; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.HoverEvent; +import net.kyori.adventure.text.format.NamedTextColor; @@ -4508,9 +4513,6 @@ index 0000000000000000000000000000000000000000..1225ad95a204434ef6af5e6e92593cbb +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 +@AllFeatures +public class MetaComparisonTest { @@ -4751,9 +4753,7 @@ index 0000000000000000000000000000000000000000..1225ad95a204434ef6af5e6e92593cbb + ); + } + -+ private void testSetAndGet(org.bukkit.inventory.ItemStack itemStack, -+ Consumer set, -+ Consumer get) { ++ private void testSetAndGet(ItemStack itemStack, Consumer set, Consumer get) { + ItemMeta craftMeta = CraftItemStack.getItemMeta(CraftItemStack.asNMSCopy(itemStack)); // TODO: This should be converted to use the old meta when this is added. + ItemMeta paperMeta = CraftItemStack.getItemMeta(CraftItemStack.asNMSCopy(itemStack)); + // Test craft meta diff --git a/patches/server/1037-Rewrite-dataconverter-system.patch b/patches/server/1037-Rewrite-dataconverter-system.patch index 71437e89b2..7f88441f12 100644 --- a/patches/server/1037-Rewrite-dataconverter-system.patch +++ b/patches/server/1037-Rewrite-dataconverter-system.patch @@ -30384,7 +30384,7 @@ index b54a3741cd3ba615c83c98985cb4b3c4c586ed7a..b148cf247acdd36f856d0495cde4cc5a return nbttagcompound; }); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 29d5fa49730d2161bb1b024995a533a08c57939b..83020837e29ee627b1081daddb4bdee147b95af3 100644 +index 4c82dae4c2d764c8310832b1a209846d4352bae9..507f908916cbeb592496f963b46e4c2121a7b5e3 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -523,7 +523,7 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/1053-Optional-per-player-mob-spawns.patch b/patches/server/1053-Optional-per-player-mob-spawns.patch index 90f5fa951b..45f24f3663 100644 --- a/patches/server/1053-Optional-per-player-mob-spawns.patch +++ b/patches/server/1053-Optional-per-player-mob-spawns.patch @@ -38,7 +38,7 @@ index f1999729cd1c00071c5e1835ee49ea5fcafa7b05..4896c3ba81ead769972fa9efdbe563d4 // Paper end diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 38ac7fd8e68f535a5e9bdd816997e865b7694af1..b1ecc218034944533967375d11297705c3fc01a3 100644 +index 10a9406e96ab0ab2404c0e0a9bef08e86a6a12a2..078a14ee8956a56b129be92a26d19c1c536c9589 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -492,7 +492,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon diff --git a/patches/server/1054-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch b/patches/server/1054-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch index a4379980b1..9980b9f1cb 100644 --- a/patches/server/1054-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch +++ b/patches/server/1054-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch @@ -37,7 +37,7 @@ index 4896c3ba81ead769972fa9efdbe563d4006e4401..5b3a886c624b36557cbfaccdc3fb05a4 } // Paper end diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index b1ecc218034944533967375d11297705c3fc01a3..aaaadb7be8abf867624a1ca83371595bef4ab633 100644 +index 078a14ee8956a56b129be92a26d19c1c536c9589..61a73a234d9bdd22958ae261b7d0359179f7a57b 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -555,7 +555,17 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon diff --git a/patches/server/1061-Improve-exact-choice-recipe-ingredients.patch b/patches/server/1061-Improve-exact-choice-recipe-ingredients.patch index a7270cced5..eaed7d5bad 100644 --- a/patches/server/1061-Improve-exact-choice-recipe-ingredients.patch +++ b/patches/server/1061-Improve-exact-choice-recipe-ingredients.patch @@ -13,7 +13,7 @@ public net.minecraft.world.item.ItemStackLinkedSet TYPE_AND_TAG diff --git a/src/main/java/io/papermc/paper/inventory/recipe/ItemOrExact.java b/src/main/java/io/papermc/paper/inventory/recipe/ItemOrExact.java new file mode 100644 -index 0000000000000000000000000000000000000000..5bcc814d5a1b88991e9c1324b88a919ca199fcda +index 0000000000000000000000000000000000000000..caaad8f54fb892dfd6c7d4e02ab9c32997f89a6a --- /dev/null +++ b/src/main/java/io/papermc/paper/inventory/recipe/ItemOrExact.java @@ -0,0 +1,63 @@ @@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..5bcc814d5a1b88991e9c1324b88a919c + + int getMaxStackSize(); + -+ boolean is(ItemStack stack); ++ boolean matches(ItemStack stack); + + record Item(Holder item) implements ItemOrExact { + @@ -40,8 +40,8 @@ index 0000000000000000000000000000000000000000..5bcc814d5a1b88991e9c1324b88a919c + } + + @Override -+ public boolean is(final ItemStack stack) { -+ return stack.is(this.item); ++ public boolean matches(final ItemStack stack) { ++ return stack.is(this.item) && stack.getComponentsPatch().isEmpty(); + } + + @Override @@ -64,7 +64,7 @@ index 0000000000000000000000000000000000000000..5bcc814d5a1b88991e9c1324b88a919c + } + + @Override -+ public boolean is(final ItemStack stack) { ++ public boolean matches(final ItemStack stack) { + return ItemStack.isSameItemSameComponents(this.stack, stack); + } + @@ -196,7 +196,7 @@ index 462a970ffa610bc1eb3c813dafb768c014d077d1..1afb544fb028b645821063ba1eaa9e3c if (i == -1) { return -1; diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java -index ad82e5aeb565b23c3ec565fa60e1f31d1710bd4e..0e214d502998e9eb959952b257844529992df0df 100644 +index ad82e5aeb565b23c3ec565fa60e1f31d1710bd4e..0990bcf65f484b9a019c91fcdae1783bac6388da 100644 --- a/src/main/java/net/minecraft/world/entity/player/Inventory.java +++ b/src/main/java/net/minecraft/world/entity/player/Inventory.java @@ -201,11 +201,11 @@ public class Inventory implements Container, Nameable { @@ -209,7 +209,7 @@ index ad82e5aeb565b23c3ec565fa60e1f31d1710bd4e..0e214d502998e9eb959952b257844529 ItemStack itemstack = (ItemStack) this.items.get(i); - if (!itemstack.isEmpty() && itemstack.is(item) && Inventory.isUsableForCrafting(itemstack)) { -+ if (!itemstack.isEmpty() && item.is(itemstack) && (!(item instanceof io.papermc.paper.inventory.recipe.ItemOrExact.Item) || isUsableForCrafting(itemstack))) { // Paper - Improve exact choice recipe ingredients ++ if (!itemstack.isEmpty() && item.matches(itemstack) && (!(item instanceof io.papermc.paper.inventory.recipe.ItemOrExact.Item) || isUsableForCrafting(itemstack))) { // Paper - Improve exact choice recipe ingredients return i; } } diff --git a/patches/server/1070-Configurable-Entity-Despawn-Time.patch b/patches/server/1070-Configurable-Entity-Despawn-Time.patch new file mode 100644 index 0000000000..9f3d4aa488 --- /dev/null +++ b/patches/server/1070-Configurable-Entity-Despawn-Time.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kevin Raneri +Date: Mon, 30 Sep 2024 09:50:55 -0700 +Subject: [PATCH] Configurable Entity Despawn Time + + +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index 8be1b051543cda2b2e9e3d337834757e53f442de..ed5b00620527c1776722d25b1b45f1544802a341 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -432,6 +432,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + private UUID originWorld; + public boolean freezeLocked = false; // Paper - Freeze Tick Lock API + public boolean fixedPose = false; // Paper - Expand Pose API ++ private final int despawnTime; // Paper - entity despawn time limit + + public void setOrigin(@javax.annotation.Nonnull Location location) { + this.origin = location.toVector(); +@@ -614,6 +615,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + + public Entity(EntityType type, Level world) { + this.id = Entity.ENTITY_COUNTER.incrementAndGet(); ++ this.despawnTime = type == EntityType.PLAYER ? -1 : world.paperConfig().entities.spawning.despawnTime.getOrDefault(type, io.papermc.paper.configuration.type.number.IntOr.Disabled.DISABLED).or(-1); // Paper - entity despawn time limit + this.passengers = ImmutableList.of(); + this.deltaMovement = Vec3.ZERO; + this.bb = Entity.INITIAL_AABB; +@@ -912,6 +914,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + + public void tick() { ++ // Paper start - entity despawn time limit ++ if (this.despawnTime >= 0 && this.tickCount >= this.despawnTime) { ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); ++ return; ++ } ++ // Paper end - entity despawn time limit + this.baseTick(); + } + diff --git a/patches/server/1071-Expanded-Art-API.patch b/patches/server/1071-Expanded-Art-API.patch new file mode 100644 index 0000000000..a088282574 --- /dev/null +++ b/patches/server/1071-Expanded-Art-API.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: kokiriglade <60290002+celerry@users.noreply.github.com> +Date: Sat, 23 Nov 2024 18:58:49 +0000 +Subject: [PATCH] Expanded Art API + + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftArt.java b/src/main/java/org/bukkit/craftbukkit/CraftArt.java +index 40af940193d0df66bbcdcf5f46132e304016a4d7..932118f5e5bfc765c852acaf21f9721d8fa5fb6a 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftArt.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftArt.java +@@ -42,6 +42,9 @@ public class CraftArt implements Art, Handleable { + + private final NamespacedKey key; + private final PaintingVariant paintingVariant; ++ private final net.kyori.adventure.text.@org.jspecify.annotations.Nullable Component adventureTitle; // Paper - name and author components, assetId key ++ private final net.kyori.adventure.text.@org.jspecify.annotations.Nullable Component adventureAuthor; // Paper - name and author components, assetId key ++ private final net.kyori.adventure.key.@org.jspecify.annotations.NonNull Key adventureAssetId; // Paper - name and author components, assetId key + private final String name; + private final int ordinal; + +@@ -58,6 +61,9 @@ public class CraftArt implements Art, Handleable { + this.name = key.toString(); + } + this.ordinal = CraftArt.count++; ++ this.adventureTitle = paintingVariant.title().map(io.papermc.paper.adventure.PaperAdventure::asAdventure).orElse(null); // Paper - name and author components, assetId key ++ this.adventureAuthor = paintingVariant.author().map(io.papermc.paper.adventure.PaperAdventure::asAdventure).orElse(null); // Paper - name and author components, assetId key ++ this.adventureAssetId = io.papermc.paper.adventure.PaperAdventure.asAdventure(paintingVariant.assetId()); // Paper - name and author components, assetId key + } + + @Override +@@ -75,6 +81,22 @@ public class CraftArt implements Art, Handleable { + return this.paintingVariant.height(); + } + ++ // Paper start - name and author components, assetId key ++ @Override ++ public net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component title() { ++ return this.adventureTitle; ++ } ++ ++ @Override ++ public net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component author() { ++ return this.adventureAuthor; ++ } ++ ++ public net.kyori.adventure.key.@org.jspecify.annotations.NonNull Key assetId() { ++ return this.adventureAssetId; ++ } ++ // Paper end - name and author components, assetId key ++ + @Override + public int getId() { + return CraftRegistry.getMinecraftRegistry(Registries.PAINTING_VARIANT).getId(this.paintingVariant); diff --git a/patches/server/1072-Call-ProjectileHitEvent-for-entity-hits.patch b/patches/server/1072-Call-ProjectileHitEvent-for-entity-hits.patch new file mode 100644 index 0000000000..7d6bd931cb --- /dev/null +++ b/patches/server/1072-Call-ProjectileHitEvent-for-entity-hits.patch @@ -0,0 +1,22 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Bjarne Koll +Date: Sat, 23 Nov 2024 22:48:26 +0100 +Subject: [PATCH] Call ProjectileHitEvent for entity hits + +A simple bugfix replacing a new vanilla call to +Projectile#hitTargetOrDeflectSelf with the bukkit replacement to call +the event. + +diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +index accc246f441c8bf5e1a755cfc0db8f97c0c01c6b..571f0699772eecbe02d71845da82a142321f2142 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +@@ -309,7 +309,7 @@ public abstract class AbstractArrow extends Projectile { + continue; + } + +- ProjectileDeflection projectiledeflection = this.hitTargetOrDeflectSelf(movingobjectpositionentity); ++ ProjectileDeflection projectiledeflection = this.preHitTargetOrDeflectSelf(movingobjectpositionentity); // Paper - also call projectile hit event + + this.hasImpulse = true; + if (this.getPierceLevel() > 0 && projectiledeflection == ProjectileDeflection.NONE) {