    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}