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 }