001package net.minecraft.world.storage;
002
003import java.io.DataInputStream;
004import java.io.DataOutputStream;
005import java.io.File;
006import java.io.FileInputStream;
007import java.io.FileOutputStream;
008import java.util.ArrayList;
009import java.util.HashMap;
010import java.util.Iterator;
011import java.util.List;
012import java.util.Map;
013import net.minecraft.nbt.CompressedStreamTools;
014import net.minecraft.nbt.NBTBase;
015import net.minecraft.nbt.NBTTagCompound;
016import net.minecraft.nbt.NBTTagShort;
017import net.minecraft.world.WorldSavedData;
018
019public class MapStorage
020{
021    private ISaveHandler saveHandler;
022
023    /** Map of item data String id to loaded MapDataBases */
024    private Map loadedDataMap = new HashMap();
025
026    /** List of loaded MapDataBases. */
027    private List loadedDataList = new ArrayList();
028
029    /**
030     * Map of MapDataBase id String prefixes ('map' etc) to max known unique Short id (the 0 part etc) for that prefix
031     */
032    private Map idCounts = new HashMap();
033
034    public MapStorage(ISaveHandler par1ISaveHandler)
035    {
036        this.saveHandler = par1ISaveHandler;
037        this.loadIdCounts();
038    }
039
040    /**
041     * Loads an existing MapDataBase corresponding to the given String id from disk, instantiating the given Class, or
042     * returns null if none such file exists. args: Class to instantiate, String dataid
043     */
044    public WorldSavedData loadData(Class par1Class, String par2Str)
045    {
046        WorldSavedData worldsaveddata = (WorldSavedData)this.loadedDataMap.get(par2Str);
047
048        if (worldsaveddata != null)
049        {
050            return worldsaveddata;
051        }
052        else
053        {
054            if (this.saveHandler != null)
055            {
056                try
057                {
058                    File file1 = this.saveHandler.getMapFileFromName(par2Str);
059
060                    if (file1 != null && file1.exists())
061                    {
062                        try
063                        {
064                            worldsaveddata = (WorldSavedData)par1Class.getConstructor(new Class[] {String.class}).newInstance(new Object[] {par2Str});
065                        }
066                        catch (Exception exception)
067                        {
068                            throw new RuntimeException("Failed to instantiate " + par1Class.toString(), exception);
069                        }
070
071                        FileInputStream fileinputstream = new FileInputStream(file1);
072                        NBTTagCompound nbttagcompound = CompressedStreamTools.readCompressed(fileinputstream);
073                        fileinputstream.close();
074                        worldsaveddata.readFromNBT(nbttagcompound.getCompoundTag("data"));
075                    }
076                }
077                catch (Exception exception1)
078                {
079                    exception1.printStackTrace();
080                }
081            }
082
083            if (worldsaveddata != null)
084            {
085                this.loadedDataMap.put(par2Str, worldsaveddata);
086                this.loadedDataList.add(worldsaveddata);
087            }
088
089            return worldsaveddata;
090        }
091    }
092
093    /**
094     * Assigns the given String id to the given MapDataBase, removing any existing ones of the same id.
095     */
096    public void setData(String par1Str, WorldSavedData par2WorldSavedData)
097    {
098        if (par2WorldSavedData == null)
099        {
100            throw new RuntimeException("Can\'t set null data");
101        }
102        else
103        {
104            if (this.loadedDataMap.containsKey(par1Str))
105            {
106                this.loadedDataList.remove(this.loadedDataMap.remove(par1Str));
107            }
108
109            this.loadedDataMap.put(par1Str, par2WorldSavedData);
110            this.loadedDataList.add(par2WorldSavedData);
111        }
112    }
113
114    /**
115     * Saves all dirty loaded MapDataBases to disk.
116     */
117    public void saveAllData()
118    {
119        for (int i = 0; i < this.loadedDataList.size(); ++i)
120        {
121            WorldSavedData worldsaveddata = (WorldSavedData)this.loadedDataList.get(i);
122
123            if (worldsaveddata.isDirty())
124            {
125                this.saveData(worldsaveddata);
126                worldsaveddata.setDirty(false);
127            }
128        }
129    }
130
131    /**
132     * Saves the given MapDataBase to disk.
133     */
134    private void saveData(WorldSavedData par1WorldSavedData)
135    {
136        if (this.saveHandler != null)
137        {
138            try
139            {
140                File file1 = this.saveHandler.getMapFileFromName(par1WorldSavedData.mapName);
141
142                if (file1 != null)
143                {
144                    NBTTagCompound nbttagcompound = new NBTTagCompound();
145                    par1WorldSavedData.writeToNBT(nbttagcompound);
146                    NBTTagCompound nbttagcompound1 = new NBTTagCompound();
147                    nbttagcompound1.setCompoundTag("data", nbttagcompound);
148                    FileOutputStream fileoutputstream = new FileOutputStream(file1);
149                    CompressedStreamTools.writeCompressed(nbttagcompound1, fileoutputstream);
150                    fileoutputstream.close();
151                }
152            }
153            catch (Exception exception)
154            {
155                exception.printStackTrace();
156            }
157        }
158    }
159
160    /**
161     * Loads the idCounts Map from the 'idcounts' file.
162     */
163    private void loadIdCounts()
164    {
165        try
166        {
167            this.idCounts.clear();
168
169            if (this.saveHandler == null)
170            {
171                return;
172            }
173
174            File file1 = this.saveHandler.getMapFileFromName("idcounts");
175
176            if (file1 != null && file1.exists())
177            {
178                DataInputStream datainputstream = new DataInputStream(new FileInputStream(file1));
179                NBTTagCompound nbttagcompound = CompressedStreamTools.read(datainputstream);
180                datainputstream.close();
181                Iterator iterator = nbttagcompound.getTags().iterator();
182
183                while (iterator.hasNext())
184                {
185                    NBTBase nbtbase = (NBTBase)iterator.next();
186
187                    if (nbtbase instanceof NBTTagShort)
188                    {
189                        NBTTagShort nbttagshort = (NBTTagShort)nbtbase;
190                        String s = nbttagshort.getName();
191                        short short1 = nbttagshort.data;
192                        this.idCounts.put(s, Short.valueOf(short1));
193                    }
194                }
195            }
196        }
197        catch (Exception exception)
198        {
199            exception.printStackTrace();
200        }
201    }
202
203    /**
204     * Returns an unique new data id for the given prefix and saves the idCounts map to the 'idcounts' file.
205     */
206    public int getUniqueDataId(String par1Str)
207    {
208        Short oshort = (Short)this.idCounts.get(par1Str);
209
210        if (oshort == null)
211        {
212            oshort = Short.valueOf((short)0);
213        }
214        else
215        {
216            oshort = Short.valueOf((short)(oshort.shortValue() + 1));
217        }
218
219        this.idCounts.put(par1Str, oshort);
220
221        if (this.saveHandler == null)
222        {
223            return oshort.shortValue();
224        }
225        else
226        {
227            try
228            {
229                File file1 = this.saveHandler.getMapFileFromName("idcounts");
230
231                if (file1 != null)
232                {
233                    NBTTagCompound nbttagcompound = new NBTTagCompound();
234                    Iterator iterator = this.idCounts.keySet().iterator();
235
236                    while (iterator.hasNext())
237                    {
238                        String s1 = (String)iterator.next();
239                        short short1 = ((Short)this.idCounts.get(s1)).shortValue();
240                        nbttagcompound.setShort(s1, short1);
241                    }
242
243                    DataOutputStream dataoutputstream = new DataOutputStream(new FileOutputStream(file1));
244                    CompressedStreamTools.write(nbttagcompound, dataoutputstream);
245                    dataoutputstream.close();
246                }
247            }
248            catch (Exception exception)
249            {
250                exception.printStackTrace();
251            }
252
253            return oshort.shortValue();
254        }
255    }
256}