From 0000000000000000000000000000000000000000 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 tries to work around 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 backporting Mojang's change in 1.17 which makes it so that the biome (generated by the seed) is checked first if the feature can be generated before actually to load the chunk. 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 18781133bfbe5d3aa12ba54a9c7826a8bc7cd0ac..35387d1154dd10a83ad0c66bb749523fb4333edc 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -335,6 +335,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 5c992812e0c066109763a30c9399e5b71a335398..fddcd205ee4d841546463913f56f998059cba248 100644 --- a/src/main/java/net/minecraft/server/BiomeManager.java +++ b/src/main/java/net/minecraft/server/BiomeManager.java @@ -22,6 +22,7 @@ public class BiomeManager { 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 dcaf9f8574a9c913b64ba3a1d8b02220db720225..271fddbbf73ca5c0e4e2722d7246c14b778d6072 100644 --- a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java +++ b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java @@ -67,10 +67,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 c3bd58069d8dbdf36f70f1dafd7c24000f31708b..a62c87bceab2c9700a7b3925f208b0ffa2b9b393 100644 --- a/src/main/java/net/minecraft/server/StructureGenerator.java +++ b/src/main/java/net/minecraft/server/StructureGenerator.java @@ -143,6 +143,14 @@ public abstract class StructureGenerator int j2 = i1 + k * l1; ChunkCoordIntPair chunkcoordintpair = this.a(structuresettingsfeature, j, seededrandom, i2, j2); if (!iworldreader.getWorldBorder().isChunkInBounds(chunkcoordintpair.x, chunkcoordintpair.z)) { continue; } // Paper + // Paper start - seed based feature search + if (structuremanager.getWorld().paperConfig.seedBasedFeatureSearch) { + BiomeBase biomeBase = structuremanager.getWorld().getBiomeManager().getBiome(new BlockPosition(chunkcoordintpair.getBlockX() + 9, 0, chunkcoordintpair.getBlockZ() + 9)); + if (!biomeBase.e().a(this)) { + continue; + } + } + // Paper end IChunkAccess ichunkaccess = iworldreader.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z, ChunkStatus.STRUCTURE_STARTS); StructureStart structurestart = structuremanager.a(SectionPosition.a(ichunkaccess.getPos(), 0), this, ichunkaccess); diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java index 822b587cc92bb25ec8618fd9d86ce2c9233a69b6..9ed21f434c5fb019b74dfe9ee0b802ccc5c07fd8 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -1451,8 +1451,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; }