<commit_before>--- ../src_base/common/net/minecraft/server/MinecraftServer.java
+++ ../src_work/common/net/minecraft/server/MinecraftServer.java
@@ -9,6 +9,7 @@
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.logging.Level;
@@ -70,6 +71,9 @@
 import net.minecraft.src.WorldServerMulti;
 import net.minecraft.src.WorldSettings;
 import net.minecraft.src.WorldType;
+import net.minecraftforge.common.DimensionManager;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.event.world.WorldEvent;
 
 public abstract class MinecraftServer implements ICommandSender, Runnable, IPlayerUsage
 {
@@ -151,7 +155,8 @@
     public final long[] tickTimeArray = new long[100];
 
     /** Stats are [dimension][tick%100] system.nanoTime is stored. */
-    public long[][] timeOfLastDimensionTick;
+    //public long[][] timeOfLastDimensionTick;
+    public Hashtable<Integer, long[]> worldTickTimes = new Hashtable<Integer, long[]>();
     private KeyPair serverKeyPair;
 
     /** Username of the server owner (for integrated servers) */
@@ -242,8 +247,6 @@
     {
         this.convertMapIfNeeded(par1Str);
         this.setUserMessage("menu.loadingLevel");
-        this.worldServers = new WorldServer[3];
-        this.timeOfLastDimensionTick = new long[this.worldServers.length][100];
         ISaveHandler var7 = this.anvilConverterForAnvilFile.getSaveLoader(par1Str, true);
         WorldInfo var9 = var7.loadWorldInfo();
         WorldSettings var8;
@@ -263,46 +266,23 @@
             var8.enableBonusChest();
         }
 
-        for (int var10 = 0; var10 < this.worldServers.length; ++var10)
-        {
-            byte var11 = 0;
-
-            if (var10 == 1)
-            {
-                var11 = -1;
-            }
-
-            if (var10 == 2)
-            {
-                var11 = 1;
-            }
-
-            if (var10 == 0)
-            {
-                if (this.isDemo())
-                {
-                    this.worldServers[var10] = new DemoWorldServer(this, var7, par2Str, var11, this.theProfiler);
-                }
-                else
-                {
-                    this.worldServers[var10] = new WorldServer(this, var7, par2Str, var11, var8, this.theProfiler);
-                }
-            }
-            else
-            {
-                this.worldServers[var10] = new WorldServerMulti(this, var7, par2Str, var11, var8, this.worldServers[0], this.theProfiler);
-            }
-
-            this.worldServers[var10].addWorldAccess(new WorldManager(this, this.worldServers[var10]));
+        WorldServer overWorld = (isDemo() ? new DemoWorldServer(this, var7, par2Str, 0, theProfiler) : new WorldServer(this, var7, par2Str, 0, var8, theProfiler));
+        for (int dim : DimensionManager.getStaticDimensionIDs())
+        {
+            WorldServer world = (dim == 0 ? overWorld : new WorldServerMulti(this, var7, par2Str, dim, var8, overWorld, theProfiler));
+            world.addWorldAccess(new WorldManager(this, world));
 
             if (!this.isSinglePlayer())
             {
-                this.worldServers[var10].getWorldInfo().setGameType(this.getGameType());
+                world.getWorldInfo().setGameType(this.getGameType());
             }
 
             this.serverConfigManager.setPlayerManager(this.worldServers);
-        }
-
+
+            MinecraftForge.EVENT_BUS.post(new WorldEvent.Load(world));
+        }
+
+        this.serverConfigManager.setPlayerManager(new WorldServer[]{ overWorld });
         this.setDifficultyForAllWorlds(this.getDifficulty());
         this.initialWorldChunkLoad();
     }
@@ -431,7 +411,9 @@
             for (int var1 = 0; var1 < this.worldServers.length; ++var1)
             {
                 WorldServer var2 = this.worldServers[var1];
+                MinecraftForge.EVENT_BUS.post(new WorldEvent.Unload(var2));
                 var2.flush();
+                DimensionManager.setWorld(var2.provider.dimensionId, null);
             }
 
             if (this.usageSnooper != null && this.usageSnooper.isSnooperRunning())
@@ -645,13 +627,15 @@
         this.theProfiler.startSection("levels");
         int var1;
 
