From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 28 Jun 2020 03:59:10 -0400
Subject: [PATCH] Fix Per World Difficulty / Remembering Difficulty

Fixes per world difficulty with /difficulty command and also
makes it so that the server keeps the last difficulty used instead
of restoring the server.properties every single load.

diff --git a/src/main/java/net/minecraft/server/CommandDifficulty.java b/src/main/java/net/minecraft/server/CommandDifficulty.java
index bc71070c670d1a64c60b9f19711a5e8a50ace56e..9efc743e028650ccc9cda5a2c9deb1836253b91d 100644
--- a/src/main/java/net/minecraft/server/CommandDifficulty.java
+++ b/src/main/java/net/minecraft/server/CommandDifficulty.java
@@ -36,10 +36,11 @@ public class CommandDifficulty {
     public static int a(CommandListenerWrapper commandlistenerwrapper, EnumDifficulty enumdifficulty) throws CommandSyntaxException {
         MinecraftServer minecraftserver = commandlistenerwrapper.getServer();
 
-        if (minecraftserver.getSaveData().getDifficulty() == enumdifficulty) {
+        WorldServer world = commandlistenerwrapper.getWorld(); // Paper
+        if (world.worldDataServer.getDifficulty() == enumdifficulty) { // Paper
             throw CommandDifficulty.a.create(enumdifficulty.c());
         } else {
-            minecraftserver.a(enumdifficulty, true);
+            minecraftserver.a(world, enumdifficulty, true); // Paper
             commandlistenerwrapper.sendMessage(new ChatMessage("commands.difficulty.success", new Object[]{enumdifficulty.b()}), true);
             return 0;
         }
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
index f5792b999ce42acb13ae9a62ceb2ddec39abe209..5504facd2e453238caa71d98743be5416d4dd4fe 100644
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
@@ -323,7 +323,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
 
     @Override
     public void updateWorldSettings() {
-        this.a(this.getDedicatedServerProperties().difficulty, true);
+        //this.a(this.getDedicatedServerProperties().difficulty, true); // Paper - Don't overwrite level.dat's difficulty, keep current
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index c249a1c3bc9013a1e769d026f4826a8edb31f076..1aabd16cd23a2bcdd6e29de63fca36226c05c428 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1525,11 +1525,14 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
         }
     }
 
-    public void a(EnumDifficulty enumdifficulty, boolean flag) {
-        if (flag || !this.saveData.isDifficultyLocked()) {
-            this.saveData.setDifficulty(this.saveData.isHardcore() ? EnumDifficulty.HARD : enumdifficulty);
-            this.bc();
-            this.getPlayerList().getPlayers().forEach(this::b);
+    // Paper start - fix per world difficulty
+    public void a(WorldServer world, EnumDifficulty enumdifficulty, boolean flag) {
+        WorldDataServer worldData = world.worldDataServer;
+        if (flag || !worldData.isDifficultyLocked()) {
+            worldData.setDifficulty(worldData.isHardcore() ? EnumDifficulty.HARD : enumdifficulty);
+            world.setSpawnFlags(worldData.getDifficulty() != EnumDifficulty.PEACEFUL && ((DedicatedServer)this).propertyManager.getProperties().spawnMonsters, this.getSpawnAnimals());
+            //world.players.forEach(this::b);
+            // Paper end
         }
     }
 
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
index d01950720cb769ad13713812abee32d05edfa46d..8a07a7de26308ceb01aaeb54f1dddfe0a3565564 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -2874,7 +2874,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
     public void a(PacketPlayInDifficultyChange packetplayindifficultychange) {
         PlayerConnectionUtils.ensureMainThread(packetplayindifficultychange, this, this.player.getWorldServer());
         if (this.player.k(2) || this.isExemptPlayer()) {
-            this.minecraftServer.a(packetplayindifficultychange.b(), false);
+            //this.minecraftServer.a(packetplayindifficultychange.b(), false); // Paper - don't allow clients to change this
         }
     }