public override Level Read(Stream src, string name, bool metadata) { using (GZipStream s = new GZipStream(src, CompressionMode.Decompress)) { Level lvl = new Level(name, 0, 0, 0); DatReader r = new DatReader(); r.src = new BinaryReader(s); int signature = r.ReadInt32(); // Format version 0 - preclassic to classic 0.12 // (technically this format doesn't have a signature, // but 99% of such maps will start with these 4 bytes) if (signature == 0x01010101) { return(ReadFormat0(lvl, s)); } // All valid .dat maps must start with these 4 bytes if (signature != 0x271BB788) { throw new InvalidDataException("Invalid .dat map signature"); } switch (r.ReadUInt8()) { // Format version 1 - classic 0.13 case 0x01: return(ReadFormat1(lvl, r)); // Format version 2 - classic 0.15 to 0.30 case 0x02: return(ReadFormat2(lvl, r)); } throw new InvalidDataException("Invalid .dat map version"); } }
public override Level Read(Stream src, string name, bool metadata) { using (GZipStream s = new GZipStream(src, CompressionMode.Decompress)) { Level lvl = new Level(name, 0, 0, 0); DatReader r = new DatReader(); r.src = new BinaryReader(s); if (r.ReadInt32() != 0x271BB788 || r.ReadUInt8() != 0x02) { throw new InvalidDataException("Unexpected constant in .dat file"); } if (r.ReadUInt16() != 0xACED) { throw new InvalidDataException("Invalid stream magic"); } if (r.ReadUInt16() != 0x0005) { throw new InvalidDataException("Invalid stream version"); } JObject obj = (JObject)ReadObject(r); ParseRootObject(lvl, obj); return(lvl); } }
static void SkipAnnotation(DatReader r) { byte typeCode; while ((typeCode = r.ReadUInt8()) != TC_ENDBLOCKDATA) { if (typeCode == TC_BLOCKDATA) { r.ReadBytes(r.ReadUInt8()); } else { ReadObject(r, typeCode); } } }
static unsafe object Value(DatReader r, char type) { if (type == 'B') { return(r.ReadUInt8()); } if (type == 'C') { return((char)r.ReadUInt16()); } if (type == 'D') { long tmp = r.ReadInt64(); return(*(double *)(&tmp)); } if (type == 'F') { int tmp = r.ReadInt32(); return(*(float *)(&tmp)); } if (type == 'I') { return(r.ReadInt32()); } if (type == 'J') { return(r.ReadInt64()); } if (type == 'S') { return(r.ReadInt16()); } if (type == 'Z') { return(r.ReadUInt8() != 0); } if (type == 'L') { return(ReadObject(r)); } if (type == '[') { return(ReadObject(r)); } throw new InvalidDataException("Invalid value code: " + type); }
static void SkipAnnotation(DatReader r) { byte typeCode; while ((typeCode = r.ReadUInt8()) != TC_ENDBLOCKDATA) { ReadContent(r, typeCode); } }
static object ReadContent(DatReader r, byte typeCode) { if (typeCode == TC_BLOCKDATA) { return(r.ReadBytes(r.ReadUInt8())); } else if (typeCode == TC_BLOCKDATALONG) { return(r.ReadBytes(r.ReadInt32())); } else { return(ReadObject(r, typeCode)); } }
static JClassDesc ClassDesc(DatReader r) { byte typeCode = r.ReadUInt8(); if (typeCode == TC_CLASSDESC) { return(NewClassDesc(r)); } if (typeCode == TC_NULL) { return(null); } if (typeCode == TC_REFERENCE) { return((JClassDesc)PrevObject(r)); } throw new InvalidDataException("Invalid type code: " + typeCode); }
static JClassDesc NewClassDesc(DatReader r) { JClassDesc desc = new JClassDesc(); desc.Name = r.ReadUtf8(); r.ReadInt64(); // serial UID r.handles.Add(desc); // read class desc info desc.Flags = r.ReadUInt8(); desc.Fields = new JFieldDesc[r.ReadUInt16()]; for (int i = 0; i < desc.Fields.Length; i++) { desc.Fields[i] = FieldDesc(r); } SkipAnnotation(r); desc.SuperClass = ClassDesc(r); return(desc); }
static JFieldDesc FieldDesc(DatReader r) { JFieldDesc desc = new JFieldDesc(); byte type = r.ReadUInt8(); desc.Type = (char)type; if (type == 'B' || type == 'C' || type == 'D' || type == 'F' || type == 'I' || type == 'J' || type == 'S' || type == 'Z') { desc.Name = r.ReadUtf8(); } else if (type == '[' || type == 'L') { desc.Name = r.ReadUtf8(); desc.ClassName = (string)ReadObject(r); } else { throw new InvalidDataException("Invalid field type: " + type); } return(desc); }
static object ReadObject(DatReader r) { return(ReadObject(r, r.ReadUInt8())); }