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 Level ReadFormat1(Level lvl, DatReader r) { r.ReadUtf8(); // level name r.ReadUtf8(); // level author r.ReadInt64(); // created timestamp (currentTimeMillis) lvl.Width = r.ReadUInt16(); lvl.Length = r.ReadUInt16(); lvl.Height = r.ReadUInt16(); lvl.blocks = r.ReadBytes(lvl.Width * lvl.Height * lvl.Length); // TODO readfully SetupClassic013(lvl); return(lvl); }
// Really annoying map format to parse, because it's just a Java serialised object // http://www.javaworld.com/article/2072752/the-java-serialization-algorithm-revealed.html // https://docs.oracle.com/javase/7/docs/platform/serialization/spec/protocol.html // Good reference tool for comparison // https://github.com/NickstaDB/SerializationDumper static Level ReadFormat2(Level lvl, DatReader r) { 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 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 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); }