add RegistryAccess for managing registries

This commit is contained in:
Jake Potrebic 2024-01-10 17:40:34 -08:00
parent a6b6ecdd22
commit 37fc71b119
No known key found for this signature in database
GPG Key ID: ECE0B3C133C016C5
12 changed files with 1355 additions and 178 deletions

View File

@ -1,92 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 2 Mar 2022 13:36:21 -0800
Subject: [PATCH] Add PaperRegistry
diff --git a/src/main/java/io/papermc/paper/registry/Reference.java b/src/main/java/io/papermc/paper/registry/Reference.java
new file mode 100644
index 0000000000000000000000000000000000000000..d880810cbf05bc45051fe29515054211572e33b4
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/Reference.java
@@ -0,0 +1,43 @@
+package io.papermc.paper.registry;
+
+import org.bukkit.Keyed;
+import org.bukkit.NamespacedKey;
+import org.bukkit.Registry;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Represents a reference to a server-backed registry value that may
+ * change.
+ *
+ * @param <T> type of the value
+ */
+public interface Reference<T extends Keyed> extends Keyed {
+
+ /**
+ * Gets the value from the registry with the key.
+ *
+ * @return the value
+ * @throws java.util.NoSuchElementException if there is no value with this key
+ */
+ @NotNull T value();
+
+ /**
+ * Gets the value from the registry with the key.
+ *
+ * @return the value or null if it doesn't exist
+ */
+ @Nullable T valueOrNull();
+
+ /**
+ * Creates a reference to a registered value.
+ *
+ * @param registry the registry the value is located in
+ * @param key the key to the value
+ * @param <T> the type of the value
+ * @return a reference
+ */
+ static <T extends Keyed> @NotNull Reference<T> create(@NotNull Registry<T> registry, @NotNull NamespacedKey key) {
+ return new ReferenceImpl<>(registry, key);
+ }
+}
diff --git a/src/main/java/io/papermc/paper/registry/ReferenceImpl.java b/src/main/java/io/papermc/paper/registry/ReferenceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..f29e76a6b66ddfec12ddf8db6dcb2df6083b5982
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/ReferenceImpl.java
@@ -0,0 +1,31 @@
+package io.papermc.paper.registry;
+
+import org.bukkit.Keyed;
+import org.bukkit.NamespacedKey;
+import org.bukkit.Registry;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.NoSuchElementException;
+
+record ReferenceImpl<T extends Keyed>(@NotNull Registry<T> registry, @NotNull NamespacedKey key) implements Reference<T> {
+
+ @Override
+ public @NotNull T value() {
+ final T value = this.registry.get(this.key);
+ if (value == null) {
+ throw new NoSuchElementException("No such value with key " + this.key);
+ }
+ return value;
+ }
+
+ @Override
+ public @Nullable T valueOrNull() {
+ return this.registry.get(this.key);
+ }
+
+ @Override
+ public @NotNull NamespacedKey getKey() {
+ return this.key;
+ }
+}

View File

