diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryComposeEvent.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryComposeEvent.java index 419dd68b69..879bb889c1 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryComposeEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryComposeEvent.java @@ -1,11 +1,8 @@ package io.papermc.paper.registry.event; import io.papermc.paper.registry.RegistryBuilder; -import io.papermc.paper.registry.tag.Tag; -import io.papermc.paper.registry.tag.TagKey; -import org.bukkit.Keyed; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; +import org.jetbrains.annotations.Contract; /** * Event object for {@link RegistryEventProvider#compose()}. This @@ -16,7 +13,6 @@ import org.jspecify.annotations.NullMarked; * @param registry entry builder type */ @ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface RegistryComposeEvent> extends RegistryEvent { @@ -28,13 +24,11 @@ public interface RegistryComposeEvent> extends R WritableRegistry registry(); /** - * Gets or creates a tag for the given tag key. This tag - * is then required to be filled either from the built-in or - * custom datapack. + * Gets the registry retriever, which can be used to retrieve or create + * entries in the registry. * - * @param tagKey the tag key - * @return the tag - * @param the tag value type + * @return the registry retriever */ - Tag getOrCreateTag(TagKey tagKey); + @Contract(pure = true) + RegistryRetriever retriever(); } diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEvent.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEvent.java index 56468b311e..94dc00cf80 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEvent.java @@ -6,7 +6,7 @@ import io.papermc.paper.registry.tag.Tag; import io.papermc.paper.registry.tag.TagKey; import org.bukkit.Keyed; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; +import org.jetbrains.annotations.Contract; /** * Event object for {@link RegistryEventProvider#entryAdd()}. This @@ -16,8 +16,6 @@ import org.jspecify.annotations.NullMarked; * @param registry entry type * @param registry entry builder type */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface RegistryEntryAddEvent> extends RegistryEvent { @@ -43,6 +41,19 @@ public interface RegistryEntryAddEvent> extends * @param tagKey the tag key * @return the tag * @param the tag value type + * @deprecated use {@link #retriever()} */ - Tag getOrCreateTag(TagKey tagKey); + @Deprecated(forRemoval = true) + default Tag getOrCreateTag(final TagKey tagKey) { + return this.retriever().getOrCreateTag(tagKey); + } + + /** + * Gets the registry retriever, which can be used to retrieve or create + * entries in the registry. + * + * @return the registry retriever + */ + @Contract(pure = true) + RegistryRetriever retriever(); } diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvent.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvent.java index 3a8643c06d..420e031bf5 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvent.java @@ -3,15 +3,12 @@ package io.papermc.paper.registry.event; import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; import io.papermc.paper.registry.RegistryKey; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * Base type for all registry events. * * @param registry entry type */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface RegistryEvent extends LifecycleEvent { diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProvider.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProvider.java index c5b1cf42a4..15c2fd3556 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProvider.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProvider.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryBuilder; import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.event.type.RegistryEntryAddEventType; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * Provider for registry events for a specific registry. @@ -21,8 +20,6 @@ import org.jspecify.annotations.NullMarked; * @param registry entry type * @param registry entry builder type */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface RegistryEventProvider> { diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProviderImpl.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProviderImpl.java index c9c5f47162..16eb6bc8a4 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProviderImpl.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProviderImpl.java @@ -6,10 +6,8 @@ import io.papermc.paper.registry.RegistryBuilder; import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.event.type.RegistryEntryAddEventType; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; @ApiStatus.Internal -@NullMarked record RegistryEventProviderImpl>(RegistryKey registryKey) implements RegistryEventProvider { static > RegistryEventProvider create(final RegistryKey registryKey) { diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java index 7c44219a56..6585fe1b33 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java @@ -23,8 +23,6 @@ import org.bukkit.entity.Cow; import org.bukkit.entity.Frog; import org.bukkit.entity.Pig; import org.bukkit.entity.Wolf; -import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; import static io.papermc.paper.registry.event.RegistryEventProviderImpl.create; @@ -32,8 +30,6 @@ import static io.papermc.paper.registry.event.RegistryEventProviderImpl.create; * Holds providers for {@link RegistryEntryAddEvent} and {@link RegistryComposeEvent} * handlers for each applicable registry. */ -@ApiStatus.Experimental -@NullMarked public final class RegistryEvents { // Start generate - RegistryEvents diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryFreezeEvent.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryFreezeEvent.java index 52050480c4..325b7f7b5a 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryFreezeEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryFreezeEvent.java @@ -1,8 +1,10 @@ package io.papermc.paper.registry.event; import io.papermc.paper.registry.RegistryBuilder; +import io.papermc.paper.registry.tag.Tag; +import io.papermc.paper.registry.tag.TagKey; +import org.bukkit.Keyed; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * Event object for {@link RegistryEventProvider#freeze()}. This @@ -15,7 +17,21 @@ import org.jspecify.annotations.NullMarked; */ @ApiStatus.ScheduledForRemoval(inVersion = "1.21.7 or 1.22, whichever comes first") @Deprecated(since = "1.21.6", forRemoval = true) -@NullMarked @ApiStatus.NonExtendable public interface RegistryFreezeEvent> extends RegistryComposeEvent { + + /** + * Gets or creates a tag for the given tag key. This tag + * is then required to be filled either from the built-in or + * custom datapack. + * + * @param tagKey the tag key + * @param the tag value type + * @return the tag + * @deprecated Use {@link #retriever()} + */ + @Deprecated(forRemoval = true) + default Tag getOrCreateTag(final TagKey tagKey) { + return this.retriever().getOrCreateTag(tagKey); + } } diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryRetriever.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryRetriever.java new file mode 100644 index 0000000000..4299ca7156 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryRetriever.java @@ -0,0 +1,35 @@ +package io.papermc.paper.registry.event; + +import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.tag.Tag; +import io.papermc.paper.registry.tag.TagKey; +import org.bukkit.Keyed; +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.NonExtendable +public interface RegistryRetriever { + + /** + * Gets or creates a tag for the given tag key. This tag + * is then required to be filled either from the built-in or + * custom datapack. + * + * @param tagKey the tag key + * @param the tag value type + * @return the tag + */ + Tag getOrCreateTag(TagKey tagKey); // TODO remove Keyed + + /** + * Gets or creates an empty instance of the given {@link TypedKey}. + *
+ * Can only create instances if the applicable registry still supports adding + * new references. If the registry doesn't, this method will throw an exception. + * + * @param key the key to get or create an instance for + * @param the type of the value associated with the key + * @return an instance of the given key, or a new instance if it does not exist + * @throws IllegalStateException if this registry does not support adding new references and the key does not exist + */ + V getOrCreate(TypedKey key); // TODO remove Keyed +} diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java b/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java index fed7ad660f..9f32ef1d8e 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java @@ -5,7 +5,6 @@ import io.papermc.paper.registry.RegistryBuilderFactory; import io.papermc.paper.registry.TypedKey; import java.util.function.Consumer; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * A registry which supports registering new objects. @@ -13,8 +12,6 @@ import org.jspecify.annotations.NullMarked; * @param registry entry type * @param registry entry builder type */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface WritableRegistry> { diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/package-info.java b/paper-api/src/main/java/io/papermc/paper/registry/event/package-info.java new file mode 100644 index 0000000000..9a6ff1553e --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/package-info.java @@ -0,0 +1,9 @@ +/** + * This package contains events related to the Paper registry system. + */ +@ApiStatus.Experimental +@NullMarked +package io.papermc.paper.registry.event; + +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddConfiguration.java b/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddConfiguration.java index d9bde790f7..776a6b2ff4 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddConfiguration.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddConfiguration.java @@ -4,15 +4,15 @@ import io.papermc.paper.plugin.bootstrap.BootstrapContext; import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfiguration; import io.papermc.paper.registry.TypedKey; import java.util.function.Predicate; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; -import org.jspecify.annotations.NullMarked; /** * Specific configuration for {@link io.papermc.paper.registry.event.RegistryEntryAddEvent}s. * * @param registry entry type */ -@NullMarked +@ApiStatus.NonExtendable public interface RegistryEntryAddConfiguration extends PrioritizedLifecycleEventHandlerConfiguration { /** diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddEventType.java b/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddEventType.java index 93447ef589..29d8e1d25e 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddEventType.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddEventType.java @@ -5,7 +5,6 @@ import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType; import io.papermc.paper.registry.RegistryBuilder; import io.papermc.paper.registry.event.RegistryEntryAddEvent; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * Lifecycle event type for {@link RegistryEntryAddEvent}s. @@ -13,8 +12,6 @@ import org.jspecify.annotations.NullMarked; * @param registry entry type * @param registry entry builder type */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface RegistryEntryAddEventType> extends LifecycleEventType, RegistryEntryAddConfiguration> { } diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/type/package-info.java b/paper-api/src/main/java/io/papermc/paper/registry/event/type/package-info.java new file mode 100644 index 0000000000..cf23472df1 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/type/package-info.java @@ -0,0 +1,9 @@ +/** + * This package contains events related to the Paper registry system. + */ +@ApiStatus.Experimental +@NullMarked +package io.papermc.paper.registry.event.type; + +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; diff --git a/paper-server/patches/sources/net/minecraft/core/registries/BuiltInRegistries.java.patch b/paper-server/patches/sources/net/minecraft/core/registries/BuiltInRegistries.java.patch index 37765a9df7..aca3e7b409 100644 --- a/paper-server/patches/sources/net/minecraft/core/registries/BuiltInRegistries.java.patch +++ b/paper-server/patches/sources/net/minecraft/core/registries/BuiltInRegistries.java.patch @@ -22,7 +22,7 @@ ResourceKey> key, R registry, BuiltInRegistries.RegistryBootstrap bootstrap ) { Bootstrap.checkBootstrapCalled(() -> "registry " + key.location()); -+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(registry.key(), registry); // Paper - initialize API registry ++ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(registry); // Paper - initialize API registry ResourceLocation resourceLocation = key.location(); LOADERS.put(resourceLocation, () -> bootstrap.run(registry)); WRITABLE_REGISTRY.register((ResourceKey)key, registry, RegistrationInfo.BUILT_IN); diff --git a/paper-server/patches/sources/net/minecraft/resources/RegistryDataLoader.java.patch b/paper-server/patches/sources/net/minecraft/resources/RegistryDataLoader.java.patch index de4d6cc2fb..0d410f6ea1 100644 --- a/paper-server/patches/sources/net/minecraft/resources/RegistryDataLoader.java.patch +++ b/paper-server/patches/sources/net/minecraft/resources/RegistryDataLoader.java.patch @@ -66,7 +66,7 @@ RegistryDataLoader.Loader create(Lifecycle registryLifecycle, Map, Exception> loadingErrors) { WritableRegistry writableRegistry = new MappedRegistry<>(this.key, registryLifecycle); -+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(this.key, writableRegistry); // Paper - initialize API registry ++ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(writableRegistry); // Paper - initialize API registry return new RegistryDataLoader.Loader<>(this, writableRegistry, loadingErrors); } diff --git a/paper-server/patches/sources/net/minecraft/server/ReloadableServerRegistries.java.patch b/paper-server/patches/sources/net/minecraft/server/ReloadableServerRegistries.java.patch index 50fa5390c7..138e996818 100644 --- a/paper-server/patches/sources/net/minecraft/server/ReloadableServerRegistries.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/ReloadableServerRegistries.java.patch @@ -21,7 +21,7 @@ return CompletableFuture.supplyAsync( () -> { WritableRegistry writableRegistry = new MappedRegistry<>(lootDataType.registryKey(), Lifecycle.experimental()); -+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerReloadableRegistry(lootDataType.registryKey(), writableRegistry); // Paper - register reloadable registry ++ io.papermc.paper.registry.PaperRegistryAccess.instance().registerReloadableRegistry(writableRegistry); // Paper - register reloadable registry Map map = new HashMap<>(); SimpleJsonResourceReloadListener.scanDirectory(resourceManager, lootDataType.registryKey(), ops, lootDataType.codec(), map); map.forEach( diff --git a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java index e96c28cecc..28b4e81375 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java @@ -97,12 +97,12 @@ public class PaperRegistryAccess implements RegistryAccess { return registry; } - public void registerReloadableRegistry(final ResourceKey> resourceKey, final net.minecraft.core.Registry registry) { - this.registerRegistry(resourceKey, registry, true); + public void registerReloadableRegistry(final net.minecraft.core.Registry registry) { + this.registerRegistry(registry, true); } - public void registerRegistry(final ResourceKey> resourceKey, final net.minecraft.core.Registry registry) { - this.registerRegistry(resourceKey, registry, false); + public void registerRegistry(final net.minecraft.core.Registry registry) { + this.registerRegistry(registry, false); } public void lockReferenceHolders(final ResourceKey> resourceKey) { @@ -115,8 +115,8 @@ public class PaperRegistryAccess implements RegistryAccess { } @SuppressWarnings("unchecked") // this method should be called right after any new MappedRegistry instances are created to later be used by the server. - private > void registerRegistry(final ResourceKey> resourceKey, final net.minecraft.core.Registry registry, final boolean replace) { - final RegistryEntry entry = PaperRegistries.getEntry(resourceKey); + private > void registerRegistry(final net.minecraft.core.Registry registry, final boolean replace) { + final RegistryEntry entry = PaperRegistries.getEntry(registry.key()); if (entry == null) { // skip registries that don't have API entries return; } @@ -129,7 +129,7 @@ public class PaperRegistryAccess implements RegistryAccess { // if the registry holder is delayed, and the entry is marked as "delayed", then load the holder with the CraftRegistry instance that wraps the actual nms Registry. ((RegistryHolder.Delayed) registryHolder).loadFrom(delayedEntry, registry); } else { - throw new IllegalArgumentException(resourceKey + " has already been created"); + throw new IllegalArgumentException(registry.key() + " has already been created"); } } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java index f606c523f6..3c2b625efe 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java @@ -6,6 +6,7 @@ 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 io.papermc.paper.registry.event.PaperRegistryRetriever; import io.papermc.paper.registry.event.RegistryEntryAddEventImpl; import io.papermc.paper.registry.event.RegistryComposeEventImpl; import java.util.function.BiFunction; @@ -103,11 +104,11 @@ public sealed interface RegistryEntryMeta permits RegistryEn ) implements ServerSide { public RegistryEntryAddEventImpl createEntryAddEvent(final TypedKey key, final B initialBuilder, final Conversions conversions) { - return new RegistryEntryAddEventImpl<>(key, initialBuilder, this.apiKey(), conversions); + return new RegistryEntryAddEventImpl<>(key, initialBuilder, this.apiKey(), conversions, new PaperRegistryRetriever(conversions)); } public RegistryComposeEventImpl createPostLoadEvent(final WritableCraftRegistry writableRegistry, final Conversions conversions) { - return new RegistryComposeEventImpl<>(this.apiKey(), writableRegistry.createApiWritableRegistry(conversions), conversions); + return new RegistryComposeEventImpl<>(this.apiKey(), writableRegistry.createApiWritableRegistry(conversions), conversions, new PaperRegistryRetriever(conversions)); } @Override diff --git a/paper-server/src/main/java/io/papermc/paper/registry/event/PaperRegistryRetriever.java b/paper-server/src/main/java/io/papermc/paper/registry/event/PaperRegistryRetriever.java new file mode 100644 index 0000000000..214e3cef97 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/event/PaperRegistryRetriever.java @@ -0,0 +1,51 @@ +package io.papermc.paper.registry.event; + +import io.papermc.paper.registry.PaperRegistries; +import io.papermc.paper.registry.PaperRegistryAccess; +import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.data.util.Conversions; +import io.papermc.paper.registry.set.NamedRegistryKeySetImpl; +import io.papermc.paper.registry.tag.Tag; +import io.papermc.paper.registry.tag.TagKey; +import java.util.Optional; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderSet; +import net.minecraft.resources.RegistryOps; +import net.minecraft.resources.ResourceKey; +import org.bukkit.Keyed; +import org.bukkit.Registry; +import org.bukkit.craftbukkit.CraftRegistry; + +public final class PaperRegistryRetriever implements RegistryRetriever { + + private final Conversions conversions; + + public PaperRegistryRetriever(final Conversions conversions) { + this.conversions = conversions; + } + + @Override + public Tag getOrCreateTag(final TagKey tagKey) { + final RegistryOps.RegistryInfo registryInfo = this.conversions.lookup().lookup(PaperRegistries.registryToNms(tagKey.registryKey())).orElseThrow(); + final HolderSet.Named tagSet = registryInfo.getter().getOrThrow(PaperRegistries.toNms(tagKey)); + return new NamedRegistryKeySetImpl<>(tagKey, tagSet); + } + + @Override + public V getOrCreate(final TypedKey key) { + final Registry registry = PaperRegistryAccess.instance().getRegistry(key.registryKey()); + final V value = registry.get(key); + if (value != null) { + return value; + } else if (!(registry instanceof final CraftRegistry craftRegistry)) { + throw new IllegalStateException("Cannot create instance for key " + key + " as the registry is not a CraftRegistry"); + } else if (!craftRegistry.constructorUsesHolder()) { + throw new IllegalStateException("Cannot create instance for key " + key + " as the registry does not yet support creating instances with Holder references"); + } else { + final ResourceKey> resourceKey = PaperRegistries.registryToNms(key.registryKey()); + final RegistryOps.RegistryInfo registryInfo = this.conversions.lookup().lookup(resourceKey).orElseThrow(() -> new IllegalStateException("Cannot create instance for key " + key + " as the registry is not registered in the lookup")); + registryInfo.getter().get(PaperRegistries.toNms(key)).orElseThrow(() -> new IllegalStateException("Cannot create instance for key " + key + " as it does not exist in the registry " + resourceKey)); + return craftRegistry.getOrThrow(key); + } + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryComposeEventImpl.java b/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryComposeEventImpl.java index 1ceb822b41..25b3ac411b 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryComposeEventImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryComposeEventImpl.java @@ -15,13 +15,7 @@ import org.bukkit.Keyed; public record RegistryComposeEventImpl>( RegistryKey registryKey, WritableRegistry registry, - Conversions conversions + Conversions conversions, + RegistryRetriever retriever ) implements RegistryFreezeEvent, PaperLifecycleEvent { - - @Override - public Tag getOrCreateTag(final TagKey tagKey) { - final RegistryOps.RegistryInfo registryInfo = this.conversions.lookup().lookup(PaperRegistries.registryToNms(tagKey.registryKey())).orElseThrow(); - final HolderSet.Named tagSet = registryInfo.getter().getOrThrow(PaperRegistries.toNms(tagKey)); - return new NamedRegistryKeySetImpl<>(tagKey, tagSet); - } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEventImpl.java b/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEventImpl.java index 332829c65e..3d33d09a09 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEventImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEventImpl.java @@ -9,6 +9,7 @@ import io.papermc.paper.registry.data.util.Conversions; import io.papermc.paper.registry.set.NamedRegistryKeySetImpl; import io.papermc.paper.registry.tag.Tag; import io.papermc.paper.registry.tag.TagKey; +import net.minecraft.advancements.critereon.BredAnimalsTrigger; import net.minecraft.core.HolderSet; import net.minecraft.resources.RegistryOps; import org.bukkit.Keyed; @@ -17,13 +18,7 @@ public record RegistryEntryAddEventImpl>( TypedKey key, B builder, RegistryKey registryKey, - Conversions conversions + Conversions conversions, + RegistryRetriever retriever ) implements RegistryEntryAddEvent, PaperLifecycleEvent { - - @Override - public Tag getOrCreateTag(final TagKey tagKey) { - final RegistryOps.RegistryInfo registryInfo = this.conversions.lookup().lookup(PaperRegistries.registryToNms(tagKey.registryKey())).orElseThrow(); - final HolderSet.Named tagSet = registryInfo.getter().getOrThrow(PaperRegistries.toNms(tagKey)); - return new NamedRegistryKeySetImpl<>(tagKey, tagSet); - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java index 408c561661..3bad0d1c4a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -4,6 +4,7 @@ import com.google.common.base.Preconditions; import io.papermc.paper.registry.PaperRegistries; import io.papermc.paper.registry.RegistryAccess; import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.TypedKey; import io.papermc.paper.registry.entry.RegistryEntryMeta; import io.papermc.paper.registry.set.NamedRegistryKeySetImpl; import io.papermc.paper.registry.tag.Tag; @@ -205,7 +206,8 @@ public class CraftRegistry implements Registry { return cached; } - final Optional> holderOptional = this.minecraftRegistry.get(CraftNamespacedKey.toMinecraft(namespacedKey)); + // Important to use the ResourceKey "get" method below because it will work before registry is frozen + final Optional> holderOptional = this.minecraftRegistry.get(MCUtil.toResourceKey(this.minecraftRegistry.key(), namespacedKey)); final Holder.Reference holder; if (holderOptional.isPresent()) { holder = holderOptional.get(); @@ -215,12 +217,9 @@ public class CraftRegistry implements Registry { // to create something to fill the API constant fields, so we create a dummy reference holder. holder = Holder.Reference.createStandAlone(this.invalidHolderOwner, MCUtil.toResourceKey(this.minecraftRegistry.key(), namespacedKey)); } else { - holder = null; - } - final B bukkit = this.createBukkit(holder); - if (bukkit == null) { return null; } + final B bukkit = this.createBukkit(holder); this.cache.put(namespacedKey, bukkit); @@ -250,10 +249,6 @@ public class CraftRegistry implements Registry { } public B createBukkit(Holder minecraft) { - if (minecraft == null) { - return null; - } - return this.minecraftToBukkit.createBukkit(minecraft); } @@ -261,6 +256,10 @@ public class CraftRegistry implements Registry { return this.minecraftToBukkit.supportsDirectHolders(); } + public boolean constructorUsesHolder() { + return this.minecraftToBukkit.constructorUsesHolder(); + } + @Override public NamespacedKey getKey(final B value) { if (value instanceof Holderable holderable) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java index c3bd4cc145..04a1ef686b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; +import io.papermc.paper.registry.HolderableBase; import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; import net.minecraft.world.entity.animal.wolf.WolfSoundVariant; @@ -91,14 +92,14 @@ public class CraftWolf extends CraftTameableAnimal implements Wolf { this.getHandle().setSoundVariant(CraftSoundVariant.bukkitToMinecraftHolder(soundVariant)); } - public static class CraftVariant implements Variant, Handleable { + public static class CraftVariant extends HolderableBase implements Variant { public static Variant minecraftToBukkit(WolfVariant minecraft) { return CraftRegistry.minecraftToBukkit(minecraft, Registries.WOLF_VARIANT); } public static Variant minecraftHolderToBukkit(Holder minecraft) { - return CraftVariant.minecraftToBukkit(minecraft.value()); + return CraftRegistry.minecraftHolderToBukkit(minecraft, Registries.WOLF_VARIANT); } public static WolfVariant bukkitToMinecraft(Variant bukkit) { @@ -106,57 +107,11 @@ public class CraftWolf extends CraftTameableAnimal implements Wolf { } public static Holder bukkitToMinecraftHolder(Variant bukkit) { - Preconditions.checkArgument(bukkit != null); - - net.minecraft.core.Registry registry = CraftRegistry.getMinecraftRegistry(Registries.WOLF_VARIANT); - - if (registry.wrapAsHolder(CraftVariant.bukkitToMinecraft(bukkit)) instanceof Holder.Reference holder) { - return holder; - } - - throw new IllegalArgumentException("No Reference holder found for " + bukkit - + ", this can happen if a plugin creates its own wolf variant with out properly registering it."); + return CraftRegistry.bukkitToMinecraftHolder(bukkit, Registries.WOLF_VARIANT); } - private final NamespacedKey key; - private final WolfVariant variant; - - public CraftVariant(NamespacedKey key, WolfVariant variant) { - this.key = key; - this.variant = variant; - } - - @Override - public WolfVariant getHandle() { - return this.variant; - } - - @Override - public NamespacedKey getKey() { - return this.key; - } - - @Override - public String toString() { - return this.key.toString(); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - - if (!(other instanceof CraftVariant otherVariant)) { - return false; - } - - return this.getKey().equals(otherVariant.getKey()); - } - - @Override - public int hashCode() { - return this.getKey().hashCode(); + public CraftVariant(Holder holder) { + super(holder); } } diff --git a/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java b/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java index 93ad172dca..f5d5b112ca 100644 --- a/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java +++ b/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java @@ -1,6 +1,7 @@ package org.bukkit.registry; import com.google.common.base.Joiner; +import io.papermc.paper.registry.RegistryAccess; import io.papermc.paper.registry.RegistryKey; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -9,12 +10,12 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.stream.Stream; import net.minecraft.resources.ResourceKey; import org.bukkit.Keyed; import org.bukkit.Registry; import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.support.environment.AllFeatures; -import org.bukkit.support.provider.RegistryArgumentProvider; import org.bukkit.support.test.RegistriesTest; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; @@ -43,6 +44,12 @@ public class RegistryConversionTest { private static final Set> IMPLEMENT_HANDLE_ABLE = new HashSet<>(); + public static Stream getValues(RegistryKey registryType) { // Paper + Registry registry = RegistryAccess.registryAccess().getRegistry(registryType); // Paper + return registry.stream().map(keyed -> (Handleable) keyed) + .map(handleAble -> Arguments.of(handleAble, handleAble.getHandle())); + } + @Order(1) @RegistriesTest public void testHandleableImplementation(io.papermc.paper.registry.RegistryKey type, Class clazz) { // Paper @@ -210,7 +217,7 @@ public class RegistryConversionTest { Map notMatching = new HashMap<>(); Method method = RegistryConversionTest.MINECRAFT_TO_BUKKIT_METHODS.get(clazz); - RegistryArgumentProvider.getValues(type).map(Arguments::get).forEach(arguments -> { // Paper + getValues(type).map(Arguments::get).forEach(arguments -> { // Paper Keyed bukkit = (Keyed) arguments[0]; Object minecraft = arguments[1]; @@ -241,7 +248,7 @@ public class RegistryConversionTest { Map notMatching = new HashMap<>(); Method method = RegistryConversionTest.BUKKIT_TO_MINECRAFT_METHODS.get(clazz); - RegistryArgumentProvider.getValues(type).map(Arguments::get).forEach(arguments -> { // Paper + getValues(type).map(Arguments::get).forEach(arguments -> { // Paper Keyed bukkit = (Keyed) arguments[0]; Object minecraft = arguments[1]; diff --git a/paper-server/src/test/java/org/bukkit/support/provider/RegistryArgumentProvider.java b/paper-server/src/test/java/org/bukkit/support/provider/RegistryArgumentProvider.java deleted file mode 100644 index beb5fc9e72..0000000000 --- a/paper-server/src/test/java/org/bukkit/support/provider/RegistryArgumentProvider.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.bukkit.support.provider; - -import java.util.stream.Stream; -import org.bukkit.Bukkit; -import org.bukkit.Keyed; -import org.bukkit.Registry; -import org.bukkit.craftbukkit.util.Handleable; -import org.bukkit.support.test.RegistryTest; -import org.junit.jupiter.api.extension.ExtensionContext; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.ArgumentsProvider; -import org.junit.jupiter.params.support.AnnotationConsumer; - -public class RegistryArgumentProvider implements ArgumentsProvider, AnnotationConsumer { - - private Class registryType; - - @Override - public void accept(RegistryTest registryTest) { - this.registryType = registryTest.value(); - } - - @Override - public Stream provideArguments(ExtensionContext extensionContext) throws Exception { - return RegistryArgumentProvider.getValues(io.papermc.paper.registry.PaperRegistryAccess.byType(this.registryType)); // Paper - } - - public static Stream getValues(io.papermc.paper.registry.RegistryKey registryType) { // Paper - Registry registry = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(registryType); // Paper - return registry.stream().map(keyed -> (Handleable) keyed) - .map(handleAble -> Arguments.of(handleAble, handleAble.getHandle())); - } -} diff --git a/paper-server/src/test/java/org/bukkit/support/test/RegistryTest.java b/paper-server/src/test/java/org/bukkit/support/test/RegistryTest.java deleted file mode 100644 index 968c90214e..0000000000 --- a/paper-server/src/test/java/org/bukkit/support/test/RegistryTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.bukkit.support.test; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import org.bukkit.Keyed; -import org.bukkit.support.provider.RegistryArgumentProvider; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ArgumentsSource; - -@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@ArgumentsSource(RegistryArgumentProvider.class) -@ParameterizedTest -public @interface RegistryTest { - - Class value(); -} diff --git a/test-plugin/src/main/java/io/papermc/testplugin/TestPluginBootstrap.java b/test-plugin/src/main/java/io/papermc/testplugin/TestPluginBootstrap.java index fe2b287b25..d5103811d0 100644 --- a/test-plugin/src/main/java/io/papermc/testplugin/TestPluginBootstrap.java +++ b/test-plugin/src/main/java/io/papermc/testplugin/TestPluginBootstrap.java @@ -2,6 +2,11 @@ package io.papermc.testplugin; import io.papermc.paper.plugin.bootstrap.BootstrapContext; import io.papermc.paper.plugin.bootstrap.PluginBootstrap; +import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.event.RegistryEvents; +import io.papermc.paper.registry.keys.WolfVariantKeys; +import net.kyori.adventure.key.Key; +import org.bukkit.entity.Wolf; import org.jetbrains.annotations.NotNull; public class TestPluginBootstrap implements PluginBootstrap { @@ -9,6 +14,11 @@ public class TestPluginBootstrap implements PluginBootstrap { @Override public void bootstrap(@NotNull BootstrapContext context) { // io.papermc.testplugin.brigtests.Registration.registerViaBootstrap(context); + + context.getLifecycleManager().registerEventHandler(RegistryEvents.ENCHANTMENT.freeze(), event -> { + final Wolf.Variant v = event.retriever().getOrCreate(WolfVariantKeys.create(Key.key("mm:test"))); + System.out.println("test"); + }); } }