Add RegistryRetriever for future use in registry API

This commit is contained in:
Jake Potrebic
2025-06-05 22:24:26 -07:00
parent 2f1c6f35d6
commit 89059c25dc
27 changed files with 197 additions and 181 deletions

View File

@@ -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 <B> registry entry builder type
*/
@ApiStatus.Experimental
@NullMarked
@ApiStatus.NonExtendable
public interface RegistryComposeEvent<T, B extends RegistryBuilder<T>> extends RegistryEvent<T> {
@@ -28,13 +24,11 @@ public interface RegistryComposeEvent<T, B extends RegistryBuilder<T>> extends R
WritableRegistry<T, B> 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 <V> the tag value type
* @return the registry retriever
*/
<V extends Keyed> Tag<V> getOrCreateTag(TagKey<V> tagKey);
@Contract(pure = true)
RegistryRetriever retriever();
}

View File

@@ -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 <T> registry entry type
* @param <B> registry entry builder type
*/
@ApiStatus.Experimental
@NullMarked
@ApiStatus.NonExtendable
public interface RegistryEntryAddEvent<T, B extends RegistryBuilder<T>> extends RegistryEvent<T> {
@@ -43,6 +41,19 @@ public interface RegistryEntryAddEvent<T, B extends RegistryBuilder<T>> extends
* @param tagKey the tag key
* @return the tag
* @param <V> the tag value type
* @deprecated use {@link #retriever()}
*/
<V extends Keyed> Tag<V> getOrCreateTag(TagKey<V> tagKey);
@Deprecated(forRemoval = true)
default <V extends Keyed> Tag<V> getOrCreateTag(final TagKey<V> 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();
}

View File

@@ -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 <T> registry entry type
*/
@ApiStatus.Experimental
@NullMarked
@ApiStatus.NonExtendable
public interface RegistryEvent<T> extends LifecycleEvent {

View File

@@ -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 <T> registry entry type
* @param <B> registry entry builder type
*/
@ApiStatus.Experimental
@NullMarked
@ApiStatus.NonExtendable
public interface RegistryEventProvider<T, B extends RegistryBuilder<T>> {

View File

@@ -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<T, B extends RegistryBuilder<T>>(RegistryKey<T> registryKey) implements RegistryEventProvider<T, B> {
static <T, B extends RegistryBuilder<T>> RegistryEventProvider<T, B> create(final RegistryKey<T> registryKey) {

View File

@@ -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

View File

@@ -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<T, B extends RegistryBuilder<T>> extends RegistryComposeEvent<T, B> {
/**
* 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 <V> the tag value type
* @return the tag
* @deprecated Use {@link #retriever()}
*/
@Deprecated(forRemoval = true)
default <V extends Keyed> Tag<V> getOrCreateTag(final TagKey<V> tagKey) {
return this.retriever().getOrCreateTag(tagKey);
}
}

View File

@@ -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 <V> the tag value type
* @return the tag
*/
<V extends Keyed> Tag<V> getOrCreateTag(TagKey<V> tagKey); // TODO remove Keyed
/**
* Gets or creates an empty instance of the given {@link TypedKey}.
* <br>
* 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 <V> 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 extends Keyed> V getOrCreate(TypedKey<V> key); // TODO remove Keyed
}

View File

@@ -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 <T> registry entry type
* @param <B> registry entry builder type
*/
@ApiStatus.Experimental
@NullMarked
@ApiStatus.NonExtendable
public interface WritableRegistry<T, B extends RegistryBuilder<T>> {

View File

@@ -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;

View File

@@ -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 <T> registry entry type
*/
@NullMarked
@ApiStatus.NonExtendable
public interface RegistryEntryAddConfiguration<T> extends PrioritizedLifecycleEventHandlerConfiguration<BootstrapContext> {
/**

View File

@@ -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 <T> registry entry type
* @param <B> registry entry builder type
*/
@ApiStatus.Experimental
@NullMarked
@ApiStatus.NonExtendable
public interface RegistryEntryAddEventType<T, B extends RegistryBuilder<T>> extends LifecycleEventType<BootstrapContext, RegistryEntryAddEvent<T, B>, RegistryEntryAddConfiguration<T>> {
}

View File

@@ -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;

View File

@@ -22,7 +22,7 @@
ResourceKey<? extends Registry<T>> key, R registry, BuiltInRegistries.RegistryBootstrap<T> 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);

View File

@@ -66,7 +66,7 @@
RegistryDataLoader.Loader<T> create(Lifecycle registryLifecycle, Map<ResourceKey<?>, Exception> loadingErrors) {
WritableRegistry<T> 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);
}

View File

@@ -21,7 +21,7 @@
return CompletableFuture.supplyAsync(
() -> {
WritableRegistry<T> 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<ResourceLocation, T> map = new HashMap<>();
SimpleJsonResourceReloadListener.scanDirectory(resourceManager, lootDataType.registryKey(), ops, lootDataType.codec(), map);
map.forEach(

View File

@@ -97,12 +97,12 @@ public class PaperRegistryAccess implements RegistryAccess {
return registry;
}
public <M> void registerReloadableRegistry(final ResourceKey<? extends net.minecraft.core.Registry<M>> resourceKey, final net.minecraft.core.Registry<M> registry) {
this.registerRegistry(resourceKey, registry, true);
public <M> void registerReloadableRegistry(final net.minecraft.core.Registry<M> registry) {
this.registerRegistry(registry, true);
}
public <M> void registerRegistry(final ResourceKey<? extends net.minecraft.core.Registry<M>> resourceKey, final net.minecraft.core.Registry<M> registry) {
this.registerRegistry(resourceKey, registry, false);
public <M> void registerRegistry(final net.minecraft.core.Registry<M> registry) {
this.registerRegistry(registry, false);
}
public <M> void lockReferenceHolders(final ResourceKey<? extends net.minecraft.core.Registry<M>> 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 <M, B extends Keyed, R extends Registry<B>> void registerRegistry(final ResourceKey<? extends net.minecraft.core.Registry<M>> resourceKey, final net.minecraft.core.Registry<M> registry, final boolean replace) {
final RegistryEntry<M, B> entry = PaperRegistries.getEntry(resourceKey);
private <M, B extends Keyed, R extends Registry<B>> void registerRegistry(final net.minecraft.core.Registry<M> registry, final boolean replace) {
final RegistryEntry<M, B> 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<B, R>) registryHolder).loadFrom(delayedEntry, registry);
} else {
throw new IllegalArgumentException(resourceKey + " has already been created");
throw new IllegalArgumentException(registry.key() + " has already been created");
}
}
}

View File

@@ -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<M, A extends Keyed> permits RegistryEn
) implements ServerSide<M, A> {
public RegistryEntryAddEventImpl<A, B> createEntryAddEvent(final TypedKey<A> 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<A, B> createPostLoadEvent(final WritableCraftRegistry<M, A, B> 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

View File

@@ -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 <V extends Keyed> Tag<V> getOrCreateTag(final TagKey<V> tagKey) {
final RegistryOps.RegistryInfo<Object> 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 extends Keyed> V getOrCreate(final TypedKey<V> key) {
final Registry<V> registry = PaperRegistryAccess.instance().getRegistry(key.registryKey());
final V value = registry.get(key);
if (value != null) {
return value;
} else if (!(registry instanceof final CraftRegistry<V, ?> 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<? extends net.minecraft.core.Registry<Object>> 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);
}
}
}

View File

@@ -15,13 +15,7 @@ import org.bukkit.Keyed;
public record RegistryComposeEventImpl<T, B extends RegistryBuilder<T>>(
RegistryKey<T> registryKey,
WritableRegistry<T, B> registry,
Conversions conversions
Conversions conversions,
RegistryRetriever retriever
) implements RegistryFreezeEvent<T, B>, PaperLifecycleEvent {
@Override
public <V extends Keyed> Tag<V> getOrCreateTag(final TagKey<V> tagKey) {
final RegistryOps.RegistryInfo<Object> 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);
}
}

View File

@@ -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<T, B extends RegistryBuilder<T>>(
TypedKey<T> key,
B builder,
RegistryKey<T> registryKey,
Conversions conversions
Conversions conversions,
RegistryRetriever retriever
) implements RegistryEntryAddEvent<T, B>, PaperLifecycleEvent {
@Override
public <V extends Keyed> Tag<V> getOrCreateTag(final TagKey<V> tagKey) {
final RegistryOps.RegistryInfo<Object> 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);
}
}

View File

@@ -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<B extends Keyed, M> implements Registry<B> {
return cached;
}
final Optional<Holder.Reference<M>> 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<Holder.Reference<M>> holderOptional = this.minecraftRegistry.get(MCUtil.toResourceKey(this.minecraftRegistry.key(), namespacedKey));
final Holder.Reference<M> holder;
if (holderOptional.isPresent()) {
holder = holderOptional.get();
@@ -215,12 +217,9 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
// 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<B extends Keyed, M> implements Registry<B> {
}
public B createBukkit(Holder<M> minecraft) {
if (minecraft == null) {
return null;
}
return this.minecraftToBukkit.createBukkit(minecraft);
}
@@ -261,6 +256,10 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
return this.minecraftToBukkit.supportsDirectHolders();
}
public boolean constructorUsesHolder() {
return this.minecraftToBukkit.constructorUsesHolder();
}
@Override
public NamespacedKey getKey(final B value) {
if (value instanceof Holderable<?> holderable) {

View File

@@ -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<WolfVariant> {
public static class CraftVariant extends HolderableBase<WolfVariant> implements Variant {
public static Variant minecraftToBukkit(WolfVariant minecraft) {
return CraftRegistry.minecraftToBukkit(minecraft, Registries.WOLF_VARIANT);
}
public static Variant minecraftHolderToBukkit(Holder<WolfVariant> 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<WolfVariant> bukkitToMinecraftHolder(Variant bukkit) {
Preconditions.checkArgument(bukkit != null);
net.minecraft.core.Registry<WolfVariant> registry = CraftRegistry.getMinecraftRegistry(Registries.WOLF_VARIANT);
if (registry.wrapAsHolder(CraftVariant.bukkitToMinecraft(bukkit)) instanceof Holder.Reference<WolfVariant> 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<WolfVariant> holder) {
super(holder);
}
}

View File

@@ -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<Class<? extends Keyed>> IMPLEMENT_HANDLE_ABLE = new HashSet<>();
public static Stream<? extends Arguments> getValues(RegistryKey<? extends Keyed> 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<? extends Keyed> type, Class<? extends Keyed> clazz) { // Paper
@@ -210,7 +217,7 @@ public class RegistryConversionTest {
Map<Object, Object> 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<Object, Object> 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];

View File

@@ -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<RegistryTest> {
private Class<? extends Keyed> registryType;
@Override
public void accept(RegistryTest registryTest) {
this.registryType = registryTest.value();
}
@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext extensionContext) throws Exception {
return RegistryArgumentProvider.getValues(io.papermc.paper.registry.PaperRegistryAccess.byType(this.registryType)); // Paper
}
public static Stream<? extends Arguments> getValues(io.papermc.paper.registry.RegistryKey<? extends Keyed> 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()));
}
}

View File

@@ -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<? extends Keyed> value();
}

View File

@@ -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");
});
}
}