aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0498-Add-StructuresLocateEvent.patch
diff options
context:
space:
mode:
authorNassim Jahnke <[email protected]>2024-01-23 18:01:39 +0100
committerNassim Jahnke <[email protected]>2024-01-23 18:06:51 +0100
commitc57d1aa24560ec71331e685e9fd27aa3d9274f69 (patch)
treeb585b2246be85ecc5047b02b704c0a5f59c96dd9 /patches/server/0498-Add-StructuresLocateEvent.patch
parente66037960b02c7b22bbed75318904c55a4177977 (diff)
downloadPaper-c57d1aa24560ec71331e685e9fd27aa3d9274f69.tar.gz
Paper-c57d1aa24560ec71331e685e9fd27aa3d9274f69.zip
Move diffs around to compile without later ones applied
Diffstat (limited to 'patches/server/0498-Add-StructuresLocateEvent.patch')
-rw-r--r--patches/server/0498-Add-StructuresLocateEvent.patch207
1 files changed, 207 insertions, 0 deletions
diff --git a/patches/server/0498-Add-StructuresLocateEvent.patch b/patches/server/0498-Add-StructuresLocateEvent.patch
new file mode 100644
index 0000000000..a0a3344871
--- /dev/null
+++ b/patches/server/0498-Add-StructuresLocateEvent.patch
@@ -0,0 +1,207 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: dfsek <[email protected]>
+Date: Wed, 16 Sep 2020 01:12:29 -0700
+Subject: [PATCH] Add StructuresLocateEvent
+
+Co-authored-by: Jake Potrebic <[email protected]>
+
+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
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/world/structure/PaperConfiguredStructure.java
+@@ -0,0 +1,35 @@
++package io.papermc.paper.world.structure;
++
++import java.util.Objects;
++import net.minecraft.core.Registry;
++import net.minecraft.core.registries.BuiltInRegistries;
++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;
++
++@DefaultQualifier(NonNull.class)
++@Deprecated(forRemoval = true)
++public final class PaperConfiguredStructure {
++
++ 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);
++ }
++ }
++}
+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 1eacb6998f99833441dd1dcb8301f25759675f53..180f8ae443d1ea44a748c7f3ebb82a0bab8d31f1 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 {
+
+ @Nullable
+ public Pair<BlockPos, Holder<Structure>> findNearestMapStructure(ServerLevel world, HolderSet<Structure> structures, BlockPos center, int radius, boolean skipReferencedStructures) {
++ // Paper start - StructuresLocateEvent
++ final org.bukkit.World bukkitWorld = world.getWorld();
++ final org.bukkit.Location origin = io.papermc.paper.util.MCUtil.toLocation(world, center);
++ final List<org.bukkit.generator.structure.Structure> apiStructures = structures.stream().map(Holder::value).map(nms -> org.bukkit.craftbukkit.generator.structure.CraftStructure.minecraftToBukkit(nms)).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.toBlockPos(event.getResult().pos()), world.registryAccess().registryOrThrow(Registries.STRUCTURE).wrapAsHolder(org.bukkit.craftbukkit.generator.structure.CraftStructure.bukkitToMinecraft(event.getResult().structure())));
++ }
++ center = io.papermc.paper.util.MCUtil.toBlockPosition(event.getOrigin());
++ radius = event.getRadius();
++ skipReferencedStructures = event.shouldFindUnexplored();
++ structures = HolderSet.direct(api -> world.registryAccess().registryOrThrow(Registries.STRUCTURE).wrapAsHolder(org.bukkit.craftbukkit.generator.structure.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/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
+index 47b5930adf1870125b1ec063895b0652890a06de..253b4cf66e94faf0bc8861318ae7549f52cd29d1 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
+@@ -73,6 +73,11 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
+ return new CraftRegistry<>(TrimPattern.class, registryHolder.registryOrThrow(Registries.TRIM_PATTERN), CraftTrimPattern::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
+--- /dev/null
++++ b/src/test/java/io/papermc/paper/world/structure/ConfiguredStructureTest.java
+@@ -0,0 +1,96 @@
++package io.papermc.paper.world.structure;
++
++import io.papermc.paper.registry.Reference;
++import net.minecraft.core.Registry;
++import net.minecraft.core.registries.Registries;
++import net.minecraft.resources.ResourceKey;
++import net.minecraft.resources.ResourceLocation;
++import net.minecraft.server.Bootstrap;
++import net.minecraft.world.level.levelgen.structure.Structure;
++import net.minecraft.world.level.levelgen.structure.BuiltinStructures;
++import org.bukkit.NamespacedKey;
++import org.bukkit.craftbukkit.util.CraftNamespacedKey;
++import org.bukkit.support.AbstractTestingBase;
++import org.junit.jupiter.api.AfterAll;
++import org.junit.jupiter.api.BeforeAll;
++import org.junit.jupiter.api.Test;
++
++import java.io.PrintStream;
++import java.lang.reflect.Field;
++import java.lang.reflect.Modifier;
++import java.util.LinkedHashMap;
++import java.util.Map;
++import java.util.StringJoiner;
++
++import static org.junit.jupiter.api.Assertions.assertEquals;
++import static org.junit.jupiter.api.Assertions.assertNotNull;
++import static org.junit.jupiter.api.Assertions.assertTrue;
++
++@Deprecated(forRemoval = true)
++public class ConfiguredStructureTest extends AbstractTestingBase {
++
++ private static final Map<ResourceLocation, String> BUILT_IN_STRUCTURES = new LinkedHashMap<>();
++ private static final Map<NamespacedKey, Reference<?>> DEFAULT_CONFIGURED_STRUCTURES = new LinkedHashMap<>();
++
++ private static PrintStream out;
++
++ @BeforeAll
++ public static void collectStructures() throws ReflectiveOperationException {
++ out = System.out;
++ System.setOut(Bootstrap.STDOUT);
++ for (Field field : BuiltinStructures.class.getDeclaredFields()) {
++ if (field.getType().equals(ResourceKey.class) && Modifier.isStatic(field.getModifiers())) {
++ BUILT_IN_STRUCTURES.put(((ResourceKey<?>) field.get(null)).location(), field.getName());
++ }
++ }
++ for (Field field : ConfiguredStructure.class.getDeclaredFields()) {
++ if (field.getType().equals(Reference.class) && Modifier.isStatic(field.getModifiers())) {
++ final Reference<?> ref = (Reference<?>) field.get(null);
++ DEFAULT_CONFIGURED_STRUCTURES.put(ref.getKey(), ref);
++ }
++ }
++ }
++
++ @Test
++ public void testMinecraftToApi() {
++ Registry<Structure> structureRegistry = AbstractTestingBase.REGISTRY_CUSTOM.registryOrThrow(Registries.STRUCTURE);
++ assertEquals(BUILT_IN_STRUCTURES.size(), structureRegistry.size(), "configured structure maps should be the same size");
++
++ Map<ResourceLocation, Structure> missing = new LinkedHashMap<>();
++ for (Structure feature : structureRegistry) {
++ final ResourceLocation key = structureRegistry.getKey(feature);
++ assertNotNull(key, "Missing built-in registry key");
++ if (key.equals(BuiltinStructures.ANCIENT_CITY.location()) || key.equals(BuiltinStructures.TRAIL_RUINS.location()) || key.equals(BuiltinStructures.TRIAL_CHAMBERS.location())) {
++ continue; // TODO remove when upstream adds "jigsaw" StructureType
++ }
++ if (DEFAULT_CONFIGURED_STRUCTURES.get(CraftNamespacedKey.fromMinecraft(key)) == null) {
++ missing.put(key, feature);
++ }
++ }
++
++ assertTrue(missing.isEmpty(), printMissing(missing));
++ }
++
++ @Test
++ public void testApiToMinecraft() {
++ Registry<Structure> structureRegistry = AbstractTestingBase.REGISTRY_CUSTOM.registryOrThrow(Registries.STRUCTURE);
++ for (NamespacedKey apiKey : DEFAULT_CONFIGURED_STRUCTURES.keySet()) {
++ assertTrue(structureRegistry.containsKey(CraftNamespacedKey.toMinecraft(apiKey)), apiKey + " does not have a minecraft counterpart");
++ }
++ }
++
++ private static String printMissing(Map<ResourceLocation, Structure> missing) {
++ final StringJoiner joiner = new StringJoiner("\n", "Missing: \n", "");
++
++ missing.forEach((key, configuredFeature) -> {
++ joiner.add("public static final Reference<ConfiguredStructure> " + BUILT_IN_STRUCTURES.get(key) + " = create(\"" + key.getPath() + "\");");
++ });
++
++ return joiner.toString();
++ }
++
++ @AfterAll
++ public static void after() {
++ System.setOut(out);
++ }
++}
+diff --git a/src/test/java/org/bukkit/PerRegistryTest.java b/src/test/java/org/bukkit/PerRegistryTest.java
+index a5db5b190bf16571d329a653de01acdae8dc8cfa..9e553a8858750c494456f04abd7bffd1d257308c 100644
+--- a/src/test/java/org/bukkit/PerRegistryTest.java
++++ b/src/test/java/org/bukkit/PerRegistryTest.java
+@@ -33,6 +33,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
+
+ data.add(Arguments.of(registry));
+ } catch (ReflectiveOperationException e) {