    001    package net.minecraft.nbt;
    002
    003    import java.io.DataInput;
    004    import java.io.DataOutput;
    005    import java.io.IOException;
    006    import java.util.Collection;
    007    import java.util.HashMap;
    008    import java.util.Iterator;
    009    import java.util.Map;
    010    import net.minecraft.crash.CrashReport;
    011    import net.minecraft.crash.CrashReportCategory;
    012    import net.minecraft.util.ReportedException;
    013
    014    public class NBTTagCompound extends NBTBase
    015    {
    016        /**
    017         * The key-value pairs for the tag. Each key is a UTF string, each value is a tag.
    018         */
    019        private Map tagMap = new HashMap();
    020
    021        public NBTTagCompound()
    022        {
    023            super("");
    024        }
    025
    026        public NBTTagCompound(String par1Str)
    027        {
    028            super(par1Str);
    029        }
    030
    031        /**
    032         * Write the actual data contents of the tag, implemented in NBT extension classes
    033         */
    034        void write(DataOutput par1DataOutput) throws IOException
    035        {
    036            Iterator var2 = this.tagMap.values().iterator();
    037
    038            while (var2.hasNext())
    039            {
    040                NBTBase var3 = (NBTBase)var2.next();
    041                NBTBase.writeNamedTag(var3, par1DataOutput);
    042            }
    043
    044            par1DataOutput.writeByte(0);
    045        }
    046
    047        /**
    048         * Read the actual data contents of the tag, implemented in NBT extension classes
    049         */
    050        void load(DataInput par1DataInput) throws IOException
    051        {
    052            this.tagMap.clear();
    053            NBTBase var2;
    054
    055            while ((var2 = NBTBase.readNamedTag(par1DataInput)).getId() != 0)
    056            {
    057                this.tagMap.put(var2.getName(), var2);
    058            }
    059        }
    060
    061        /**
    062         * Returns all the values in the tagMap HashMap.
    063         */
    064        public Collection getTags()
    065        {
    066            return this.tagMap.values();
    067        }
    068
    069        /**
    070         * Gets the type byte for the tag.
    071         */
    072        public byte getId()
    073        {
    074            return (byte)10;
    075        }
    076
    077        /**
    078         * Stores the given tag into the map with the given string key. This is mostly used to store tag lists.
    079         */
    080        public void setTag(String par1Str, NBTBase par2NBTBase)
    081        {
    082            this.tagMap.put(par1Str, par2NBTBase.setName(par1Str));
    083        }
    084
    085        /**
    086         * Stores a new NBTTagByte with the given byte value into the map with the given string key.
    087         */
    088        public void setByte(String par1Str, byte par2)
    089        {
    090            this.tagMap.put(par1Str, new NBTTagByte(par1Str, par2));
    091        }
    092
    093        /**
    094         * Stores a new NBTTagShort with the given short value into the map with the given string key.
    095         */
    096        public void setShort(String par1Str, short par2)
    097        {
    098            this.tagMap.put(par1Str, new NBTTagShort(par1Str, par2));
    099        }
    100
    101        /**
    102         * Stores a new NBTTagInt with the given integer value into the map with the given string key.
    103         */
    104        public void setInteger(String par1Str, int par2)
    105        {
    106            this.tagMap.put(par1Str, new NBTTagInt(par1Str, par2));
    107        }
    108
    109        /**
    110         * Stores a new NBTTagLong with the given long value into the map with the given string key.
    111         */
    112        public void setLong(String par1Str, long par2)
    113        {
    114            this.tagMap.put(par1Str, new NBTTagLong(par1Str, par2));
    115        }
    116
    117        /**
    118         * Stores a new NBTTagFloat with the given float value into the map with the given string key.
    119         */
    120        public void setFloat(String par1Str, float par2)
    121        {
    122            this.tagMap.put(par1Str, new NBTTagFloat(par1Str, par2));
    123        }
    124
    125        /**
    126         * Stores a new NBTTagDouble with the given double value into the map with the given string key.
    127         */
    128        public void setDouble(String par1Str, double par2)
    129        {
    130            this.tagMap.put(par1Str, new NBTTagDouble(par1Str, par2));
    131        }
    132
    133        /**
    134         * Stores a new NBTTagString with the given string value into the map with the given string key.
    135         */
    136        public void setString(String par1Str, String par2Str)
    137        {
    138            this.tagMap.put(par1Str, new NBTTagString(par1Str, par2Str));
    139        }
    140
    141        /**
    142         * Stores a new NBTTagByteArray with the given array as data into the map with the given string key.
    143         */
    144        public void setByteArray(String par1Str, byte[] par2ArrayOfByte)
    145        {
    146            this.tagMap.put(par1Str, new NBTTagByteArray(par1Str, par2ArrayOfByte));
    147        }
    148
    149        /**
    150         * Stores a new NBTTagIntArray with the given array as data into the map with the given string key.
    151         */
    152        public void setIntArray(String par1Str, int[] par2ArrayOfInteger)
    153        {
    154            this.tagMap.put(par1Str, new NBTTagIntArray(par1Str, par2ArrayOfInteger));
    155        }
    156
    157        /**
    158         * Stores the given NBTTagCompound into the map with the given string key.
    159         */
    160        public void setCompoundTag(String par1Str, NBTTagCompound par2NBTTagCompound)
    161        {
    162            this.tagMap.put(par1Str, par2NBTTagCompound.setName(par1Str));
    163        }
    164
    165        /**
    166         * Stores the given boolean value as a NBTTagByte, storing 1 for true and 0 for false, using the given string key.
    167         */
    168        public void setBoolean(String par1Str, boolean par2)
    169        {
    170            this.setByte(par1Str, (byte)(par2 ? 1 : 0));
    171        }
    172
    173        /**
    174         * gets a generic tag with the specified name
    175         */
    176        public NBTBase getTag(String par1Str)
    177        {
    178            return (NBTBase)this.tagMap.get(par1Str);
    179        }
    180
    181        /**
    182         * Returns whether the given string has been previously stored as a key in the map.
    183         */
    184        public boolean hasKey(String par1Str)
    185        {
    186            return this.tagMap.containsKey(par1Str);
    187        }
    188
    189        /**
    190         * Retrieves a byte value using the specified key, or 0 if no such key was stored.
    191         */
    192        public byte getByte(String par1Str)
    193        {
    194            try
    195            {
    196                return !this.tagMap.containsKey(par1Str) ? 0 : ((NBTTagByte)this.tagMap.get(par1Str)).data;
    197            }
    198            catch (ClassCastException var3)
    199            {
    200                throw new ReportedException(this.createCrashReport(par1Str, 1, var3));
    201            }
    202        }
    203
    204        /**
    205         * Retrieves a short value using the specified key, or 0 if no such key was stored.
    206         */
    207        public short getShort(String par1Str)
    208        {
    209            try
    210            {
    211                return !this.tagMap.containsKey(par1Str) ? 0 : ((NBTTagShort)this.tagMap.get(par1Str)).data;
    212            }
    213            catch (ClassCastException var3)
    214            {
    215                throw new ReportedException(this.createCrashReport(par1Str, 2, var3));
    216            }
    217        }
    218
    219        /**
    220         * Retrieves an integer value using the specified key, or 0 if no such key was stored.
    221         */
    222        public int getInteger(String par1Str)
    223        {
    224            try
    225            {
    226                return !this.tagMap.containsKey(par1Str) ? 0 : ((NBTTagInt)this.tagMap.get(par1Str)).data;
    227            }
    228            catch (ClassCastException var3)
    229            {
    230                throw new ReportedException(this.createCrashReport(par1Str, 3, var3));
    231            }
    232        }
    233
    234        /**
    235         * Retrieves a long value using the specified key, or 0 if no such key was stored.
    236         */
    237        public long getLong(String par1Str)
    238        {
    239            try
    240            {
    241                return !this.tagMap.containsKey(par1Str) ? 0L : ((NBTTagLong)this.tagMap.get(par1Str)).data;
    242            }
    243            catch (ClassCastException var3)
    244            {
    245                throw new ReportedException(this.createCrashReport(par1Str, 4, var3));
    246            }
    247        }
    248
    249        /**
    250         * Retrieves a float value using the specified key, or 0 if no such key was stored.
    251         */
    252        public float getFloat(String par1Str)
    253        {
    254            try
    255            {
    256                return !this.tagMap.containsKey(par1Str) ? 0.0F : ((NBTTagFloat)this.tagMap.get(par1Str)).data;
    257            }
    258            catch (ClassCastException var3)
    259            {
    260                throw new ReportedException(this.createCrashReport(par1Str, 5, var3));
    261            }
    262        }
    263
    264        /**
    265         * Retrieves a double value using the specified key, or 0 if no such key was stored.
    266         */
    267        public double getDouble(String par1Str)
    268        {
    269            try
    270            {
    271                return !this.tagMap.containsKey(par1Str) ? 0.0D : ((NBTTagDouble)this.tagMap.get(par1Str)).data;
    272            }
    273            catch (ClassCastException var3)
    274            {
    275                throw new ReportedException(this.createCrashReport(par1Str, 6, var3));
    276            }
    277        }
    278
    279        /**
    280         * Retrieves a string value using the specified key, or an empty string if no such key was stored.
    281         */
    282        public String getString(String par1Str)
    283        {
    284            try
    285            {
    286                return !this.tagMap.containsKey(par1Str) ? "" : ((NBTTagString)this.tagMap.get(par1Str)).data;
    287            }
    288            catch (ClassCastException var3)
    289            {
    290                throw new ReportedException(this.createCrashReport(par1Str, 8, var3));
    291            }
    292        }
    293
    294        /**
    295         * Retrieves a byte array using the specified key, or a zero-length array if no such key was stored.
    296         */
    297        public byte[] getByteArray(String par1Str)
    298        {
    299            try
    300            {
    301                return !this.tagMap.containsKey(par1Str) ? new byte[0] : ((NBTTagByteArray)this.tagMap.get(par1Str)).byteArray;
    302            }
    303            catch (ClassCastException var3)
    304            {
    305                throw new ReportedException(this.createCrashReport(par1Str, 7, var3));
    306            }
    307        }
    308
    309        /**
    310         * Retrieves an int array using the specified key, or a zero-length array if no such key was stored.
    311         */
    312        public int[] getIntArray(String par1Str)
    313        {
    314            try
    315            {
    316                return !this.tagMap.containsKey(par1Str) ? new int[0] : ((NBTTagIntArray)this.tagMap.get(par1Str)).intArray;
    317            }
    318            catch (ClassCastException var3)
    319            {
    320                throw new ReportedException(this.createCrashReport(par1Str, 11, var3));
    321            }
    322        }
    323
    324        /**
    325         * Retrieves a NBTTagCompound subtag matching the specified key, or a new empty NBTTagCompound if no such key was
    326         * stored.
    327         */
    328        public NBTTagCompound getCompoundTag(String par1Str)
    329        {
    330            try
    331            {
    332                return !this.tagMap.containsKey(par1Str) ? new NBTTagCompound(par1Str) : (NBTTagCompound)this.tagMap.get(par1Str);
    333            }
    334            catch (ClassCastException var3)
    335            {
    336                throw new ReportedException(this.createCrashReport(par1Str, 10, var3));
    337            }
    338        }
    339
    340        /**
    341         * Retrieves a NBTTagList subtag matching the specified key, or a new empty NBTTagList if no such key was stored.
    342         */
    343        public NBTTagList getTagList(String par1Str)
    344        {
    345            try
    346            {
    347                return !this.tagMap.containsKey(par1Str) ? new NBTTagList(par1Str) : (NBTTagList)this.tagMap.get(par1Str);
    348            }
    349            catch (ClassCastException var3)
    350            {
    351                throw new ReportedException(this.createCrashReport(par1Str, 9, var3));
    352            }
    353        }
    354
    355        /**
    356         * Retrieves a boolean value using the specified key, or false if no such key was stored. This uses the getByte
    357         * method.
    358         */
    359        public boolean getBoolean(String par1Str)
    360        {
    361            return this.getByte(par1Str) != 0;
    362        }
    363
    364        /**
    365         * Remove the specified tag.
    366         */
    367        public void removeTag(String par1Str)
    368        {
    369            this.tagMap.remove(par1Str);
    370        }
    371
    372        public String toString()
    373        {
    374            return "" + this.tagMap.size() + " entries";
    375        }
    376
    377        /**
    378         * Return whether this compound has no tags.
    379         */
    380        public boolean hasNoTags()
    381        {
    382            return this.tagMap.isEmpty();
    383        }
    384
    385        /**
    386         * Create a crash report which indicates a NBT read error.
    387         */
    388        private CrashReport createCrashReport(String par1Str, int par2, ClassCastException par3ClassCastException)
    389        {
    390            CrashReport var4 = CrashReport.func_85055_a(par3ClassCastException, "Reading NBT data");
    391            CrashReportCategory var5 = var4.func_85057_a("Corrupt NBT tag", 1);
    392            var5.addCrashSectionCallable("Tag type found", new CallableTagCompound1(this, par1Str));
    393            var5.addCrashSectionCallable("Tag type expected", new CallableTagCompound2(this, par2));
    394            var5.addCrashSection("Tag name", par1Str);
    395
    396            if (this.getName() != null && this.getName().length() > 0)
    397            {
    398                var5.addCrashSection("Tag parent", this.getName());
    399            }
    400
    401            return var4;
    402        }
    403
    404        /**
    405         * Creates a clone of the tag.
    406         */
    407        public NBTBase copy()
    408        {
    409            NBTTagCompound var1 = new NBTTagCompound(this.getName());
    410            Iterator var2 = this.tagMap.keySet().iterator();
    411
    412            while (var2.hasNext())
    413            {
    414                String var3 = (String)var2.next();
    415                var1.setTag(var3, ((NBTBase)this.tagMap.get(var3)).copy());
    416            }
    417
    418            return var1;
    419        }
    420
    421        public boolean equals(Object par1Obj)
    422        {
    423            if (super.equals(par1Obj))
    424            {
    425                NBTTagCompound var2 = (NBTTagCompound)par1Obj;
    426                return this.tagMap.entrySet().equals(var2.tagMap.entrySet());
    427            }
    428            else
    429            {
    430                return false;
    431            }
    432        }
    433
    434        public int hashCode()
    435        {
    436            return super.hashCode() ^ this.tagMap.hashCode();
    437        }
    438
    439        /**
    440         * Return the tag map for this compound.
    441         */
    442        static Map getTagMap(NBTTagCompound par0NBTTagCompound)
    443        {
    444            return par0NBTTagCompound.tagMap;
    445        }
    446    }