mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 20:07:41 +01:00
Replace ConfiguredStructure api with Structure (#8642)
This commit is contained in:
parent
81f79b407d
commit
f8ba85ffbf
@ -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 <T> type
|
||||
+ * @return the server-backed registry
|
||||
+ * @throws IllegalArgumentException if there isn't a registry for that type
|
||||
+ */
|
||||
+ <T extends Keyed> @org.jetbrains.annotations.NotNull Registry<T> registryFor(Class<T> classOfT);
|
||||
// Paper end
|
||||
}
|
||||
|
@ -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 <b>before</b> a set of configured structures is located.
|
||||
@ -206,15 +210,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+
|
||||
+ private final Location origin;
|
||||
+ private Result result;
|
||||
+ private List<ConfiguredStructure> configuredStructures;
|
||||
+ private List<Structure> structures;
|
||||
+ private List<ConfiguredStructure> legacy$structures;
|
||||
+ private int radius;
|
||||
+ private boolean findUnexplored;
|
||||
+ private boolean cancelled;
|
||||
+
|
||||
+ public StructuresLocateEvent(@NotNull World world, @NotNull Location origin, @NotNull List<ConfiguredStructure> configuredStructures, int radius, boolean findUnexplored) {
|
||||
+ public StructuresLocateEvent(@NotNull World world, @NotNull Location origin, @NotNull List<Structure> 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.
|
||||
+ * <p>
|
||||
+ * Returns {@code null} if it has not been set by {@link StructuresLocateEvent#setResult(Result)}.
|
||||
+ * Since this event fires <i>before</i> 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<ConfiguredStructure> 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<ConfiguredStructure> 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<Structure> 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<Structure> structures) {
|
||||
+ this.structures = structures;
|
||||
+ this.legacy$structures = new TransformingRandomAccessList<>(this.structures, ConfiguredStructure::fromModern, ConfiguredStructure::toModern);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
@ -274,7 +302,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ * <p>
|
||||
+ * 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
|
||||
+ * <p>
|
||||
+ * 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<ConfiguredStructure> PILLAGER_OUTPOST = create("pillager_outpost");
|
||||
@ -441,6 +489,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ private static @NotNull Reference<ConfiguredStructure> 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<io.papermc.paper.world.structure.ConfiguredStructure> CONFIGURED_STRUCTURE = Bukkit.getRegistry(io.papermc.paper.world.structure.ConfiguredStructure.class);
|
||||
+ // Paper end
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
<T extends Keyed> @org.jetbrains.annotations.NotNull Registry<T> registryFor(Class<T> classOfT);
|
||||
public int nextEntityId();
|
||||
+
|
||||
+ /**
|
||||
+ * Just don't use it.
|
||||
|
@ -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<T extends Keyed> extends Iterable<T> {
|
||||
* @see io.papermc.paper.world.structure.ConfiguredStructure
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
Registry<io.papermc.paper.world.structure.ConfiguredStructure> CONFIGURED_STRUCTURE = Bukkit.getRegistry(io.papermc.paper.world.structure.ConfiguredStructure.class);
|
||||
+
|
||||
+ /**
|
||||
+ * Potion effect types.
|
||||
+ *
|
||||
|
@ -1,242 +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: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<API extends Keyed, MINECRAFT> implements org.bukkit.Registry<API> {
|
||||
+
|
||||
+ @SuppressWarnings("FieldMayBeFinal") // non-final for testing
|
||||
+ private static Supplier<RegistryAccess> REGISTRY_ACCESS = Suppliers.memoize(() -> MinecraftServer.getServer().registryAccess());
|
||||
+ private static final Map<RegistryKey<?, ?>, PaperRegistry<?, ?>> INTERNAL_REGISTRIES = new HashMap<>();
|
||||
+ public static final Map<RegistryKey<?, ?>, PaperRegistry<?, ?>> REGISTRIES = Collections.unmodifiableMap(INTERNAL_REGISTRIES);
|
||||
+ private static final Map<Class<?>, PaperRegistry<?, ?>> REGISTRY_BY_API_CLASS = new HashMap<>();
|
||||
+ private static final Map<ResourceKey<? extends Registry<?>>, PaperRegistry<?, ?>> REGISTRY_BY_RES_KEY = new HashMap<>();
|
||||
+
|
||||
+ private boolean registered;
|
||||
+ private final RegistryKey<API, MINECRAFT> registryKey;
|
||||
+ private final Supplier<Registry<MINECRAFT>> registry;
|
||||
+ private final Map<NamespacedKey, API> cache = new ConcurrentHashMap<>();
|
||||
+ private final Map<NamespacedKey, ResourceKey<MINECRAFT>> resourceKeyCache = new ConcurrentHashMap<>();
|
||||
+
|
||||
+ public PaperRegistry(RegistryKey<API, MINECRAFT> 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<MINECRAFT> nmsHolder) {
|
||||
+ return Objects.requireNonNull(this.convertToApi(nmsHolder), nmsHolder + " has a null api representation");
|
||||
+ }
|
||||
+
|
||||
+ public @Nullable API convertToApi(Holder<MINECRAFT> nmsHolder) {
|
||||
+ final Optional<ResourceKey<MINECRAFT>> 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<Holder<MINECRAFT>> holders, Consumer<API> apiConsumer, boolean throwOnNull) {
|
||||
+ for (Holder<MINECRAFT> 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<MINECRAFT> 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<API> 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 <T> Supplier<Registry<T>> registryFor(ResourceKey<? extends Registry<T>> 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 <T extends Keyed> PaperRegistry<T, ?> getRegistry(Class<T> classOfT) {
|
||||
+ Preconditions.checkArgument(REGISTRY_BY_API_CLASS.containsKey(classOfT), "No registry for that type");
|
||||
+ return (PaperRegistry<T, ?>) REGISTRY_BY_API_CLASS.get(classOfT);
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("unchecked")
|
||||
+ public static <T> PaperRegistry<?, T> getRegistry(ResourceKey<? extends Registry<T>> resourceKey) {
|
||||
+ Preconditions.checkArgument(REGISTRY_BY_RES_KEY.containsKey(resourceKey));
|
||||
+ return (PaperRegistry<?, T>) REGISTRY_BY_RES_KEY.get(resourceKey);
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("unchecked")
|
||||
+ public static <A extends Keyed, M> PaperRegistry<A, M> getRegistry(RegistryKey<A, M> registryKey) {
|
||||
+ Preconditions.checkArgument(INTERNAL_REGISTRIES.containsKey(registryKey));
|
||||
+ return (PaperRegistry<A, M>) 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<API extends Keyed, MINECRAFT>(Class<API> apiClass, ResourceKey<? extends Registry<MINECRAFT>> 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<TickTa
|
||||
|
||||
this.worldData.setDataConfiguration(worlddataconfiguration);
|
||||
this.resources.managers.updateRegistryTags(this.registryAccess());
|
||||
+ io.papermc.paper.registry.PaperRegistry.clearCaches(); // Paper
|
||||
new io.papermc.paper.event.server.ServerResourcesReloadedEvent(cause).callEvent(); // Paper
|
||||
// Paper start
|
||||
if (Thread.currentThread() != this.serverThread) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
public int nextEntityId() {
|
||||
return net.minecraft.world.entity.Entity.nextEntityId();
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public <T extends org.bukkit.Keyed> Registry<T> registryFor(Class<T> 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
|
@ -5,25 +5,6 @@ Subject: [PATCH] Add StructuresLocateEvent
|
||||
|
||||
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
|
||||
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<API extends Keyed, MINECRAFT>(Class<API> apiClass, ResourceKey<? extends Registry<MINECRAFT>> resourceKey) {
|
||||
+
|
||||
+ public static final RegistryKey<ConfiguredStructure, Structure> 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<ConfiguredStructure, Structure> {
|
||||
+
|
||||
+ static final class ConfiguredStructureRegistry extends PaperRegistry<ConfiguredStructure, Structure> {
|
||||
+
|
||||
+ private static final Supplier<Registry<Structure>> STRUCTURE_FEATURE_REGISTRY = registryFor(Registries.STRUCTURE);
|
||||
+
|
||||
+ public ConfiguredStructureRegistry() {
|
||||
+ super(RegistryKey.CONFIGURED_STRUCTURE_REGISTRY);
|
||||
+ public LegacyRegistry(final Registry<Structure> 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<BlockPos, Holder<Structure>> findNearestMapStructure(ServerLevel world, HolderSet<Structure> 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<io.papermc.paper.world.structure.ConfiguredStructure> 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<org.bukkit.generator.structure.Structure> 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<StructurePlacement, Set<Holder<Structure>>> 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<B extends Keyed, M> implements Registry<B> {
|
||||
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<ResourceLocation, String> BUILT_IN_STRUCTURES = new LinkedHashMap<>();
|
||||
|
@ -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;
|
||||
|
@ -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<TickTa
|
||||
|
||||
this.worldData.setDataConfiguration(worlddataconfiguration);
|
||||
this.resources.managers.updateRegistryTags(this.registryAccess());
|
||||
io.papermc.paper.registry.PaperRegistry.clearCaches(); // Paper
|
||||
+ net.minecraft.world.item.alchemy.PotionBrewing.reload(); // Paper
|
||||
new io.papermc.paper.event.server.ServerResourcesReloadedEvent(cause).callEvent(); // Paper
|
||||
// Paper start
|
||||
|
@ -71,8 +71,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
public <T extends org.bukkit.Keyed> Registry<T> registryFor(Class<T> classOfT) {
|
||||
return io.papermc.paper.registry.PaperRegistry.getRegistry(classOfT);
|
||||
public int nextEntityId() {
|
||||
return net.minecraft.world.entity.Entity.nextEntityId();
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
18
patches/server/TODO-Registry-Modification-API.patch
Normal file
18
patches/server/TODO-Registry-Modification-API.patch
Normal file
@ -0,0 +1,18 @@
|
||||
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 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<B extends Keyed, M> implements Registry<B> {
|
||||
if (bukkitClass == StructureType.class) {
|
||||
return new CraftRegistry<>(BuiltInRegistries.STRUCTURE_TYPE, CraftStructureType::new);
|
||||
}
|
||||
+ // TODO registry modification API
|
||||
|
||||
return null;
|
||||
}
|
Loading…
Reference in New Issue
Block a user