-        for (var1 = 0; var1 < this.worldServers.length; ++var1)
-        {
+        Integer[] ids = DimensionManager.getIDs();
+        for (int x = 0; x < ids.length; x++)
+        {
+            int id = ids[x];
             long var2 = System.nanoTime();
 
-            if (var1 == 0 || this.getAllowNether())
-            {
-                WorldServer var4 = this.worldServers[var1];
+            if (id == 0 || this.getAllowNether())
+            {
+                WorldServer var4 = DimensionManager.getWorld(id);
                 this.theProfiler.startSection(var4.getWorldInfo().getWorldName());
                 this.theProfiler.startSection("pools");
                 var4.getWorldVec3Pool().clear();
@@ -698,9 +682,11 @@
                 this.theProfiler.endSection();
             }
 
-            this.timeOfLastDimensionTick[var1][this.tickCounter % 100] = System.nanoTime() - var2;
-        }
-
+            worldTickTimes.get(id)[this.tickCounter % 100] = System.nanoTime() - var2;
+        }
+
+        this.theProfiler.endStartSection("dim_unloading");
+        DimensionManager.unloadWorlds(worldTickTimes);
         this.theProfiler.endStartSection("connection");
         this.getNetworkThread().networkTick();
         this.theProfiler.endStartSection("players");
@@ -754,7 +740,13 @@
      */
     public WorldServer worldServerForDimension(int par1)
     {
-        return par1 == -1 ? this.worldServers[1] : (par1 == 1 ? this.worldServers[2] : this.worldServers[0]);
+        WorldServer ret = DimensionManager.getWorld(par1);
+        if (ret == null)
+        {
+            DimensionManager.initDimension(par1);
+            ret = DimensionManager.getWorld(par1);
+        }
+        return ret;
     }
 
     @SideOnly(Side.SERVER)
@@ -863,7 +855,7 @@
 
     public String getServerModName()
     {
-        return "vanilla";
+        return "forge,fml";
     }
 
     /**
@@ -1125,6 +1117,7 @@
 
             if (var2 != null)
             {
+                MinecraftForge.EVENT_BUS.post(new WorldEvent.Unload(var2));
                 var2.flush();
             }
         }<commit_msg>Fix issue where worlds were potentially unloaded improperly on server shutdown.<commit_after>--- ../src_base/common/net/minecraft/server/MinecraftServer.java
+++ ../src_work/common/net/minecraft/server/MinecraftServer.java
@@ -9,6 +9,7 @@
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.logging.Level;
@@ -70,6 +71,9 @@
 import net.minecraft.src.WorldServerMulti;
 import net.minecraft.src.WorldSettings;
 import net.minecraft.src.WorldType;
+import net.minecraftforge.common.DimensionManager;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.event.world.WorldEvent;
 
 public abstract class MinecraftServer implements ICommandSender, Runnable, IPlayerUsage
 {
@@ -151,7 +155,8 @@
     public final long[] tickTimeArray = new long[100];
 
     /** Stats are [dimension][tick%100] system.nanoTime is stored. */
-    public long[][] timeOfLastDimensionTick;
+    //public long[][] timeOfLastDimensionTick;
+    public Hashtable<Integer, long[]> worldTickTimes = new Hashtable<Integer, long[]>();
     private KeyPair serverKeyPair;
 
     /** Username of the server owner (for integrated servers) */
@@ -242,8 +247,6 @@
     {
         this.convertMapIfNeeded(par1Str);
         this.setUserMessage("menu.loadingLevel");
-        this.worldServers = new WorldServer[3];
-        this.timeOfLastDimensionTick = new long[this.worldServers.length][100];
         ISaveHandler var7 = this.anvilConverterForAnvilFile.getSaveLoader(par1Str, true);
         WorldInfo var9 = var7.loadWorldInfo();
         WorldSettings var8;
@@ -263,46 +266,23 @@
             var8.enableBonusChest();
         }
 
-        for (int var10 = 0; var10 < this.worldServers.length; ++var10)
-        {
-            byte var11 = 0;
-
-            if (var10 == 1)
-            {
-                var11 = -1;
-            }
-
-            if (var10 == 2)
-            {
-                var11 = 1;
-            }
-
-            if (var10 == 0)
-            {
-                if (this.isDemo())
-                {
-                    this.worldServers[var10] = new DemoWorldServer(this, var7, par2Str, var11, this.theProfiler);
-                }
-                else
-                {
-                    this.worldServers[var10] = new WorldServer(this, var7, par2Str, var11, var8, this.theProfiler);
-                }
-            }
-            else
-            {
-                this.worldServers[var10] = new WorldServerMulti(this, var7, par2Str, var11, var8, this.worldServers[0], this.theProfiler);
-            }
-
-            this.worldServers[var10].addWorldAccess(new WorldManager(this, this.worldServers[var10]));
+        WorldServer overWorld = (isDemo() ? new DemoWorldServer(this, var7, par2Str, 0, theProfiler) : new WorldServer(this, var7, par2Str, 0, var8, theProfiler));
+        for (int dim : DimensionManager.getStaticDimensionIDs())
+        {
+            WorldServer world = (dim == 0 ? overWorld : new WorldServerMulti(this, var7, par2Str, dim, var8, overWorld, theProfiler));
+            world.addWorldAccess(new WorldManager(this, world));
 
             if (!this.isSinglePlayer())
             {
-                this.worldServers[var10].getWorldInfo().setGameType(this.getGameType());
+                world.getWorldInfo().setGameType(this.getGameType());
             }
 
             this.serverConfigManager.setPlayerManager(this.worldServers);
-        }
-
+
+            MinecraftForge.EVENT_BUS.post(new WorldEvent.Load(world));
+        }
+
+        this.serverConfigManager.setPlayerManager(new WorldServer[]{ overWorld });
         this.setDifficultyForAllWorlds(this.getDifficulty());
         this.initialWorldChunkLoad();
     }
