/// <inheritdoc /> public Structure Load(string filename) { using (var fs = File.OpenRead(filename)) using (var bs = new BrotliStream(fs, CompressionMode.Decompress)) using (var s = new BinaryReader(bs)) { var idMap = new TranslationMap(); var diffMap = new DiffMap(); var identBytes = new byte[ScarifStructure.Magic.Length]; var read = s.Read(identBytes, 0, identBytes.Length); var ident = Encoding.UTF8.GetString(identBytes); if (ident != ScarifStructure.Magic || read != identBytes.Length) { throw new IOException("Input file not SCARIF structure"); } var version = s.ReadInt32(); if (version != 1) { throw new IOException("Input file not SCARIF v1"); } var numChunks = s.ReadInt32(); var numIdMapEntries = s.ReadInt32(); for (var entryIdx = 0; entryIdx < numIdMapEntries; entryIdx++) { var id = s.ReadInt16(); var name = ReadNullTerminatedString(s); idMap.Add(id, name); } var lowestPos = new BlockPos(int.MaxValue, int.MaxValue, int.MaxValue); var highestPos = new BlockPos(int.MinValue, int.MinValue, int.MinValue); for (var chunkIdx = 0; chunkIdx < numChunks; chunkIdx++) { var chunkX = s.ReadInt32(); var chunkZ = s.ReadInt32(); var numBlocks = s.ReadInt32(); var blocks = new Dictionary <BlockPos, Block>(); for (var blockIdx = 0; blockIdx < numBlocks; blockIdx++) { // Format: // 0b 0000 1111 // xxxx zzzz var xz = s.ReadByte(); var x = (byte)((xz & 0xF0) >> 4); var z = (byte)(xz & 0x0F); var y = s.ReadByte(); EnforceBounds(chunkX * 16 + x, y, chunkZ * 16 + z, ref lowestPos, ref highestPos); var id = s.ReadInt16(); var flags = (BlockFlags)s.ReadByte(); byte metadata = 0; NbtTree tileTag = null; if (flags.Has(BlockFlags.Metadata)) { metadata = s.ReadByte(); } if (flags.Has(BlockFlags.Nbt)) { var len = s.ReadInt32(); if (len <= 0) { throw new IOException("Zero-length NBT present"); } var bytes = s.ReadBytes(len); using (var ms = new MemoryStream(bytes)) { tileTag = new NbtTree(ms); } } if (idMap.ContainsKey(id)) { blocks[new BlockPos(x, y, z)] = new Block(idMap.TranslateBlock(id), metadata, tileTag?.Root); } else { throw new IOException($"Unknown block ID found: {id}"); } } diffMap.Add(new ChunkPosition(chunkX, chunkZ), blocks); } return(new ScarifStructure(idMap, diffMap, lowestPos, highestPos)); } }
private static string TranslateBlockId(TranslationMap map, int id) { return(map.ContainsKey((short)id) ? map[(short)id] : $"unknown:{id}"); }