aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0869-Fix-World-locateNearestStructure.patch
blob: 747ca89c54bc412fda0500516990afe7d519fe20 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 1 Mar 2022 14:12:17 -0800
Subject: [PATCH] Fix World#locateNearestStructure

1.18.2 switched to TagKeys to reference tags of objects, and this method
  impl needs to be changed to reflect that

diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 2285fb8bc025fafc0531f2ce1b658c3a458e02d0..edceca7fe37c9b10a80829182c0b3af82b3d163d 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -2056,6 +2056,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
             this.resources.managers.updateRegistryTags(this.registryAccess());
             io.papermc.paper.registry.PaperRegistry.clearCaches(); // Paper
             net.minecraft.world.item.alchemy.PotionBrewing.reload(); // Paper
+            // Paper start - clear cache cause datapacks can add more configured structures
+            for (ServerLevel level : this.levels.values()) {
+                level.getWorld().structureCache.clear();
+            }
+            // Paper end
             new io.papermc.paper.event.server.ServerResourcesReloadedEvent(cause).callEvent(); // Paper
             if (Thread.currentThread() != this.serverThread) return; // Paper
             //this.getPlayerList().saveAll(); // Paper - we don't need to do this
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 1347ea594d3e771f02a73d95454388d4533c8be8..60e5a9e11ab7f4c2af4e9a2c9066cce02b544af8 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1793,7 +1793,16 @@ public class ServerLevel extends Level implements WorldGenLevel {
             if (optional.isEmpty()) {
                 return null;
             } else {
-                Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>> pair = this.getChunkSource().getGenerator().findNearestMapFeature(this, (HolderSet) optional.get(), pos, radius, skipExistingChunks);
+                // Paper start
+                return this.findNearestMapFeature(optional.get(), pos, radius, skipExistingChunks);
+            }
+        }
+    }
+    public @Nullable BlockPos findNearestMapFeature(HolderSet<ConfiguredStructureFeature<?, ?>> holderSet, BlockPos pos, int radius, boolean skipExistingChunks) {
+        {
+            {
+                Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>> pair = this.getChunkSource().getGenerator().findNearestMapFeature(this, holderSet, pos, radius, skipExistingChunks);
+                // Paper end
 
                 return pair != null ? (BlockPos) pair.getFirst() : null;
             }
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index a3ddeb9862bc87294c215dc906cd8cca8f699b62..b2c5fbfcb64f3056d7975db43b2db45bfd5e9890 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -2071,10 +2071,22 @@ public class CraftWorld extends CraftRegionAccessor implements World {
 
     }
 
+    public final Map<StructureType, List<Holder.Reference<net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature<?, ?>>>> structureCache = new java.util.HashMap<>(); // Paper
     @Override
     public Location locateNearestStructure(Location origin, StructureType structureType, int radius, boolean findUnexplored) {
         BlockPos originPos = new BlockPos(origin.getX(), origin.getY(), origin.getZ());
-        BlockPos nearest = this.getHandle().findNearestMapFeature(TagKey.create(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY, CraftNamespacedKey.toMinecraft(structureType.getKey())), originPos, radius, findUnexplored);
+        // Paper start - fix because you can't just create random TagKeys
+        if (!this.getHandle().serverLevelData.worldGenSettings().generateFeatures()) { // from ServerLevel#findNearestMapFeature
+            return null;
+        }
+        final List<Holder.Reference<net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature<?, ?>>> features = this.structureCache.computeIfAbsent(structureType, (type) -> {
+            final Registry<net.minecraft.world.level.levelgen.feature.StructureFeature<?>> structureFeatureRegistry = this.getHandle().registryAccess().registryOrThrow(Registry.STRUCTURE_FEATURE_REGISTRY);
+            return this.getHandle().registryAccess().registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY).holders().filter(holder -> {
+                return structureType.getKey().equals(org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(Objects.requireNonNull(structureFeatureRegistry.getKey(holder.value().feature))));
+            }).toList();
+        });
+        BlockPos nearest = this.getHandle().findNearestMapFeature(net.minecraft.core.HolderSet.direct(features), originPos, radius, findUnexplored);
+        // Paper end
         return (nearest == null) ? null : new Location(this, nearest.getX(), nearest.getY(), nearest.getZ());
     }