From f8ba85ffbfc54a362b5361f4e16cf808859ecfbc Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Tue, 28 Feb 2023 08:36:01 -0800 Subject: [PATCH] Replace ConfiguredStructure api with Structure (#8642) --- patches/api/Add-PaperRegistry.patch | 20 -- patches/api/Add-StructuresLocateEvent.patch | 94 +++++-- patches/api/Expand-world-key-API.patch | 4 +- patches/api/More-PotionEffectType-API.patch | 3 +- patches/server/Add-PaperRegistry.patch | 242 ------------------ .../server/Add-StructuresLocateEvent.patch | 83 +++--- patches/server/Basic-PlayerProfile-API.patch | 2 +- patches/server/Custom-Potion-Mixes.patch | 2 +- patches/server/Expand-world-key-API.patch | 4 +- patches/server/MC-Utils.patch | 5 + patches/server/Rewrite-chunk-system.patch | 4 +- .../TODO-Registry-Modification-API.patch | 18 ++ 12 files changed, 139 insertions(+), 342 deletions(-) delete mode 100644 patches/server/Add-PaperRegistry.patch create mode 100644 patches/server/TODO-Registry-Modification-API.patch diff --git a/patches/api/Add-PaperRegistry.patch b/patches/api/Add-PaperRegistry.patch index ece8c14047..dbc8697ebd 100644 --- a/patches/api/Add-PaperRegistry.patch +++ b/patches/api/Add-PaperRegistry.patch @@ -90,23 +90,3 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return this.key; + } +} -diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/org/bukkit/UnsafeValues.java -+++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -0,0 +0,0 @@ public interface UnsafeValues { - * Use this when sending custom packets, so that there are no collisions on the client or server. - */ - public int nextEntityId(); -+ -+ /** -+ * Gets the server-backed registry for a type. -+ * -+ * @param classOfT type -+ * @param type -+ * @return the server-backed registry -+ * @throws IllegalArgumentException if there isn't a registry for that type -+ */ -+ @org.jetbrains.annotations.NotNull Registry registryFor(Class classOfT); - // Paper end - } diff --git a/patches/api/Add-StructuresLocateEvent.patch b/patches/api/Add-StructuresLocateEvent.patch index 66a5729ca4..6a91899558 100644 --- a/patches/api/Add-StructuresLocateEvent.patch +++ b/patches/api/Add-StructuresLocateEvent.patch @@ -176,17 +176,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ +package io.papermc.paper.event.world; + ++import io.papermc.paper.math.Position; ++import io.papermc.paper.util.TransformingRandomAccessList; +import io.papermc.paper.world.structure.ConfiguredStructure; ++import java.util.Collections; ++import java.util.List; ++import java.util.Objects; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.world.WorldEvent; ++import org.bukkit.generator.structure.Structure; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -+ -+import java.util.ArrayList; -+import java.util.List; ++import org.jetbrains.annotations.UnmodifiableView; + +/** + * Called before a set of configured structures is located. @@ -206,15 +210,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + private final Location origin; + private Result result; -+ private List configuredStructures; ++ private List structures; ++ private List legacy$structures; + private int radius; + private boolean findUnexplored; + private boolean cancelled; + -+ public StructuresLocateEvent(@NotNull World world, @NotNull Location origin, @NotNull List configuredStructures, int radius, boolean findUnexplored) { ++ public StructuresLocateEvent(@NotNull World world, @NotNull Location origin, @NotNull List structures, int radius, boolean findUnexplored) { + super(world); + this.origin = origin; -+ this.configuredStructures = configuredStructures; ++ this.setStructures(structures); + this.radius = radius; + this.findUnexplored = findUnexplored; + } @@ -229,23 +234,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + /** -+ * Gets the {@link Location} and {@link ConfiguredStructure} set as the result, if it was defined. ++ * Gets the {@link Location} and {@link Structure} set as the result, if it was defined. + *

+ * Returns {@code null} if it has not been set by {@link StructuresLocateEvent#setResult(Result)}. + * Since this event fires before the search is done, the actual result is unknown at this point. + * + * @return The result location and structure, if it has been set. null if it has not. -+ * @see World#locateNearestStructure(Location, org.bukkit.StructureType, int, boolean) ++ * @see World#locateNearestStructure(Location, org.bukkit.generator.structure.StructureType, int, boolean) + */ + public @Nullable Result getResult() { + return this.result; + } + + /** -+ * Sets the result {@link Location} and {@link ConfiguredStructure}. This causes the search to be ++ * Sets the result {@link Location} and {@link Structure}. This causes the search to be + * skipped, and the result object passed here to be used as the result. + * -+ * @param result the {@link Location} and {@link ConfiguredStructure} of the search. ++ * @param result the {@link Location} and {@link Structure} of the search. + */ + public void setResult(@Nullable Result result) { + this.result = result; @@ -255,18 +260,41 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * Gets a mutable list of ConfiguredStructures that are valid targets for the search. + * + * @return a mutable list of ConfiguredStructures ++ * @deprecated use {@link #getStructures()} + */ ++ @Deprecated(forRemoval = true) + public @NotNull List getConfiguredStructures() { -+ return this.configuredStructures; ++ return this.legacy$structures; + } + + /** + * Sets the list of ConfiguredStructures that are valid targets for the search. + * + * @param configuredStructures a list of ConfiguredStructure targets ++ * @deprecated use {@link #setStructures(List)} + */ ++ @Deprecated(forRemoval = true) + public void setConfiguredStructures(@NotNull List configuredStructures) { -+ this.configuredStructures = new ArrayList<>(configuredStructures); ++ this.setStructures(configuredStructures.stream().map(ConfiguredStructure::toModern).toList()); ++ } ++ ++ /** ++ * Gets an unmodifiable list of Structures that are valid targets for the search. ++ * ++ * @return an unmodifiable list of Structures ++ */ ++ public @NotNull @UnmodifiableView List getStructures() { ++ return Collections.unmodifiableList(this.structures); ++ } ++ ++ /** ++ * Sets the list of Structures that are valid targets for the search. ++ * ++ * @param structures a list of Structures targets ++ */ ++ public void setStructures(final @NotNull List structures) { ++ this.structures = structures; ++ this.legacy$structures = new TransformingRandomAccessList<>(this.structures, ConfiguredStructure::fromModern, ConfiguredStructure::toModern); + } + + /** @@ -274,7 +302,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + *

+ * This radius may not always be obeyed during the structure search! + * -+ * @return the search radius. ++ * @return the search radius (in chunks) + */ + public int getRadius() { + return this.radius; @@ -285,7 +313,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + *

+ * This radius may not always be obeyed during the structure search! + * -+ * @param radius the search radius. ++ * @param radius the search radius (in chunks) + */ + public void setRadius(int radius) { + this.radius = radius; @@ -335,7 +363,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + /** + * Result for {@link StructuresLocateEvent}. + */ -+ public record Result(@NotNull Location position, @NotNull ConfiguredStructure configuredStructure) { ++ public record Result(@NotNull Position pos, @NotNull Structure structure) { ++ ++ @Deprecated(forRemoval = true) ++ public Result(final @NotNull Location position, @NotNull ConfiguredStructure configuredStructure) { ++ this(position, configuredStructure.toModern()); ++ } ++ ++ @Deprecated(forRemoval = true) ++ public @NotNull ConfiguredStructure configuredStructure() { ++ return Objects.requireNonNull(ConfiguredStructure.fromModern(this.structure), "Please use the newer Structure API"); ++ } ++ ++ @Deprecated(forRemoval = true) ++ public @NotNull Location position() { ++ //noinspection DataFlowIssue ++ return this.pos.toLocation(null); ++ } + } +} diff --git a/src/main/java/io/papermc/paper/world/structure/ConfiguredStructure.java b/src/main/java/io/papermc/paper/world/structure/ConfiguredStructure.java @@ -347,19 +391,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +package io.papermc.paper.world.structure; + +import io.papermc.paper.registry.Reference; ++import java.util.Objects; +import org.bukkit.Keyed; +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.StructureType; ++import org.bukkit.generator.structure.Structure; ++import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; -+ -+import java.util.Objects; ++import org.jetbrains.annotations.Nullable; + +/** + * Represents a configured structure each with a + * {@link StructureType}. Multiple ConfiguredStructures can have + * the same {@link StructureType}. ++ * @deprecated use {@link Structure} + */ ++@Deprecated(forRemoval = true) +public final class ConfiguredStructure implements Keyed { + + public static final Reference PILLAGER_OUTPOST = create("pillager_outpost"); @@ -441,6 +489,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + private static @NotNull Reference create(@NotNull String name) { + return Reference.create(Registry.CONFIGURED_STRUCTURE, NamespacedKey.minecraft(name)); + } ++ ++ @ApiStatus.Internal ++ public @NotNull Structure toModern() { ++ return Objects.requireNonNull(Registry.STRUCTURE.get(this.key)); ++ } ++ ++ @ApiStatus.Internal ++ public static @Nullable ConfiguredStructure fromModern(@NotNull Structure structure) { ++ return Registry.CONFIGURED_STRUCTURE.get(structure.getKey()); ++ } +} diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -454,7 +512,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + /** + * Configured structures. + * @see io.papermc.paper.world.structure.ConfiguredStructure ++ * @deprecated use {@link #STRUCTURE} + */ ++ @Deprecated(forRemoval = true) + Registry CONFIGURED_STRUCTURE = Bukkit.getRegistry(io.papermc.paper.world.structure.ConfiguredStructure.class); + // Paper end diff --git a/patches/api/Expand-world-key-API.patch b/patches/api/Expand-world-key-API.patch index 81260cf123..070f843b12 100644 --- a/patches/api/Expand-world-key-API.patch +++ b/patches/api/Expand-world-key-API.patch @@ -82,9 +82,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java @@ -0,0 +0,0 @@ public interface UnsafeValues { - * @throws IllegalArgumentException if there isn't a registry for that type + * Use this when sending custom packets, so that there are no collisions on the client or server. */ - @org.jetbrains.annotations.NotNull Registry registryFor(Class classOfT); + public int nextEntityId(); + + /** + * Just don't use it. diff --git a/patches/api/More-PotionEffectType-API.patch b/patches/api/More-PotionEffectType-API.patch index 107b226b2c..2c0101ad5b 100644 --- a/patches/api/More-PotionEffectType-API.patch +++ b/patches/api/More-PotionEffectType-API.patch @@ -9,9 +9,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/Registry.java +++ b/src/main/java/org/bukkit/Registry.java @@ -0,0 +0,0 @@ public interface Registry extends Iterable { - * @see io.papermc.paper.world.structure.ConfiguredStructure */ + @Deprecated(forRemoval = true) Registry CONFIGURED_STRUCTURE = Bukkit.getRegistry(io.papermc.paper.world.structure.ConfiguredStructure.class); ++ + /** + * Potion effect types. + * diff --git a/patches/server/Add-PaperRegistry.patch b/patches/server/Add-PaperRegistry.patch deleted file mode 100644 index 52e0b47041..0000000000 --- a/patches/server/Add-PaperRegistry.patch +++ /dev/null @@ -1,242 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Wed, 2 Mar 2022 13:33:08 -0800 -Subject: [PATCH] Add PaperRegistry - -PaperRegistry is a server-backed impl of bukkit's Registry interface - -diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistry.java b/src/main/java/io/papermc/paper/registry/PaperRegistry.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/registry/PaperRegistry.java -@@ -0,0 +0,0 @@ -+package io.papermc.paper.registry; -+ -+import com.google.common.base.Preconditions; -+import com.google.common.base.Suppliers; -+import net.minecraft.core.Holder; -+import net.minecraft.core.Registry; -+import net.minecraft.core.RegistryAccess; -+import net.minecraft.resources.ResourceKey; -+import net.minecraft.resources.ResourceLocation; -+import net.minecraft.server.MinecraftServer; -+import org.bukkit.Keyed; -+import org.bukkit.NamespacedKey; -+import org.bukkit.craftbukkit.util.CraftNamespacedKey; -+import org.checkerframework.checker.nullness.qual.NonNull; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.checkerframework.framework.qual.DefaultQualifier; -+ -+import java.util.Collections; -+import java.util.HashMap; -+import java.util.Iterator; -+import java.util.Map; -+import java.util.Objects; -+import java.util.Optional; -+import java.util.concurrent.ConcurrentHashMap; -+import java.util.function.Consumer; -+import java.util.function.Supplier; -+ -+@DefaultQualifier(NonNull.class) -+public abstract class PaperRegistry implements org.bukkit.Registry { -+ -+ @SuppressWarnings("FieldMayBeFinal") // non-final for testing -+ private static Supplier REGISTRY_ACCESS = Suppliers.memoize(() -> MinecraftServer.getServer().registryAccess()); -+ private static final Map, PaperRegistry> INTERNAL_REGISTRIES = new HashMap<>(); -+ public static final Map, PaperRegistry> REGISTRIES = Collections.unmodifiableMap(INTERNAL_REGISTRIES); -+ private static final Map, PaperRegistry> REGISTRY_BY_API_CLASS = new HashMap<>(); -+ private static final Map>, PaperRegistry> REGISTRY_BY_RES_KEY = new HashMap<>(); -+ -+ private boolean registered; -+ private final RegistryKey registryKey; -+ private final Supplier> registry; -+ private final Map cache = new ConcurrentHashMap<>(); -+ private final Map> resourceKeyCache = new ConcurrentHashMap<>(); -+ -+ public PaperRegistry(RegistryKey registryKey) { -+ this.registryKey = registryKey; -+ this.registry = Suppliers.memoize(() -> REGISTRY_ACCESS.get().registryOrThrow(this.registryKey.resourceKey())); -+ } -+ -+ @Override -+ public @Nullable API get(NamespacedKey key) { -+ return this.cache.computeIfAbsent(key, k -> { -+ final @Nullable MINECRAFT nms = this.registry.get().get(CraftNamespacedKey.toMinecraft(k)); -+ if (nms != null) { -+ return this.convertToApi(k, nms); -+ } -+ return null; -+ }); -+ } -+ -+ public abstract @Nullable API convertToApi(NamespacedKey key, MINECRAFT nms); -+ -+ public API convertToApiOrThrow(ResourceLocation resourceLocation, MINECRAFT nms) { -+ return Objects.requireNonNull(this.convertToApi(resourceLocation, nms), resourceLocation + " has a null api representation"); -+ } -+ -+ public @Nullable API convertToApi(ResourceLocation resourceLocation, MINECRAFT nms) { -+ return this.convertToApi(CraftNamespacedKey.fromMinecraft(resourceLocation), nms); -+ } -+ -+ public API convertToApiOrThrow(Holder nmsHolder) { -+ return Objects.requireNonNull(this.convertToApi(nmsHolder), nmsHolder + " has a null api representation"); -+ } -+ -+ public @Nullable API convertToApi(Holder nmsHolder) { -+ final Optional> key = nmsHolder.unwrapKey(); -+ if (nmsHolder.isBound() && key.isPresent()) { -+ return this.convertToApi(key.get().location(), nmsHolder.value()); -+ } else if (!nmsHolder.isBound() && key.isPresent()) { -+ return this.convertToApi(key.get().location(), this.registry.get().getOrThrow(key.get())); -+ } else if (nmsHolder.isBound() && key.isEmpty()) { -+ final @Nullable ResourceLocation loc = this.registry.get().getKey(nmsHolder.value()); -+ if (loc != null) { -+ return this.convertToApi(loc, nmsHolder.value()); -+ } -+ } -+ throw new IllegalStateException("Cannot convert " + nmsHolder + " to an API type in: " + this.registryKey); -+ } -+ -+ public void convertToApi(Iterable> holders, Consumer apiConsumer, boolean throwOnNull) { -+ for (Holder holder : holders) { -+ final @Nullable API api = this.convertToApi(holder); -+ if (api == null && throwOnNull) { -+ throw new NullPointerException(holder + " has a null api representation"); -+ } else if (api != null) { -+ apiConsumer.accept(api); -+ } -+ } -+ } -+ -+ public MINECRAFT getMinecraftValue(API apiValue) { -+ return this.registry.get().getOptional(CraftNamespacedKey.toMinecraft(apiValue.getKey())).orElseThrow(); -+ } -+ -+ public Holder getMinecraftHolder(API apiValue) { -+ return this.registry.get().getHolderOrThrow(this.resourceKeyCache.computeIfAbsent(apiValue.getKey(), key -> ResourceKey.create(this.registryKey.resourceKey(), CraftNamespacedKey.toMinecraft(key)))); -+ } -+ -+ @Override -+ public Iterator iterator() { -+ return this.registry.get().keySet().stream().map(key -> this.get(CraftNamespacedKey.fromMinecraft(key))).iterator(); -+ } -+ -+ public void clearCache() { -+ this.cache.clear(); -+ } -+ -+ public void register() { -+ if (this.registered) { -+ throw new IllegalStateException("Already registered: " + this.registryKey.apiClass()); -+ } -+ INTERNAL_REGISTRIES.put(this.registryKey, this); -+ REGISTRY_BY_API_CLASS.put(this.registryKey.apiClass(), this); -+ REGISTRY_BY_RES_KEY.put(this.registryKey.resourceKey(), this); -+ this.registered = true; -+ } -+ -+ @Override -+ public boolean equals(@Nullable Object o) { -+ if (this == o) return true; -+ if (o == null || !PaperRegistry.class.isAssignableFrom(o.getClass())) return false; -+ PaperRegistry that = (PaperRegistry) o; -+ return this.registryKey.equals(that.registryKey); -+ } -+ -+ @Override -+ public int hashCode() { -+ return Objects.hash(this.registryKey); -+ } -+ -+ protected static Supplier> registryFor(ResourceKey> registryKey) { -+ return Suppliers.memoize(() -> REGISTRY_ACCESS.get().registryOrThrow(registryKey)); -+ } -+ -+ public static void clearCaches() { -+ for (PaperRegistry registry : INTERNAL_REGISTRIES.values()) { -+ registry.clearCache(); -+ } -+ } -+ -+ @SuppressWarnings("unchecked") -+ public static PaperRegistry getRegistry(Class classOfT) { -+ Preconditions.checkArgument(REGISTRY_BY_API_CLASS.containsKey(classOfT), "No registry for that type"); -+ return (PaperRegistry) REGISTRY_BY_API_CLASS.get(classOfT); -+ } -+ -+ @SuppressWarnings("unchecked") -+ public static PaperRegistry getRegistry(ResourceKey> resourceKey) { -+ Preconditions.checkArgument(REGISTRY_BY_RES_KEY.containsKey(resourceKey)); -+ return (PaperRegistry) REGISTRY_BY_RES_KEY.get(resourceKey); -+ } -+ -+ @SuppressWarnings("unchecked") -+ public static PaperRegistry getRegistry(RegistryKey registryKey) { -+ Preconditions.checkArgument(INTERNAL_REGISTRIES.containsKey(registryKey)); -+ return (PaperRegistry) INTERNAL_REGISTRIES.get(registryKey); -+ } -+} -diff --git a/src/main/java/io/papermc/paper/registry/RegistryKey.java b/src/main/java/io/papermc/paper/registry/RegistryKey.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/registry/RegistryKey.java -@@ -0,0 +0,0 @@ -+package io.papermc.paper.registry; -+ -+import net.minecraft.core.Registry; -+import net.minecraft.resources.ResourceKey; -+import org.bukkit.Keyed; -+ -+public record RegistryKey(Class apiClass, ResourceKey> resourceKey) { -+} -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Registry registryFor(Class classOfT) { -+ return io.papermc.paper.registry.PaperRegistry.getRegistry(classOfT); -+ } - // Paper end - - /** -diff --git a/src/test/java/org/bukkit/support/AbstractTestingBase.java b/src/test/java/org/bukkit/support/AbstractTestingBase.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/test/java/org/bukkit/support/AbstractTestingBase.java -+++ b/src/test/java/org/bukkit/support/AbstractTestingBase.java -@@ -0,0 +0,0 @@ public abstract class AbstractTestingBase { - layers = WorldLoader.loadAndReplaceLayer(resourceManager, layers, RegistryLayer.WORLDGEN, RegistryDataLoader.WORLDGEN_REGISTRIES); - REGISTRY_CUSTOM = layers.compositeAccess().freeze(); - io.papermc.paper.testing.DummyServer.setup(); // Paper -+ // Paper start -+ try { -+ java.lang.reflect.Field field = io.papermc.paper.registry.PaperRegistry.class.getDeclaredField("REGISTRY_ACCESS"); -+ field.trySetAccessible(); -+ field.set(null, com.google.common.base.Suppliers.ofInstance(REGISTRY_CUSTOM)); -+ } catch (ReflectiveOperationException ex) { -+ throw new IllegalStateException("Could not reflectively set RegistryAccess in PaperRegistry", ex); -+ } -+ // Paper end - // Register vanilla pack - DATA_PACK = ReloadableServerResources.loadResources(resourceManager, REGISTRY_CUSTOM, FeatureFlags.REGISTRY.allFlags(), Commands.CommandSelection.DEDICATED, 0, MoreExecutors.directExecutor(), MoreExecutors.directExecutor()).join(); - // Bind tags diff --git a/patches/server/Add-StructuresLocateEvent.patch b/patches/server/Add-StructuresLocateEvent.patch index 2702105d0a..bd3e10f101 100644 --- a/patches/server/Add-StructuresLocateEvent.patch +++ b/patches/server/Add-StructuresLocateEvent.patch @@ -5,25 +5,6 @@ Subject: [PATCH] Add StructuresLocateEvent Co-authored-by: Jake Potrebic -diff --git a/src/main/java/io/papermc/paper/registry/RegistryKey.java b/src/main/java/io/papermc/paper/registry/RegistryKey.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/io/papermc/paper/registry/RegistryKey.java -+++ b/src/main/java/io/papermc/paper/registry/RegistryKey.java -@@ -0,0 +0,0 @@ - package io.papermc.paper.registry; - -+import io.papermc.paper.world.structure.ConfiguredStructure; - import net.minecraft.core.Registry; -+import net.minecraft.core.registries.Registries; - import net.minecraft.resources.ResourceKey; -+import net.minecraft.world.level.levelgen.structure.Structure; - import org.bukkit.Keyed; - - public record RegistryKey(Class apiClass, ResourceKey> resourceKey) { -+ -+ public static final RegistryKey CONFIGURED_STRUCTURE_REGISTRY = new RegistryKey<>(ConfiguredStructure.class, Registries.STRUCTURE); -+ - } 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..0000000000000000000000000000000000000000 @@ -32,42 +13,33 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ +package io.papermc.paper.world.structure; + -+import io.papermc.paper.registry.PaperRegistry; -+import io.papermc.paper.registry.RegistryKey; ++import java.util.Objects; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; -+import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.levelgen.structure.Structure; +import org.bukkit.NamespacedKey; +import org.bukkit.StructureType; ++import org.bukkit.craftbukkit.CraftRegistry; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.framework.qual.DefaultQualifier; + -+import java.util.Objects; -+import java.util.function.Supplier; -+ +@DefaultQualifier(NonNull.class) ++@Deprecated(forRemoval = true) +public final class PaperConfiguredStructure { + + private PaperConfiguredStructure() { + } + -+ public static void init() { -+ new ConfiguredStructureRegistry().register(); -+ } ++ @Deprecated(forRemoval = true) ++ public static final class LegacyRegistry extends CraftRegistry { + -+ static final class ConfiguredStructureRegistry extends PaperRegistry { -+ -+ private static final Supplier> STRUCTURE_FEATURE_REGISTRY = registryFor(Registries.STRUCTURE); -+ -+ public ConfiguredStructureRegistry() { -+ super(RegistryKey.CONFIGURED_STRUCTURE_REGISTRY); ++ public LegacyRegistry(final Registry minecraftRegistry) { ++ super(minecraftRegistry, LegacyRegistry::minecraftToBukkit); + } + -+ @Override -+ public @Nullable ConfiguredStructure convertToApi(NamespacedKey key, Structure nms) { ++ 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); @@ -82,41 +54,43 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Nullable public Pair> findNearestMapStructure(ServerLevel world, HolderSet structures, BlockPos center, int radius, boolean skipReferencedStructures) { -+ // Paper start - StructureLocateEvent ++ // Paper start - StructuresLocateEvent + final org.bukkit.World bukkitWorld = world.getWorld(); + final org.bukkit.Location origin = io.papermc.paper.util.MCUtil.toLocation(world, center); -+ final var paperRegistry = io.papermc.paper.registry.PaperRegistry.getRegistry(io.papermc.paper.registry.RegistryKey.CONFIGURED_STRUCTURE_REGISTRY); -+ final List configuredStructures = new ArrayList<>(); -+ paperRegistry.convertToApi(structures, configuredStructures::add, false); // gracefully handle missing api, use tests to check (or exclude) -+ if (!configuredStructures.isEmpty()) { -+ final io.papermc.paper.event.world.StructuresLocateEvent event = new io.papermc.paper.event.world.StructuresLocateEvent(bukkitWorld, origin, configuredStructures, radius, skipReferencedStructures); ++ final List apiStructures = structures.stream().map(Holder::value).map(nms -> org.bukkit.craftbukkit.generator.strucutre.CraftStructure.minecraftToBukkit(nms, world.registryAccess())).toList(); ++ if (!apiStructures.isEmpty()) { ++ final io.papermc.paper.event.world.StructuresLocateEvent event = new io.papermc.paper.event.world.StructuresLocateEvent(bukkitWorld, origin, apiStructures, radius, skipReferencedStructures); + if (!event.callEvent()) { + return null; + } + if (event.getResult() != null) { -+ return Pair.of(io.papermc.paper.util.MCUtil.toBlockPosition(event.getResult().position()), paperRegistry.getMinecraftHolder(event.getResult().configuredStructure())); ++ return Pair.of(io.papermc.paper.util.MCUtil.toBlockPos(event.getResult().pos()), world.registryAccess().registryOrThrow(Registries.STRUCTURE).wrapAsHolder(org.bukkit.craftbukkit.generator.strucutre.CraftStructure.bukkitToMinecraft(event.getResult().structure()))); + } + center = io.papermc.paper.util.MCUtil.toBlockPosition(event.getOrigin()); + radius = event.getRadius(); + skipReferencedStructures = event.shouldFindUnexplored(); -+ structures = HolderSet.direct(paperRegistry::getMinecraftHolder, event.getConfiguredStructures()); ++ structures = HolderSet.direct(api -> world.registryAccess().registryOrThrow(Registries.STRUCTURE).wrapAsHolder(org.bukkit.craftbukkit.generator.strucutre.CraftStructure.bukkitToMinecraft(api)), event.getStructures()); + } + // Paper end ChunkGeneratorStructureState chunkgeneratorstructurestate = world.getChunkSource().getGeneratorState(); Map>> map = new Object2ObjectArrayMap(); Iterator iterator = structures.iterator(); -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -0,0 +0,0 @@ public final class CraftServer implements Server { - this.structureManager = new CraftStructureManager(console.getStructureManager()); +--- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +@@ -0,0 +0,0 @@ public class CraftRegistry implements Registry { + return new CraftRegistry<>(BuiltInRegistries.STRUCTURE_TYPE, CraftStructureType::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 - Bukkit.setServer(this); -+ io.papermc.paper.world.structure.PaperConfiguredStructure.init(); // Paper - - // Register all the Enchantments and PotionTypes now so we can stop new registration immediately after - Enchantments.SHARPNESS.getClass(); + 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..0000000000000000000000000000000000000000 @@ -151,6 +125,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + ++@Deprecated(forRemoval = true) +public class ConfiguredStructureTest extends AbstractTestingBase { + + private static final Map BUILT_IN_STRUCTURES = new LinkedHashMap<>(); diff --git a/patches/server/Basic-PlayerProfile-API.patch b/patches/server/Basic-PlayerProfile-API.patch index c0fcab752b..53bd804d79 100644 --- a/patches/server/Basic-PlayerProfile-API.patch +++ b/patches/server/Basic-PlayerProfile-API.patch @@ -574,8 +574,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import com.destroystokyo.paper.profile.CraftPlayerProfile; +import com.destroystokyo.paper.profile.PlayerProfile; import com.google.common.util.concurrent.ThreadFactoryBuilder; + import io.papermc.paper.math.Position; import com.google.gson.JsonArray; - import com.google.gson.JsonObject; @@ -0,0 +0,0 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkStatus; diff --git a/patches/server/Custom-Potion-Mixes.patch b/patches/server/Custom-Potion-Mixes.patch index d9f6541143..5dbb2ad3e6 100644 --- a/patches/server/Custom-Potion-Mixes.patch +++ b/patches/server/Custom-Potion-Mixes.patch @@ -28,9 +28,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Registry registryFor(Class classOfT) { - return io.papermc.paper.registry.PaperRegistry.getRegistry(classOfT); + public int nextEntityId() { + return net.minecraft.world.entity.Entity.nextEntityId(); } + + @Override diff --git a/patches/server/MC-Utils.patch b/patches/server/MC-Utils.patch index 49990751b7..5ec64525be 100644 --- a/patches/server/MC-Utils.patch +++ b/patches/server/MC-Utils.patch @@ -3470,6 +3470,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +package io.papermc.paper.util; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; ++import io.papermc.paper.math.Position; +import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet; +import java.lang.ref.Cleaner; +import net.minecraft.core.BlockPos; @@ -3933,6 +3934,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return new BlockPos(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + } + ++ public static BlockPos toBlockPos(Position pos) { ++ return new BlockPos(pos.blockX(), pos.blockY(), pos.blockZ()); ++ } ++ + public static boolean isEdgeOfChunk(BlockPos pos) { + final int modX = pos.getX() & 15; + final int modZ = pos.getZ() & 15; diff --git a/patches/server/Rewrite-chunk-system.patch b/patches/server/Rewrite-chunk-system.patch index 1923c0e788..7fced7d63f 100644 --- a/patches/server/Rewrite-chunk-system.patch +++ b/patches/server/Rewrite-chunk-system.patch @@ -11847,10 +11847,10 @@ diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/io/papermc/paper/util/MCUtil.java +++ b/src/main/java/io/papermc/paper/util/MCUtil.java -@@ -0,0 +0,0 @@ - package io.papermc.paper.util; +@@ -0,0 +0,0 @@ package io.papermc.paper.util; import com.google.common.util.concurrent.ThreadFactoryBuilder; + import io.papermc.paper.math.Position; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.internal.Streams; diff --git a/patches/server/TODO-Registry-Modification-API.patch b/patches/server/TODO-Registry-Modification-API.patch new file mode 100644 index 0000000000..a284b1b8c5 --- /dev/null +++ b/patches/server/TODO-Registry-Modification-API.patch @@ -0,0 +1,18 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +@@ -0,0 +0,0 @@ public class CraftRegistry implements Registry { + if (bukkitClass == StructureType.class) { + return new CraftRegistry<>(BuiltInRegistries.STRUCTURE_TYPE, CraftStructureType::new); + } ++ // TODO registry modification API + + return null; + }