@ -0,0 +1,445 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 2 Mar 2022 13:36:21 -0800
Subject: [PATCH] Add RegistryAccess for managing registries
diff --git a/src/main/java/io/papermc/paper/registry/Reference.java b/src/main/java/io/papermc/paper/registry/Reference.java
new file mode 100644
index 0000000000000000000000000000000000000000..92ec13c2bd515fedfd5057201ae4ba15c184bacd
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/Reference.java
@@ -0,0 +1,47 @@
+package io.papermc.paper.registry;
+
+import org.bukkit.Keyed;
+import org.bukkit.NamespacedKey;
+import org.bukkit.Registry;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Represents a reference to a server-backed registry value that may
+ * change.
+ *
+ * @param <T> type of the value
+ */
+@Deprecated(forRemoval = true, since = "1.20.4")
+public interface Reference<T extends Keyed> extends Keyed {
+
+ /**
+ * Gets the value from the registry with the key.
+ *
+ * @return the value
+ * @throws java.util.NoSuchElementException if there is no value with this key
+ */
+ @Deprecated(forRemoval = true, since = "1.20.4")
+ @NotNull T value();
+
+ /**
+ * Gets the value from the registry with the key.
+ *
+ * @return the value or null if it doesn't exist
+ */
+ @Deprecated(forRemoval = true, since = "1.20.4")
+ @Nullable T valueOrNull();
+
+ /**
+ * Creates a reference to a registered value.
+ *
+ * @param registry the registry the value is located in
+ * @param key the key to the value
+ * @param <T> the type of the value
+ * @return a reference
+ */
+ @Deprecated(forRemoval = true, since = "1.20.4")
+ static <T extends Keyed> @NotNull Reference<T> create(@NotNull Registry<T> registry, @NotNull NamespacedKey key) {
+ return new ReferenceImpl<>(registry, key);
+ }
+}
diff --git a/src/main/java/io/papermc/paper/registry/ReferenceImpl.java b/src/main/java/io/papermc/paper/registry/ReferenceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..f29e76a6b66ddfec12ddf8db6dcb2df6083b5982
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/ReferenceImpl.java
@@ -0,0 +1,31 @@
+package io.papermc.paper.registry;
+
+import org.bukkit.Keyed;
+import org.bukkit.NamespacedKey;
+import org.bukkit.Registry;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.NoSuchElementException;
+
+record ReferenceImpl<T extends Keyed>(@NotNull Registry<T> registry, @NotNull NamespacedKey key) implements Reference<T> {
+
+ @Override
+ public @NotNull T value() {
+ final T value = this.registry.get(this.key);
+ if (value == null) {
+ throw new NoSuchElementException("No such value with key " + this.key);
+ }
+ return value;
+ }
+
+ @Override
+ public @Nullable T valueOrNull() {
+ return this.registry.get(this.key);
+ }
+
+ @Override
+ public @NotNull NamespacedKey getKey() {
+ return this.key;
+ }
+}
diff --git a/src/main/java/io/papermc/paper/registry/RegistryAccess.java b/src/main/java/io/papermc/paper/registry/RegistryAccess.java
new file mode 100644
index 0000000000000000000000000000000000000000..77516c302c0d3e79724eb0c43ee61430b5266e21
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/RegistryAccess.java
@@ -0,0 +1,45 @@
+package io.papermc.paper.registry;
+
+import org.bukkit.Keyed;
+import org.bukkit.Registry;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+@ApiStatus.NonExtendable
+@ApiStatus.Experimental
+public interface RegistryAccess {
+
+ /**
+ * Get the {@link RegistryAccess} instance for the server.
+ *
+ * @return the RegistryAccess instance
+ */
+ static @NotNull RegistryAccess registryAccess() {
+ return RegistryAccessHolder.INSTANCE;
+ }
+
+ /**
+ * Gets the registry based on the type.
+ *
+ * @param type the type
+ * @return the registry or null if none found
+ * @param <T> the type
+ * @deprecated use {@link #getRegistry(RegistryKey)} with keys from {@link RegistryKey}
+ */
+ @Deprecated(since = "1.20.4", forRemoval = true)
+ <T extends Keyed> @Nullable Registry<T> getRegistry(@NotNull Class<T> type);
+
+ /**
+ * Gets the registry with the specified key.
+ *
+ * @param registryKey the key
+ * @return the registry
+ * @param <T> the type
+ * @throws java.util.NoSuchElementException if no registry with the key is found
+ * @throws IllegalArgumentException if the registry is not available yet
+ */
+ // Future note: We should have no trouble removing this generic qualifier when
+ // registry types no longer have to be "keyed" as it shouldn't break ABI or API.
+ <T extends Keyed> @NotNull Registry<T> getRegistry(@NotNull RegistryKey<T> registryKey);
+}
diff --git a/src/main/java/io/papermc/paper/registry/RegistryAccessHolder.java b/src/main/java/io/papermc/paper/registry/RegistryAccessHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..82e4d668059a15998a978d1ce0e03ff857e660de
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/RegistryAccessHolder.java
@@ -0,0 +1,11 @@
+package io.papermc.paper.registry;
+
+import java.util.ServiceLoader;
+
+final class RegistryAccessHolder {
+
+ static final RegistryAccess INSTANCE = ServiceLoader.load(RegistryAccess.class).findFirst().orElseThrow(() -> new IllegalStateException("No RegistryAccess implementation found"));
+
+ private RegistryAccessHolder() {
+ }
+}
diff --git a/src/main/java/io/papermc/paper/registry/RegistryKey.java b/src/main/java/io/papermc/paper/registry/RegistryKey.java
index c4b30b16ce4db754b958c493ad86d0863592c263..f8159d08422fcf10ebd2309afeb355ff0a1420c9 100644
--- a/src/main/java/io/papermc/paper/registry/RegistryKey.java
+++ b/src/main/java/io/papermc/paper/registry/RegistryKey.java
@@ -2,11 +2,15 @@ package io.papermc.paper.registry;
import net.kyori.adventure.key.Keyed;
import org.bukkit.GameEvent;
+import org.bukkit.MusicInstrument;
import org.bukkit.block.Biome;
+import org.bukkit.damage.DamageType;
+import org.bukkit.enchantments.Enchantment;
import org.bukkit.generator.structure.Structure;
import org.bukkit.generator.structure.StructureType;
import org.bukkit.inventory.meta.trim.TrimMaterial;
import org.bukkit.inventory.meta.trim.TrimPattern;
+import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.ApiStatus;
import static io.papermc.paper.registry.RegistryKeyImpl.create;
@@ -40,6 +44,18 @@ public sealed interface RegistryKey<T> extends Keyed permits RegistryKeyImpl {
* @see io.papermc.paper.registry.keys.StructureTypeKeys
*/
RegistryKey<StructureType> STRUCTURE_TYPE = create("worldgen/structure_type");
+ /**
+ * Built-in registry for instruments.
+ */
+ RegistryKey<MusicInstrument> INSTRUMENT = create("instrument");
+ /**
+ * Built-in registry for enchantments.
+ */
+ RegistryKey<Enchantment> ENCHANTMENT = create("enchantment");
+ /**
+ * Built-in registry for potion effect types (mob effects).
+ */
+ RegistryKey<PotionEffectType> MOB_EFFECT = create("mob_effect");
/* ********************** *
* Data-driven Registries *
@@ -64,4 +80,8 @@ public sealed interface RegistryKey<T> extends Keyed permits RegistryKeyImpl {
* @see io.papermc.paper.registry.keys.TrimPatternKeys
*/
RegistryKey<TrimPattern> TRIM_PATTERN = create("trim_pattern");
+ /**
+ * Data-driven registry for damage types.
+ */
+ RegistryKey<DamageType> DAMAGE_TYPE = create("damage_type");
}
diff --git a/src/main/java/io/papermc/paper/registry/RegistryKeyImpl.java b/src/main/java/io/papermc/paper/registry/RegistryKeyImpl.java
index 9ad300fa1668cb59bbd85ff8091591db69b8c9dc..791813220b2504214b1adecc69093cd600fb0f8c 100644
--- a/src/main/java/io/papermc/paper/registry/RegistryKeyImpl.java
+++ b/src/main/java/io/papermc/paper/registry/RegistryKeyImpl.java
@@ -11,9 +11,14 @@ record RegistryKeyImpl<T>(@NotNull Key key) implements RegistryKey<T> {
static final Set<RegistryKey<?>> REGISTRY_KEYS = Sets.newIdentityHashSet();
static <T> RegistryKey<T> create(@Subst("some_key") final String key) {
- final RegistryKey<T> registryKey = new RegistryKeyImpl<>(Key.key(Key.MINECRAFT_NAMESPACE, key));
+ final RegistryKey<T> registryKey = createInternal(key);
REGISTRY_KEYS.add(registryKey);
return registryKey;
}
+ // creates the key without adding to the internal set of keys
+ static <T> RegistryKey<T> createInternal(@Subst("some_key") final String key) {
+ return new RegistryKeyImpl<>(Key.key(Key.MINECRAFT_NAMESPACE, key));
+ }
+
}
diff --git a/src/main/java/io/papermc/paper/registry/TypedKey.java b/src/main/java/io/papermc/paper/registry/TypedKey.java
index 271454cd1b92ada4301025b57348ea77da9116a1..6f5a062ba7ee7173468ecea3c1855a233bf3855e 100644
--- a/src/main/java/io/papermc/paper/registry/TypedKey.java
+++ b/src/main/java/io/papermc/paper/registry/TypedKey.java
@@ -38,7 +38,7 @@ public sealed interface TypedKey<T> extends Keyed permits TypedKeyImpl {
* @return a new key for the value key and registry key
*/
@ApiStatus.Experimental
- static <T extends Keyed> @NotNull TypedKey<T> create(final @NotNull RegistryKey<T> registryKey, final @NotNull Key key) {
+ static <T> @NotNull TypedKey<T> create(final @NotNull RegistryKey<T> registryKey, final @NotNull Key key) {
return new TypedKeyImpl<>(key, registryKey);
}
}
diff --git a/src/main/java/io/papermc/paper/registry/TypedKeyImpl.java b/src/main/java/io/papermc/paper/registry/TypedKeyImpl.java
index 3c3fd73f7742bb8602e2f9164dd4c1208a412255..1a97b3359c4ece5c29131da7c3f208aaa8fab66e 100644
--- a/src/main/java/io/papermc/paper/registry/TypedKeyImpl.java
+++ b/src/main/java/io/papermc/paper/registry/TypedKeyImpl.java
@@ -4,5 +4,5 @@ import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.Keyed;
import org.jetbrains.annotations.NotNull;
-record TypedKeyImpl<T extends Keyed>(@NotNull Key key, @NotNull RegistryKey<T> registryKey) implements TypedKey<T> {
+record TypedKeyImpl<T>(@NotNull Key key, @NotNull RegistryKey<T> registryKey) implements TypedKey<T> {
}
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index e832c6a8a10bc29d9ab20cbdf394cf836eb2f6a5..1a2e4ebc2e86b00e7de8ddc7b6eeb6e9da09fbd8 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -2375,8 +2375,11 @@ public final class Bukkit {
* @param tClass of the registry to get
* @param <T> type of the registry
* @return the corresponding registry or null if not present
+ * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)}
+ * with keys from {@link io.papermc.paper.registry.RegistryKey}
*/
@Nullable
+ @Deprecated(since = "1.20.4")
public static <T extends Keyed> Registry<T> getRegistry(@NotNull Class<T> tClass) {
return server.getRegistry(tClass);
}
diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java
index b3f8a2611ceb57f5d0b5c300fa80d8bad121498d..fb81595d7a80bee2632a44b77e63d6064929aea0 100644
--- a/src/main/java/org/bukkit/Registry.java
+++ b/src/main/java/org/bukkit/Registry.java
@@ -127,7 +127,7 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
*
* @see Enchantment
*/
- Registry<Enchantment> ENCHANTMENT = Objects.requireNonNull(Bukkit.getRegistry(Enchantment.class), "No registry present for Enchantment. This is a bug.");
+ Registry<Enchantment> ENCHANTMENT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.ENCHANTMENT); // Paper
/**
* Server entity types.
*
@@ -139,7 +139,7 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
*
* @see MusicInstrument
*/
- Registry<MusicInstrument> INSTRUMENT = Objects.requireNonNull(Bukkit.getRegistry(MusicInstrument.class), "No registry present for MusicInstrument. This is a bug.");
+ Registry<MusicInstrument> INSTRUMENT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.INSTRUMENT); // Paper
/**
* Default server loot tables.
*
@@ -157,7 +157,7 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
*
* @see PotionEffectType
*/
- Registry<PotionEffectType> EFFECT = Objects.requireNonNull(Bukkit.getRegistry(PotionEffectType.class), "No registry present for PotionEffectType. This is a bug.");
+ Registry<PotionEffectType> EFFECT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.MOB_EFFECT); // Paper
/**
* Server particles.
*
@@ -180,14 +180,16 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
* Server structures.
*
* @see Structure
+ * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#STRUCTURE}
*/
- Registry<Structure> STRUCTURE = Bukkit.getRegistry(Structure.class);
+ @Deprecated(since = "1.20.4") // Paper
+ Registry<Structure> STRUCTURE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Structure.class); // Paper
/**
* Server structure types.
*
* @see StructureType
*/
- Registry<StructureType> STRUCTURE_TYPE = Bukkit.getRegistry(StructureType.class);
+ Registry<StructureType> STRUCTURE_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.STRUCTURE_TYPE); // Paper
/**
* Sound keys.
*
@@ -198,21 +200,25 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
* Trim materials.
*
* @see TrimMaterial
+ * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#TRIM_MATERIAL}
*/
- Registry<TrimMaterial> TRIM_MATERIAL = Bukkit.getRegistry(TrimMaterial.class);
+ @Deprecated(since = "1.20.4") // Paper
+ Registry<TrimMaterial> TRIM_MATERIAL = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(TrimMaterial.class); // Paper
/**
* Trim patterns.
*
* @see TrimPattern
+ * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#TRIM_PATTERN}
*/
- Registry<TrimPattern> TRIM_PATTERN = Bukkit.getRegistry(TrimPattern.class);
+ @Deprecated(since = "1.20.4")
+ Registry<TrimPattern> TRIM_PATTERN = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(TrimPattern.class); // Paper
/**
* Damage types.
*
* @see DamageType
*/
@ApiStatus.Experimental
- Registry<DamageType> DAMAGE_TYPE = Objects.requireNonNull(Bukkit.getRegistry(DamageType.class), "No registry present for DamageType. This is a bug.");
+ Registry<DamageType> DAMAGE_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(DamageType.class); // Paper
/**
* Villager profession.
*
@@ -267,7 +273,7 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
*
* @see GameEvent
*/
- Registry<GameEvent> GAME_EVENT = Objects.requireNonNull(Bukkit.getRegistry(GameEvent.class), "No registry present for GameEvent. This is a bug.");
+ Registry<GameEvent> GAME_EVENT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.GAME_EVENT); // Paper
/**
* Get the object by its key.
*
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 9477563308adc64fff065eb0a50654baa0d22b84..1a47630004d5ee1019eaed0ed8dd9a9f58c55e4a 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -2027,8 +2027,11 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
* @param tClass of the registry to get
* @param <T> type of the registry
* @return the corresponding registry or null if not present
+ * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)}
+ * with keys from {@link io.papermc.paper.registry.RegistryKey}
*/
@Nullable
+ @Deprecated(since = "1.20.4") // Paper
<T extends Keyed> Registry<T> getRegistry(@NotNull Class<T> tClass);
/**
diff --git a/src/test/java/io/papermc/paper/registry/TestRegistryAccess.java b/src/test/java/io/papermc/paper/registry/TestRegistryAccess.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e99d7d84150664f16cbbd6f58eb3a316017fe5f
--- /dev/null
+++ b/src/test/java/io/papermc/paper/registry/TestRegistryAccess.java
@@ -0,0 +1,20 @@
+package io.papermc.paper.registry;
+
+import org.bukkit.Keyed;
+import org.bukkit.Registry;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class TestRegistryAccess implements RegistryAccess {
+
+ @Override
+ @Deprecated(since = "1.20.4", forRemoval = true)
+ public @Nullable <T extends Keyed> Registry<T> getRegistry(final @NotNull Class<T> type) {
+ throw new UnsupportedOperationException("Not supported");
+ }
+
+ @Override
+ public @NotNull <T extends Keyed> Registry<T> getRegistry(final @NotNull RegistryKey<T> registryKey) {
+ throw new UnsupportedOperationException("Not supported");
+ }
+}
diff --git a/src/test/java/org/bukkit/support/TestServer.java b/src/test/java/org/bukkit/support/TestServer.java
index b208150297a23c0b4acb79135416809718f5650e..f11c639f1dc3c5034678d80bde3127a2e81a4a93 100644
--- a/src/test/java/org/bukkit/support/TestServer.java
+++ b/src/test/java/org/bukkit/support/TestServer.java
@@ -36,26 +36,11 @@ public final class TestServer {
when(instance.getBukkitVersion()).thenReturn("BukkitVersion_" + TestServer.class.getPackage().getImplementationVersion());
- Map<Class<? extends Keyed>, Registry<?>> registers = new HashMap<>();
- when(instance.getRegistry(any())).then(invocationOnMock -> registers.computeIfAbsent(invocationOnMock.getArgument(0), aClass -> new Registry<Keyed>() {
- private final Map<NamespacedKey, Keyed> cache = new HashMap<>();
-
- @Override
- public Keyed get(NamespacedKey key) {
- return cache.computeIfAbsent(key, key2 -> mock(aClass, withSettings().stubOnly()));
- }
-
- @NotNull
- @Override
- public Stream<Keyed> stream() {
- throw new UnsupportedOperationException("Not supported");
- }
-
- @Override
- public Iterator<Keyed> iterator() {
- throw new UnsupportedOperationException("Not supported");
- }
- }));
+ // Paper start - RegistryAccess
+ when(instance.getRegistry(any())).then(invocationOnMock -> {
+ return io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(((Class<Keyed>)invocationOnMock.getArgument(0)));
+ });
+ // Paper end - RegistryAccess
UnsafeValues unsafeValues = mock(withSettings().stubOnly());
when(instance.getUnsafe()).thenReturn(unsafeValues);
diff --git a/src/test/resources/META-INF/services/io.papermc.paper.registry.RegistryAccess b/src/test/resources/META-INF/services/io.papermc.paper.registry.RegistryAccess
new file mode 100644
index 0000000000000000000000000000000000000000..f0a5e6d6b99aeef349fe465080ef2ff7b58617a6
--- /dev/null
+++ b/src/test/resources/META-INF/services/io.papermc.paper.registry.RegistryAccess
@@ -0,0 +1 @@
+io.papermc.paper.registry.TestRegistryAccess

View File

@ -513,22 +513,22 @@ index 0000000000000000000000000000000000000000..1e7b53f9bc13dcd5a0a4a40004591e4f
+ }
+}
diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java
index b3f8a2611ceb57f5d0b5c300fa80d8bad121498d..4bc53793aade0887fa650a4bbf51d2e57678bd90 100644
index fb81595d7a80bee2632a44b77e63d6064929aea0..cda594d2ed656462e175ca9cb9d8eb924263e4b1 100644
--- a/src/main/java/org/bukkit/Registry.java
+++ b/src/main/java/org/bukkit/Registry.java
@@ -268,6 +268,17 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
@@ -274,6 +274,17 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
* @see GameEvent
*/
Registry<GameEvent> GAME_EVENT = Objects.requireNonNull(Bukkit.getRegistry(GameEvent.class), "No registry present for GameEvent. This is a bug.");
Registry<GameEvent> GAME_EVENT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.GAME_EVENT); // Paper
+
+ // Paper start
+ /**
+ * Configured structures.
+ * @see io.papermc.paper.world.structure.ConfiguredStructure
+ * @deprecated use {@link #STRUCTURE}
+ * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#STRUCTURE}
+ */
+ @Deprecated(forRemoval = true)
+ Registry<io.papermc.paper.world.structure.ConfiguredStructure> CONFIGURED_STRUCTURE = Bukkit.getRegistry(io.papermc.paper.world.structure.ConfiguredStructure.class);
+ Registry<io.papermc.paper.world.structure.ConfiguredStructure> CONFIGURED_STRUCTURE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.world.structure.ConfiguredStructure.class);
+ // Paper end
+
/**

View File

@ -70,7 +70,7 @@ index 0000000000000000000000000000000000000000..58f78d5e91beacaf710f62461cf869f7
+
+}
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index 4b3c91575f2609ad1b1177384f6f21151a535054..6ac4c0c6c2245e6bee9575ff4804994648112d78 100644
index 3cf33c3072d67b01db79b8794f660ebbe20f216d..b4405c9398c2ee405d180117a85107f67caf604a 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -328,9 +328,11 @@ public final class Bukkit {
@ -85,7 +85,7 @@ index 4b3c91575f2609ad1b1177384f6f21151a535054..6ac4c0c6c2245e6bee9575ff48049946
public static DataPackManager getDataPackManager() {
return server.getDataPackManager();
}
@@ -2562,6 +2564,14 @@ public final class Bukkit {
@@ -2565,6 +2567,14 @@ public final class Bukkit {
public static com.destroystokyo.paper.entity.ai.MobGoals getMobGoals() {
return server.getMobGoals();
}
@ -101,7 +101,7 @@ index 4b3c91575f2609ad1b1177384f6f21151a535054..6ac4c0c6c2245e6bee9575ff48049946
@NotNull
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 5bb94245c33105e57131b3d0867ef707c4aed79c..052d0e420f2631ff925bb5df4a41a1cecc2d7e16 100644
index 07bb145e19f9f9df36375f23e198b67f8edf2174..77d9c117dbf4915d4da94ed31abb37865d9c6b0c 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -264,9 +264,11 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
@ -116,7 +116,7 @@ index 5bb94245c33105e57131b3d0867ef707c4aed79c..052d0e420f2631ff925bb5df4a41a1ce
public DataPackManager getDataPackManager();
/**
@@ -2232,5 +2234,11 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
@@ -2235,5 +2237,11 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
*/
@NotNull
com.destroystokyo.paper.entity.ai.MobGoals getMobGoals();

