001    package net.minecraftforge.common;
002    
003    import java.util.ArrayList;
004    import java.util.Hashtable;
005    import java.util.Map;
006    import java.util.Map.Entry;
007    import java.util.logging.Level;
008    
009    import com.google.common.collect.ArrayListMultimap;
010    import com.google.common.collect.ImmutableListMultimap;
011    import com.google.common.collect.ListMultimap;
012    import com.google.common.collect.Maps;
013    
014    import cpw.mods.fml.common.FMLCommonHandler;
015    
016    import net.minecraft.server.MinecraftServer;
017    import net.minecraft.src.*;
018    
019    public class DimensionManager
020    {
021        private static Hashtable<Integer, Class<? extends WorldProvider>> providers = new Hashtable<Integer, Class<? extends WorldProvider>>();
022        private static Hashtable<Integer, Boolean> spawnSettings = new Hashtable<Integer, Boolean>();
023        private static Hashtable<Integer, WorldServer> worlds = new Hashtable<Integer, WorldServer>();
024        private static boolean hasInit = false;
025        private static Hashtable<Integer, Integer> dimensions = new Hashtable<Integer, Integer>();
026        private static Map<World, ListMultimap<ChunkCoordIntPair, String>> persistentChunkStore = Maps.newHashMap();
027    
028        public static boolean registerProviderType(int id, Class<? extends WorldProvider> provider, boolean keepLoaded)
029        {
030            if (providers.containsValue(id))
031            {
032                return false;
033            }
034            providers.put(id, provider);
035            spawnSettings.put(id, keepLoaded);
036            return true;
037        }
038    
039        public static void init()
040        {
041            if (hasInit)
042            {
043                return;
044            }
045            registerProviderType( 0, WorldProviderSurface.class, true);
046            registerProviderType(-1, WorldProviderHell.class,    true);
047            registerProviderType( 1, WorldProviderEnd.class,     false);
048            registerDimension( 0,  0);
049            registerDimension(-1, -1);
050            registerDimension( 1,  1);
051        }
052    
053        public static void registerDimension(int id, int providerType)
054        {
055            if (!providers.containsKey(providerType))
056            {
057                throw new IllegalArgumentException(String.format("Failed to register dimensiuon for id %d, provider type %d does not exist", id, providerType));
058            }
059            if (dimensions.containsKey(id))
060            {
061                throw new IllegalArgumentException(String.format("Failed to register dimensiuon for id %d, One is already registered", id));
062            }
063            dimensions.put(id, providerType);
064        }
065    
066        public static int getProviderType(int dim)
067        {
068            if (!dimensions.containsKey(dim))
069            {
070                throw new IllegalArgumentException(String.format("Could not get provider type for dimension %d, does not exist", dim));
071            }
072            return dimensions.get(dim);
073        }
074    
075        public static WorldProvider getProvider(int dim)
076        {
077            return getWorld(dim).provider;
078        }
079    
080        public static Integer[] getIDs()
081        {
082            return dimensions.keySet().toArray(new Integer[0]);
083        }
084    
085        public static void setWorld(int id, WorldServer world)
086        {
087            worlds.put(id, world);
088    
089            ArrayList<WorldServer> tmp = new ArrayList<WorldServer>();
090            tmp.add(worlds.get( 0));
091            tmp.add(worlds.get(-1));
092            tmp.add(worlds.get( 1));
093    
094            for (Entry<Integer, WorldServer> entry : worlds.entrySet())
095            {
096                int dim = entry.getKey();
097                if (dim >= -1 && dim <= 1)
098                {
099                    continue;
100                }
101                tmp.add(entry.getValue());
102            }
103    
104            MinecraftServer.getServer().worldServers = tmp.toArray(new WorldServer[0]);
105            MinecraftServer.getServer().worldTickTimes.put(id, new long[100]);
106        }
107    
108        public static WorldServer getWorld(int id)
109        {
110            return worlds.get(id);
111        }
112    
113        public static WorldServer[] getWorlds()
114        {
115            return worlds.values().toArray(new WorldServer[0]);
116        }
117    
118        public static boolean shouldLoadSpawn(int dim)
119        {
120            int id = getProviderType(dim);
121            return spawnSettings.contains(id) && spawnSettings.get(id);
122        }
123    
124        static
125        {
126            init();
127        }
128    
129        public static WorldProvider createProviderFor(int dim)
130        {
131            try
132            {
133                if (dimensions.containsKey(dim))
134                {
135                    WorldProvider provider = providers.get(getProviderType(dim)).newInstance();
136                    provider.setDimension(dim);
137                    return provider;
138                }
139                else
140                {
141                    return null;
142                }
143            }
144            catch (Exception e)
145            {
146                FMLCommonHandler.instance().getFMLLogger().log(Level.SEVERE,String.format("An error occured trying to create an instance of WorldProvider %d (%s)",
147                        dim, providers.get(getProviderType(dim)).getSimpleName()),e);
148                throw new RuntimeException(e);
149            }
150        }
151    }