@@ -431,7 +411,14 @@
             for (int var1 = 0; var1 < this.worldServers.length; ++var1)
             {
                 WorldServer var2 = this.worldServers[var1];
+                MinecraftForge.EVENT_BUS.post(new WorldEvent.Unload(var2));
                 var2.flush();
+            }
+
+            WorldServer[] tmp = worldServers;
+            for (WorldServer world : tmp)
+            {
+                DimensionManager.setWorld(world.provider.dimensionId, null);
             }
 
             if (this.usageSnooper != null && this.usageSnooper.isSnooperRunning())
@@ -645,13 +632,15 @@
         this.theProfiler.startSection("levels");
         int var1;
 
-        for (var1 = 0; var1 < this.worldServers.length; ++var1)
-        {
+        Integer[] ids = DimensionManager.getIDs();
+        for (int x = 0; x < ids.length; x++)
+        {
+            int id = ids[x];
             long var2 = System.nanoTime();
 
-            if (var1 == 0 || this.getAllowNether())
-            {
-                WorldServer var4 = this.worldServers[var1];
+            if (id == 0 || this.getAllowNether())
+            {
+                WorldServer var4 = DimensionManager.getWorld(id);
                 this.theProfiler.startSection(var4.getWorldInfo().getWorldName());
                 this.theProfiler.startSection("pools");
                 var4.getWorldVec3Pool().clear();
@@ -698,9 +687,11 @@
                 this.theProfiler.endSection();
             }
 
-            this.timeOfLastDimensionTick[var1][this.tickCounter % 100] = System.nanoTime() - var2;
-        }
-
+            worldTickTimes.get(id)[this.tickCounter % 100] = System.nanoTime() - var2;
+        }
+
+        this.theProfiler.endStartSection("dim_unloading");
+        DimensionManager.unloadWorlds(worldTickTimes);
         this.theProfiler.endStartSection("connection");
         this.getNetworkThread().networkTick();
         this.theProfiler.endStartSection("players");
@@ -754,7 +745,13 @@
      */
     public WorldServer worldServerForDimension(int par1)
     {
-        return par1 == -1 ? this.worldServers[1] : (par1 == 1 ? this.worldServers[2] : this.worldServers[0]);
+        WorldServer ret = DimensionManager.getWorld(par1);
+        if (ret == null)
+        {
+            DimensionManager.initDimension(par1);
+            ret = DimensionManager.getWorld(par1);
+        }
+        return ret;
     }
 
     @SideOnly(Side.SERVER)
@@ -863,7 +860,7 @@
 
     public String getServerModName()
     {
-        return "vanilla";
+        return "forge,fml";
     }
 
     /**
@@ -1125,6 +1122,7 @@
 
             if (var2 != null)
             {
+                MinecraftForge.EVENT_BUS.post(new WorldEvent.Unload(var2));
                 var2.flush();
             }
         }
{'fraction_non_alphanumeric': 0.13447639550976473, 'fraction_numerical': 0.03352298938951253, 'mean_word_length': 2.0822274881516587, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4331827', 'n_tokens_mistral': 4244, 'n_tokens_neox': 3992, 'n_words': 671}