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 }