View File

@ -5,13 +5,13 @@ Subject: [PATCH] More PotionEffectType API
diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java
index 4bc53793aade0887fa650a4bbf51d2e57678bd90..18c672f3855a329bf8f87a9de81b677e8e360b41 100644
index cda594d2ed656462e175ca9cb9d8eb924263e4b1..e94dc58e895f38a3eaddcab395b7fde7d5e61147 100644
--- a/src/main/java/org/bukkit/Registry.java
+++ b/src/main/java/org/bukkit/Registry.java
@@ -277,6 +277,31 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
@@ -283,6 +283,31 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
*/
@Deprecated(forRemoval = true)
Registry<io.papermc.paper.world.structure.ConfiguredStructure> CONFIGURED_STRUCTURE = Bukkit.getRegistry(io.papermc.paper.world.structure.ConfiguredStructure.class);
Registry<io.papermc.paper.world.structure.ConfiguredStructure> CONFIGURED_STRUCTURE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.world.structure.ConfiguredStructure.class);
+
+ /**
+ * Potion effect types.

View File

@ -155,10 +155,10 @@ index 0000000000000000000000000000000000000000..3ede1e8f7bf0436fdc5bf395c0f9eaf1
+ }
+}
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index f941836afda889d8824b1f89bfe9a66cf71ed2a0..22ec7dda6853db6539e98e8d39d8a13be8926f07 100644
index 8ea7b10f7d8076b8c75577845ac37f8a7191b32f..f16b12101218943674bb866403ed7ce5ad5c8592 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -2604,6 +2604,15 @@ public final class Bukkit {
@@ -2607,6 +2607,15 @@ public final class Bukkit {
public static io.papermc.paper.datapack.DatapackManager getDatapackManager() {
return server.getDatapackManager();
}
@ -175,10 +175,10 @@ index f941836afda889d8824b1f89bfe9a66cf71ed2a0..22ec7dda6853db6539e98e8d39d8a13b
@NotNull
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index aee14b81d16c26c3c7e1c5849a829bfe012aa5fb..96f9f3ac492eb6f4628d47f0be4239ab9bc7df54 100644
index e872ddc6690e0ecc3a815fbb3c17bb8f782279f3..a53697fcbda55d623da557b66b5cd2d26c57dba2 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -2268,5 +2268,12 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
@@ -2271,5 +2271,12 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
*/
@NotNull
io.papermc.paper.datapack.DatapackManager getDatapackManager();

View File

