From e0da6d4b81114315f4a09c6202560df1c86f8eb2 Mon Sep 17 00:00:00 2001 From: Max Lee Date: Fri, 24 Jan 2020 20:07:14 +0100 Subject: [PATCH] Seed based feature search (Fixes #2312) (#2852) --- .../0434-Seed-based-feature-search.patch | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 Spigot-Server-Patches/0434-Seed-based-feature-search.patch diff --git a/Spigot-Server-Patches/0434-Seed-based-feature-search.patch b/Spigot-Server-Patches/0434-Seed-based-feature-search.patch new file mode 100644 index 0000000000..d31115bc6b --- /dev/null +++ b/Spigot-Server-Patches/0434-Seed-based-feature-search.patch @@ -0,0 +1,113 @@ +From f6980b7867cefdfbb83471c04034465e6e3f004e Mon Sep 17 00:00:00 2001 +From: Phoenix616 +Date: Mon, 13 Jan 2020 15:40:32 +0100 +Subject: [PATCH] Seed based feature search + +This fixes the issue where the server will load surrounding chunks up to +a radius of 100 chunks in order to search for features e.g. when running +the /locate command or for treasure maps (issue #2312). +This is done by using the same seed checking functionality that is used +by the server when generating these features before actually attempting +to load the chunk to check if a feature is available in it. + +The only downside of this is that it breaks once the seed or generator +changes but this should usually not happen. A config option to disable +this improvement is added though in case that should ever be necessary. + +diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +index 3b8488d3f..bce502181 100644 +--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java ++++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +@@ -359,6 +359,12 @@ public class PaperWorldConfig { + } + } + ++ public boolean seedBasedFeatureSearch = true; ++ private void seedBasedFeatureSearch() { ++ seedBasedFeatureSearch = getBoolean("seed-based-feature-search", seedBasedFeatureSearch); ++ log("Feature search is based on seed: " + seedBasedFeatureSearch); ++ } ++ + public int maxCollisionsPerEntity; + private void maxEntityCollision() { + maxCollisionsPerEntity = getInt( "max-entity-collisions", this.spigotConfig.getInt("max-entity-collisions", 8) ); +diff --git a/src/main/java/net/minecraft/server/BiomeManager.java b/src/main/java/net/minecraft/server/BiomeManager.java +index e96f544f1..68423645d 100644 +--- a/src/main/java/net/minecraft/server/BiomeManager.java ++++ b/src/main/java/net/minecraft/server/BiomeManager.java +@@ -12,10 +12,12 @@ public class BiomeManager { + this.c = genlayerzoomer; + } + ++ public BiomeManager withProvider(WorldChunkManager worldchunkmanager) { return a(worldchunkmanager); } // Paper - OBFHELPER + public BiomeManager a(WorldChunkManager worldchunkmanager) { + return new BiomeManager(worldchunkmanager, this.b, this.c); + } + ++ public BiomeBase getBiome(BlockPosition blockposition) { return a(blockposition); } // Paper - OBFHELPER + public BiomeBase a(BlockPosition blockposition) { + return this.c.a(this.b, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this.a); + } +diff --git a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java +index f2a19acd8..09f1308b0 100644 +--- a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java ++++ b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java +@@ -64,10 +64,12 @@ public class ChunkCoordIntPair { + } + } + ++ public int getBlockX() { return d(); } // Paper - OBFHELPER + public int d() { + return this.x << 4; + } + ++ public int getBlockZ() { return e(); } // Paper - OBFHELPER + public int e() { + return this.z << 4; + } +diff --git a/src/main/java/net/minecraft/server/StructureGenerator.java b/src/main/java/net/minecraft/server/StructureGenerator.java +index e8ce2ecf2..acfe732af 100644 +--- a/src/main/java/net/minecraft/server/StructureGenerator.java ++++ b/src/main/java/net/minecraft/server/StructureGenerator.java +@@ -109,6 +109,15 @@ public abstract class StructureGenerator + if (flag1 || flag2) { + ChunkCoordIntPair chunkcoordintpair = this.a(chunkgenerator, seededrandom, j, k, i1, j1); + if (!world.getWorldBorder().isChunkInBounds(chunkcoordintpair.x, chunkcoordintpair.z)) { continue; } // Paper ++ // Paper start - seed based feature search ++ if (world.paperConfig.seedBasedFeatureSearch) { ++ BiomeManager biomeManager = world.getBiomeManager().withProvider(chunkgenerator.getWorldChunkManager()); ++ BiomeBase biomeBase = biomeManager.getBiome(new BlockPosition(chunkcoordintpair.getBlockX() + 9, 0, chunkcoordintpair.getBlockZ() + 9)); ++ if (!shouldGenerate(biomeManager, chunkgenerator, seededrandom, chunkcoordintpair.x, chunkcoordintpair.z, biomeBase)) { ++ continue; ++ } ++ } ++ // Paper end + StructureStart structurestart = world.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z, ChunkStatus.STRUCTURE_STARTS).a(this.b()); + + if (structurestart != null && structurestart.e()) { +@@ -165,6 +174,7 @@ public abstract class StructureGenerator + return new ChunkCoordIntPair(i + k, j + l); + } + ++ public boolean shouldGenerate(BiomeManager biomemanager, ChunkGenerator chunkgenerator, Random random, int chunkX, int chunkZ, BiomeBase biomebase) { return a(biomemanager, chunkgenerator, random, chunkX, chunkZ, biomebase); } // Paper - OBFHELPER + public abstract boolean a(BiomeManager biomemanager, ChunkGenerator chunkgenerator, Random random, int i, int j, BiomeBase biomebase); + + public abstract StructureGenerator.a a(); +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 9df079d8a..8a2bb79ad 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -1588,8 +1588,8 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + return this.methodProfiler; + } + +- @Override +- public BiomeManager d() { ++ public BiomeManager getBiomeManager() { return d(); } // Paper - OBFHELPER ++ @Override public BiomeManager d() { + return this.biomeManager; + } + } +-- +2.18.0.windows.1 +