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 }