From 8551cb23b030bb289886de957d8b00466e13d4ab Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Mon, 23 Dec 2024 14:33:20 -0800 Subject: [PATCH] For new registry values, allow copying from existing --- .../registry/event/WritableRegistry.java | 13 ++++++++ .../0017-Moonrise-optimisation-patches.patch | 8 ++--- .../minecraft/core/MappedRegistry.java.patch | 25 +++++++++++++++- .../paper/registry/WritableCraftRegistry.java | 30 +++++++++++-------- 4 files changed, 59 insertions(+), 17 deletions(-) diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java b/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java index 744f455b14..30f5816550 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java @@ -25,4 +25,17 @@ public interface WritableRegistry> { * @param value a consumer for the entry's builder */ void register(TypedKey key, Consumer value); + + /** + * Register a new value with the specified key. This will + * fire a {@link RegistryEntryAddEvent} for the new entry. The + * builder in the consumer will be pre-filled with the values + * from the copyFrom key. + * + * @param key the entry's key (must be unique from others) + * @param copyFrom the key to copy values from (must already be registered) + * @param value a consumer for the entry's builder + * @throws IllegalArgumentException if copyFrom doesn't exist + */ + void register(TypedKey key, TypedKey copyFrom, Consumer value); } diff --git a/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch index 337302aaa2..45b4a15fe7 100644 --- a/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch @@ -23508,10 +23508,10 @@ index 3d3eec1db91cb47395f40c4f47aa77164ad42175..216f97207dac88cc1dc3df59c6ee8a62 + // Paper end - optimise collisions } diff --git a/net/minecraft/core/MappedRegistry.java b/net/minecraft/core/MappedRegistry.java -index 47b1fafd91b39e73c4e9134b0b8048000fba108a..76994c1491221c06cca5405ba239e6ff642b19ed 100644 +index 452c358c2cfa0c39e0b09853cd4a9a12c6ced65d..5f752603aa5611ce9d3dd44cc5b70c27ac46a86e 100644 --- a/net/minecraft/core/MappedRegistry.java +++ b/net/minecraft/core/MappedRegistry.java -@@ -50,6 +50,19 @@ public class MappedRegistry implements WritableRegistry { +@@ -51,6 +51,19 @@ public class MappedRegistry implements WritableRegistry { return this.getTags(); } @@ -23531,10 +23531,10 @@ index 47b1fafd91b39e73c4e9134b0b8048000fba108a..76994c1491221c06cca5405ba239e6ff public MappedRegistry(ResourceKey> key, Lifecycle registryLifecycle) { this(key, registryLifecycle, false); } -@@ -114,6 +127,7 @@ public class MappedRegistry implements WritableRegistry { - this.toId.put(value, size); +@@ -116,6 +129,7 @@ public class MappedRegistry implements WritableRegistry { this.registrationInfos.put(key, registrationInfo); this.registryLifecycle = this.registryLifecycle.add(registrationInfo.lifecycle()); + this.temporaryUnfrozenMap.put(key.location(), value); // Paper - support pre-filling in registry mod API + this.injectFluidRegister(key, value); // Paper - fluid method optimisations return reference; } diff --git a/paper-server/patches/sources/net/minecraft/core/MappedRegistry.java.patch b/paper-server/patches/sources/net/minecraft/core/MappedRegistry.java.patch index 400d714abe..2a92380a2f 100644 --- a/paper-server/patches/sources/net/minecraft/core/MappedRegistry.java.patch +++ b/paper-server/patches/sources/net/minecraft/core/MappedRegistry.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/MappedRegistry.java +++ b/net/minecraft/core/MappedRegistry.java -@@ -33,11 +_,11 @@ +@@ -33,17 +_,18 @@ public class MappedRegistry implements WritableRegistry { private final ResourceKey> key; private final ObjectList> byId = new ObjectArrayList<>(256); @@ -17,6 +17,29 @@ private Lifecycle registryLifecycle; private final Map, HolderSet.Named> frozenTags = new IdentityHashMap<>(); MappedRegistry.TagSet allTags = MappedRegistry.TagSet.unbound(); + private boolean frozen; + @Nullable + private Map> unregisteredIntrusiveHolders; ++ public final Map temporaryUnfrozenMap = new HashMap<>(); // Paper - support pre-filling in registry mod API + + @Override + public Stream> listTags() { +@@ -114,6 +_,7 @@ + this.toId.put(value, size); + this.registrationInfos.put(key, registrationInfo); + this.registryLifecycle = this.registryLifecycle.add(registrationInfo.lifecycle()); ++ this.temporaryUnfrozenMap.put(key.location(), value); // Paper - support pre-filling in registry mod API + return reference; + } + } +@@ -275,6 +_,7 @@ + return this; + } else { + this.frozen = true; ++ this.temporaryUnfrozenMap.clear(); // Paper - support pre-filling in registry mod API + this.byValue.forEach((object, reference) -> reference.bindValue((T)object)); + List list = this.byKey + .entrySet() @@ -509,4 +_,13 @@ Stream> getTags(); diff --git a/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java b/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java index 6c17623e76..01bfe05e81 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java @@ -1,21 +1,19 @@ package io.papermc.paper.registry; +import com.google.common.base.Preconditions; import com.mojang.serialization.Lifecycle; +import io.papermc.paper.adventure.PaperAdventure; import io.papermc.paper.registry.data.util.Conversions; -import io.papermc.paper.registry.entry.RegistryEntry; import io.papermc.paper.registry.entry.RegistryEntryMeta; -import io.papermc.paper.registry.entry.RegistryTypeMapper; import io.papermc.paper.registry.event.WritableRegistry; import java.util.Optional; -import java.util.function.BiFunction; import java.util.function.Consumer; import net.minecraft.core.MappedRegistry; import net.minecraft.core.RegistrationInfo; import net.minecraft.resources.ResourceKey; import org.bukkit.Keyed; -import org.bukkit.NamespacedKey; import org.bukkit.craftbukkit.CraftRegistry; -import org.bukkit.craftbukkit.util.ApiVersion; +import org.jspecify.annotations.Nullable; public class WritableCraftRegistry> extends CraftRegistry { @@ -33,10 +31,17 @@ public class WritableCraftRegistry key, final Consumer value, final Conversions conversions) { + public void register(final TypedKey key, final @Nullable TypedKey copyFrom, final Consumer value, final Conversions conversions) { final ResourceKey resourceKey = PaperRegistries.toNms(key); this.registry.validateWrite(resourceKey); - final B builder = this.newBuilder(conversions); + final B builder; + if (copyFrom != null) { + final M existing = this.registry.temporaryUnfrozenMap.get(PaperAdventure.asVanilla(copyFrom)); + Preconditions.checkArgument(existing != null, "Cannot copy from unregistered key: %s", copyFrom); + builder = this.meta.builderFiller().fill(conversions, existing); + } else { + builder = this.meta.builderFiller().create(conversions); + } value.accept(builder); PaperRegistryListenerManager.INSTANCE.registerWithListeners( this.registry, @@ -52,10 +57,6 @@ public class WritableCraftRegistry { private final Conversions conversions; @@ -66,7 +67,12 @@ public class WritableCraftRegistry key, final Consumer value) { - WritableCraftRegistry.this.register(key, value, this.conversions); + WritableCraftRegistry.this.register(key, null, value, this.conversions); + } + + @Override + public void register(final TypedKey key, final TypedKey copyFrom, final Consumer value) { + WritableCraftRegistry.this.register(key, copyFrom, value, this.conversions); } } }