@ -499,10 +499,10 @@ index 0000000000000000000000000000000000000000..a6b50c9d8af589cc4747e14d343d2045
+ }
+}
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index a24de4474114af533e1e8b78c4fd0e8c5edd14b8..010d7e8a831b32060a471ef877ac43ce237a7258 100644
index 56d52748b7f2c4120887ec499ce59436327b486a..9234ed4ef6c9ea654256e673e3a17ee1d99db4eb 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -2635,6 +2635,141 @@ public final class Bukkit {
@@ -2638,6 +2638,141 @@ public final class Bukkit {
}
// Paper end
@ -645,10 +645,10 @@ index a24de4474114af533e1e8b78c4fd0e8c5edd14b8..010d7e8a831b32060a471ef877ac43ce
public static Server.Spigot spigot() {
return server.spigot();
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index c8704bc90a4f7040e5fa1c0377d5533bd14a4249..627913905269739e91c5007e372856e321cb9312 100644
index bcd82dd9ec85ad49111e8f25c3640d41da8ea7bb..a42565cdd7c93794e3f3232d035daf4fb2863dcf 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -2297,4 +2297,119 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
@@ -2300,4 +2300,119 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
*/
@NotNull org.bukkit.potion.PotionBrewer getPotionBrewer();
// Paper end

View File

@ -31,10 +31,10 @@ index ee5368372e136541eafe1d7ffb395de670fe4843..31a81ac909976492f0c6b93ad4900887
@Override
public @NotNull String translationKey() {
diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java
index 18c672f3855a329bf8f87a9de81b677e8e360b41..e1fb4d8cca6a9c59047b1396f5c40bea957d777a 100644
index e94dc58e895f38a3eaddcab395b7fde7d5e61147..cf772c2f7c350c5ab203a7f9c650d741810eeb92 100644
--- a/src/main/java/org/bukkit/Registry.java
+++ b/src/main/java/org/bukkit/Registry.java
@@ -313,6 +313,49 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
@@ -319,6 +319,49 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
@Nullable
T get(@NotNull NamespacedKey key);
@ -84,7 +84,7 @@ index 18c672f3855a329bf8f87a9de81b677e8e360b41..e1fb4d8cca6a9c59047b1396f5c40bea
/**
* Returns a new stream, which contains all registry items, which are registered to the registry.
*
@@ -379,5 +422,12 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
@@ -385,5 +428,12 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
public Iterator<T> iterator() {
return map.values().iterator();
}

View File

@ -0,0 +1,829 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Mon, 27 Feb 2023 18:28:39 -0800
Subject: [PATCH] Add RegistryAccess for managing Registries
RegistryAccess is independant from CraftServer and
doesn't require one to be created allowing the
org.bukkit.Registry class to be loaded earlier.
== AT ==
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..e21bcb349ac36d141fd8bd51f7a1d9fc7532b510
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/PaperRegistries.java
@@ -0,0 +1,84 @@
+package io.papermc.paper.registry;
+
+import io.papermc.paper.registry.entry.RegistryEntry;
+import io.papermc.paper.registry.legacy.DelayedRegistryEntry;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import net.minecraft.core.Registry;
+import net.minecraft.core.registries.Registries;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.world.item.enchantment.Enchantment;
+import net.minecraft.world.level.levelgen.structure.Structure;
+import org.bukkit.GameEvent;
+import org.bukkit.Keyed;
+import org.bukkit.MusicInstrument;
+import org.bukkit.craftbukkit.CraftGameEvent;
+import org.bukkit.craftbukkit.CraftMusicInstrument;
+import org.bukkit.craftbukkit.damage.CraftDamageType;
+import org.bukkit.craftbukkit.enchantments.CraftEnchantment;
+import org.bukkit.craftbukkit.generator.structure.CraftStructure;
+import org.bukkit.craftbukkit.generator.structure.CraftStructureType;
+import org.bukkit.craftbukkit.inventory.trim.CraftTrimMaterial;
+import org.bukkit.craftbukkit.inventory.trim.CraftTrimPattern;
+import org.bukkit.craftbukkit.potion.CraftPotionEffectType;
+import org.bukkit.damage.DamageType;
+import org.bukkit.generator.structure.StructureType;
+import org.bukkit.inventory.meta.trim.TrimMaterial;
+import org.bukkit.inventory.meta.trim.TrimPattern;
+import org.bukkit.potion.PotionEffectType;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.checkerframework.framework.qual.DefaultQualifier;
+
+import static io.papermc.paper.registry.entry.RegistryEntry.entry;
+
+@DefaultQualifier(NonNull.class)
+public final class PaperRegistries {
+
+ static final List<RegistryEntry<?, ?>> REGISTRY_ENTRIES;
+ private static final Map<RegistryKey<?>, RegistryEntry<?, ?>> BY_REGISTRY_KEY;
+ private static final Map<ResourceKey<?>, RegistryEntry<?, ?>> BY_RESOURCE_KEY;
+ static {
+ REGISTRY_ENTRIES = List.of(
+ // built-ins
+ entry(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT, Enchantment.class, CraftEnchantment::new),
+ entry(Registries.GAME_EVENT, RegistryKey.GAME_EVENT, GameEvent.class, CraftGameEvent::new),
+ entry(Registries.INSTRUMENT, RegistryKey.INSTRUMENT, MusicInstrument.class, CraftMusicInstrument::new),
+ entry(Registries.MOB_EFFECT, RegistryKey.MOB_EFFECT, PotionEffectType.class, CraftPotionEffectType::new),
+ entry(Registries.STRUCTURE_TYPE, RegistryKey.STRUCTURE_TYPE, StructureType.class, CraftStructureType::new),
+
+ // data-drivens
+ 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()
+ );
+ final Map<RegistryKey<?>, RegistryEntry<?, ?>> byRegistryKey = new IdentityHashMap<>(REGISTRY_ENTRIES.size());
+ final Map<ResourceKey<?>, RegistryEntry<?, ?>> byResourceKey = new IdentityHashMap<>(REGISTRY_ENTRIES.size());
+ for (final RegistryEntry<?, ?> entry : REGISTRY_ENTRIES) {
+ byRegistryKey.put(entry.apiRegistryKey(), entry);
+ byResourceKey.put(entry.minecraftRegistryKey(), entry);
+ }
+ BY_REGISTRY_KEY = Collections.unmodifiableMap(byRegistryKey);
+ BY_RESOURCE_KEY = Collections.unmodifiableMap(byResourceKey);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <M, T extends Keyed> @Nullable RegistryEntry<M, T> getEntry(final ResourceKey<? extends Registry<M>> resourceKey) {
+ return (RegistryEntry<M, T>) BY_RESOURCE_KEY.get(resourceKey);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <M, T extends Keyed> @Nullable RegistryEntry<M, T> getEntry(final RegistryKey<? super T> registryKey) {
+ return (RegistryEntry<M, T>) BY_REGISTRY_KEY.get(registryKey);
+ }
+
+ public static boolean isDelayed(final RegistryKey<?> registryKey) {
+ return BY_REGISTRY_KEY.get(registryKey) instanceof DelayedRegistryEntry<?, ?>;
+ }
+
+ private PaperRegistries() {
+ }
+}
diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java b/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java
new file mode 100644
index 0000000000000000000000000000000000000000..ae2a25ee0ae5d29d4271e8911103d54c4f71a308
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java
@@ -0,0 +1,102 @@
+package io.papermc.paper.registry;
+
+import com.google.common.base.Suppliers;
+import io.papermc.paper.registry.entry.RegistryEntry;
+import io.papermc.paper.registry.legacy.DelayedRegistry;
+import io.papermc.paper.registry.legacy.DelayedRegistryEntry;
+import io.papermc.paper.registry.legacy.LegacyRegistryIdentifiers;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BooleanSupplier;
+import java.util.function.Supplier;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.server.MinecraftServer;
+import org.bukkit.Keyed;
+import org.bukkit.Registry;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.checkerframework.framework.qual.DefaultQualifier;
+import org.jetbrains.annotations.VisibleForTesting;
+
+import static java.util.Objects.requireNonNull;
+
+@DefaultQualifier(NonNull.class)
+public class PaperRegistryAccess implements RegistryAccess {
+
+ private final Map<RegistryKey<?>, Supplier<Registry<?>>> registries = Collections.synchronizedMap(new IdentityHashMap<>());
+
+ public static PaperRegistryAccess instance() {
+ return (PaperRegistryAccess) RegistryAccessHolder.INSTANCE;
+ }
+
+ @VisibleForTesting
+ public Set<RegistryKey<?>> loadedRegistryKeys() {
+ return Collections.unmodifiableSet(this.registries.keySet());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Deprecated(forRemoval = true)
+ @Override
+ public <T extends Keyed> @Nullable Registry<T> getRegistry(final Class<T> type) {
+ final RegistryKey<T> registryKey;
+ final Supplier<@Nullable RegistryEntry<?, T>> entrySupplier;
+ registryKey = requireNonNull(byType(type), () -> type + " is not a valid registry type");
+ entrySupplier = () -> PaperRegistries.getEntry(registryKey);
+ final @Nullable Supplier<Registry<?>> registry = this.registries.get(registryKey);
+ if (registry != null) {
+ return possiblyUnwrap((Registry<T>) registry.get(), true);
+ } else if (entrySupplier.get() instanceof final DelayedRegistryEntry<?, T> delayedRegistryEntry) {
+ return possiblyUnwrap((Registry<T>) this.registries.computeIfAbsent(registryKey, $$ -> {
+ return Suppliers.memoize(() -> delayedRegistryEntry.createApiRegistry(null));
+ }).get(), true);
+ } else {
+ return null;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T extends Keyed> Registry<T> getRegistry(final RegistryKey<T> key) {
+ final @Nullable Supplier<Registry<?>> registry = this.registries.get(key);
+ if (registry == null) {
+ throw new IllegalArgumentException(key + " is not a valid registry key or that registry is not available yet");
+ }
+ return possiblyUnwrap((Registry<T>) registry.get(), false);
+ }
+
+ public <M> void registerRegistry(final ResourceKey<? extends net.minecraft.core.Registry<M>> resourceKey, final net.minecraft.core.Registry<M> registry) {
+ final @Nullable RegistryEntry<M, ?> entry = PaperRegistries.getEntry(resourceKey);
+ if (entry == null) { // skip registries that don't have API entries
+ return;
+ }
+ if (this.registries.containsKey(entry.apiRegistryKey())) {
+ throw new IllegalArgumentException(resourceKey + " has already been created");
+ }
+ this.registries.put(entry.apiRegistryKey(), Suppliers.memoize(() -> entry.createApiRegistry(registry)));
+ }
+
+ private static <T extends Keyed> Registry<T> possiblyUnwrap(final Registry<T> registry, final boolean fromLegacy) {
+ if (registry instanceof final DelayedRegistry<T> delayedRegistry && !fromLegacy) { // if not coming from legacy, unwrap the delayed registry
+ return delayedRegistry.delegate();
+ }
+ return registry;
+ }
+
+ public net.minecraft.core.RegistryAccess getDelayedRegistryAccess() {
+ return MinecraftServer.getServer().registryAccess();
+ }
+
+ public BooleanSupplier delayedValidCheck() {
+ //noinspection ConstantValue
+ return () -> MinecraftServer.getServer() != null;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Deprecated
+ @VisibleForTesting
+ public static <T extends Keyed> @Nullable RegistryKey<T> byType(final Class<T> type) {
+ return (RegistryKey<T>) LegacyRegistryIdentifiers.CLASS_TO_KEY_MAP.get(type);
+ }
+}
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..0672a6e5bddfc1665086bc7bfb972fd795405b08
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/entry/RegistryEntry.java
@@ -0,0 +1,35 @@
+package io.papermc.paper.registry.entry;
+
+import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.legacy.DelayedRegistryEntry;
+import java.util.function.BiFunction;
+import net.minecraft.core.Registry;
+import net.minecraft.resources.ResourceKey;
+import org.bukkit.Keyed;
+import org.bukkit.NamespacedKey;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+public interface RegistryEntry<M, B extends Keyed> { // TODO remove Keyed
+
+ ResourceKey<? extends Registry<M>> minecraftRegistryKey();
+
+ RegistryKey<B> apiRegistryKey();
+
+ Class<?> classToPreload();
+
+ org.bukkit.Registry<B> createApiRegistry(@Nullable Registry<M> nmsRegistry);
+
+ /**
+ * This should only be used if the registry instance needs to exist early due to the need
+ * to populate a field in {@link org.bukkit.Registry}. Data-driven registries shouldn't exist
+ * as fields, but instead be obtained via {@link io.papermc.paper.registry.RegistryAccess#getRegistry(RegistryKey)}
+ */
+ @Deprecated
+ default RegistryEntry<M, B> delayed() {
+ return new DelayedRegistryEntry<>(this);
+ }
+
+ static <M, B extends Keyed> RegistryEntry<M, B> entry(final ResourceKey<? extends Registry<M>> minecraftRegistryKey, final RegistryKey<B> apiRegistryKey, final Class<?> classToPreload, final BiFunction<NamespacedKey, M, B> minecraftToBukkit) {
+ return new RegistryEntryImpl<>(minecraftRegistryKey, apiRegistryKey, classToPreload, minecraftToBukkit);
+ }
+}
diff --git a/src/main/java/io/papermc/paper/registry/entry/RegistryEntryImpl.java b/src/main/java/io/papermc/paper/registry/entry/RegistryEntryImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..d5bd057b70d4941fc4bf7044573e7f1a75e06a53
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/entry/RegistryEntryImpl.java
@@ -0,0 +1,51 @@
+package io.papermc.paper.registry.entry;
+
+import com.google.common.base.Preconditions;
+import io.papermc.paper.registry.RegistryKey;
+import java.util.function.BiFunction;
+import net.minecraft.core.Registry;
+import net.minecraft.resources.ResourceKey;
+import org.bukkit.Keyed;
+import org.bukkit.NamespacedKey;
+import org.bukkit.craftbukkit.CraftRegistry;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+public class RegistryEntryImpl<M, B extends Keyed> implements RegistryEntry<M, B> { // TODO remove Keyed
+
+ private final ResourceKey<? extends Registry<M>> minecraftRegistryKey;
+ private final RegistryKey<B> apiRegistryKey;
+ private final Class<?> classToPreload;
+ private final BiFunction<NamespacedKey, M, B> minecraftToBukkit;
+
+ RegistryEntryImpl(final ResourceKey<? extends Registry<M>> minecraftRegistryKey, final RegistryKey<B> apiRegistryKey, final Class<?> classToPreload, final BiFunction<NamespacedKey, M, B> minecraftToBukkit) {
+ this.minecraftRegistryKey = minecraftRegistryKey;
+ this.apiRegistryKey = apiRegistryKey;
+ this.classToPreload = classToPreload;
+ this.minecraftToBukkit = minecraftToBukkit;
+ }
+
+ @Override
+ public org.bukkit.Registry<B> createApiRegistry(final @Nullable Registry<M> nmsRegistry) {
+ Preconditions.checkState(nmsRegistry != null, "Cannot access %s yet", this.minecraftRegistryKey());
+ return new CraftRegistry<>(this.classToPreload, nmsRegistry, this.minecraftToBukkit);
+ }
+
+ @Override
+ public ResourceKey<? extends Registry<M>> minecraftRegistryKey() {
+ return this.minecraftRegistryKey;
+ }
+
+ @Override
+ public RegistryKey<B> apiRegistryKey() {
+ return this.apiRegistryKey;
+ }
+
+ @Override
+ public Class<?> classToPreload() {
+ return this.classToPreload;
+ }
+
+ public BiFunction<NamespacedKey, M, B> minecraftToBukkit() {
+ return this.minecraftToBukkit;
+ }
+}
diff --git a/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java b/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java
new file mode 100644
index 0000000000000000000000000000000000000000..070671f9c7adb4ac59249337e1f7cfe3278bfa9f
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java
@@ -0,0 +1,48 @@
+package io.papermc.paper.registry.legacy;
+
+import java.util.Iterator;
+import java.util.function.BooleanSupplier;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
+import org.bukkit.Keyed;
+import org.bukkit.NamespacedKey;
+import org.bukkit.Registry;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import oshi.util.Memoizer;
+
+/**
+ * This is to support the now-deprecated fields in {@link Registry} for
+ * data-driven registries.
+ */
+public final class DelayedRegistry<T extends Keyed> implements Registry<T> {
+
+ private final Supplier<? extends Registry<T>> delegate;
+ private final BooleanSupplier validCheck;
+
+ public DelayedRegistry(final Supplier<? extends Registry<T>> delegate, final BooleanSupplier validCheck) {
+ this.delegate = Memoizer.memoize(delegate);
+ this.validCheck = validCheck;
+ }
+
+ public Registry<T> delegate() {
+ if (!this.validCheck.getAsBoolean()) {
+ throw new IllegalStateException("You are trying to access this registry too early!");
+ }
+ return this.delegate.get();
+ }
+
+ @Override
+ public @Nullable T get(final NamespacedKey key) {
+ return this.delegate().get(key);
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ return this.delegate().iterator();
+ }
+
+ @Override
+ public Stream<T> stream() {
+ return this.delegate().stream();
+ }
+}
diff --git a/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistryEntry.java b/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistryEntry.java
new file mode 100644
index 0000000000000000000000000000000000000000..9cd106aeffa7d767c5c3ef60321b0529c5a2eaf5
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistryEntry.java
@@ -0,0 +1,41 @@
+package io.papermc.paper.registry.legacy;
+
+import io.papermc.paper.registry.PaperRegistryAccess;
+import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.entry.RegistryEntry;
+import net.minecraft.core.Registry;
+import net.minecraft.resources.ResourceKey;
+import org.bukkit.Keyed;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+public final class DelayedRegistryEntry<M, T extends Keyed> implements RegistryEntry<M, T> {
+
+ private final RegistryEntry<M, T> delegate;
+
+ public DelayedRegistryEntry(final RegistryEntry<M, T> delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public ResourceKey<? extends Registry<M>> minecraftRegistryKey() {
+ return this.delegate.minecraftRegistryKey();
+ }
+
+ @Override
+ public RegistryKey<T> apiRegistryKey() {
+ return this.delegate.apiRegistryKey();
+ }
+
+ @Override
+ public Class<?> classToPreload() {
+ return this.delegate.classToPreload();
+ }
+
+ @Override
+ public org.bukkit.Registry<T> createApiRegistry(final @Nullable Registry<M> registry) {
+ if (registry == null && !PaperRegistryAccess.instance().delayedValidCheck().getAsBoolean()) {
+ return new DelayedRegistry<>(() -> this.delegate.createApiRegistry(PaperRegistryAccess.instance().getDelayedRegistryAccess().registryOrThrow(this.minecraftRegistryKey())), PaperRegistryAccess.instance().delayedValidCheck());
+ }
+ return this.delegate.createApiRegistry(PaperRegistryAccess.instance().getDelayedRegistryAccess().registryOrThrow(this.minecraftRegistryKey()));
+ }
+}
diff --git a/src/main/java/io/papermc/paper/registry/legacy/LegacyRegistryIdentifiers.java b/src/main/java/io/papermc/paper/registry/legacy/LegacyRegistryIdentifiers.java
new file mode 100644
index 0000000000000000000000000000000000000000..18dab3d1a5c873cfef09a8eba69d1e6d228b62eb
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/legacy/LegacyRegistryIdentifiers.java
@@ -0,0 +1,32 @@
+package io.papermc.paper.registry.legacy;
+
+import com.google.common.collect.ImmutableMap;
+import io.papermc.paper.registry.RegistryKey;
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.util.Map;
+
+@Deprecated
+public final class LegacyRegistryIdentifiers {
+
+ public static final Map<Class<?>, RegistryKey<?>> CLASS_TO_KEY_MAP;
+
+ static {
+ final ImmutableMap.Builder<Class<?>, RegistryKey<?>> builder = ImmutableMap.builder();
+ try {
+ for (final Field field : RegistryKey.class.getFields()) {
+ if (field.getType() == RegistryKey.class) {
+ // get the legacy type from the RegistryKey generic parameter on the field
+ final Class<?> legacyType = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
+ builder.put(legacyType, (RegistryKey<?>) field.get(null));
+ }
+ }
+ } catch (final ReflectiveOperationException ex) {
+ throw new RuntimeException(ex);
+ }
+ CLASS_TO_KEY_MAP = builder.build();
+ }
+
+ private LegacyRegistryIdentifiers() {
+ }
+}
diff --git a/src/main/java/io/papermc/paper/registry/legacy/package-info.java b/src/main/java/io/papermc/paper/registry/legacy/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..4396982af55872fafbfeaf8161ad6f392726c773
--- /dev/null
+++ b/src/main/java/io/papermc/paper/registry/legacy/package-info.java
@@ -0,0 +1,5 @@
+@DefaultQualifier(NonNull.class)
+package io.papermc.paper.registry.legacy;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
diff --git a/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java b/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java
index 94da73ef6c77308a8bc21db4c0bca22a79376b58..75603bd309a6113909b2f8a58c1a9bcf48aafb52 100644
--- a/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java
+++ b/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java
@@ -305,6 +305,7 @@ public class BuiltInRegistries {
ResourceKey<? extends Registry<T>> key, R registry, BuiltInRegistries.RegistryBootstrap<T> initializer, Lifecycle lifecycle
) {
Bootstrap.checkBootstrapCalled(() -> "registry " + key);
+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(registry.key(), registry); // Paper - initialize API registry
ResourceLocation resourceLocation = key.location();
LOADERS.put(resourceLocation, () -> initializer.run(registry));
WRITABLE_REGISTRY.register((ResourceKey)key, registry, lifecycle); // Paper - decompile fix
diff --git a/src/main/java/net/minecraft/resources/RegistryDataLoader.java b/src/main/java/net/minecraft/resources/RegistryDataLoader.java
index 596dd6487a24d09c271bda0a4c98f8149934e9ac..94aa4b22ebbc2e95398d28e10fd81027d9d40f71 100644
--- a/src/main/java/net/minecraft/resources/RegistryDataLoader.java
+++ b/src/main/java/net/minecraft/resources/RegistryDataLoader.java
@@ -185,6 +185,7 @@ public class RegistryDataLoader {
RegistryDataLoader.Loader loader = (resourceManager, registryInfoGetter) -> RegistryDataLoader.loadRegistryContents(
registryInfoGetter, resourceManager, this.key, writableRegistry, this.elementCodec, exceptions
);
+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(this.key, writableRegistry); // Paper - initialize API registry
return Pair.of(writableRegistry, loader);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
index 826c45f35c80ae4bf536fbe3b48354e3626fe2e1..d10e7d8b5d8e64bb4a11c759b63785e5cef87045 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
@@ -84,52 +84,15 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
return ((Handleable<M>) bukkit).getHandle();
}
- /**
- * Note: Newly added registries should also be added to RegistriesArgumentProvider in the test package
- *
- * @param bukkitClass the bukkit class of the registry
- * @param registryHolder the minecraft registry holder
- * @return the bukkit registry of the provided class
- */
- public static <B extends Keyed> Registry<?> createRegistry(Class<B> bukkitClass, RegistryAccess registryHolder) {
- if (bukkitClass == Enchantment.class) {
- return new CraftRegistry<>(Enchantment.class, registryHolder.registryOrThrow(Registries.ENCHANTMENT), CraftEnchantment::new);
- }
- if (bukkitClass == GameEvent.class) {
- return new CraftRegistry<>(GameEvent.class, registryHolder.registryOrThrow(Registries.GAME_EVENT), CraftGameEvent::new);
- }
- if (bukkitClass == MusicInstrument.class) {
- return new CraftRegistry<>(MusicInstrument.class, registryHolder.registryOrThrow(Registries.INSTRUMENT), CraftMusicInstrument::new);
- }
- if (bukkitClass == PotionEffectType.class) {
- return new CraftRegistry<>(PotionEffectType.class, registryHolder.registryOrThrow(Registries.MOB_EFFECT), CraftPotionEffectType::new);
- }
- if (bukkitClass == Structure.class) {
- return new CraftRegistry<>(Structure.class, registryHolder.registryOrThrow(Registries.STRUCTURE), CraftStructure::new);
- }
- if (bukkitClass == StructureType.class) {
- return new CraftRegistry<>(StructureType.class, BuiltInRegistries.STRUCTURE_TYPE, CraftStructureType::new);
- }
- if (bukkitClass == TrimMaterial.class) {
- return new CraftRegistry<>(TrimMaterial.class, registryHolder.registryOrThrow(Registries.TRIM_MATERIAL), CraftTrimMaterial::new);
- }
- if (bukkitClass == TrimPattern.class) {
- return new CraftRegistry<>(TrimPattern.class, registryHolder.registryOrThrow(Registries.TRIM_PATTERN), CraftTrimPattern::new);
- }
- if (bukkitClass == DamageType.class) {
- return new CraftRegistry<>(DamageType.class, registryHolder.registryOrThrow(Registries.DAMAGE_TYPE), CraftDamageType::new);
- }
-
- return null;
- }
+ // Paper - move to PaperRegistries
- private final Class<? super B> bukkitClass;
+ 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 boolean init;
- public CraftRegistry(Class<? super B> bukkitClass, net.minecraft.core.Registry<M> minecraftRegistry, BiFunction<NamespacedKey, M, B> minecraftToBukkit) {
+ public CraftRegistry(Class<?> bukkitClass, net.minecraft.core.Registry<M> minecraftRegistry, BiFunction<NamespacedKey, M, B> minecraftToBukkit) { // Paper - relax preload class
this.bukkitClass = bukkitClass;
this.minecraftRegistry = minecraftRegistry;
this.minecraftToBukkit = minecraftToBukkit;
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index c353f7a3a9ad0099ef7330dde988d1a174a0e327..a23213a9882bb4e2ddcd1d7c3fbb843f5f1cbbaf 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -281,7 +281,7 @@ public final class CraftServer implements Server {
protected final DedicatedServer console;
protected final DedicatedPlayerList playerList;
private final Map<String, World> worlds = new LinkedHashMap<String, World>();
- private final Map<Class<?>, Registry<?>> registries = new HashMap<>();
+ // private final Map<Class<?>, Registry<?>> registries = new HashMap<>(); // Paper - replace with RegistryAccess
private YamlConfiguration configuration;
private YamlConfiguration commandsConfiguration;
private final Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
@@ -2675,7 +2675,7 @@ public final class CraftServer implements Server {
@Override
public <T extends Keyed> Registry<T> getRegistry(Class<T> aClass) {
- return (Registry<T>) this.registries.computeIfAbsent(aClass, key -> CraftRegistry.createRegistry(aClass, this.console.registryAccess()));
+ return io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(aClass); // Paper - replace with RegistryAccess
}
@Deprecated
diff --git a/src/main/resources/META-INF/services/io.papermc.paper.registry.RegistryAccess b/src/main/resources/META-INF/services/io.papermc.paper.registry.RegistryAccess
new file mode 100644
index 0000000000000000000000000000000000000000..8a083d45004f82fc9c51c219fb20f34624adb501
--- /dev/null
+++ b/src/main/resources/META-INF/services/io.papermc.paper.registry.RegistryAccess
@@ -0,0 +1 @@
+io.papermc.paper.registry.PaperRegistryAccess
diff --git a/src/test/java/io/papermc/paper/registry/DummyRegistryAccess.java b/src/test/java/io/papermc/paper/registry/DummyRegistryAccess.java
new file mode 100644
index 0000000000000000000000000000000000000000..64fec4a1b81e51c790734c525fed886e31c30e67
--- /dev/null
+++ b/src/test/java/io/papermc/paper/registry/DummyRegistryAccess.java
@@ -0,0 +1,22 @@
+package io.papermc.paper.registry;
+
+import java.util.function.BooleanSupplier;
+import net.minecraft.core.RegistryAccess;
+import org.bukkit.support.AbstractTestingBase;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
+
+@DefaultQualifier(NonNull.class)
+public class DummyRegistryAccess extends PaperRegistryAccess {
+
+ @Override
+ public RegistryAccess getDelayedRegistryAccess() {
+ return AbstractTestingBase.REGISTRY_CUSTOM;
+ }
+
+ @Override
+ public BooleanSupplier delayedValidCheck() {
+ //noinspection ConstantValue
+ return () -> AbstractTestingBase.REGISTRY_CUSTOM != null;
+ }
+}
diff --git a/src/test/java/io/papermc/paper/registry/LegacyRegistryIdentifierTest.java b/src/test/java/io/papermc/paper/registry/LegacyRegistryIdentifierTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b9d00e65639521eecd44bd2be3e012264c3785f5
--- /dev/null
+++ b/src/test/java/io/papermc/paper/registry/LegacyRegistryIdentifierTest.java
@@ -0,0 +1,20 @@
+package io.papermc.paper.registry;
+
+import org.bukkit.GameEvent;
+import org.bukkit.MusicInstrument;
+import org.bukkit.inventory.meta.trim.TrimPattern;
+import org.bukkit.support.AbstractTestingBase;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+@Deprecated
+class LegacyRegistryIdentifierTest extends AbstractTestingBase {
+
+ @Test
+ void testSeveralConversions() {
+ assertSame(RegistryKey.GAME_EVENT, PaperRegistryAccess.byType(GameEvent.class));
+ assertSame(RegistryKey.TRIM_PATTERN, PaperRegistryAccess.byType(TrimPattern.class));
+ assertSame(RegistryKey.INSTRUMENT, PaperRegistryAccess.byType(MusicInstrument.class));
+ }
+}
diff --git a/src/test/java/org/bukkit/registry/RegistryArgumentAddedTest.java b/src/test/java/org/bukkit/registry/RegistryArgumentAddedTest.java
index 4adaafafb7140e983a4e90f0ff0deaaf0887a9a5..848ad252c06031d33e659f6116e911f966810442 100644
--- a/src/test/java/org/bukkit/registry/RegistryArgumentAddedTest.java
+++ b/src/test/java/org/bukkit/registry/RegistryArgumentAddedTest.java
@@ -21,14 +21,17 @@ public class RegistryArgumentAddedTest extends AbstractTestingBase {
// Make sure every registry is created
Class.forName(Registry.class.getName());
- Set<Class<?>> loadedRegistries = new HashSet<>(DummyServer.registers.keySet());
- Set<Class<?>> notFound = new HashSet<>();
+ // Paper start
+ Set<io.papermc.paper.registry.RegistryKey<?>> loadedRegistries = java.util.Collections.newSetFromMap(new java.util.IdentityHashMap<>());
+ loadedRegistries.addAll(io.papermc.paper.registry.PaperRegistryAccess.instance().loadedRegistryKeys());
+ // Paper end
+ Set<io.papermc.paper.registry.RegistryKey<?>> notFound = new HashSet<>(); // Paper
RegistriesArgumentProvider
.getData()
.map(Arguments::get)
.map(array -> array[0])
- .map(clazz -> (Class<?>) clazz)
+ .map(clazz -> (io.papermc.paper.registry.RegistryKey<?>) clazz) // Paper
.forEach(clazz -> {
if (!loadedRegistries.remove(clazz)) {
notFound.add(clazz);
diff --git a/src/test/java/org/bukkit/registry/RegistryConversionTest.java b/src/test/java/org/bukkit/registry/RegistryConversionTest.java
index 8c6b7f9804cf56269cc5a1b5924db2d2bf556f88..782c2ce424fc124e18145615187dc1e9d33f80ae 100644
--- a/src/test/java/org/bukkit/registry/RegistryConversionTest.java
+++ b/src/test/java/org/bukkit/registry/RegistryConversionTest.java
@@ -37,9 +37,9 @@ public class RegistryConversionTest extends AbstractTestingBase {
@Order(1)
@RegistriesTest
- public void testHandleableImplementation(Class<? extends Keyed> clazz) {
+ public void testHandleableImplementation(io.papermc.paper.registry.RegistryKey<? extends Keyed> type, Class<? extends Keyed> clazz) { // Paper
Set<Class<? extends Keyed>> notImplemented = new HashSet<>();
- Registry<? extends Keyed> registry = Bukkit.getRegistry(clazz);
+ Registry<? extends Keyed> registry = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(type); // Paper
for (Keyed item : registry) {
if (!(item instanceof Handleable<?>)) {
@@ -59,7 +59,7 @@ public class RegistryConversionTest extends AbstractTestingBase {
@Order(2)
@RegistriesTest
- public void testMinecraftToBukkitPresent(Class<? extends Keyed> clazz, ResourceKey<net.minecraft.core.Registry<?>> registryKey,
+ public void testMinecraftToBukkitPresent(io.papermc.paper.registry.RegistryKey<? extends Keyed> type, Class<? extends Keyed> clazz, ResourceKey<net.minecraft.core.Registry<?>> registryKey, // Paper
Class<? extends Keyed> craftClazz, Class<?> minecraftClazz) {
Method method = null;
try {
@@ -107,7 +107,7 @@ public class RegistryConversionTest extends AbstractTestingBase {
@Order(2)
@RegistriesTest
- public void testBukkitToMinecraftPresent(Class<? extends Keyed> clazz, ResourceKey<net.minecraft.core.Registry<?>> registryKey,
+ public void testBukkitToMinecraftPresent(io.papermc.paper.registry.RegistryKey<? extends Keyed> type, Class<? extends Keyed> clazz, ResourceKey<net.minecraft.core.Registry<?>> registryKey, // Paper
Class<? extends Keyed> craftClazz, Class<?> minecraftClazz) {
Method method = null;
try {
@@ -153,9 +153,9 @@ public class RegistryConversionTest extends AbstractTestingBase {
""", minecraftClazz.getName(), clazz.getSimpleName());
}
- @Order(2)
+ @Order(3)
@RegistriesTest
- public void testMinecraftToBukkitNullValue(Class<? extends Keyed> clazz) throws IllegalAccessException {
+ public void testMinecraftToBukkitNullValue(io.papermc.paper.registry.RegistryKey<? extends Keyed> type, Class<? extends Keyed> clazz) throws IllegalAccessException { // Paper
this.checkValidMinecraftToBukkit(clazz);
try {
@@ -174,7 +174,7 @@ public class RegistryConversionTest extends AbstractTestingBase {
@Order(3)
@RegistriesTest
- public void testBukkitToMinecraftNullValue(Class<? extends Keyed> clazz) throws IllegalAccessException {
+ public void testBukkitToMinecraftNullValue(io.papermc.paper.registry.RegistryKey<? extends Keyed> type, Class<? extends Keyed> clazz) throws IllegalAccessException { // Paper
this.checkValidBukkitToMinecraft(clazz);
try {
@@ -193,14 +193,14 @@ public class RegistryConversionTest extends AbstractTestingBase {
@Order(3)
@RegistriesTest
- public void testMinecraftToBukkit(Class<? extends Keyed> clazz) {
+ public void testMinecraftToBukkit(io.papermc.paper.registry.RegistryKey<? extends Keyed> type, Class<? extends Keyed> clazz) { // Paper
this.checkValidMinecraftToBukkit(clazz);
this.checkValidHandle(clazz);
Map<Object, Object> notMatching = new HashMap<>();
Method method = RegistryConversionTest.MINECRAFT_TO_BUKKIT_METHODS.get(clazz);
- RegistryArgumentProvider.getValues(clazz).map(Arguments::get).forEach(arguments -> {
+ RegistryArgumentProvider.getValues(type).map(Arguments::get).forEach(arguments -> { // Paper
Keyed bukkit = (Keyed) arguments[0];
Object minecraft = arguments[1];
@@ -224,14 +224,14 @@ public class RegistryConversionTest extends AbstractTestingBase {
@Order(3)
@RegistriesTest
- public void testBukkitToMinecraft(Class<? extends Keyed> clazz) {
+ public void testBukkitToMinecraft(io.papermc.paper.registry.RegistryKey<? extends Keyed> type, Class<? extends Keyed> clazz) { // Paper
this.checkValidBukkitToMinecraft(clazz);
this.checkValidHandle(clazz);
Map<Object, Object> notMatching = new HashMap<>();
Method method = RegistryConversionTest.BUKKIT_TO_MINECRAFT_METHODS.get(clazz);
- RegistryArgumentProvider.getValues(clazz).map(Arguments::get).forEach(arguments -> {
+ RegistryArgumentProvider.getValues(type).map(Arguments::get).forEach(arguments -> { // Paper
Keyed bukkit = (Keyed) arguments[0];
Object minecraft = arguments[1];
@@ -259,7 +259,7 @@ public class RegistryConversionTest extends AbstractTestingBase {
*/
@Order(3)
@RegistriesTest
- public void testMinecraftToBukkitNoValidMinecraft(Class<? extends Keyed> clazz, ResourceKey<net.minecraft.core.Registry<?>> registryKey,
+ public void testMinecraftToBukkitNoValidMinecraft(io.papermc.paper.registry.RegistryKey<? extends Keyed> type, Class<? extends Keyed> clazz, ResourceKey<net.minecraft.core.Registry<?>> registryKey, // Paper
Class<? extends Keyed> craftClazz, Class<?> minecraftClazz) throws IllegalAccessException {
this.checkValidMinecraftToBukkit(clazz);
diff --git a/src/test/java/org/bukkit/support/DummyServer.java b/src/test/java/org/bukkit/support/DummyServer.java
index 3b3e44c5ed24f653f7dc1e5d3d4f0ff76084f277..18436e523f156f18baff5da39ff6fd441d02c2a0 100644
--- a/src/test/java/org/bukkit/support/DummyServer.java
+++ b/src/test/java/org/bukkit/support/DummyServer.java
@@ -43,10 +43,7 @@ public final class DummyServer {
when(instance.getLootTable(any())).then(mock -> new CraftLootTable(mock.getArgument(0),
AbstractTestingBase.DATA_PACK.getLootData().getLootTable(CraftNamespacedKey.toMinecraft(mock.getArgument(0)))));
- when(instance.getRegistry(any())).then((Answer<Registry<?>>) mock -> {
- Class<? extends Keyed> aClass = mock.getArgument(0);
- return registers.computeIfAbsent(aClass, key -> CraftRegistry.createRegistry(aClass, AbstractTestingBase.REGISTRY_CUSTOM));
- });
+ // Paper - RegistryAccess
// Paper start - testing additions
final Thread currentThread = Thread.currentThread();
diff --git a/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java b/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java
index 167cd003a52b722772708a528d724db14c89c35a..35f2f4b2e354bd4d39925e409f6b8e806a76bc30 100644
--- a/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java
+++ b/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java
@@ -1,6 +1,7 @@
package org.bukkit.support.provider;
import com.google.common.collect.Lists;
+import io.papermc.paper.registry.RegistryKey;
import java.util.List;
import java.util.stream.Stream;
import net.minecraft.core.registries.Registries;
@@ -33,16 +34,16 @@ public class RegistriesArgumentProvider implements ArgumentsProvider {
private static final List<Arguments> DATA = Lists.newArrayList();
static {
- // Order: Bukkit class, Minecraft Registry key, CraftBukkit class, Minecraft class
- DATA.add(Arguments.of(Enchantment.class, Registries.ENCHANTMENT, CraftEnchantment.class, net.minecraft.world.item.enchantment.Enchantment.class));
- DATA.add(Arguments.of(GameEvent.class, Registries.GAME_EVENT, CraftGameEvent.class, net.minecraft.world.level.gameevent.GameEvent.class));
- DATA.add(Arguments.of(MusicInstrument.class, Registries.INSTRUMENT, CraftMusicInstrument.class, Instrument.class));
- DATA.add(Arguments.of(PotionEffectType.class, Registries.MOB_EFFECT, CraftPotionEffectType.class, MobEffect.class));
- DATA.add(Arguments.of(Structure.class, Registries.STRUCTURE, CraftStructure.class, net.minecraft.world.level.levelgen.structure.Structure.class));
- DATA.add(Arguments.of(StructureType.class, Registries.STRUCTURE_TYPE, CraftStructureType.class, net.minecraft.world.level.levelgen.structure.StructureType.class));
- DATA.add(Arguments.of(TrimMaterial.class, Registries.TRIM_MATERIAL, CraftTrimMaterial.class, net.minecraft.world.item.armortrim.TrimMaterial.class));
- DATA.add(Arguments.of(TrimPattern.class, Registries.TRIM_PATTERN, CraftTrimPattern.class, net.minecraft.world.item.armortrim.TrimPattern.class));
- DATA.add(Arguments.of(DamageType.class, Registries.DAMAGE_TYPE, CraftDamageType.class, net.minecraft.world.damagesource.DamageType.class));
+ // Order: RegistryKey, Bukkit class, Minecraft Registry key, CraftBukkit class, Minecraft class
+ DATA.add(Arguments.of(RegistryKey.ENCHANTMENT, Enchantment.class, Registries.ENCHANTMENT, CraftEnchantment.class, net.minecraft.world.item.enchantment.Enchantment.class));
+ DATA.add(Arguments.of(RegistryKey.GAME_EVENT, GameEvent.class, Registries.GAME_EVENT, CraftGameEvent.class, net.minecraft.world.level.gameevent.GameEvent.class));
+ DATA.add(Arguments.of(RegistryKey.INSTRUMENT, MusicInstrument.class, Registries.INSTRUMENT, CraftMusicInstrument.class, Instrument.class));
+ DATA.add(Arguments.of(RegistryKey.MOB_EFFECT, PotionEffectType.class, Registries.MOB_EFFECT, CraftPotionEffectType.class, MobEffect.class));
+ DATA.add(Arguments.of(RegistryKey.STRUCTURE, Structure.class, Registries.STRUCTURE, CraftStructure.class, net.minecraft.world.level.levelgen.structure.Structure.class));
+ DATA.add(Arguments.of(RegistryKey.STRUCTURE_TYPE, StructureType.class, Registries.STRUCTURE_TYPE, CraftStructureType.class, net.minecraft.world.level.levelgen.structure.StructureType.class));
+ DATA.add(Arguments.of(RegistryKey.TRIM_MATERIAL, TrimMaterial.class, Registries.TRIM_MATERIAL, CraftTrimMaterial.class, net.minecraft.world.item.armortrim.TrimMaterial.class));
+ DATA.add(Arguments.of(RegistryKey.TRIM_PATTERN, TrimPattern.class, Registries.TRIM_PATTERN, CraftTrimPattern.class, net.minecraft.world.item.armortrim.TrimPattern.class));
+ DATA.add(Arguments.of(RegistryKey.DAMAGE_TYPE, DamageType.class, Registries.DAMAGE_TYPE, CraftDamageType.class, net.minecraft.world.damagesource.DamageType.class));
}
@Override
diff --git a/src/test/java/org/bukkit/support/provider/RegistryArgumentProvider.java b/src/test/java/org/bukkit/support/provider/RegistryArgumentProvider.java
index f2ceb5e67536dfa5de792dc64a7898fd2e8aa810..beb5fc9e721f5de54064c3d241df9ca9f4cd4f65 100644
--- a/src/test/java/org/bukkit/support/provider/RegistryArgumentProvider.java
+++ b/src/test/java/org/bukkit/support/provider/RegistryArgumentProvider.java
@@ -22,11 +22,11 @@ public class RegistryArgumentProvider implements ArgumentsProvider, AnnotationCo
@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext extensionContext) throws Exception {
- return RegistryArgumentProvider.getValues(this.registryType);
+ return RegistryArgumentProvider.getValues(io.papermc.paper.registry.PaperRegistryAccess.byType(this.registryType)); // Paper
}
- public static Stream<? extends Arguments> getValues(Class<? extends Keyed> registryType) {
- Registry<?> registry = Bukkit.getRegistry(registryType);
+ 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()));
}
diff --git a/src/test/resources/META-INF/services/io.papermc.paper.registry.RegistryAccess b/src/test/resources/META-INF/services/io.papermc.paper.registry.RegistryAccess
new file mode 100644
index 0000000000000000000000000000000000000000..6c7526bbc7318f510f81f4073a158f7136017a56
--- /dev/null
+++ b/src/test/resources/META-INF/services/io.papermc.paper.registry.RegistryAccess
@@ -0,0 +1 @@
+io.papermc.paper.registry.DummyRegistryAccess

View File

@ -1,18 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Mon, 27 Feb 2023 18:28:39 -0800
Subject: [PATCH] TODO Registry Modification API
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
index 826c45f35c80ae4bf536fbe3b48354e3626fe2e1..110987de809339b4ce14eaf377782ebf3460164a 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
@@ -119,6 +119,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
if (bukkitClass == DamageType.class) {
return new CraftRegistry<>(DamageType.class, registryHolder.registryOrThrow(Registries.DAMAGE_TYPE), CraftDamageType::new);
}
+ // TODO registry modification API
return null;
}

View File

@ -5,12 +5,49 @@ Subject: [PATCH] Add StructuresLocateEvent
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/src/main/java/io/papermc/paper/registry/PaperRegistries.java
index e21bcb349ac36d141fd8bd51f7a1d9fc7532b510..94639a2a51f51eda3978a5a9f8acea83db83b482 100644
--- a/src/main/java/io/papermc/paper/registry/PaperRegistries.java
+++ b/src/main/java/io/papermc/paper/registry/PaperRegistries.java
@@ -37,6 +37,12 @@ import static io.papermc.paper.registry.entry.RegistryEntry.entry;
@DefaultQualifier(NonNull.class)
public final class PaperRegistries {
+ @Deprecated(forRemoval = true)
+ @org.jetbrains.annotations.VisibleForTesting
+ public static final RegistryKey<io.papermc.paper.world.structure.ConfiguredStructure> CONFIGURED_STRUCTURE_REGISTRY_KEY = RegistryKeyImpl.createInternal("worldgen/structure");
+ @Deprecated(forRemoval = true)
+ static final RegistryEntry<Structure, io.papermc.paper.world.structure.ConfiguredStructure> CONFIGURED_STRUCTURE_REGISTRY_ENTRY = entry(Registries.STRUCTURE, CONFIGURED_STRUCTURE_REGISTRY_KEY, io.papermc.paper.world.structure.ConfiguredStructure.class, io.papermc.paper.world.structure.PaperConfiguredStructure::minecraftToBukkit).delayed();
+
static final List<RegistryEntry<?, ?>> REGISTRY_ENTRIES;
private static final Map<RegistryKey<?>, RegistryEntry<?, ?>> BY_REGISTRY_KEY;
private static final Map<ResourceKey<?>, RegistryEntry<?, ?>> BY_RESOURCE_KEY;
diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java b/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java
index ae2a25ee0ae5d29d4271e8911103d54c4f71a308..1c17491c69916cd4c86ffa9b0a63f2845ad17e7c 100644
--- a/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java
+++ b/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java
@@ -42,8 +42,13 @@ public class PaperRegistryAccess implements RegistryAccess {
public <T extends Keyed> @Nullable Registry<T> getRegistry(final Class<T> type) {
final RegistryKey<T> registryKey;
final Supplier<@Nullable RegistryEntry<?, T>> entrySupplier;
- registryKey = requireNonNull(byType(type), () -> type + " is not a valid registry type");
- entrySupplier = () -> PaperRegistries.getEntry(registryKey);
+ if (type == io.papermc.paper.world.structure.ConfiguredStructure.class) { // manually handle "duplicate" registries to avoid polluting maps in PaperRegistries
+ registryKey = (RegistryKey<T>) PaperRegistries.CONFIGURED_STRUCTURE_REGISTRY_KEY;
+ entrySupplier = () -> (RegistryEntry<?, T>) PaperRegistries.CONFIGURED_STRUCTURE_REGISTRY_ENTRY;
+ } else {
+ registryKey = requireNonNull(byType(type), () -> type + " is not a valid registry type");
+ entrySupplier = () -> PaperRegistries.getEntry(registryKey);
+ }
final @Nullable Supplier<Registry<?>> registry = this.registries.get(registryKey);
if (registry != null) {
return possiblyUnwrap((Registry<T>) registry.get(), true);
diff --git a/src/main/java/io/papermc/paper/world/structure/PaperConfiguredStructure.java b/src/main/java/io/papermc/paper/world/structure/PaperConfiguredStructure.java
new file mode 100644
index 0000000000000000000000000000000000000000..2667067fd13f61e0464ba88ae4e4a7078351d1a8
index 0000000000000000000000000000000000000000..013d614a1cf1ab2b5a6ec190c2b4ba7753268731
--- /dev/null
+++ b/src/main/java/io/papermc/paper/world/structure/PaperConfiguredStructure.java
@@ -0,0 +1,35 @@
@@ -0,0 +1,27 @@
+package io.papermc.paper.world.structure;
+
+import java.util.Objects;
@ -32,22 +69,14 @@ index 0000000000000000000000000000000000000000..2667067fd13f61e0464ba88ae4e4a707
+ private PaperConfiguredStructure() {
+ }
+
+ @Deprecated(forRemoval = true)
+ public static final class LegacyRegistry extends CraftRegistry<ConfiguredStructure, Structure> {
+
+ public LegacyRegistry(final Registry<Structure> minecraftRegistry) {
+ super(ConfiguredStructure.class, minecraftRegistry, LegacyRegistry::minecraftToBukkit);
+ }
+
+ private static @Nullable ConfiguredStructure minecraftToBukkit(NamespacedKey key, Structure nms) {
+ final ResourceLocation structureTypeLoc = Objects.requireNonNull(BuiltInRegistries.STRUCTURE_TYPE.getKey(nms.type()), "unexpected structure type " + nms.type());
+ final @Nullable StructureType structureType = StructureType.getStructureTypes().get(structureTypeLoc.getPath());
+ return structureType == null ? null : new ConfiguredStructure(key, structureType);
+ }
+ public static @Nullable ConfiguredStructure minecraftToBukkit(NamespacedKey key, Structure nms) {
+ final ResourceLocation structureTypeLoc = Objects.requireNonNull(BuiltInRegistries.STRUCTURE_TYPE.getKey(nms.type()), "unexpected structure type " + nms.type());
+ final @Nullable StructureType structureType = StructureType.getStructureTypes().get(structureTypeLoc.getPath());
+ return structureType == null ? null : new ConfiguredStructure(key, structureType);
+ }
+}
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
index 3e57142dd9cb23d43857d5a4cb30962e4b696b74..a6d5b3fa7e3437e0aec54eec4079e9f3267c64b8 100644
index 4a731b9170222a5a2b0089ef5e9527dbd46a9ad5..edd968686292237e95afdf99a291f501386144ef 100644
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
@@ -121,6 +121,24 @@ public abstract class ChunkGenerator {
@ -75,22 +104,6 @@ index 3e57142dd9cb23d43857d5a4cb30962e4b696b74..a6d5b3fa7e3437e0aec54eec4079e9f3
ChunkGeneratorStructureState chunkgeneratorstructurestate = world.getChunkSource().getGeneratorState();
Map<StructurePlacement, Set<Holder<Structure>>> map = new Object2ObjectArrayMap();
Iterator iterator = structures.iterator();
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
index 110987de809339b4ce14eaf377782ebf3460164a..b12b99253543445475b73a1d3d7c6364856b49e8 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
@@ -120,6 +120,11 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
return new CraftRegistry<>(DamageType.class, registryHolder.registryOrThrow(Registries.DAMAGE_TYPE), CraftDamageType::new);
}
// TODO registry modification API
+ // Paper start - remove this after a while along with all ConfiguredStructure stuff
+ if (bukkitClass == io.papermc.paper.world.structure.ConfiguredStructure.class) {
+ return new io.papermc.paper.world.structure.PaperConfiguredStructure.LegacyRegistry(registryHolder.registryOrThrow(Registries.STRUCTURE));
+ }
+ // Paper end
return null;
}
diff --git a/src/test/java/io/papermc/paper/world/structure/ConfiguredStructureTest.java b/src/test/java/io/papermc/paper/world/structure/ConfiguredStructureTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9178fe0d01b998ca1442bf2511f8fc00db9388ba
@ -194,26 +207,26 @@ index 0000000000000000000000000000000000000000..9178fe0d01b998ca1442bf2511f8fc00
+ }
+}
diff --git a/src/test/java/org/bukkit/registry/PerRegistryTest.java b/src/test/java/org/bukkit/registry/PerRegistryTest.java
index 4e4ea083063daf22f1bb785ef212958ea889c43b..1c4966520b6401e6571aa44d5934dfa280bc80e3 100644
index 4e4ea083063daf22f1bb785ef212958ea889c43b..523b4b208e05c6b70014440200e3196cc84f36cc 100644
--- a/src/test/java/org/bukkit/registry/PerRegistryTest.java
+++ b/src/test/java/org/bukkit/registry/PerRegistryTest.java
@@ -36,6 +36,7 @@ public class PerRegistryTest extends AbstractTestingBase {
if (!(object instanceof CraftRegistry<?, ?> registry)) {
continue;
}
+ if (object instanceof io.papermc.paper.world.structure.PaperConfiguredStructure.LegacyRegistry) continue; // Paper - skip
+ if (object == Registry.CONFIGURED_STRUCTURE) continue; // Paper - skip
data.add(Arguments.of(registry));
} catch (ReflectiveOperationException e) {
diff --git a/src/test/java/org/bukkit/registry/RegistryArgumentAddedTest.java b/src/test/java/org/bukkit/registry/RegistryArgumentAddedTest.java
index 4adaafafb7140e983a4e90f0ff0deaaf0887a9a5..65cc33c45553e755371ec4313dd38bb61eb7d61c 100644
index 848ad252c06031d33e659f6116e911f966810442..f538a209af064c1f1333d30f90bfc21523b2f4cd 100644
--- a/src/test/java/org/bukkit/registry/RegistryArgumentAddedTest.java
+++ b/src/test/java/org/bukkit/registry/RegistryArgumentAddedTest.java
@@ -23,6 +23,7 @@ public class RegistryArgumentAddedTest extends AbstractTestingBase {
Set<Class<?>> loadedRegistries = new HashSet<>(DummyServer.registers.keySet());
Set<Class<?>> notFound = new HashSet<>();
+ loadedRegistries.remove(io.papermc.paper.world.structure.ConfiguredStructure.class); // Paper - ignore
@@ -26,6 +26,7 @@ public class RegistryArgumentAddedTest extends AbstractTestingBase {
loadedRegistries.addAll(io.papermc.paper.registry.PaperRegistryAccess.instance().loadedRegistryKeys());
// Paper end
Set<io.papermc.paper.registry.RegistryKey<?>> notFound = new HashSet<>(); // Paper
+ loadedRegistries.remove(io.papermc.paper.registry.PaperRegistries.CONFIGURED_STRUCTURE_REGISTRY_KEY); // Paper - ignore
RegistriesArgumentProvider
.getData()

View File

@ -5,18 +5,18 @@ Subject: [PATCH] Improve Registry
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
index b12b99253543445475b73a1d3d7c6364856b49e8..4fc02698a9312496e7f9bce1c64f317374d2a42f 100644
index d10e7d8b5d8e64bb4a11c759b63785e5cef87045..0dc5a40b60d4cec129d02503596842ca23dd7c58 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
@@ -131,6 +131,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
@@ -88,6 +88,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
private final Class<? super B> bukkitClass;
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 boolean init;
@@ -175,6 +176,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
@@ -132,6 +133,7 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
}
this.cache.put(namespacedKey, bukkit);
@ -24,7 +24,7 @@ index b12b99253543445475b73a1d3d7c6364856b49e8..4fc02698a9312496e7f9bce1c64f3173
return bukkit;
}
@@ -197,4 +199,11 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
@@ -154,4 +156,11 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
return this.minecraftToBukkit.apply(namespacedKey, minecraft);
}
@ -61,7 +61,7 @@ index 88e9acd2084c5e7738017a91a454fc5407ab833b..dbb1619f8e8d98feb30f76beb8c23ebc
}
diff --git a/src/test/java/org/bukkit/registry/PerRegistryTest.java b/src/test/java/org/bukkit/registry/PerRegistryTest.java
index 1c4966520b6401e6571aa44d5934dfa280bc80e3..010de6fbb75eb5d51639695d260f916072fdb22d 100644
index 523b4b208e05c6b70014440200e3196cc84f36cc..12b93a6e091de47522d060fa0cd84fe41318c46a 100644
--- a/src/test/java/org/bukkit/registry/PerRegistryTest.java
+++ b/src/test/java/org/bukkit/registry/PerRegistryTest.java
@@ -49,19 +49,22 @@ public class PerRegistryTest extends AbstractTestingBase {