001    package net.minecraft.src;
002    
003    import cpw.mods.fml.common.Side;
004    import cpw.mods.fml.common.asm.SideOnly;
005    import java.io.DataInputStream;
006    import java.io.DataOutputStream;
007    import java.io.File;
008    import java.io.IOException;
009    import java.util.ArrayList;
010    import java.util.Collection;
011    import java.util.Collections;
012    import java.util.Iterator;
013    import java.util.List;
014    
015    public class AnvilSaveConverter extends SaveFormatOld
016    {
017        public AnvilSaveConverter(File par1File)
018        {
019            super(par1File);
020        }
021    
022        @SideOnly(Side.CLIENT)
023        public List getSaveList()
024        {
025            ArrayList var1 = new ArrayList();
026            File[] var2 = this.savesDirectory.listFiles();
027            File[] var3 = var2;
028            int var4 = var2.length;
029    
030            for (int var5 = 0; var5 < var4; ++var5)
031            {
032                File var6 = var3[var5];
033    
034                if (var6.isDirectory())
035                {
036                    String var7 = var6.getName();
037                    WorldInfo var8 = this.getWorldInfo(var7);
038    
039                    if (var8 != null && (var8.getSaveVersion() == 19132 || var8.getSaveVersion() == 19133))
040                    {
041                        boolean var9 = var8.getSaveVersion() != this.getSaveVersion();
042                        String var10 = var8.getWorldName();
043    
044                        if (var10 == null || MathHelper.stringNullOrLengthZero(var10))
045                        {
046                            var10 = var7;
047                        }
048    
049                        long var11 = 0L;
050                        var1.add(new SaveFormatComparator(var7, var10, var8.getLastTimePlayed(), var11, var8.getGameType(), var9, var8.isHardcoreModeEnabled(), var8.areCommandsAllowed()));
051                    }
052                }
053            }
054    
055            return var1;
056        }
057    
058        protected int getSaveVersion()
059        {
060            return 19133;
061        }
062    
063        public void flushCache()
064        {
065            RegionFileCache.clearRegionFileReferences();
066        }
067    
068        /**
069         * Returns back a loader for the specified save directory
070         */
071        public ISaveHandler getSaveLoader(String par1Str, boolean par2)
072        {
073            return new AnvilSaveHandler(this.savesDirectory, par1Str, par2);
074        }
075    
076        /**
077         * Checks if the save directory uses the old map format
078         */
079        public boolean isOldMapFormat(String par1Str)
080        {
081            WorldInfo var2 = this.getWorldInfo(par1Str);
082            return var2 != null && var2.getSaveVersion() != this.getSaveVersion();
083        }
084    
085        /**
086         * Converts the specified map to the new map format. Args: worldName, loadingScreen
087         */
088        public boolean convertMapFormat(String par1Str, IProgressUpdate par2IProgressUpdate)
089        {
090            par2IProgressUpdate.setLoadingProgress(0);
091            ArrayList var3 = new ArrayList();
092            ArrayList var4 = new ArrayList();
093            ArrayList var5 = new ArrayList();
094            File var6 = new File(this.savesDirectory, par1Str);
095            File var7 = new File(var6, "DIM-1");
096            File var8 = new File(var6, "DIM1");
097            System.out.println("Scanning folders...");
098            this.addRegionFilesToCollection(var6, var3);
099    
100            if (var7.exists())
101            {
102                this.addRegionFilesToCollection(var7, var4);
103            }
104    
105            if (var8.exists())
106            {
107                this.addRegionFilesToCollection(var8, var5);
108            }
109    
110            int var9 = var3.size() + var4.size() + var5.size();
111            System.out.println("Total conversion count is " + var9);
112            WorldInfo var10 = this.getWorldInfo(par1Str);
113            Object var11 = null;
114    
115            if (var10.getTerrainType() == WorldType.FLAT)
116            {
117                var11 = new WorldChunkManagerHell(BiomeGenBase.plains, 0.5F, 0.5F);
118            }
119            else
120            {
121                var11 = new WorldChunkManager(var10.getSeed(), var10.getTerrainType());
122            }
123    
124            this.convertFile(new File(var6, "region"), var3, (WorldChunkManager)var11, 0, var9, par2IProgressUpdate);
125            this.convertFile(new File(var7, "region"), var4, new WorldChunkManagerHell(BiomeGenBase.hell, 1.0F, 0.0F), var3.size(), var9, par2IProgressUpdate);
126            this.convertFile(new File(var8, "region"), var5, new WorldChunkManagerHell(BiomeGenBase.sky, 0.5F, 0.0F), var3.size() + var4.size(), var9, par2IProgressUpdate);
127            var10.setSaveVersion(19133);
128    
129            if (var10.getTerrainType() == WorldType.DEFAULT_1_1)
130            {
131                var10.setTerrainType(WorldType.DEFAULT);
132            }
133    
134            this.createFile(par1Str);
135            ISaveHandler var12 = this.getSaveLoader(par1Str, false);
136            var12.saveWorldInfo(var10);
137            return true;
138        }
139    
140        /**
141         * par: filename for the level.dat_mcr backup
142         */
143        private void createFile(String par1Str)
144        {
145            File var2 = new File(this.savesDirectory, par1Str);
146    
147            if (!var2.exists())
148            {
149                System.out.println("Warning: Unable to create level.dat_mcr backup");
150            }
151            else
152            {
153                File var3 = new File(var2, "level.dat");
154    
155                if (!var3.exists())
156                {
157                    System.out.println("Warning: Unable to create level.dat_mcr backup");
158                }
159                else
160                {
161                    File var4 = new File(var2, "level.dat_mcr");
162    
163                    if (!var3.renameTo(var4))
164                    {
165                        System.out.println("Warning: Unable to create level.dat_mcr backup");
166                    }
167                }
168            }
169        }
170    
171        private void convertFile(File par1File, Iterable par2Iterable, WorldChunkManager par3WorldChunkManager, int par4, int par5, IProgressUpdate par6IProgressUpdate)
172        {
173            Iterator var7 = par2Iterable.iterator();
174    
175            while (var7.hasNext())
176            {
177                File var8 = (File)var7.next();
178                this.convertChunks(par1File, var8, par3WorldChunkManager, par4, par5, par6IProgressUpdate);
179                ++par4;
180                int var9 = (int)Math.round(100.0D * (double)par4 / (double)par5);
181                par6IProgressUpdate.setLoadingProgress(var9);
182            }
183        }
184    
185        /**
186         * copies a 32x32 chunk set from par2File to par1File, via AnvilConverterData
187         */
188        private void convertChunks(File par1File, File par2File, WorldChunkManager par3WorldChunkManager, int par4, int par5, IProgressUpdate par6IProgressUpdate)
189        {
190            try
191            {
192                String var7 = par2File.getName();
193                RegionFile var8 = new RegionFile(par2File);
194                RegionFile var9 = new RegionFile(new File(par1File, var7.substring(0, var7.length() - ".mcr".length()) + ".mca"));
195    
196                for (int var10 = 0; var10 < 32; ++var10)
197                {
198                    int var11;
199    
200                    for (var11 = 0; var11 < 32; ++var11)
201                    {
202                        if (var8.isChunkSaved(var10, var11) && !var9.isChunkSaved(var10, var11))
203                        {
204                            DataInputStream var12 = var8.getChunkDataInputStream(var10, var11);
205    
206                            if (var12 == null)
207                            {
208                                System.out.println("Failed to fetch input stream");
209                            }
210                            else
211                            {
212                                NBTTagCompound var13 = CompressedStreamTools.read(var12);
213                                var12.close();
214                                NBTTagCompound var14 = var13.getCompoundTag("Level");
215                                AnvilConverterData var15 = ChunkLoader.load(var14);
216                                NBTTagCompound var16 = new NBTTagCompound();
217                                NBTTagCompound var17 = new NBTTagCompound();
218                                var16.setTag("Level", var17);
219                                ChunkLoader.convertToAnvilFormat(var15, var17, par3WorldChunkManager);
220                                DataOutputStream var18 = var9.getChunkDataOutputStream(var10, var11);
221                                CompressedStreamTools.write(var16, var18);
222                                var18.close();
223                            }
224                        }
225                    }
226    
227                    var11 = (int)Math.round(100.0D * (double)(par4 * 1024) / (double)(par5 * 1024));
228                    int var20 = (int)Math.round(100.0D * (double)((var10 + 1) * 32 + par4 * 1024) / (double)(par5 * 1024));
229    
230                    if (var20 > var11)
231                    {
232                        par6IProgressUpdate.setLoadingProgress(var20);
233                    }
234                }
235    
236                var8.close();
237                var9.close();
238            }
239            catch (IOException var19)
240            {
241                var19.printStackTrace();
242            }
243        }
244    
245        /**
246         * filters the files in the par1 directory, and adds them to the par2 collections
247         */
248        private void addRegionFilesToCollection(File par1File, Collection par2Collection)
249        {
250            File var3 = new File(par1File, "region");
251            File[] var4 = var3.listFiles(new AnvilSaveConverterFileFilter(this));
252    
253            if (var4 != null)
254            {
255                Collections.addAll(par2Collection, var4);
256            }
257        }
258    }