From de69a052afbc2390ff58f9b67148837bd757d72f Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 17 Sep 2018 23:05:31 -0400
Subject: [PATCH] Support Overriding World Seeds

Allows you to add to paper.yml

seed-overrides:
  world_name: some seed value

This will ignore every where a seed is set/created/loaded and force
a world to use the specified seed.

This seed will end up being saved to the world data file, so it is
a permanent change in that it won't go back if you remove it from paper.yml

diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index 214b577b32..559e6b42ba 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -11,6 +11,7 @@ import java.lang.reflect.Modifier;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import java.util.logging.Level;
 import java.util.regex.Pattern;
@@ -19,6 +20,7 @@ import com.google.common.collect.Lists;
 import net.minecraft.server.MinecraftServer;
 import org.bukkit.Bukkit;
 import org.bukkit.command.Command;
+import org.bukkit.configuration.ConfigurationSection;
 import org.bukkit.configuration.InvalidConfigurationException;
 import org.bukkit.configuration.file.YamlConfiguration;
 import co.aikar.timings.Timings;
@@ -310,4 +312,23 @@ public class PaperConfig {
         }
         tabSpamLimit = getInt("settings.spam-limiter.tab-spam-limit", tabSpamLimit);
     }
+
+    public static Map<String, Long> seedOverride = new java.util.HashMap<>();
+    private static void worldSeedOverrides() {
+        ConfigurationSection seeds = config.getConfigurationSection("seed-overrides");
+        if (seeds != null) {
+            TimingsManager.hiddenConfigs.add("seed-overrides");
+            for (String key : seeds.getKeys(false)) {
+                String seedString = seeds.getString(key);
+                long seed;
+                try {
+                    seed = Long.parseLong(seedString);
+                } catch (Exception e) {
+                    seed = (long) seedString.hashCode();
+                }
+                log("Seed Override: " + key + " => " + seed);
+                seedOverride.put(key, seed);
+            }
+        }
+    }
 }
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 9e5fe97947..52ec526fc6 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -378,7 +378,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
             this.convertWorld(name); // Run conversion now
 
             org.bukkit.generator.ChunkGenerator gen = this.server.getGenerator(name);
-            WorldSettings worldsettings = new WorldSettings(i, this.getGamemode(), this.getGenerateStructures(), this.isHardcore(), worldtype);
+            WorldSettings worldsettings = new WorldSettings(com.destroystokyo.paper.PaperConfig.seedOverride.getOrDefault(name, i), this.getGamemode(), this.getGenerateStructures(), this.isHardcore(), worldtype); // Paper
             worldsettings.setGeneratorSettings(jsonelement);
 
             if (j == 0) {
diff --git a/src/main/java/net/minecraft/server/WorldData.java b/src/main/java/net/minecraft/server/WorldData.java
index 561b6d9469..95518e54d1 100644
--- a/src/main/java/net/minecraft/server/WorldData.java
+++ b/src/main/java/net/minecraft/server/WorldData.java
@@ -127,7 +127,7 @@ public class WorldData {
             this.d = nbttagcompound2.getBoolean("Snapshot");
         }
 
-        this.e = nbttagcompound.getLong("RandomSeed");
+        this.e = com.destroystokyo.paper.PaperConfig.seedOverride.getOrDefault(nbttagcompound.getString("LevelName"), nbttagcompound.getLong("RandomSeed")); // Paper
         if (nbttagcompound.hasKeyOfType("generatorName", 8)) {
             String s = nbttagcompound.getString("generatorName");
 
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 4cf2887904..f36b642466 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1015,7 +1015,7 @@ public final class CraftServer implements Server {
         WorldSettings worldSettings;
         // See MinecraftServer.a(String, String, long, WorldType, JsonElement)
         if (worlddata == null) {
-            worldSettings = new WorldSettings(creator.seed(), EnumGamemode.getById(getDefaultGameMode().getValue()), generateStructures, hardcore, type);
+            worldSettings = new WorldSettings(com.destroystokyo.paper.PaperConfig.seedOverride.getOrDefault(name, creator.seed()), EnumGamemode.getById(getDefaultGameMode().getValue()), generateStructures, hardcore, type); // Paper
             JsonElement parsedSettings = new JsonParser().parse(creator.generatorSettings());
             if (parsedSettings.isJsonObject()) {
                 worldSettings.setGeneratorSettings(parsedSettings.getAsJsonObject());
-- 
2.25.1