From 33680168b1aaa776f384a20a46a403784858e7d3 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 f3f2a0b69..6f76351b8 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.logging.Logger;
@@ -20,6 +21,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;
@@ -355,4 +357,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 9b2703fd2..ef49fc258 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -350,7 +350,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
             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 33d878378..b9cc0e898 100644
--- a/src/main/java/net/minecraft/server/WorldData.java
+++ b/src/main/java/net/minecraft/server/WorldData.java
@@ -110,7 +110,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 93a8f4cdf..d43f8ce9a 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -987,7 +987,7 @@ public final class CraftServer implements Server {
         WorldData worlddata = sdm.getWorldData();
         WorldSettings worldSettings = null;
         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.20.0