diff options
11 files changed, 875 insertions, 338 deletions
diff --git a/patches/api/0003-Test-changes.patch b/patches/api/0003-Test-changes.patch index 41dfb8bc77..7649a1904f 100644 --- a/patches/api/0003-Test-changes.patch +++ b/patches/api/0003-Test-changes.patch @@ -102,7 +102,7 @@ index 0000000000000000000000000000000000000000..77154095cfb8b259bdb318e8ff40cb6f + } +} diff --git a/src/test/java/org/bukkit/AnnotationTest.java b/src/test/java/org/bukkit/AnnotationTest.java -index 64e7aef6220097edefdff3b98a771b988365930d..f8b8969ee7a0b6f7b3224ff081e35c14a398c9d0 100644 +index 64e7aef6220097edefdff3b98a771b988365930d..07f904a78f51b220a5891aca1afffac4f46d58b4 100644 --- a/src/test/java/org/bukkit/AnnotationTest.java +++ b/src/test/java/org/bukkit/AnnotationTest.java @@ -29,7 +29,13 @@ public class AnnotationTest { @@ -200,7 +200,7 @@ index 64e7aef6220097edefdff3b98a771b988365930d..f8b8969ee7a0b6f7b3224ff081e35c14 ParameterNode paramNode = parameters == null ? null : parameters.get(i); String paramName = paramNode == null ? null : paramNode.name; -@@ -91,13 +147,18 @@ public class AnnotationTest { +@@ -91,17 +147,37 @@ public class AnnotationTest { Collections.sort(errors); @@ -223,7 +223,26 @@ index 64e7aef6220097edefdff3b98a771b988365930d..f8b8969ee7a0b6f7b3224ff081e35c14 } private static void collectClasses(@NotNull File from, @NotNull Map<String, ClassNode> to) throws IOException { -@@ -125,6 +186,23 @@ public class AnnotationTest { + if (from.isDirectory()) { ++ // Paper start - skip packages with @NullMarked ++ final File packageInfo = new File(from, "package-info.class"); ++ if (packageInfo.exists()) { ++ try (final FileInputStream in = new FileInputStream(packageInfo)) { ++ final ClassReader cr = new ClassReader(in); ++ ++ final ClassNode node = new ClassNode(); ++ cr.accept(node, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); ++ ++ if (isClassNullMarked0(node)) { ++ return; // skip packages with @NullMarked ++ } ++ } ++ } ++ // Paper end - skip packages with @NullMarked + final File[] files = from.listFiles(); + assert files != null; + +@@ -125,6 +201,23 @@ public class AnnotationTest { } } @@ -247,7 +266,7 @@ index 64e7aef6220097edefdff3b98a771b988365930d..f8b8969ee7a0b6f7b3224ff081e35c14 private static boolean isClassIncluded(@NotNull ClassNode clazz, @NotNull Map<String, ClassNode> allClasses) { // Exclude private, synthetic or deprecated classes and annotations, since their members can't be null if ((clazz.access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_DEPRECATED | Opcodes.ACC_ANNOTATION)) != 0) { -@@ -140,6 +218,11 @@ public class AnnotationTest { +@@ -140,6 +233,11 @@ public class AnnotationTest { // Exceptions are excluded return false; } @@ -259,7 +278,7 @@ index 64e7aef6220097edefdff3b98a771b988365930d..f8b8969ee7a0b6f7b3224ff081e35c14 for (String excludedClass : EXCLUDED_CLASSES) { if (excludedClass.equals(clazz.name)) { -@@ -152,7 +235,7 @@ public class AnnotationTest { +@@ -152,7 +250,7 @@ public class AnnotationTest { private static boolean isMethodIncluded(@NotNull ClassNode clazz, @NotNull MethodNode method, @NotNull Map<String, ClassNode> allClasses) { // Exclude private, synthetic and deprecated methods @@ -268,7 +287,7 @@ index 64e7aef6220097edefdff3b98a771b988365930d..f8b8969ee7a0b6f7b3224ff081e35c14 return false; } -@@ -170,11 +253,30 @@ public class AnnotationTest { +@@ -170,11 +268,30 @@ public class AnnotationTest { if ("<init>".equals(method.name) && isAnonymous(clazz)) { return false; } diff --git a/patches/api/0472-Introduce-registry-entry-and-builders.patch b/patches/api/0472-Introduce-registry-entry-and-builders.patch index 7528cb4dc3..5a49b02971 100644 --- a/patches/api/0472-Introduce-registry-entry-and-builders.patch +++ b/patches/api/0472-Introduce-registry-entry-and-builders.patch @@ -24,10 +24,10 @@ index 647f6a1ec1f9d3c203b41f90a99bfd415bf67366..9b39e33514b15a9d07104e2ad826d0da * Built-in registry for cat variants. diff --git a/src/main/java/io/papermc/paper/registry/data/EnchantmentRegistryEntry.java b/src/main/java/io/papermc/paper/registry/data/EnchantmentRegistryEntry.java new file mode 100644 -index 0000000000000000000000000000000000000000..f092077453cb13dd8d849550896c2ef1cfa81b7a +index 0000000000000000000000000000000000000000..a9d6447110ae3979be049258ce529b56bb8c3c5b --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/data/EnchantmentRegistryEntry.java -@@ -0,0 +1,331 @@ +@@ -0,0 +1,329 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.RegistryBuilder; @@ -45,14 +45,12 @@ index 0000000000000000000000000000000000000000..f092077453cb13dd8d849550896c2ef1 +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Range; +import org.jetbrains.annotations.Unmodifiable; -+import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +/** + * A data-centric version-specific registry entry for the {@link Enchantment} type. + */ -+@NullMarked +public interface EnchantmentRegistryEntry { + @@ -361,10 +359,10 @@ index 0000000000000000000000000000000000000000..f092077453cb13dd8d849550896c2ef1 +} diff --git a/src/main/java/io/papermc/paper/registry/data/GameEventRegistryEntry.java b/src/main/java/io/papermc/paper/registry/data/GameEventRegistryEntry.java new file mode 100644 -index 0000000000000000000000000000000000000000..980fe12b75258b51cc2498590cadb9de80805b1f +index 0000000000000000000000000000000000000000..c5051075657f606c3ca81373671bce6bb138309f --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/data/GameEventRegistryEntry.java -@@ -0,0 +1,49 @@ +@@ -0,0 +1,47 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.RegistryBuilder; @@ -372,13 +370,11 @@ index 0000000000000000000000000000000000000000..980fe12b75258b51cc2498590cadb9de +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Range; -+import org.jspecify.annotations.NullMarked; + +/** + * A data-centric version-specific registry entry for the {@link GameEvent} type. + */ -+@NullMarked +public interface GameEventRegistryEntry { + @@ -416,28 +412,25 @@ index 0000000000000000000000000000000000000000..980fe12b75258b51cc2498590cadb9de +} 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..4e2c99acd7dc307981ba8e33a62835f0f29fd73e +index 0000000000000000000000000000000000000000..a42dd7cd8700f696128cb6ec5b8b878f7d3acd7f --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/data/PaintingVariantRegistryEntry.java -@@ -0,0 +1,131 @@ +@@ -0,0 +1,128 @@ +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. + */ -+@NullMarked +public interface PaintingVariantRegistryEntry { + @@ -553,10 +546,10 @@ index 0000000000000000000000000000000000000000..4e2c99acd7dc307981ba8e33a62835f0 +} 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 +index 0000000000000000000000000000000000000000..ddc1d8a7983bfd5117a6ac90d64f0681500596ce --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/data/package-info.java -@@ -0,0 +1,9 @@ +@@ -0,0 +1,12 @@ +/** + * Collection of registry entry types that may be created or modified via the + * {@link io.papermc.paper.registry.event.RegistryEvent}. @@ -565,7 +558,10 @@ index 0000000000000000000000000000000000000000..4f8f536f437c5f483ac7bce393e664fd + * Registry entries are not expected to be used during plugin runtime interactions with the API but are mostly + * exposed during registry creation/modification. + */ ++@NullMarked +package io.papermc.paper.registry.data; ++ ++import org.jspecify.annotations.NullMarked; 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..40deffbd0930508bb04e9aedfd62ad2144855198 100644 --- a/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java diff --git a/patches/server/0463-Add-RegistryAccess-for-managing-Registries.patch b/patches/server/0463-Add-RegistryAccess-for-managing-Registries.patch index 9c82b85992..e49d9c714b 100644 --- a/patches/server/0463-Add-RegistryAccess-for-managing-Registries.patch +++ b/patches/server/0463-Add-RegistryAccess-for-managing-Registries.patch @@ -12,10 +12,10 @@ 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..cd8a6a4c2a63029f8f859765088c227bbd456813 +index 0000000000000000000000000000000000000000..ea99f30a311512e4450c38e9e1bb7df0b758a93c --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/PaperRegistries.java -@@ -0,0 +1,154 @@ +@@ -0,0 +1,153 @@ +package io.papermc.paper.registry; + +import com.google.common.base.Preconditions; @@ -83,8 +83,7 @@ index 0000000000000000000000000000000000000000..cd8a6a4c2a63029f8f859765088c227b +import org.bukkit.potion.PotionEffectType; +import org.jspecify.annotations.Nullable; + -+import static io.papermc.paper.registry.entry.RegistryEntry.apiOnly; -+import static io.papermc.paper.registry.entry.RegistryEntry.entry; ++import static io.papermc.paper.registry.entry.RegistryEntryBuilder.start; + +public final class PaperRegistries { + @@ -94,39 +93,39 @@ index 0000000000000000000000000000000000000000..cd8a6a4c2a63029f8f859765088c227b + static { + REGISTRY_ENTRIES = List.of( + // built-ins -+ entry(Registries.GAME_EVENT, RegistryKey.GAME_EVENT, GameEvent.class, CraftGameEvent::new), -+ 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), -+ entry(Registries.ITEM, RegistryKey.ITEM, ItemType.class, CraftItemType::new), -+ entry(Registries.CAT_VARIANT, RegistryKey.CAT_VARIANT, Cat.Type.class, CraftCat.CraftType::new), -+ entry(Registries.FROG_VARIANT, RegistryKey.FROG_VARIANT, Frog.Variant.class, CraftFrog.CraftVariant::new), -+ entry(Registries.VILLAGER_PROFESSION, RegistryKey.VILLAGER_PROFESSION, Villager.Profession.class, CraftVillager.CraftProfession::new), -+ entry(Registries.VILLAGER_TYPE, RegistryKey.VILLAGER_TYPE, Villager.Type.class, CraftVillager.CraftType::new), -+ entry(Registries.MAP_DECORATION_TYPE, RegistryKey.MAP_DECORATION_TYPE, MapCursor.Type.class, CraftMapCursor.CraftType::new), -+ entry(Registries.MENU, RegistryKey.MENU, MenuType.class, CraftMenuType::new), -+ 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), ++ start(Registries.GAME_EVENT, RegistryKey.GAME_EVENT).craft(GameEvent.class, CraftGameEvent::new).build(), ++ start(Registries.STRUCTURE_TYPE, RegistryKey.STRUCTURE_TYPE).craft(StructureType.class, CraftStructureType::new).build(), ++ start(Registries.MOB_EFFECT, RegistryKey.MOB_EFFECT).craft(PotionEffectType.class, CraftPotionEffectType::new).build(), ++ start(Registries.BLOCK, RegistryKey.BLOCK).craft(BlockType.class, CraftBlockType::new).build(), ++ start(Registries.ITEM, RegistryKey.ITEM).craft(ItemType.class, CraftItemType::new).build(), ++ start(Registries.CAT_VARIANT, RegistryKey.CAT_VARIANT).craft(Cat.Type.class, CraftCat.CraftType::new).build(), ++ start(Registries.FROG_VARIANT, RegistryKey.FROG_VARIANT).craft(Frog.Variant.class, CraftFrog.CraftVariant::new).build(), ++ start(Registries.VILLAGER_PROFESSION, RegistryKey.VILLAGER_PROFESSION).craft(Villager.Profession.class, CraftVillager.CraftProfession::new).build(), ++ start(Registries.VILLAGER_TYPE, RegistryKey.VILLAGER_TYPE).craft(Villager.Type.class, CraftVillager.CraftType::new).build(), ++ start(Registries.MAP_DECORATION_TYPE, RegistryKey.MAP_DECORATION_TYPE).craft(MapCursor.Type.class, CraftMapCursor.CraftType::new).build(), ++ start(Registries.MENU, RegistryKey.MENU).craft(MenuType.class, CraftMenuType::new).build(), ++ start(Registries.ATTRIBUTE, RegistryKey.ATTRIBUTE).craft(Attribute.class, CraftAttribute::new).build(), ++ start(Registries.FLUID, RegistryKey.FLUID).craft(Fluid.class, CraftFluid::new).build(), ++ start(Registries.SOUND_EVENT, RegistryKey.SOUND_EVENT).craft(Sound.class, CraftSound::new).build(), + + // data-drivens -+ entry(Registries.BIOME, RegistryKey.BIOME, Biome.class, CraftBiome::new).delayed(), -+ entry(Registries.STRUCTURE, RegistryKey.STRUCTURE, Structure.class, CraftStructure::new).delayed(), -+ entry(Registries.TRIM_MATERIAL, RegistryKey.TRIM_MATERIAL, TrimMaterial.class, CraftTrimMaterial::new).delayed(), -+ 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(), -+ entry(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT, Enchantment.class, CraftEnchantment::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.INSTRUMENT, RegistryKey.INSTRUMENT, MusicInstrument.class, CraftMusicInstrument::new).delayed(), ++ start(Registries.BIOME, RegistryKey.BIOME).craft(Biome.class, CraftBiome::new).build().delayed(), ++ start(Registries.STRUCTURE, RegistryKey.STRUCTURE).craft(Structure.class, CraftStructure::new).build().delayed(), ++ start(Registries.TRIM_MATERIAL, RegistryKey.TRIM_MATERIAL).craft(TrimMaterial.class, CraftTrimMaterial::new).build().delayed(), ++ start(Registries.TRIM_PATTERN, RegistryKey.TRIM_PATTERN).craft(TrimPattern.class, CraftTrimPattern::new).build().delayed(), ++ start(Registries.DAMAGE_TYPE, RegistryKey.DAMAGE_TYPE).craft(DamageType.class, CraftDamageType::new).build().delayed(), ++ start(Registries.WOLF_VARIANT, RegistryKey.WOLF_VARIANT).craft(Wolf.Variant.class, CraftWolf.CraftVariant::new).build().delayed(), ++ start(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT).craft(Enchantment.class, CraftEnchantment::new).build().withSerializationUpdater(FieldRename.ENCHANTMENT_RENAME).delayed(), ++ start(Registries.JUKEBOX_SONG, RegistryKey.JUKEBOX_SONG).craft(JukeboxSong.class, CraftJukeboxSong::new).build().delayed(), ++ start(Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN).craft(PatternType.class, CraftPatternType::new).build().delayed(), ++ start(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT).craft(Art.class, CraftArt::new).build().delayed(), ++ start(Registries.INSTRUMENT, RegistryKey.INSTRUMENT).craft(MusicInstrument.class, CraftMusicInstrument::new).build().delayed(), + + // api-only -+ 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<MemoryKey<?>>) (org.bukkit.Registry) org.bukkit.Registry.MEMORY_MODULE_TYPE) ++ start(Registries.ENTITY_TYPE, RegistryKey.ENTITY_TYPE).apiOnly(PaperSimpleRegistry::entityType), ++ start(Registries.PARTICLE_TYPE, RegistryKey.PARTICLE_TYPE).apiOnly(PaperSimpleRegistry::particleType), ++ start(Registries.POTION, RegistryKey.POTION).apiOnly(PaperSimpleRegistry::potion), ++ start(Registries.MEMORY_MODULE_TYPE, RegistryKey.MEMORY_MODULE_TYPE).apiOnly(() -> (org.bukkit.Registry<MemoryKey<?>>) (org.bukkit.Registry) org.bukkit.Registry.MEMORY_MODULE_TYPE) + ); + final Map<RegistryKey<?>, RegistryEntry<?, ?>> byRegistryKey = new IdentityHashMap<>(REGISTRY_ENTRIES.size()); + final Map<ResourceKey<?>, RegistryEntry<?, ?>> byResourceKey = new IdentityHashMap<>(REGISTRY_ENTRIES.size()); @@ -460,16 +459,19 @@ index 0000000000000000000000000000000000000000..ceb217dbbb84e8bd51365dd47bf91971 +} diff --git a/src/main/java/io/papermc/paper/registry/entry/CraftRegistryEntry.java b/src/main/java/io/papermc/paper/registry/entry/CraftRegistryEntry.java new file mode 100644 -index 0000000000000000000000000000000000000000..45cbc425da64f0bd3290600869ad425d9e6e912b +index 0000000000000000000000000000000000000000..fbc80d89dbbac9b776f970813b04f6384a685f6e --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/entry/CraftRegistryEntry.java -@@ -0,0 +1,48 @@ +@@ -0,0 +1,51 @@ +package io.papermc.paper.registry.entry; + +import com.google.common.base.Preconditions; ++import com.mojang.datafixers.util.Either; +import io.papermc.paper.registry.RegistryHolder; +import io.papermc.paper.registry.RegistryKey; +import java.util.function.BiFunction; ++import java.util.function.Function; ++import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import org.bukkit.Keyed; @@ -482,14 +484,14 @@ index 0000000000000000000000000000000000000000..45cbc425da64f0bd3290600869ad425d + private static final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> EMPTY = (namespacedKey, apiVersion) -> namespacedKey; + + protected final Class<?> classToPreload; -+ protected final BiFunction<NamespacedKey, M, B> minecraftToBukkit; ++ protected final Either<BiFunction<? super NamespacedKey, M, ? extends B>, Function<Holder<M>, ? extends B>> minecraftToBukkit; + protected BiFunction<NamespacedKey, ApiVersion, NamespacedKey> updater = EMPTY; + + protected CraftRegistryEntry( + final ResourceKey<? extends Registry<M>> mcKey, + final RegistryKey<B> apiKey, + final Class<?> classToPreload, -+ final BiFunction<NamespacedKey, M, B> minecraftToBukkit ++ final Either<BiFunction<? super NamespacedKey, M, ? extends B>, Function<Holder<M>, ? extends B>> minecraftToBukkit + ) { + super(mcKey, apiKey); + Preconditions.checkArgument(!classToPreload.getPackageName().startsWith("net.minecraft"), classToPreload + " should not be in the net.minecraft package as the class-to-preload"); @@ -514,19 +516,17 @@ index 0000000000000000000000000000000000000000..45cbc425da64f0bd3290600869ad425d +} diff --git a/src/main/java/io/papermc/paper/registry/entry/RegistryEntry.java b/src/main/java/io/papermc/paper/registry/entry/RegistryEntry.java new file mode 100644 -index 0000000000000000000000000000000000000000..2889d87f0989ae5744cd4c1e57240830aa574155 +index 0000000000000000000000000000000000000000..f0a81a8b88d31139390e952a0eb8a526e6851c5f --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/entry/RegistryEntry.java -@@ -0,0 +1,48 @@ +@@ -0,0 +1,29 @@ +package io.papermc.paper.registry.entry; + +import io.papermc.paper.registry.RegistryHolder; +import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.legacy.DelayedRegistryEntry; +import java.util.function.BiFunction; -+import java.util.function.Supplier; +import net.minecraft.core.Registry; -+import net.minecraft.resources.ResourceKey; +import org.bukkit.Keyed; +import org.bukkit.NamespacedKey; +import org.bukkit.craftbukkit.util.ApiVersion; @@ -548,22 +548,74 @@ index 0000000000000000000000000000000000000000..2889d87f0989ae5744cd4c1e57240830 + default RegistryEntry<M, B> delayed() { + return new DelayedRegistryEntry<>(this); + } ++} +diff --git a/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java b/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c3d783e1a037c0797995713728ff43b2838f6591 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java +@@ -0,0 +1,63 @@ ++package io.papermc.paper.registry.entry; + -+ static <M, B extends Keyed> RegistryEntry<M, B> entry( ++import com.mojang.datafixers.util.Either; ++import io.papermc.paper.registry.RegistryKey; ++import java.util.function.BiFunction; ++import java.util.function.Function; ++import java.util.function.Supplier; ++import net.minecraft.core.Holder; ++import net.minecraft.core.Registry; ++import net.minecraft.resources.ResourceKey; ++import org.bukkit.Keyed; ++import org.bukkit.NamespacedKey; ++ ++public class RegistryEntryBuilder<M, A extends Keyed> { // TODO remove Keyed ++ ++ public static <M, A extends Keyed> RegistryEntryBuilder<M, A> start( // TODO remove Keyed + final ResourceKey<? extends Registry<M>> mcKey, -+ final RegistryKey<B> apiKey, -+ final Class<?> classToPreload, -+ final BiFunction<NamespacedKey, M, B> minecraftToBukkit ++ final RegistryKey<A> apiKey + ) { -+ return new CraftRegistryEntry<>(mcKey, apiKey, classToPreload, minecraftToBukkit); ++ return new RegistryEntryBuilder<>(mcKey, apiKey); + } + -+ static <M, B extends Keyed> RegistryEntry<M, B> apiOnly( -+ final ResourceKey<? extends Registry<M>> mcKey, -+ final RegistryKey<B> apiKey, -+ final Supplier<org.bukkit.Registry<B>> apiRegistrySupplier -+ ) { -+ return new ApiRegistryEntry<>(mcKey, apiKey, apiRegistrySupplier); ++ protected final ResourceKey<? extends Registry<M>> mcKey; ++ protected final RegistryKey<A> apiKey; ++ ++ private RegistryEntryBuilder(final ResourceKey<? extends Registry<M>> mcKey, RegistryKey<A> apiKey) { ++ this.mcKey = mcKey; ++ this.apiKey = apiKey; ++ } ++ ++ public RegistryEntry<M, A> apiOnly(final Supplier<org.bukkit.Registry<A>> apiRegistrySupplier) { ++ return new ApiRegistryEntry<>(this.mcKey, this.apiKey, apiRegistrySupplier); ++ } ++ ++ public CraftStage<M, A> craft(final Class<?> classToPreload, final BiFunction<? super NamespacedKey, M, ? extends A> minecraftToBukkit) { ++ return new CraftStage<>(this.mcKey, this.apiKey, classToPreload, Either.left(minecraftToBukkit)); ++ } ++ ++ public CraftStage<M, A> craft(final Class<?> classToPreload, final Function<Holder<M>, ? extends A> minecraftToBukkit) { ++ return new CraftStage<>(this.mcKey, this.apiKey, classToPreload, Either.right(minecraftToBukkit)); ++ } ++ ++ public static final class CraftStage<M, A extends Keyed> extends RegistryEntryBuilder<M, A> { // TODO remove Keyed ++ ++ private final Class<?> classToPreload; ++ private final Either<BiFunction<? super NamespacedKey, M, ? extends A>, Function<Holder<M>, ? extends A>> minecraftToBukkit; ++ ++ private CraftStage( ++ final ResourceKey<? extends Registry<M>> mcKey, ++ final RegistryKey<A> apiKey, ++ final Class<?> classToPreload, ++ final Either<BiFunction<? super NamespacedKey, M, ? extends A>, Function<Holder<M>, ? extends A>> minecraftToBukkit ++ ) { ++ super(mcKey, apiKey); ++ this.classToPreload = classToPreload; ++ this.minecraftToBukkit = minecraftToBukkit; ++ } ++ ++ public RegistryEntry<M, A> build() { ++ return new CraftRegistryEntry<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit); ++ } + } +} diff --git a/src/main/java/io/papermc/paper/registry/entry/RegistryEntryInfo.java b/src/main/java/io/papermc/paper/registry/entry/RegistryEntryInfo.java @@ -748,6 +800,26 @@ index 0000000000000000000000000000000000000000..ca07ef31161e938d48214992b34cafb7 +package io.papermc.paper.registry; + +import org.jspecify.annotations.NullMarked; +diff --git a/src/main/java/io/papermc/paper/util/Holderable.java b/src/main/java/io/papermc/paper/util/Holderable.java +new file mode 100644 +index 0000000000000000000000000000000000000000..404ab0df12bc8182520c77328017c128d22993eb +--- /dev/null ++++ b/src/main/java/io/papermc/paper/util/Holderable.java +@@ -0,0 +1,14 @@ ++package io.papermc.paper.util; ++ ++import net.minecraft.core.Holder; ++import org.bukkit.craftbukkit.util.Handleable; ++ ++public interface Holderable<M> extends Handleable<M> { ++ ++ Holder<M> getHolder(); ++ ++ @Override ++ default M getHandle() { ++ return this.getHolder().value(); ++ } ++} diff --git a/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java b/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java index 3f72e30b57fb2a4231e22a2234729408c1240af4..4638ba98dbbdb0f880337347be85a6e0fbed2191 100644 --- a/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java @@ -784,11 +856,92 @@ index 257cfce009fb6fcd24d1fddfd8001e9b2a8ae1ae..185752185549ebd5f431932b63d8e5fe Map<ResourceLocation, T> map = new HashMap<>(); SimpleJsonResourceReloadListener.scanDirectory(resourceManager, type.registryKey(), ops, type.codec(), map); map.forEach((id, value) -> writableRegistry.register(ResourceKey.create(type.registryKey(), id), (T)value, DEFAULT_REGISTRATION_INFO)); +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftParticle.java b/src/main/java/org/bukkit/craftbukkit/CraftParticle.java +index 0be9c773a636b6d19668a3509baa7f37d60eb3b7..508129cd23e89b65d1e2764f495a60bb4a8bd575 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftParticle.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftParticle.java +@@ -216,18 +216,18 @@ public abstract class CraftParticle<D> implements Keyed { + } + + public CraftParticleRegistry(net.minecraft.core.Registry<net.minecraft.core.particles.ParticleType<?>> minecraftRegistry) { +- super(CraftParticle.class, minecraftRegistry, null, FieldRename.PARTICLE_TYPE_RENAME); ++ super(CraftParticle.class, minecraftRegistry, (com.mojang.datafixers.util.Either<java.util.function.BiFunction<? super org.bukkit.NamespacedKey,net.minecraft.core.particles.ParticleType<?>,? extends CraftParticle<?>>, java.util.function.Function<net.minecraft.core.Holder<net.minecraft.core.particles.ParticleType<?>>,? extends CraftParticle<?>>>) null, FieldRename.PARTICLE_TYPE_RENAME); // Paper - switch to Holder + } + + @Override +- public CraftParticle<?> createBukkit(NamespacedKey namespacedKey, net.minecraft.core.particles.ParticleType<?> particle) { ++ public CraftParticle<?> createBukkit(NamespacedKey namespacedKey, net.minecraft.core.Holder<net.minecraft.core.particles.ParticleType<?>> particle) { // Paper - switch to Holder + if (particle == null) { + return null; + } + + BiFunction<NamespacedKey, net.minecraft.core.particles.ParticleType<?>, CraftParticle<?>> function = CraftParticleRegistry.PARTICLE_MAP.getOrDefault(namespacedKey, CraftParticleRegistry.VOID_FUNCTION); + +- return function.apply(namespacedKey, particle); ++ return function.apply(namespacedKey, particle.value()); // Paper - switch to Holder + } + } + } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java -index 0d091c7b328fb70a82f5b5ded7dec61b7cd3d59a..249f0dcad04a35244da6dab837a461bb42aad00a 100644 +index 0d091c7b328fb70a82f5b5ded7dec61b7cd3d59a..459ad788f4dadb72d0dc519125ba1e7a0d6e2530 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java -@@ -127,96 +127,12 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { +@@ -93,13 +93,40 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { + Preconditions.checkArgument(minecraft != null); + + net.minecraft.core.Registry<M> registry = CraftRegistry.getMinecraftRegistry(registryKey); +- B bukkit = bukkitRegistry.get(CraftNamespacedKey.fromMinecraft(registry.getResourceKey(minecraft) +- .orElseThrow(() -> new IllegalStateException(String.format("Cannot convert '%s' to bukkit representation, since it is not registered.", minecraft))).location())); ++ // Paper start - support direct Holders ++ final java.util.Optional<ResourceKey<M>> resourceKey = registry.getResourceKey(minecraft); ++ if (resourceKey.isEmpty() && bukkitRegistry instanceof final CraftRegistry<?, ?> craftRegistry && craftRegistry.supportsDirectHolders()) { ++ return ((CraftRegistry<B, M>) registry).convertDirectHolder(Holder.direct(minecraft)); ++ } else if (resourceKey.isEmpty()) { ++ throw new IllegalStateException(String.format("Cannot convert '%s' to bukkit representation, since it is not registered.", minecraft)); ++ } ++ final B bukkit = bukkitRegistry.get(CraftNamespacedKey.fromMinecraft(resourceKey.get().location())); ++ // Paper end - support direct Holders ++ ++ Preconditions.checkArgument(bukkit != null); ++ ++ return bukkit; ++ } + ++ // Paper start - support direct Holders ++ public static <B extends Keyed, M> B minecraftHolderToBukkit(final Holder<M> minecraft, final Registry<B> bukkitRegistry) { ++ Preconditions.checkArgument(minecraft != null); ++ ++ final B bukkit; ++ if (bukkitRegistry instanceof final CraftRegistry<?, ?> craftRegistry && craftRegistry.supportsDirectHolders()) { ++ bukkit = minecraft.unwrap().map( ++ key -> bukkitRegistry.get(io.papermc.paper.util.MCUtil.fromResourceKey(key)), ++ value -> ((CraftRegistry<B, M>) bukkitRegistry).convertDirectHolder(minecraft) ++ ); ++ } else { ++ Preconditions.checkArgument(minecraft.kind() == Holder.Kind.REFERENCE, "Cannot convert direct holder to bukkit representation"); ++ bukkit = bukkitRegistry.get(io.papermc.paper.util.MCUtil.fromResourceKey(minecraft.unwrapKey().orElseThrow())); ++ } + Preconditions.checkArgument(bukkit != null); + + return bukkit; + } ++ // Paper end - support direct Holders + + /** + * Usage note: Only use this method to delegate the conversion methods from the individual Craft classes to here. +@@ -116,6 +143,11 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { + + public static <B extends Keyed, M> Holder<M> bukkitToMinecraftHolder(B bukkit, ResourceKey<net.minecraft.core.Registry<M>> registryKey) { + Preconditions.checkArgument(bukkit != null); ++ // Paper start - support direct Holder ++ if (bukkit instanceof io.papermc.paper.util.Holderable<?>) { ++ return ((io.papermc.paper.util.Holderable<M>) bukkit).getHolder(); ++ } ++ // Paper end - support direct Holder + + net.minecraft.core.Registry<M> registry = CraftRegistry.getMinecraftRegistry(registryKey); + +@@ -127,96 +159,12 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { + ", this can happen if a plugin creates its own registry entry with out properly registering it."); } @@ -888,7 +1041,7 @@ index 0d091c7b328fb70a82f5b5ded7dec61b7cd3d59a..249f0dcad04a35244da6dab837a461bb } if (bukkit instanceof Registry.SimpleRegistry<?> simple) { -@@ -234,23 +150,21 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { +@@ -234,23 +182,26 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { return bukkit.get(namespacedKey); } @@ -896,13 +1049,19 @@ index 0d091c7b328fb70a82f5b5ded7dec61b7cd3d59a..249f0dcad04a35244da6dab837a461bb + private final Class<?> bukkitClass; // Paper - relax preload class private final Map<NamespacedKey, B> cache = new HashMap<>(); private final net.minecraft.core.Registry<M> minecraftRegistry; - private final BiFunction<NamespacedKey, M, B> minecraftToBukkit; +- private final BiFunction<NamespacedKey, M, B> minecraftToBukkit; - private final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> updater; ++ private final com.mojang.datafixers.util.Either<BiFunction<? super NamespacedKey, M, ? extends B>,java.util.function.Function<Holder<M>, ? extends B>> minecraftToBukkit; // Paper - switch to Holder + private final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> serializationUpdater; // Paper - rename to make it *clear* what it is *only* for private boolean init; - public CraftRegistry(Class<? super B> bukkitClass, net.minecraft.core.Registry<M> minecraftRegistry, BiFunction<NamespacedKey, M, B> minecraftToBukkit, BiFunction<NamespacedKey, ApiVersion, NamespacedKey> updater) { -+ public CraftRegistry(Class<?> bukkitClass, net.minecraft.core.Registry<M> minecraftRegistry, BiFunction<NamespacedKey, M, B> minecraftToBukkit, BiFunction<NamespacedKey, ApiVersion, NamespacedKey> serializationUpdater) { // Paper - relax preload class ++ public CraftRegistry(Class<?> bukkitClass, net.minecraft.core.Registry<M> minecraftRegistry, BiFunction<? super NamespacedKey, M, B> minecraftToBukkit, BiFunction<NamespacedKey, ApiVersion, NamespacedKey> serializationUpdater) { // Paper - relax preload class ++ // Paper start - switch to Holder ++ this(bukkitClass, minecraftRegistry, com.mojang.datafixers.util.Either.left(minecraftToBukkit), serializationUpdater); ++ } ++ public CraftRegistry(Class<?> bukkitClass, net.minecraft.core.Registry<M> minecraftRegistry, com.mojang.datafixers.util.Either<BiFunction<? super NamespacedKey, M, ? extends B>, java.util.function.Function<Holder<M>, ? extends B>> minecraftToBukkit, BiFunction<NamespacedKey, ApiVersion, NamespacedKey> serializationUpdater) { // Paper - relax preload class ++ // Paper end - support Holders this.bukkitClass = bukkitClass; this.minecraftRegistry = minecraftRegistry; this.minecraftToBukkit = minecraftToBukkit; @@ -917,6 +1076,45 @@ index 0d091c7b328fb70a82f5b5ded7dec61b7cd3d59a..249f0dcad04a35244da6dab837a461bb @Override public B get(NamespacedKey namespacedKey) { +@@ -280,7 +231,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { + return this.get(namespacedKey); + } + +- B bukkit = this.createBukkit(namespacedKey, this.minecraftRegistry.getOptional(CraftNamespacedKey.toMinecraft(namespacedKey)).orElse(null)); ++ B bukkit = this.createBukkit(namespacedKey, this.minecraftRegistry.get(CraftNamespacedKey.toMinecraft(namespacedKey)).orElse(null)); // Paper - switch to Holder + if (bukkit == null) { + return null; + } +@@ -311,11 +262,27 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { + return this.stream().iterator(); + } + +- public B createBukkit(NamespacedKey namespacedKey, M minecraft) { ++ public B createBukkit(NamespacedKey namespacedKey, Holder<M> minecraft) { // Paper - switch to Holder + if (minecraft == null) { + return null; + } + +- return this.minecraftToBukkit.apply(namespacedKey, minecraft); ++ // Paper start - switch to Holder ++ return this.minecraftToBukkit.map( ++ minecraftToBukkit -> minecraftToBukkit.apply(namespacedKey, minecraft.value()), ++ minecraftToBukkit -> minecraftToBukkit.apply(minecraft) ++ ); ++ // Paper end - switch to Holder ++ } ++ ++ // Paper start - support Direct Holders ++ public boolean supportsDirectHolders() { ++ return this.minecraftToBukkit.right().isPresent(); ++ } ++ ++ public B convertDirectHolder(Holder<M> holder) { ++ Preconditions.checkArgument( this.supportsDirectHolders() && holder.kind() == Holder.Kind.DIRECT); ++ return this.minecraftToBukkit.right().orElseThrow().apply(holder); + } ++ // Paper end - support Direct Holders + } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index f75d73402cf633254fe1ef4e919f09db48165190..5ae8f646083fb580ac8d28fcbfe8ed2208b45d09 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/patches/server/0899-Improve-Registry.patch b/patches/server/0899-Improve-Registry.patch index 6cfe8ce318..31168f9746 100644 --- a/patches/server/0899-Improve-Registry.patch +++ b/patches/server/0899-Improve-Registry.patch @@ -29,18 +29,18 @@ index fb8f68f1aedfb26e4d95fe5bad87f0f2cc91c287..2838ef9d89ec8d7bd8981eff4a2ffe2c } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java -index 249f0dcad04a35244da6dab837a461bb42aad00a..273844c9071b8d5cf6009c6c94a6c47a9d0cc700 100644 +index 459ad788f4dadb72d0dc519125ba1e7a0d6e2530..6033035e87d004997fee62801942c57628b91e6d 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java -@@ -152,6 +152,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { +@@ -184,6 +184,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { private final Class<?> bukkitClass; // Paper - relax preload class private final Map<NamespacedKey, B> cache = new HashMap<>(); + private final Map<B, NamespacedKey> byValue = new java.util.IdentityHashMap<>(); // Paper - improve Registry private final net.minecraft.core.Registry<M> minecraftRegistry; - private final BiFunction<NamespacedKey, M, B> minecraftToBukkit; + private final com.mojang.datafixers.util.Either<BiFunction<? super NamespacedKey, M, ? extends B>,java.util.function.Function<Holder<M>, ? extends B>> minecraftToBukkit; // Paper - switch to Holder private final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> serializationUpdater; // Paper - rename to make it *clear* what it is *only* for -@@ -200,6 +201,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { +@@ -237,6 +238,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { } this.cache.put(namespacedKey, bukkit); @@ -48,10 +48,10 @@ index 249f0dcad04a35244da6dab837a461bb42aad00a..273844c9071b8d5cf6009c6c94a6c47a return bukkit; } -@@ -232,4 +234,11 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { - - return this.minecraftToBukkit.apply(namespacedKey, minecraft); +@@ -285,4 +287,11 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { + return this.minecraftToBukkit.right().orElseThrow().apply(holder); } + // Paper end - support Direct Holders + + // Paper start - improve Registry + @Override diff --git a/patches/server/0906-Fixup-NamespacedKey-handling.patch b/patches/server/0906-Fixup-NamespacedKey-handling.patch index 2de1c49d0b..beae8a9f42 100644 --- a/patches/server/0906-Fixup-NamespacedKey-handling.patch +++ b/patches/server/0906-Fixup-NamespacedKey-handling.patch @@ -18,10 +18,10 @@ index 90b82ad996b2b85628c9a5ddeef9410150b7f70c..5fd22a80e9d05afbea273471cee99173 public static NamespacedKey minecraftToBukkitKey(ResourceKey<LootTable> minecraft) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java -index 273844c9071b8d5cf6009c6c94a6c47a9d0cc700..45c78c113e881b277e1216293ad918ee40b44325 100644 +index 6033035e87d004997fee62801942c57628b91e6d..47951e62aa384542c3ba92e1ef6162031d05a300 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java -@@ -127,6 +127,16 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { +@@ -159,6 +159,19 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { + ", this can happen if a plugin creates its own registry entry with out properly registering it."); } @@ -31,6 +31,9 @@ index 273844c9071b8d5cf6009c6c94a6c47a9d0cc700..45c78c113e881b277e1216293ad918ee + } + + public static <T extends org.bukkit.Keyed, M> java.util.Optional<T> unwrapAndConvertHolder(final Registry<T> registry, final Holder<M> value) { ++ if (registry instanceof CraftRegistry<?,?> craftRegistry && craftRegistry.supportsDirectHolders() && value.kind() == Holder.Kind.DIRECT) { ++ return java.util.Optional.of(((CraftRegistry<T, M>) registry).convertDirectHolder(value)); ++ } + return value.unwrapKey().map(key -> registry.get(CraftNamespacedKey.fromMinecraft(key.location()))); + } + // Paper end - fixup upstream being dum @@ -80,22 +83,6 @@ index bcac1359c667ef1ee46384f9c7a5adf4010d2b08..b1b139b773b37e6ec2afea85c500387d } @Override -diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java -index 0fdd9dd47594a7e7e785c34c09d9b4a79aad2439..0d3b1692af010bfd7ea83e22e9571dc954906f71 100644 ---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java -+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java -@@ -38,8 +38,9 @@ public class CraftMetaArmor extends CraftMetaItem implements ArmorMeta { - super(tag); - - getOrEmpty(tag, CraftMetaArmor.TRIM).ifPresent((trimCompound) -> { -- TrimMaterial trimMaterial = CraftTrimMaterial.minecraftHolderToBukkit(trimCompound.material()); -- TrimPattern trimPattern = CraftTrimPattern.minecraftHolderToBukkit(trimCompound.pattern()); -+ TrimMaterial trimMaterial = org.bukkit.craftbukkit.CraftRegistry.unwrapAndConvertHolder(io.papermc.paper.registry.RegistryKey.TRIM_MATERIAL, trimCompound.material()).orElse(null); // Paper - fix upstream not being correct -+ TrimPattern trimPattern = org.bukkit.craftbukkit.CraftRegistry.unwrapAndConvertHolder(io.papermc.paper.registry.RegistryKey.TRIM_PATTERN, trimCompound.pattern()).orElse(null); // Paper - fix upstream not being correct -+ if (trimMaterial == null || trimPattern == null) return; // Paper - just delete the trim because upstream is not doing this right - - this.trim = new ArmorTrim(trimMaterial, trimPattern); - diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java index 1c1a2d66d1ebcbe2ded732e759d0f9d471d43b56..eb44c19f6af624df458981e46c73a64358d6e1ce 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java diff --git a/patches/server/0944-improve-checking-handled-tags-in-itemmeta.patch b/patches/server/0944-improve-checking-handled-tags-in-itemmeta.patch index 9ca8bac6e1..32bf88b7e5 100644 --- a/patches/server/0944-improve-checking-handled-tags-in-itemmeta.patch +++ b/patches/server/0944-improve-checking-handled-tags-in-itemmeta.patch @@ -231,7 +231,7 @@ index 6d76cc1db3ac3f1ae74c13511937fb86082a0b3d..f4a6ee6dfcb2d516a9a1a9c81494b50a public M getItemMeta(ItemMeta itemMeta) { diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java -index 0d3b1692af010bfd7ea83e22e9571dc954906f71..e83a662f82b144b11a003a682633cd0ee797fd19 100644 +index 0fdd9dd47594a7e7e785c34c09d9b4a79aad2439..6532bdaf6cbd10ecc5ace1b89899ad82e7bca206 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java @@ -34,8 +34,8 @@ public class CraftMetaArmor extends CraftMetaItem implements ArmorMeta { @@ -244,7 +244,7 @@ index 0d3b1692af010bfd7ea83e22e9571dc954906f71..e83a662f82b144b11a003a682633cd0e + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaArmor.TRIM).ifPresent((trimCompound) -> { - TrimMaterial trimMaterial = org.bukkit.craftbukkit.CraftRegistry.unwrapAndConvertHolder(io.papermc.paper.registry.RegistryKey.TRIM_MATERIAL, trimCompound.material()).orElse(null); // Paper - fix upstream not being correct + TrimMaterial trimMaterial = CraftTrimMaterial.minecraftHolderToBukkit(trimCompound.material()); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java index ecce5d0da946ca279c5608068442cc53437dd2a5..00b5c4ab6111f980db1b9e99f901667741266440 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java diff --git a/patches/server/1028-Registry-Modification-API.patch b/patches/server/1028-Registry-Modification-API.patch index adac59c3b3..4f2f3fd574 100644 --- a/patches/server/1028-Registry-Modification-API.patch +++ b/patches/server/1028-Registry-Modification-API.patch @@ -9,7 +9,7 @@ public net.minecraft.resources.RegistryOps lookupProvider public net.minecraft.resources.RegistryOps$HolderLookupAdapter diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/src/main/java/io/papermc/paper/registry/PaperRegistries.java -index cd8a6a4c2a63029f8f859765088c227bbd456813..86c9f87cdb41c0d1ccc2a61b501f969cfaae47bc 100644 +index ea99f30a311512e4450c38e9e1bb7df0b758a93c..875b3e761d83ab3ddfe05fdf978136c7d683bb0c 100644 --- a/src/main/java/io/papermc/paper/registry/PaperRegistries.java +++ b/src/main/java/io/papermc/paper/registry/PaperRegistries.java @@ -3,6 +3,7 @@ package io.papermc.paper.registry; @@ -20,15 +20,7 @@ index cd8a6a4c2a63029f8f859765088c227bbd456813..86c9f87cdb41c0d1ccc2a61b501f969c import java.util.Collections; import java.util.IdentityHashMap; import java.util.List; -@@ -67,6 +68,7 @@ import org.jspecify.annotations.Nullable; - - import static io.papermc.paper.registry.entry.RegistryEntry.apiOnly; - import static io.papermc.paper.registry.entry.RegistryEntry.entry; -+import static io.papermc.paper.registry.entry.RegistryEntry.writable; - - public final class PaperRegistries { - -@@ -149,6 +151,15 @@ public final class PaperRegistries { +@@ -148,6 +149,15 @@ public final class PaperRegistries { return ResourceKey.create((ResourceKey<? extends Registry<M>>) PaperRegistries.registryToNms(typedKey.registryKey()), PaperAdventure.asVanilla(typedKey.key())); } @@ -65,7 +57,7 @@ index 4bf7915867dbe762ef0b070d67d5f7b7d1ee4f03..ed071ed34e16812f133102b0d66a5201 return delayedRegistry.delegate(); diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistryBuilder.java b/src/main/java/io/papermc/paper/registry/PaperRegistryBuilder.java new file mode 100644 -index 0000000000000000000000000000000000000000..69e63689083207de2f409557d4a9a17f8ad7ae3e +index 0000000000000000000000000000000000000000..6a60d7b7edeedb150afea41d58855b2d8521f297 --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/PaperRegistryBuilder.java @@ -0,0 +1,25 @@ @@ -81,22 +73,22 @@ index 0000000000000000000000000000000000000000..69e63689083207de2f409557d4a9a17f + @FunctionalInterface + interface Filler<M, T, B extends PaperRegistryBuilder<M, T>> { + -+ B fill(Conversions conversions, TypedKey<T> key, @Nullable M nms); ++ B fill(Conversions conversions, @Nullable M nms); + + default Factory<M, T, B> asFactory() { -+ return (lookup, key) -> this.fill(lookup, key, null); ++ return (lookup) -> this.fill(lookup, null); + } + } + + @FunctionalInterface + interface Factory<M, T, B extends PaperRegistryBuilder<M, T>> { + -+ B create(Conversions conversions, TypedKey<T> key); ++ B create(Conversions conversions); + } +} diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistryListenerManager.java b/src/main/java/io/papermc/paper/registry/PaperRegistryListenerManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..60d9b806a09bb103e36ce1f932a5a34ef408770a +index 0000000000000000000000000000000000000000..4f98c15d40e95031326d0524c51f2864ce52223e --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/PaperRegistryListenerManager.java @@ -0,0 +1,183 @@ @@ -204,7 +196,7 @@ index 0000000000000000000000000000000000000000..60d9b806a09bb103e36ce1f932a5a34e + } + final RegistryEntry.Modifiable<M, T, B> modifiableEntry = RegistryEntry.Modifiable.asModifiable(entry); + @SuppressWarnings("PatternValidation") final TypedKey<T> typedKey = TypedKey.create(entry.apiKey(), Key.key(key.location().getNamespace(), key.location().getPath())); -+ final B builder = modifiableEntry.fillBuilder(conversions, typedKey, nms); ++ final B builder = modifiableEntry.fillBuilder(conversions, nms); + return this.registerWithListeners(registry, modifiableEntry, key, nms, builder, registrationInfo, registerMethod, conversions); + } + @@ -317,12 +309,13 @@ index 6d134ace042758da722960cbcb48e52508dafd61..cc39bc68d29055ef6429f08f975412bd } 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..ef91352d442d9ddd666af6bde9a186ce15e5aa04 +index 0000000000000000000000000000000000000000..b00fda3b478031c6a9f2b3f04ea54b1952f1a2dd --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java -@@ -0,0 +1,92 @@ +@@ -0,0 +1,80 @@ +package io.papermc.paper.registry; + ++import com.mojang.datafixers.util.Either; +import com.mojang.serialization.Lifecycle; +import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.registry.data.util.Conversions; @@ -331,6 +324,8 @@ index 0000000000000000000000000000000000000000..ef91352d442d9ddd666af6bde9a186ce +import java.util.Optional; +import java.util.function.BiFunction; +import java.util.function.Consumer; ++import java.util.function.Function; ++import net.minecraft.core.Holder; +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.RegistrationInfo; +import net.minecraft.resources.ResourceKey; @@ -338,7 +333,6 @@ index 0000000000000000000000000000000000000000..ef91352d442d9ddd666af6bde9a186ce +import org.bukkit.NamespacedKey; +import org.bukkit.craftbukkit.CraftRegistry; +import org.bukkit.craftbukkit.util.ApiVersion; -+import org.jspecify.annotations.Nullable; + +public class WritableCraftRegistry<M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> extends CraftRegistry<T, M> { + @@ -347,7 +341,6 @@ index 0000000000000000000000000000000000000000..ef91352d442d9ddd666af6bde9a186ce + private final RegistryEntry.BuilderHolder<M, T, B> entry; + private final MappedRegistry<M> registry; + private final PaperRegistryBuilder.Factory<M, T, ? extends B> builderFactory; -+ private final BiFunction<? super NamespacedKey, M, T> minecraftToBukkit; + + public WritableCraftRegistry( + final RegistryEntry.BuilderHolder<M, T, B> entry, @@ -355,19 +348,18 @@ index 0000000000000000000000000000000000000000..ef91352d442d9ddd666af6bde9a186ce + final MappedRegistry<M> registry, + final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> serializationUpdater, + final PaperRegistryBuilder.Factory<M, T, ? extends B> builderFactory, -+ final BiFunction<? super NamespacedKey, M, T> minecraftToBukkit ++ final Either<BiFunction<? super NamespacedKey, M, ? extends T>, Function<Holder<M>, ? extends T>> minecraftToBukkit + ) { -+ super(classToPreload, registry, null, serializationUpdater); ++ super(classToPreload, registry, minecraftToBukkit, serializationUpdater); + this.entry = entry; + this.registry = registry; + this.builderFactory = builderFactory; -+ this.minecraftToBukkit = minecraftToBukkit; + } + + public void register(final TypedKey<T> key, final Consumer<? super B> value, final Conversions conversions) { -+ final ResourceKey<M> resourceKey = ResourceKey.create(this.registry.key(), PaperAdventure.asVanilla(key.key())); ++ final ResourceKey<M> resourceKey = PaperRegistries.toNms(key); + this.registry.validateWrite(resourceKey); -+ final B builder = this.newBuilder(conversions, key); ++ final B builder = this.newBuilder(conversions); + value.accept(builder); + PaperRegistryListenerManager.INSTANCE.registerWithListeners( + this.registry, @@ -379,24 +371,12 @@ index 0000000000000000000000000000000000000000..ef91352d442d9ddd666af6bde9a186ce + ); + } + -+ @Override -+ public final @Nullable T createBukkit(final NamespacedKey namespacedKey, final @Nullable M minecraft) { -+ if (minecraft == null) { -+ return null; -+ } -+ return this.minecraftToBukkit(namespacedKey, minecraft); -+ } -+ + public WritableRegistry<T, B> createApiWritableRegistry(final Conversions conversions) { + return new ApiWritableRegistry(conversions); + } + -+ public T minecraftToBukkit(final NamespacedKey namespacedKey, final M minecraft) { -+ return this.minecraftToBukkit.apply(namespacedKey, minecraft); -+ } -+ -+ protected B newBuilder(final Conversions conversions, final TypedKey<T> key) { -+ return this.builderFactory.create(conversions, key); ++ protected B newBuilder(final Conversions conversions) { ++ return this.builderFactory.create(conversions); + } + + public class ApiWritableRegistry implements WritableRegistry<T, B> { @@ -415,21 +395,46 @@ index 0000000000000000000000000000000000000000..ef91352d442d9ddd666af6bde9a186ce +} diff --git a/src/main/java/io/papermc/paper/registry/data/util/Conversions.java b/src/main/java/io/papermc/paper/registry/data/util/Conversions.java new file mode 100644 -index 0000000000000000000000000000000000000000..1e9a0143bc3b70dfc5e129a0fe849ff3e01447ab +index 0000000000000000000000000000000000000000..b1710da835cee3333bfb1c238b37ec0c4d16ba09 --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/data/util/Conversions.java -@@ -0,0 +1,33 @@ +@@ -0,0 +1,58 @@ +package io.papermc.paper.registry.data.util; + ++import com.google.common.base.Preconditions; +import com.mojang.serialization.JavaOps; +import io.papermc.paper.adventure.WrapperAwareSerializer; ++import java.util.Optional; +import net.kyori.adventure.text.Component; ++import net.minecraft.core.Registry; ++import net.minecraft.core.RegistryAccess; +import net.minecraft.resources.RegistryOps; ++import net.minecraft.resources.ResourceKey; ++import org.bukkit.craftbukkit.CraftRegistry; +import org.jetbrains.annotations.Contract; +import org.jspecify.annotations.Nullable; + +public class Conversions { + ++ private static @Nullable Conversions globalInstance; ++ public static Conversions global() { ++ if (globalInstance == null) { ++ final RegistryAccess globalAccess = CraftRegistry.getMinecraftRegistry(); ++ Preconditions.checkState(globalAccess != null, "Global registry access is not available"); ++ globalInstance = new Conversions(new RegistryOps.RegistryInfoLookup() { ++ @Override ++ public <T> Optional<RegistryOps.RegistryInfo<T>> lookup(final ResourceKey<? extends Registry<? extends T>> registryRef) { ++ final Registry<T> registry = globalAccess.lookupOrThrow(registryRef); ++ return Optional.of( ++ new RegistryOps.RegistryInfo<>(registry, registry, registry.registryLifecycle()) ++ ); ++ } ++ }); ++ } ++ return globalInstance; ++ } ++ ++ + private final RegistryOps.RegistryInfoLookup lookup; + private final WrapperAwareSerializer serializer; + @@ -464,19 +469,21 @@ index 0000000000000000000000000000000000000000..5b88be976c7773459ce1b6daf58d7ea7 +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/registry/entry/AddableRegistryEntry.java b/src/main/java/io/papermc/paper/registry/entry/AddableRegistryEntry.java new file mode 100644 -index 0000000000000000000000000000000000000000..aeec9b3ae2911f041d000b3db72f37974020ba60 +index 0000000000000000000000000000000000000000..b77e3615879332566161da4935ed59dad1185012 --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/entry/AddableRegistryEntry.java -@@ -0,0 +1,44 @@ +@@ -0,0 +1,46 @@ +package io.papermc.paper.registry.entry; + ++import com.mojang.datafixers.util.Either; +import io.papermc.paper.registry.PaperRegistryBuilder; +import io.papermc.paper.registry.RegistryHolder; +import io.papermc.paper.registry.RegistryKey; -+import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.WritableCraftRegistry; +import io.papermc.paper.registry.data.util.Conversions; +import java.util.function.BiFunction; ++import java.util.function.Function; ++import net.minecraft.core.Holder; +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; @@ -491,7 +498,7 @@ index 0000000000000000000000000000000000000000..aeec9b3ae2911f041d000b3db72f3797 + final ResourceKey<? extends Registry<M>> mcKey, + final RegistryKey<T> apiKey, + final Class<?> classToPreload, -+ final BiFunction<NamespacedKey, M, T> minecraftToBukkit, ++ final Either<BiFunction<? super NamespacedKey, M, ? extends T>, Function<Holder<M>, ? extends T>> minecraftToBukkit, + final PaperRegistryBuilder.Filler<M, T, B> builderFiller + ) { + super(mcKey, apiKey, classToPreload, minecraftToBukkit); @@ -508,23 +515,25 @@ index 0000000000000000000000000000000000000000..aeec9b3ae2911f041d000b3db72f3797 + } + + @Override -+ public B fillBuilder(final Conversions conversions, final TypedKey<T> key, final M nms) { -+ return this.builderFiller.fill(conversions, key, nms); ++ public B fillBuilder(final Conversions conversions, final M nms) { ++ return this.builderFiller.fill(conversions, nms); + } +} diff --git a/src/main/java/io/papermc/paper/registry/entry/ModifiableRegistryEntry.java b/src/main/java/io/papermc/paper/registry/entry/ModifiableRegistryEntry.java new file mode 100644 -index 0000000000000000000000000000000000000000..515a995e3862f8e7cb93d149315ea32e04a08716 +index 0000000000000000000000000000000000000000..4095d508801e3e1fab7d12d3899c2350dc41f0be --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/entry/ModifiableRegistryEntry.java -@@ -0,0 +1,32 @@ +@@ -0,0 +1,34 @@ +package io.papermc.paper.registry.entry; + ++import com.mojang.datafixers.util.Either; +import io.papermc.paper.registry.PaperRegistryBuilder; +import io.papermc.paper.registry.RegistryKey; -+import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.data.util.Conversions; +import java.util.function.BiFunction; ++import java.util.function.Function; ++import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import org.bukkit.Keyed; @@ -538,7 +547,7 @@ index 0000000000000000000000000000000000000000..515a995e3862f8e7cb93d149315ea32e + final ResourceKey<? extends Registry<M>> mcKey, + final RegistryKey<T> apiKey, + final Class<?> toPreload, -+ final BiFunction<NamespacedKey, M, T> minecraftToBukkit, ++ final Either<BiFunction<? super NamespacedKey, M, ? extends T>, Function<Holder<M>, ? extends T>> minecraftToBukkit, + final PaperRegistryBuilder.Filler<M, T, B> builderFiller + ) { + super(mcKey, apiKey, toPreload, minecraftToBukkit); @@ -546,15 +555,15 @@ index 0000000000000000000000000000000000000000..515a995e3862f8e7cb93d149315ea32e + } + + @Override -+ public B fillBuilder(final Conversions conversions, final TypedKey<T> key, final M nms) { -+ return this.builderFiller.fill(conversions, key, nms); ++ public B fillBuilder(final Conversions conversions, final M nms) { ++ return this.builderFiller.fill(conversions, nms); + } +} diff --git a/src/main/java/io/papermc/paper/registry/entry/RegistryEntry.java b/src/main/java/io/papermc/paper/registry/entry/RegistryEntry.java -index 2889d87f0989ae5744cd4c1e57240830aa574155..9494bcf82101340e04559d850570698947b7a9ff 100644 +index f0a81a8b88d31139390e952a0eb8a526e6851c5f..32089721edfd806d082bd267bba040e249dbf75b 100644 --- a/src/main/java/io/papermc/paper/registry/entry/RegistryEntry.java +++ b/src/main/java/io/papermc/paper/registry/entry/RegistryEntry.java -@@ -1,7 +1,13 @@ +@@ -1,13 +1,20 @@ package io.papermc.paper.registry.entry; +import io.papermc.paper.registry.PaperRegistryBuilder; @@ -567,8 +576,7 @@ index 2889d87f0989ae5744cd4c1e57240830aa574155..9494bcf82101340e04559d8505706989 +import io.papermc.paper.registry.event.RegistryFreezeEventImpl; import io.papermc.paper.registry.legacy.DelayedRegistryEntry; import java.util.function.BiFunction; - import java.util.function.Supplier; -@@ -10,6 +16,7 @@ import net.minecraft.resources.ResourceKey; + import net.minecraft.core.Registry; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; import org.bukkit.craftbukkit.util.ApiVersion; @@ -576,13 +584,14 @@ index 2889d87f0989ae5744cd4c1e57240830aa574155..9494bcf82101340e04559d8505706989 public interface RegistryEntry<M, B extends Keyed> extends RegistryEntryInfo<M, B> { // TODO remove Keyed -@@ -29,6 +36,65 @@ public interface RegistryEntry<M, B extends Keyed> extends RegistryEntryInfo<M, +@@ -26,4 +33,63 @@ public interface RegistryEntry<M, B extends Keyed> extends RegistryEntryInfo<M, + default RegistryEntry<M, B> delayed() { return new DelayedRegistryEntry<>(this); } - ++ + interface BuilderHolder<M, T, B extends PaperRegistryBuilder<M, T>> extends RegistryEntryInfo<M, T> { + -+ B fillBuilder(Conversions conversions, TypedKey<T> key, M nms); ++ B fillBuilder(Conversions conversions, M nms); + } + + /** @@ -638,46 +647,51 @@ index 2889d87f0989ae5744cd4c1e57240830aa574155..9494bcf82101340e04559d8505706989 + private static <M, B extends Keyed> RegistryEntryInfo<M, B> possiblyUnwrap(final RegistryEntryInfo<M, B> entry) { + return entry instanceof final DelayedRegistryEntry<M, B> delayed ? delayed.delegate() : entry; + } + } +diff --git a/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java b/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java +index c3d783e1a037c0797995713728ff43b2838f6591..2171757dbe705a3cf377931975ea0f85f54e7bf8 100644 +--- a/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java ++++ b/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java +@@ -1,6 +1,7 @@ + package io.papermc.paper.registry.entry; + + import com.mojang.datafixers.util.Either; ++import io.papermc.paper.registry.PaperRegistryBuilder; + import io.papermc.paper.registry.RegistryKey; + import java.util.function.BiFunction; + import java.util.function.Function; +@@ -59,5 +60,17 @@ public class RegistryEntryBuilder<M, A extends Keyed> { // TODO remove Keyed + public RegistryEntry<M, A> build() { + return new CraftRegistryEntry<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit); + } + - static <M, B extends Keyed> RegistryEntry<M, B> entry( - final ResourceKey<? extends Registry<M>> mcKey, - final RegistryKey<B> apiKey, -@@ -45,4 +111,24 @@ public interface RegistryEntry<M, B extends Keyed> extends RegistryEntryInfo<M, - ) { - return new ApiRegistryEntry<>(mcKey, apiKey, apiRegistrySupplier); - } ++ public <B extends PaperRegistryBuilder<M, A>> RegistryEntry<M, A> modifiable(final PaperRegistryBuilder.Filler<M, A, B> filler) { ++ return new ModifiableRegistryEntry<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit, filler); ++ } + -+ static <M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> RegistryEntry<M, T> modifiable( -+ final ResourceKey<? extends Registry<M>> mcKey, -+ final RegistryKey<T> apiKey, -+ final Class<?> toPreload, -+ final BiFunction<NamespacedKey, M, T> minecraftToBukkit, -+ final PaperRegistryBuilder.Filler<M, T, B> filler -+ ) { -+ return new ModifiableRegistryEntry<>(mcKey, apiKey, toPreload, minecraftToBukkit, filler); -+ } ++ public <B extends PaperRegistryBuilder<M, A>> RegistryEntry<M, A> addable(final PaperRegistryBuilder.Filler<M, A, B> filler) { ++ return new AddableRegistryEntry<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit, filler); ++ } + -+ static <M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> RegistryEntry<M, T> writable( -+ final ResourceKey<? extends Registry<M>> mcKey, -+ final RegistryKey<T> apiKey, -+ final Class<?> toPreload, -+ final BiFunction<NamespacedKey, M, T> minecraftToBukkit, -+ final PaperRegistryBuilder.Filler<M, T, B> filler -+ ) { -+ return new WritableRegistryEntry<>(mcKey, apiKey, toPreload, minecraftToBukkit, filler); -+ } ++ public <B extends PaperRegistryBuilder<M, A>> RegistryEntry<M, A> writable(final PaperRegistryBuilder.Filler<M, A, B> filler) { ++ return new WritableRegistryEntry<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit, filler); ++ } + } } diff --git a/src/main/java/io/papermc/paper/registry/entry/WritableRegistryEntry.java b/src/main/java/io/papermc/paper/registry/entry/WritableRegistryEntry.java new file mode 100644 -index 0000000000000000000000000000000000000000..562accce731630327d116afd1c9d559df7e386bd +index 0000000000000000000000000000000000000000..080e2d44a4da98a9b147c9f641378315d53b356c --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/entry/WritableRegistryEntry.java -@@ -0,0 +1,22 @@ +@@ -0,0 +1,25 @@ +package io.papermc.paper.registry.entry; + ++import com.mojang.datafixers.util.Either; +import io.papermc.paper.registry.PaperRegistryBuilder; +import io.papermc.paper.registry.RegistryKey; +import java.util.function.BiFunction; ++import java.util.function.Function; ++import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import org.bukkit.Keyed; @@ -689,7 +703,7 @@ index 0000000000000000000000000000000000000000..562accce731630327d116afd1c9d559d + final ResourceKey<? extends Registry<M>> mcKey, + final RegistryKey<T> apiKey, + final Class<?> classToPreload, -+ final BiFunction<NamespacedKey, M, T> minecraftToBukkit, ++ final Either<BiFunction<? super NamespacedKey, M, ? extends T>, Function<Holder<M>, ? extends T>> minecraftToBukkit, + final PaperRegistryBuilder.Filler<M, T, B> builderFiller + ) { + super(mcKey, apiKey, classToPreload, minecraftToBukkit, builderFiller); @@ -1210,43 +1224,15 @@ index 4638ba98dbbdb0f880337347be85a6e0fbed2191..bc448f8511c629d1f13d4baf717a11e6 } } diff --git a/src/main/java/net/minecraft/resources/RegistryDataLoader.java b/src/main/java/net/minecraft/resources/RegistryDataLoader.java -index b8c1840eeda982c0c6350e49fae2784a599ef3ce..1b167e8e0b42a49de1c5f0ea33dc9bef6ddd0f83 100644 +index b8c1840eeda982c0c6350e49fae2784a599ef3ce..1aaa18b91a13cffac5f3d03fbae207f8ea91d3c7 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 { - public static RegistryAccess.Frozen load( - ResourceManager resourceManager, List<HolderLookup.RegistryLookup<?>> registries, List<RegistryDataLoader.RegistryData<?>> entries - ) { -- return load((loader, infoGetter) -> loader.loadFromResources(resourceManager, infoGetter), registries, entries); -+ return load((loader, infoGetter, conversions) -> loader.loadFromResources(resourceManager, infoGetter, conversions), registries, entries); // Paper - pass conversions - } - - public static RegistryAccess.Frozen load( -@@ -139,7 +139,7 @@ public class RegistryDataLoader { - List<HolderLookup.RegistryLookup<?>> registries, - List<RegistryDataLoader.RegistryData<?>> entries - ) { -- return load((loader, infoGetter) -> loader.loadFromNetwork(data, factory, infoGetter), registries, entries); -+ return load((loader, infoGetter, conversions) -> loader.loadFromNetwork(data, factory, infoGetter, conversions), registries, entries); // Paper - pass conversions - } - - private static RegistryAccess.Frozen load( -@@ -148,7 +148,8 @@ public class RegistryDataLoader { - Map<ResourceKey<?>, Exception> map = new HashMap<>(); - List<RegistryDataLoader.Loader<?>> list = entries.stream().map(entry -> entry.create(Lifecycle.stable(), map)).collect(Collectors.toUnmodifiableList()); - RegistryOps.RegistryInfoLookup registryInfoLookup = createContext(registries, list); -- list.forEach(loader -> loadable.apply((RegistryDataLoader.Loader<?>)loader, registryInfoLookup)); -+ final io.papermc.paper.registry.data.util.Conversions conversions = new io.papermc.paper.registry.data.util.Conversions(registryInfoLookup); // Paper - create conversions -+ list.forEach(loader -> loadable.apply((RegistryDataLoader.Loader<?>)loader, registryInfoLookup, conversions)); - list.forEach(loader -> { - Registry<?> registry = loader.registry(); - -@@ -238,13 +239,13 @@ public class RegistryDataLoader { +@@ -238,13 +238,13 @@ public class RegistryDataLoader { } private static <E> void loadElementFromResource( - WritableRegistry<E> registry, Decoder<E> decoder, RegistryOps<JsonElement> ops, ResourceKey<E> key, Resource resource, RegistrationInfo entryInfo -+ WritableRegistry<E> registry, Decoder<E> decoder, RegistryOps<JsonElement> ops, ResourceKey<E> key, Resource resource, RegistrationInfo entryInfo, io.papermc.paper.registry.data.util.Conversions conversions ++ WritableRegistry<E> registry, Decoder<E> decoder, RegistryOps<JsonElement> ops, ResourceKey<E> key, Resource resource, RegistrationInfo entryInfo, io.papermc.paper.registry.data.util.Conversions conversions // Paper - pass conversions ) throws IOException { try (Reader reader = resource.openAsReader()) { JsonElement jsonElement = JsonParser.parseReader(reader); @@ -1257,17 +1243,15 @@ index b8c1840eeda982c0c6350e49fae2784a599ef3ce..1b167e8e0b42a49de1c5f0ea33dc9bef } } -@@ -253,7 +254,8 @@ public class RegistryDataLoader { - RegistryOps.RegistryInfoLookup infoGetter, - WritableRegistry<E> registry, - Decoder<E> elementDecoder, -- Map<ResourceKey<?>, Exception> errors -+ Map<ResourceKey<?>, Exception> errors, -+ io.papermc.paper.registry.data.util.Conversions conversions // Paper - pass conversions - ) { +@@ -258,6 +258,7 @@ public class RegistryDataLoader { FileToIdConverter fileToIdConverter = FileToIdConverter.registry(registry.key()); RegistryOps<JsonElement> registryOps = RegistryOps.create(JsonOps.INSTANCE, infoGetter); -@@ -265,7 +267,7 @@ public class RegistryDataLoader { + ++ final io.papermc.paper.registry.data.util.Conversions conversions = new io.papermc.paper.registry.data.util.Conversions(infoGetter); // Paper - create conversions + for (Entry<ResourceLocation, Resource> entry : fileToIdConverter.listMatchingResources(resourceManager).entrySet()) { + ResourceLocation resourceLocation = entry.getKey(); + ResourceKey<E> resourceKey = ResourceKey.create(registry.key(), fileToIdConverter.fileToId(resourceLocation)); +@@ -265,7 +266,7 @@ public class RegistryDataLoader { RegistrationInfo registrationInfo = REGISTRATION_INFO_CACHE.apply(resource.knownPackInfo()); try { @@ -1276,7 +1260,7 @@ index b8c1840eeda982c0c6350e49fae2784a599ef3ce..1b167e8e0b42a49de1c5f0ea33dc9bef } catch (Exception var14) { errors.put( resourceKey, -@@ -274,6 +276,7 @@ public class RegistryDataLoader { +@@ -274,6 +275,7 @@ public class RegistryDataLoader { } } @@ -1284,17 +1268,15 @@ index b8c1840eeda982c0c6350e49fae2784a599ef3ce..1b167e8e0b42a49de1c5f0ea33dc9bef TagLoader.loadTagsForRegistry(resourceManager, registry); } -@@ -283,7 +286,8 @@ public class RegistryDataLoader { - RegistryOps.RegistryInfoLookup infoGetter, - WritableRegistry<E> registry, - Decoder<E> decoder, -- Map<ResourceKey<?>, Exception> loadingErrors -+ Map<ResourceKey<?>, Exception> loadingErrors, -+ io.papermc.paper.registry.data.util.Conversions conversions // Paper - pass conversions - ) { - RegistryDataLoader.NetworkedRegistryData networkedRegistryData = data.get(registry.key()); - if (networkedRegistryData != null) { -@@ -309,7 +313,7 @@ public class RegistryDataLoader { +@@ -291,6 +293,7 @@ public class RegistryDataLoader { + RegistryOps<JsonElement> registryOps2 = RegistryOps.create(JsonOps.INSTANCE, infoGetter); + FileToIdConverter fileToIdConverter = FileToIdConverter.registry(registry.key()); + ++ final io.papermc.paper.registry.data.util.Conversions conversions = new io.papermc.paper.registry.data.util.Conversions(infoGetter); // Paper - create conversions + for (RegistrySynchronization.PackedRegistryEntry packedRegistryEntry : networkedRegistryData.elements) { + ResourceKey<E> resourceKey = ResourceKey.create(registry.key(), packedRegistryEntry.id()); + Optional<Tag> optional = packedRegistryEntry.data(); +@@ -309,7 +312,7 @@ public class RegistryDataLoader { try { Resource resource = factory.getResourceOrThrow(resourceLocation); @@ -1303,35 +1285,6 @@ index b8c1840eeda982c0c6350e49fae2784a599ef3ce..1b167e8e0b42a49de1c5f0ea33dc9bef } catch (Exception var17) { loadingErrors.put(resourceKey, new IllegalStateException("Failed to parse local data", var17)); } -@@ -321,22 +325,23 @@ public class RegistryDataLoader { - } - - static record Loader<T>(RegistryDataLoader.RegistryData<T> data, WritableRegistry<T> registry, Map<ResourceKey<?>, Exception> loadingErrors) { -- public void loadFromResources(ResourceManager resourceManager, RegistryOps.RegistryInfoLookup infoGetter) { -- RegistryDataLoader.loadContentsFromManager(resourceManager, infoGetter, this.registry, this.data.elementCodec, this.loadingErrors); -+ public void loadFromResources(ResourceManager resourceManager, RegistryOps.RegistryInfoLookup infoGetter, io.papermc.paper.registry.data.util.Conversions conversions) { // Paper - pass conversions -+ RegistryDataLoader.loadContentsFromManager(resourceManager, infoGetter, this.registry, this.data.elementCodec, this.loadingErrors, conversions); // Paper - pass conversions - } - - public void loadFromNetwork( - Map<ResourceKey<? extends Registry<?>>, RegistryDataLoader.NetworkedRegistryData> data, - ResourceProvider factory, -- RegistryOps.RegistryInfoLookup infoGetter -+ RegistryOps.RegistryInfoLookup infoGetter, -+ io.papermc.paper.registry.data.util.Conversions conversions // Paper - ) { -- RegistryDataLoader.loadContentsFromNetwork(data, factory, infoGetter, this.registry, this.data.elementCodec, this.loadingErrors); -+ RegistryDataLoader.loadContentsFromNetwork(data, factory, infoGetter, this.registry, this.data.elementCodec, this.loadingErrors, conversions); // Paper - pass conversions - } - } - - @FunctionalInterface - interface LoadingFunction { -- void apply(RegistryDataLoader.Loader<?> loader, RegistryOps.RegistryInfoLookup infoGetter); -+ void apply(RegistryDataLoader.Loader<?> loader, RegistryOps.RegistryInfoLookup infoGetter, io.papermc.paper.registry.data.util.Conversions conversions); // Paper - pass conversions - } - - public static record NetworkedRegistryData(List<RegistrySynchronization.PackedRegistryEntry> elements, TagNetworkSerialization.NetworkPayload tags) { diff --git a/src/main/java/net/minecraft/server/ReloadableServerRegistries.java b/src/main/java/net/minecraft/server/ReloadableServerRegistries.java index 185752185549ebd5f431932b63d8e5fea50a2cb2..f4d25d1aed5bcd3b8119ac7356a9cccc9d4ff54c 100644 --- a/src/main/java/net/minecraft/server/ReloadableServerRegistries.java @@ -1365,24 +1318,10 @@ index 185752185549ebd5f431932b63d8e5fea50a2cb2..f4d25d1aed5bcd3b8119ac7356a9cccc return writableRegistry; }, prepareExecutor); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java -index 45c78c113e881b277e1216293ad918ee40b44325..8314059455d91f01b986c5c0a239f41817834bd6 100644 +index 47951e62aa384542c3ba92e1ef6162031d05a300..f271197337a65e1af8812735c84d6b1d5c331fb7 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java -@@ -164,11 +164,11 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { - private final Map<NamespacedKey, B> cache = new HashMap<>(); - private final Map<B, NamespacedKey> byValue = new java.util.IdentityHashMap<>(); // Paper - improve Registry - private final net.minecraft.core.Registry<M> minecraftRegistry; -- private final BiFunction<NamespacedKey, M, B> minecraftToBukkit; -+ private final BiFunction<? super NamespacedKey, M, B> minecraftToBukkit; // Paper - private final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> serializationUpdater; // Paper - rename to make it *clear* what it is *only* for - private boolean init; - -- public CraftRegistry(Class<?> bukkitClass, net.minecraft.core.Registry<M> minecraftRegistry, BiFunction<NamespacedKey, M, B> minecraftToBukkit, BiFunction<NamespacedKey, ApiVersion, NamespacedKey> serializationUpdater) { // Paper - relax preload class -+ public CraftRegistry(Class<?> bukkitClass, net.minecraft.core.Registry<M> minecraftRegistry, BiFunction<? super NamespacedKey, M, B> minecraftToBukkit, BiFunction<NamespacedKey, ApiVersion, NamespacedKey> serializationUpdater) { // Paper - relax preload class - this.bukkitClass = bukkitClass; - this.minecraftRegistry = minecraftRegistry; - this.minecraftToBukkit = minecraftToBukkit; -@@ -251,4 +251,17 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { +@@ -307,4 +307,17 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> { return this.byValue.get(value); } // Paper end - improve Registry @@ -1409,7 +1348,7 @@ index 0000000000000000000000000000000000000000..8bee1a5ed877a04e4d027593df1f42ce +io.papermc.paper.registry.event.RegistryEventTypeProviderImpl diff --git a/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java b/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java new file mode 100644 -index 0000000000000000000000000000000000000000..f2f1dfe4277ce1e84a9494bee285badc958c8d3f +index 0000000000000000000000000000000000000000..55f5fc45cfd5be16b4d8e6d083ff10a744196a5e --- /dev/null +++ b/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java @@ -0,0 +1,44 @@ @@ -1452,7 +1391,7 @@ index 0000000000000000000000000000000000000000..f2f1dfe4277ce1e84a9494bee285badc + <M, T> void testEquality(final RegistryEntry.BuilderHolder<M, T, ?> registryEntry) { + final Registry<M> registry = RegistryHelper.getRegistry().lookupOrThrow(registryEntry.mcKey()); + for (final Map.Entry<ResourceKey<M>, M> entry : registry.entrySet()) { -+ final M built = registryEntry.fillBuilder(new Conversions(new RegistryOps.HolderLookupAdapter(RegistryHelper.getRegistry())), PaperRegistries.fromNms(entry.getKey()), entry.getValue()).build(); ++ final M built = registryEntry.fillBuilder(new Conversions(new RegistryOps.HolderLookupAdapter(RegistryHelper.getRegistry())), entry.getValue()).build(); + assertEquals(entry.getValue(), built); + } + } diff --git a/patches/server/1029-Add-registry-entry-and-builders.patch b/patches/server/1029-Add-registry-entry-and-builders.patch index a0aa6a26c8..bc35d90ba9 100644 --- a/patches/server/1029-Add-registry-entry-and-builders.patch +++ b/patches/server/1029-Add-registry-entry-and-builders.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add registry entry and builders diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/src/main/java/io/papermc/paper/registry/PaperRegistries.java -index 86c9f87cdb41c0d1ccc2a61b501f969cfaae47bc..fd024576e70e0c121c1477a0b7777af18159b7c4 100644 +index 875b3e761d83ab3ddfe05fdf978136c7d683bb0c..dcca8bbba5c54001c3cf4fdcd8eeb08ffb1ba574 100644 --- a/src/main/java/io/papermc/paper/registry/PaperRegistries.java +++ b/src/main/java/io/papermc/paper/registry/PaperRegistries.java @@ -2,6 +2,9 @@ package io.papermc.paper.registry; @@ -18,34 +18,34 @@ index 86c9f87cdb41c0d1ccc2a61b501f969cfaae47bc..fd024576e70e0c121c1477a0b7777af1 import io.papermc.paper.registry.entry.RegistryEntry; import io.papermc.paper.registry.tag.TagKey; import java.util.Collections; -@@ -78,7 +81,7 @@ public final class PaperRegistries { +@@ -76,7 +79,7 @@ public final class PaperRegistries { static { REGISTRY_ENTRIES = List.of( // built-ins -- entry(Registries.GAME_EVENT, RegistryKey.GAME_EVENT, GameEvent.class, CraftGameEvent::new), -+ writable(Registries.GAME_EVENT, RegistryKey.GAME_EVENT, GameEvent.class, CraftGameEvent::new, PaperGameEventRegistryEntry.PaperBuilder::new), - 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), -@@ -100,10 +103,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(), -- entry(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT, Enchantment.class, CraftEnchantment::new).withSerializationUpdater(FieldRename.ENCHANTMENT_RENAME).delayed(), -+ 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(), -+ 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(), +- start(Registries.GAME_EVENT, RegistryKey.GAME_EVENT).craft(GameEvent.class, CraftGameEvent::new).build(), ++ start(Registries.GAME_EVENT, RegistryKey.GAME_EVENT).craft(GameEvent.class, CraftGameEvent::new).writable(PaperGameEventRegistryEntry.PaperBuilder::new), + start(Registries.STRUCTURE_TYPE, RegistryKey.STRUCTURE_TYPE).craft(StructureType.class, CraftStructureType::new).build(), + start(Registries.MOB_EFFECT, RegistryKey.MOB_EFFECT).craft(PotionEffectType.class, CraftPotionEffectType::new).build(), + start(Registries.BLOCK, RegistryKey.BLOCK).craft(BlockType.class, CraftBlockType::new).build(), +@@ -98,10 +101,10 @@ public final class PaperRegistries { + start(Registries.TRIM_PATTERN, RegistryKey.TRIM_PATTERN).craft(TrimPattern.class, CraftTrimPattern::new).build().delayed(), + start(Registries.DAMAGE_TYPE, RegistryKey.DAMAGE_TYPE).craft(DamageType.class, CraftDamageType::new).build().delayed(), + start(Registries.WOLF_VARIANT, RegistryKey.WOLF_VARIANT).craft(Wolf.Variant.class, CraftWolf.CraftVariant::new).build().delayed(), +- start(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT).craft(Enchantment.class, CraftEnchantment::new).build().withSerializationUpdater(FieldRename.ENCHANTMENT_RENAME).delayed(), ++ start(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT).craft(Enchantment.class, CraftEnchantment::new).writable(PaperEnchantmentRegistryEntry.PaperBuilder::new).withSerializationUpdater(FieldRename.ENCHANTMENT_RENAME).delayed(), + start(Registries.JUKEBOX_SONG, RegistryKey.JUKEBOX_SONG).craft(JukeboxSong.class, CraftJukeboxSong::new).build().delayed(), + start(Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN).craft(PatternType.class, CraftPatternType::new).build().delayed(), +- start(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT).craft(Art.class, CraftArt::new).build().delayed(), ++ start(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT).craft(Art.class, CraftArt::new).writable(PaperPaintingVariantRegistryEntry.PaperBuilder::new).delayed(), + start(Registries.INSTRUMENT, RegistryKey.INSTRUMENT).craft(MusicInstrument.class, CraftMusicInstrument::new).build().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..1b1c6838452d3001070a5d43cc49e3a09de7153d +index 0000000000000000000000000000000000000000..0191aa22a35551136e8f3da9a6a3a003af38f37b --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/data/PaperEnchantmentRegistryEntry.java -@@ -0,0 +1,230 @@ +@@ -0,0 +1,229 @@ +package io.papermc.paper.registry.data; + +import com.google.common.base.Preconditions; @@ -103,7 +103,6 @@ index 0000000000000000000000000000000000000000..1b1c6838452d3001070a5d43cc49e3a0 + + public PaperEnchantmentRegistryEntry( + final Conversions conversions, -+ final TypedKey<org.bukkit.enchantments.Enchantment> ignoredKey, + final @Nullable Enchantment internal + ) { + this.conversions = conversions; @@ -188,8 +187,8 @@ index 0000000000000000000000000000000000000000..1b1c6838452d3001070a5d43cc49e3a0 + public static final class PaperBuilder extends PaperEnchantmentRegistryEntry implements EnchantmentRegistryEntry.Builder, + PaperRegistryBuilder<Enchantment, org.bukkit.enchantments.Enchantment> { + -+ public PaperBuilder(final Conversions conversions, final TypedKey<org.bukkit.enchantments.Enchantment> key, final @Nullable Enchantment internal) { -+ super(conversions, key, internal); ++ public PaperBuilder(final Conversions conversions, final @Nullable Enchantment internal) { ++ super(conversions, internal); + } + + @Override @@ -278,10 +277,10 @@ index 0000000000000000000000000000000000000000..1b1c6838452d3001070a5d43cc49e3a0 +} diff --git a/src/main/java/io/papermc/paper/registry/data/PaperGameEventRegistryEntry.java b/src/main/java/io/papermc/paper/registry/data/PaperGameEventRegistryEntry.java new file mode 100644 -index 0000000000000000000000000000000000000000..2100e8aca6f7ae7b90545bd3f4d4b800dba65daa +index 0000000000000000000000000000000000000000..249c1b0dd4f1fbfd64cde461adfcbe5752013335 --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/data/PaperGameEventRegistryEntry.java -@@ -0,0 +1,54 @@ +@@ -0,0 +1,52 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.PaperRegistryBuilder; @@ -300,7 +299,6 @@ index 0000000000000000000000000000000000000000..2100e8aca6f7ae7b90545bd3f4d4b800 + + public PaperGameEventRegistryEntry( + final Conversions ignoredConversions, -+ final io.papermc.paper.registry.TypedKey<org.bukkit.GameEvent> ignoredKey, + final @Nullable GameEvent internal + ) { + if (internal == null) return; @@ -318,10 +316,9 @@ index 0000000000000000000000000000000000000000..2100e8aca6f7ae7b90545bd3f4d4b800 + + public PaperBuilder( + final Conversions conversions, -+ final io.papermc.paper.registry.TypedKey<org.bukkit.GameEvent> key, + final @Nullable GameEvent internal + ) { -+ super(conversions, key, internal); ++ super(conversions, internal); + } + + @Override @@ -338,15 +335,14 @@ index 0000000000000000000000000000000000000000..2100e8aca6f7ae7b90545bd3f4d4b800 +} 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..68b3d747f759f615a3c942de3f4d7a0fe856cd84 +index 0000000000000000000000000000000000000000..31430bfbec5bfbfd68a5fe60ab91d4dc0871da83 --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/data/PaperPaintingVariantRegistryEntry.java -@@ -0,0 +1,120 @@ +@@ -0,0 +1,116 @@ +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; @@ -356,14 +352,12 @@ index 0000000000000000000000000000000000000000..68b3d747f759f615a3c942de3f4d7a0f +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(); @@ -376,7 +370,6 @@ index 0000000000000000000000000000000000000000..68b3d747f759f615a3c942de3f4d7a0f + + public PaperPaintingVariantRegistryEntry( + final Conversions conversions, -+ final TypedKey<Art> ignoredKey, + final @Nullable PaintingVariant internal + ) { + this.conversions = conversions; @@ -416,8 +409,8 @@ index 0000000000000000000000000000000000000000..68b3d747f759f615a3c942de3f4d7a0f + + public static final class PaperBuilder extends PaperPaintingVariantRegistryEntry implements PaintingVariantRegistryEntry.Builder, PaperRegistryBuilder<PaintingVariant, Art> { + -+ public PaperBuilder(final Conversions conversions, final TypedKey<Art> key, final @Nullable PaintingVariant internal) { -+ super(conversions, key, internal); ++ public PaperBuilder(final Conversions conversions, final @Nullable PaintingVariant internal) { ++ super(conversions, internal); + } + + @Override diff --git a/patches/server/1030-Tag-Lifecycle-Events.patch b/patches/server/1030-Tag-Lifecycle-Events.patch index 291ec0be33..8eefc8bd9e 100644 --- a/patches/server/1030-Tag-Lifecycle-Events.patch +++ b/patches/server/1030-Tag-Lifecycle-Events.patch @@ -461,10 +461,10 @@ index 0000000000000000000000000000000000000000..d6d4bfc6f45d646afeace422a038c670 +) { +} diff --git a/src/main/java/net/minecraft/resources/RegistryDataLoader.java b/src/main/java/net/minecraft/resources/RegistryDataLoader.java -index 1b167e8e0b42a49de1c5f0ea33dc9bef6ddd0f83..f102d3ea4e470fca2c3f74a0e3c1552bd3bd29f4 100644 +index 1aaa18b91a13cffac5f3d03fbae207f8ea91d3c7..21c90a4f6e84ef447fd4653feb3eb64b0ecb378c 100644 --- a/src/main/java/net/minecraft/resources/RegistryDataLoader.java +++ b/src/main/java/net/minecraft/resources/RegistryDataLoader.java -@@ -277,7 +277,7 @@ public class RegistryDataLoader { +@@ -276,7 +276,7 @@ public class RegistryDataLoader { } io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), conversions); // Paper - run pre-freeze listeners diff --git a/patches/server/1032-DataComponent-API.patch b/patches/server/1032-DataComponent-API.patch index 2493615d74..b66dd48c80 100644 --- a/patches/server/1032-DataComponent-API.patch +++ b/patches/server/1032-DataComponent-API.patch @@ -3697,26 +3697,26 @@ 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 fd024576e70e0c121c1477a0b7777af18159b7c4..132afec6bceb6c866de0aeb83db9613d4e74e2e7 100644 +index dcca8bbba5c54001c3cf4fdcd8eeb08ffb1ba574..21f5c8af86c866ff7e0f7af3b3b810824b087d26 100644 --- a/src/main/java/io/papermc/paper/registry/PaperRegistries.java +++ b/src/main/java/io/papermc/paper/registry/PaperRegistries.java @@ -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.DataComponentTypes; +import io.papermc.paper.datacomponent.PaperDataComponentType; import io.papermc.paper.registry.data.PaperEnchantmentRegistryEntry; import io.papermc.paper.registry.data.PaperGameEventRegistryEntry; import io.papermc.paper.registry.data.PaperPaintingVariantRegistryEntry; -@@ -95,6 +97,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), -+ entry(Registries.DATA_COMPONENT_TYPE, RegistryKey.DATA_COMPONENT_TYPE, DataComponentType.class, PaperDataComponentType::of), +@@ -93,6 +95,7 @@ public final class PaperRegistries { + start(Registries.ATTRIBUTE, RegistryKey.ATTRIBUTE).craft(Attribute.class, CraftAttribute::new).build(), + start(Registries.FLUID, RegistryKey.FLUID).craft(Fluid.class, CraftFluid::new).build(), + start(Registries.SOUND_EVENT, RegistryKey.SOUND_EVENT).craft(Sound.class, CraftSound::new).build(), ++ start(Registries.DATA_COMPONENT_TYPE, RegistryKey.DATA_COMPONENT_TYPE).craft(DataComponentTypes.class, PaperDataComponentType::of).build(), // data-drivens - entry(Registries.BIOME, RegistryKey.BIOME, Biome.class, CraftBiome::new).delayed(), + start(Registries.BIOME, RegistryKey.BIOME).craft(Biome.class, CraftBiome::new).build().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..78975412da0f0c2b802bfce6d30d56b26d8023e2 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java diff --git a/patches/server/1073-Switch-Impl-types-to-Holderable.patch b/patches/server/1073-Switch-Impl-types-to-Holderable.patch new file mode 100644 index 0000000000..b0f0306fc0 --- /dev/null +++ b/patches/server/1073-Switch-Impl-types-to-Holderable.patch @@ -0,0 +1,405 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic <[email protected]> +Date: Sun, 24 Nov 2024 15:08:19 -0800 +Subject: [PATCH] Switch Impl types to Holderable + + +diff --git a/src/main/java/io/papermc/paper/util/Holderable.java b/src/main/java/io/papermc/paper/util/Holderable.java +index 404ab0df12bc8182520c77328017c128d22993eb..0d2496168efe69bd82d3b73b41f798e9ac03ffa4 100644 +--- a/src/main/java/io/papermc/paper/util/Holderable.java ++++ b/src/main/java/io/papermc/paper/util/Holderable.java +@@ -1,8 +1,22 @@ + package io.papermc.paper.util; + ++import com.google.gson.JsonElement; ++import com.google.gson.JsonParser; ++import com.google.gson.JsonSyntaxException; ++import com.mojang.serialization.Codec; ++import com.mojang.serialization.JsonOps; ++import net.kyori.adventure.key.Key; + import net.minecraft.core.Holder; ++import net.minecraft.resources.RegistryOps; ++import org.bukkit.Keyed; ++import org.bukkit.Registry; ++import org.bukkit.craftbukkit.CraftRegistry; + import org.bukkit.craftbukkit.util.Handleable; ++import org.intellij.lang.annotations.Subst; ++import org.jspecify.annotations.NullMarked; ++import org.jspecify.annotations.Nullable; + ++@NullMarked + public interface Holderable<M> extends Handleable<M> { + + Holder<M> getHolder(); +@@ -11,4 +25,42 @@ public interface Holderable<M> extends Handleable<M> { + default M getHandle() { + return this.getHolder().value(); + } ++ ++ static <T extends Keyed, M> @Nullable T fromBukkitSerializationString(@Subst("test:key") String string, Codec<? extends Holder<M>> codec, Registry<T> registry) { ++ if (registry instanceof CraftRegistry<T, M> craftRegistry && craftRegistry.supportsDirectHolders()) { ++ try { ++ JsonElement element = JsonParser.parseString(string); ++ final RegistryOps<JsonElement> ops = CraftRegistry.getMinecraftRegistry().createSerializationContext(JsonOps.INSTANCE); ++ Holder<M> holder = codec.decode(ops, element).getOrThrow().getFirst(); ++ return craftRegistry.convertDirectHolder(holder); ++ } catch (JsonSyntaxException ex) { ++ // ignore, try to parse as a key ++ } ++ } ++ if (!Key.parseable(string)) { ++ return null; ++ } ++ return registry.get(Key.key(string)); ++ } ++ ++ default String toBukkitSerializationString(Codec<? super Holder<M>> codec) { ++ final RegistryOps<JsonElement> ops = CraftRegistry.getMinecraftRegistry().createSerializationContext(JsonOps.INSTANCE); ++ return codec.encodeStart(ops, this.getHolder()).getOrThrow().getAsString(); ++ } ++ ++ /** ++ * All implementations should use this as their hashCode implementation ++ */ ++ default int implHashCode() { ++ return this.getHolder().hashCode(); ++ } ++ ++ /** ++ * All implementations should use this as their equals implementation ++ */ ++ default boolean implEquals(final Object o) { ++ if (o == null || this.getClass() != o.getClass()) return false; ++ final Holderable<?> that = (Holderable<?>) o; ++ return this.getHolder().equals(that.getHolder()); ++ } + } +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftMusicInstrument.java b/src/main/java/org/bukkit/craftbukkit/CraftMusicInstrument.java +index 2838ef9d89ec8d7bd8981eff4a2ffe2c11ee9271..d4df11c3f4eadfb5635b4a5c2461955c7a48df19 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftMusicInstrument.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftMusicInstrument.java +@@ -10,14 +10,14 @@ import org.bukkit.Registry; + import org.bukkit.craftbukkit.util.Handleable; + import org.jetbrains.annotations.NotNull; + +-public class CraftMusicInstrument extends MusicInstrument implements Handleable<Instrument> { ++public class CraftMusicInstrument extends MusicInstrument implements io.papermc.paper.util.Holderable<Instrument> { + + public static MusicInstrument minecraftToBukkit(Instrument minecraft) { + return CraftRegistry.minecraftToBukkit(minecraft, Registries.INSTRUMENT, Registry.INSTRUMENT); + } + + public static MusicInstrument minecraftHolderToBukkit(Holder<Instrument> minecraft) { +- return CraftMusicInstrument.minecraftToBukkit(minecraft.value()); ++ return CraftRegistry.minecraftHolderToBukkit(minecraft, Registry.INSTRUMENT); // Paper - switch to Holder + } + + public static Instrument bukkitToMinecraft(MusicInstrument bukkit) { +@@ -25,41 +25,46 @@ public class CraftMusicInstrument extends MusicInstrument implements Handleable< + } + + public static Holder<Instrument> bukkitToMinecraftHolder(MusicInstrument bukkit) { +- Preconditions.checkArgument(bukkit != null); +- +- net.minecraft.core.Registry<Instrument> registry = CraftRegistry.getMinecraftRegistry(Registries.INSTRUMENT); +- +- if (registry.wrapAsHolder(CraftMusicInstrument.bukkitToMinecraft(bukkit)) instanceof Holder.Reference<Instrument> holder) { +- return holder; +- } +- +- throw new IllegalArgumentException("No Reference holder found for " + bukkit +- + ", this can happen if a plugin creates its own instrument without properly registering it."); ++ return CraftRegistry.bukkitToMinecraftHolder(bukkit, Registries.INSTRUMENT); // Paper - switch to Holder + } + + public static String bukkitToString(MusicInstrument bukkit) { + Preconditions.checkArgument(bukkit != null); + +- return bukkit.getKey().toString(); ++ return ((CraftMusicInstrument) bukkit).toBukkitSerializationString(Instrument.CODEC); // Paper - switch to Holder + } + + public static MusicInstrument stringToBukkit(String string) { + Preconditions.checkArgument(string != null); + +- return Registry.INSTRUMENT.get(NamespacedKey.fromString(string)); ++ return io.papermc.paper.util.Holderable.fromBukkitSerializationString(string, Instrument.CODEC, Registry.INSTRUMENT); // Paper - switch to Holder + } + + private final NamespacedKey key; + private final Instrument handle; + +- public CraftMusicInstrument(NamespacedKey key, Instrument handle) { +- this.key = key; +- this.handle = handle; ++ // Paper start - switch to Holder ++ @Override ++ public boolean equals(final Object o) { ++ return this.implEquals(o); ++ } ++ ++ @Override ++ public int hashCode() { ++ return this.implHashCode(); ++ } ++ ++ private final Holder<Instrument> holder; ++ public CraftMusicInstrument(Holder<Instrument> holder) { ++ this.holder = holder; ++ this.key = holder.unwrapKey().map(io.papermc.paper.util.MCUtil::fromResourceKey).orElse(null); ++ this.handle = holder.value(); ++ // Paper end - switch to Holder + } + + @Override +- public Instrument getHandle() { +- return this.handle; ++ public Holder<Instrument> getHolder() { // Paper - switch to Holder ++ return this.holder; // Paper - switch to Holder + } + + @NotNull +@@ -79,26 +84,10 @@ public class CraftMusicInstrument extends MusicInstrument implements Handleable< + } + // Paper end - add translationKey methods + +- @Override +- public boolean equals(Object other) { +- if (this == other) { +- return true; +- } +- +- if (!(other instanceof CraftMusicInstrument)) { +- return false; +- } +- +- return this.getKey().equals(((MusicInstrument) other).getKey()); +- } +- +- @Override +- public int hashCode() { +- return this.getKey().hashCode(); +- } ++ // Paper - switch to Holder + + @Override + public String toString() { +- return "CraftMusicInstrument{key=" + this.key + "}"; ++ return "CraftMusicInstrument{key=" + this.holder + "}"; // Paper + } + } +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java +index 6532bdaf6cbd10ecc5ace1b89899ad82e7bca206..5a12073e158a8b96d6192fdf8b2921e58e2c5522 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java +@@ -58,17 +58,13 @@ public class CraftMetaArmor extends CraftMetaItem implements ArmorMeta { + String patternKeyString = SerializableMeta.getString(trimData, CraftMetaArmor.TRIM_PATTERN.BUKKIT, true); + + if (materialKeyString != null && patternKeyString != null) { +- NamespacedKey materialKey = NamespacedKey.fromString(materialKeyString); +- NamespacedKey patternKey = NamespacedKey.fromString(patternKeyString); +- +- if (materialKey != null && patternKey != null) { +- TrimMaterial trimMaterial = Registry.TRIM_MATERIAL.get(materialKey); +- TrimPattern trimPattern = Registry.TRIM_PATTERN.get(patternKey); +- +- if (trimMaterial != null && trimPattern != null) { +- this.trim = new ArmorTrim(trimMaterial, trimPattern); +- } ++ // Paper start - switch to Holder ++ TrimMaterial trimMaterial = CraftTrimMaterial.stringToBukkit(materialKeyString); ++ TrimPattern trimPattern = CraftTrimPattern.stringToBukkit(patternKeyString); ++ if (trimMaterial != null && trimPattern != null) { ++ this.trim = new ArmorTrim(trimMaterial, trimPattern); + } ++ // Paper end - switch to Holder + } + } + } +@@ -134,8 +130,8 @@ public class CraftMetaArmor extends CraftMetaItem implements ArmorMeta { + + if (this.hasTrim()) { + Map<String, String> trimData = new HashMap<>(); +- trimData.put(CraftMetaArmor.TRIM_MATERIAL.BUKKIT, this.trim.getMaterial().getKey().toString()); +- trimData.put(CraftMetaArmor.TRIM_PATTERN.BUKKIT, this.trim.getPattern().getKey().toString()); ++ trimData.put(CraftMetaArmor.TRIM_MATERIAL.BUKKIT, CraftTrimMaterial.bukkitToString(this.trim.getMaterial())); // Paper - switch to Holder ++ trimData.put(CraftMetaArmor.TRIM_PATTERN.BUKKIT, CraftTrimPattern.bukkitToString(this.trim.getPattern())); // Paper - switch to Holder + builder.put(CraftMetaArmor.TRIM.BUKKIT, trimData); + } + +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java b/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java +index 38578ef887227ecc8e8bba281eae17a849b4fbe6..b729ee4fadc78248e2c772c80915f778e1560dd7 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java +@@ -11,14 +11,14 @@ import org.bukkit.craftbukkit.util.Handleable; + import org.bukkit.inventory.meta.trim.TrimMaterial; + import org.jetbrains.annotations.NotNull; + +-public class CraftTrimMaterial implements TrimMaterial, Handleable<net.minecraft.world.item.equipment.trim.TrimMaterial> { ++public class CraftTrimMaterial implements TrimMaterial, io.papermc.paper.util.Holderable<net.minecraft.world.item.equipment.trim.TrimMaterial> { // Paper - switch to Holder + + public static TrimMaterial minecraftToBukkit(net.minecraft.world.item.equipment.trim.TrimMaterial minecraft) { + return CraftRegistry.minecraftToBukkit(minecraft, Registries.TRIM_MATERIAL, Registry.TRIM_MATERIAL); + } + + public static TrimMaterial minecraftHolderToBukkit(Holder<net.minecraft.world.item.equipment.trim.TrimMaterial> minecraft) { +- return CraftTrimMaterial.minecraftToBukkit(minecraft.value()); ++ return CraftRegistry.minecraftHolderToBukkit(minecraft, Registry.TRIM_MATERIAL); // Paper - switch to Holder + } + + public static net.minecraft.world.item.equipment.trim.TrimMaterial bukkitToMinecraft(TrimMaterial bukkit) { +@@ -26,29 +26,47 @@ public class CraftTrimMaterial implements TrimMaterial, Handleable<net.minecraft + } + + public static Holder<net.minecraft.world.item.equipment.trim.TrimMaterial> bukkitToMinecraftHolder(TrimMaterial bukkit) { ++ return CraftRegistry.bukkitToMinecraftHolder(bukkit, Registries.TRIM_MATERIAL); // Paper - switch to Holder ++ } ++ ++ private final NamespacedKey key; ++ private final net.minecraft.world.item.equipment.trim.TrimMaterial handle; ++ ++ // Paper start - switch to Holder ++ private final Holder<net.minecraft.world.item.equipment.trim.TrimMaterial> holder; ++ ++ public static String bukkitToString(TrimMaterial bukkit) { + Preconditions.checkArgument(bukkit != null); + +- net.minecraft.core.Registry<net.minecraft.world.item.equipment.trim.TrimMaterial> registry = CraftRegistry.getMinecraftRegistry(Registries.TRIM_MATERIAL); ++ return ((CraftTrimMaterial) bukkit).toBukkitSerializationString(net.minecraft.world.item.equipment.trim.TrimMaterial.CODEC); // Paper - switch to Holder ++ } ++ ++ public static TrimMaterial stringToBukkit(String string) { ++ Preconditions.checkArgument(string != null); + +- if (registry.wrapAsHolder(CraftTrimMaterial.bukkitToMinecraft(bukkit)) instanceof Holder.Reference<net.minecraft.world.item.equipment.trim.TrimMaterial> holder) { +- return holder; +- } ++ return io.papermc.paper.util.Holderable.fromBukkitSerializationString(string, net.minecraft.world.item.equipment.trim.TrimMaterial.CODEC, Registry.TRIM_MATERIAL); // Paper - switch to Holder ++ } + +- throw new IllegalArgumentException("No Reference holder found for " + bukkit +- + ", this can happen if a plugin creates its own trim material without properly registering it."); ++ @Override ++ public boolean equals(final Object o) { ++ return this.implEquals(o); + } + +- private final NamespacedKey key; +- private final net.minecraft.world.item.equipment.trim.TrimMaterial handle; ++ @Override ++ public int hashCode() { ++ return this.implHashCode(); ++ } + +- public CraftTrimMaterial(NamespacedKey key, net.minecraft.world.item.equipment.trim.TrimMaterial handle) { +- this.key = key; +- this.handle = handle; ++ public CraftTrimMaterial(final Holder<net.minecraft.world.item.equipment.trim.TrimMaterial> holder) { ++ this.key = holder.unwrapKey().map(io.papermc.paper.util.MCUtil::fromResourceKey).orElse(null); ++ this.handle = holder.value(); ++ this.holder = holder; ++ // Paper end - switch to Holder + } + + @Override +- public net.minecraft.world.item.equipment.trim.TrimMaterial getHandle() { +- return this.handle; ++ public Holder<net.minecraft.world.item.equipment.trim.TrimMaterial> getHolder() { // Paper - switch to Holder ++ return this.holder; // Paper - switch to Holder + } + + @Override +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java b/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java +index 36df80a8be8a2485823f699e45c99674dbe71507..c4be5c785e50be925171c8083774b736d99361b2 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java +@@ -11,14 +11,14 @@ import org.bukkit.craftbukkit.util.Handleable; + import org.bukkit.inventory.meta.trim.TrimPattern; + import org.jetbrains.annotations.NotNull; + +-public class CraftTrimPattern implements TrimPattern, Handleable<net.minecraft.world.item.equipment.trim.TrimPattern> { ++public class CraftTrimPattern implements TrimPattern, io.papermc.paper.util.Holderable<net.minecraft.world.item.equipment.trim.TrimPattern> { // Paper - switch to Holder + + public static TrimPattern minecraftToBukkit(net.minecraft.world.item.equipment.trim.TrimPattern minecraft) { + return CraftRegistry.minecraftToBukkit(minecraft, Registries.TRIM_PATTERN, Registry.TRIM_PATTERN); + } + + public static TrimPattern minecraftHolderToBukkit(Holder<net.minecraft.world.item.equipment.trim.TrimPattern> minecraft) { +- return CraftTrimPattern.minecraftToBukkit(minecraft.value()); ++ return CraftRegistry.minecraftHolderToBukkit(minecraft, Registry.TRIM_PATTERN); // Paper - switch to Holder + } + + public static net.minecraft.world.item.equipment.trim.TrimPattern bukkitToMinecraft(TrimPattern bukkit) { +@@ -26,29 +26,47 @@ public class CraftTrimPattern implements TrimPattern, Handleable<net.minecraft.w + } + + public static Holder<net.minecraft.world.item.equipment.trim.TrimPattern> bukkitToMinecraftHolder(TrimPattern bukkit) { ++ return CraftRegistry.bukkitToMinecraftHolder(bukkit, Registries.TRIM_PATTERN); // Paper - switch to Holder ++ } ++ ++ private final NamespacedKey key; ++ private final net.minecraft.world.item.equipment.trim.TrimPattern handle; ++ ++ // Paper start - switch to Holder ++ private final Holder<net.minecraft.world.item.equipment.trim.TrimPattern> holder; // Paper - switch to Holder ++ ++ public static String bukkitToString(TrimPattern bukkit) { + Preconditions.checkArgument(bukkit != null); + +- net.minecraft.core.Registry<net.minecraft.world.item.equipment.trim.TrimPattern> registry = CraftRegistry.getMinecraftRegistry(Registries.TRIM_PATTERN); ++ return ((CraftTrimPattern) bukkit).toBukkitSerializationString(net.minecraft.world.item.equipment.trim.TrimPattern.CODEC); // Paper - switch to Holder ++ } ++ ++ public static TrimPattern stringToBukkit(String string) { ++ Preconditions.checkArgument(string != null); + +- if (registry.wrapAsHolder(CraftTrimPattern.bukkitToMinecraft(bukkit)) instanceof Holder.Reference<net.minecraft.world.item.equipment.trim.TrimPattern> holder) { +- return holder; +- } ++ return io.papermc.paper.util.Holderable.fromBukkitSerializationString(string, net.minecraft.world.item.equipment.trim.TrimPattern.CODEC, Registry.TRIM_PATTERN); // Paper - switch to Holder ++ } + +- throw new IllegalArgumentException("No Reference holder found for " + bukkit +- + ", this can happen if a plugin creates its own trim pattern without properly registering it."); ++ @Override ++ public boolean equals(final Object o) { ++ return this.implEquals(o); + } + +- private final NamespacedKey key; +- private final net.minecraft.world.item.equipment.trim.TrimPattern handle; ++ @Override ++ public int hashCode() { ++ return this.implHashCode(); ++ } + +- public CraftTrimPattern(NamespacedKey key, net.minecraft.world.item.equipment.trim.TrimPattern handle) { +- this.key = key; +- this.handle = handle; ++ public CraftTrimPattern(Holder<net.minecraft.world.item.equipment.trim.TrimPattern> handle) { ++ this.key = handle.unwrapKey().map(io.papermc.paper.util.MCUtil::fromResourceKey).orElse(null); ++ this.handle = handle.value(); ++ this.holder = handle; ++ // Paper end - switch to Holder + } + + @Override +- public net.minecraft.world.item.equipment.trim.TrimPattern getHandle() { +- return this.handle; ++ public Holder<net.minecraft.world.item.equipment.trim.TrimPattern> getHolder() { // Paper - switch to Holder ++ return this.holder; // Paper - switch to Holder + } + + @Override +diff --git a/src/test/java/org/bukkit/registry/RegistryConversionTest.java b/src/test/java/org/bukkit/registry/RegistryConversionTest.java +index 01e351f4e292efe78fc1a1db0f31b2c0a313b101..092b88e0ac3ba37322fbe86bab98dc6f91a9c866 100644 +--- a/src/test/java/org/bukkit/registry/RegistryConversionTest.java ++++ b/src/test/java/org/bukkit/registry/RegistryConversionTest.java +@@ -269,6 +269,7 @@ public class RegistryConversionTest { + Class<? extends Keyed> craftClazz, Class<?> minecraftClazz) throws IllegalAccessException { + this.checkValidMinecraftToBukkit(clazz); + ++ if (type == io.papermc.paper.registry.RegistryKey.TRIM_MATERIAL || type == io.papermc.paper.registry.RegistryKey.TRIM_PATTERN || type == io.papermc.paper.registry.RegistryKey.INSTRUMENT) return; // Paper - manually skip for now + try { + + Object minecraft = mock(minecraftClazz); |