namespace Nbt.Test; using System.IO.Compression; using K4os.Compression.LZ4.Streams; using Nbt.Serialization; using Nbt.Tag; public static class Program { public static void Main(string[] args) { WorldFileReading(); } private static void Test() { const string filePath = @"D:\Minecraft\game\profiles\test\saves\creatif\players\hbdu68.dat"; INbtTag rootTag; using (var inputStream = File.OpenRead(filePath)) { using var reader = NbtReader.Create(inputStream); rootTag = reader.ReadNamedTag().Tag; } // SNbt.Serialize(Console.Out, rootTag, new() { Style = SNbt.SerializationStyle.Indented }); var s = JsonNbt.Serialize(rootTag); var t = JsonNbt.Deserialize(s); Console.WriteLine(rootTag.Equals(t)); } private static void WorldFileReading() { const string inputFile = @"/home/hbecher/Téléchargements/sc-murder/region/r.-3.0.mca"; // chunk coordinates and last modified timestamps // two 4kiB tables (1024 ints) var allOfTheShite = new NbtCompound(); Span buf4 = stackalloc byte[4]; using var inputStream = File.OpenRead(inputFile); for (var chunkX = 0; chunkX < 32; chunkX++) { for (var chunkZ = 0; chunkZ < 32; chunkZ++) { var chunkOffset = (chunkX + (chunkZ << 5)) << 2; inputStream.Position = chunkOffset; inputStream.Read(buf4); buf4.Reverse(); var rawLoc = BitConverter.ToUInt32(buf4); var offset = (int)((rawLoc & ~0xFFu) << 4); var size = (int)((rawLoc & 0xFFu) << 12); if (offset == 0 && size == 0) { continue; } using (inputStream.Mark()) { inputStream.Position += 1024 * 4; inputStream.Read(buf4); } buf4.Reverse(); var timestamp = BitConverter.ToInt32(buf4); using (inputStream.Mark()) { inputStream.Position = offset; inputStream.Read(buf4); buf4.Reverse(); var length = BitConverter.ToInt32(buf4); var compressionMode = inputStream.ReadByte(); Stream inflaterStream; bool leaveOpen = false; switch (compressionMode) { case 1: inflaterStream = new GZipStream(inputStream, CompressionMode.Decompress, true); break; case 2: inflaterStream = new ZLibStream(inputStream, CompressionMode.Decompress, true); break; case 3: inflaterStream = inputStream; leaveOpen = true; break; case 4: inflaterStream = LZ4Stream.Decode(inputStream, leaveOpen: true); break; default: continue; } INbtTag tag; using (var nbtReader = new NbtReader(inflaterStream, leaveOpen)) { tag = nbtReader.ReadNamedTag().Tag; } allOfTheShite[$"{chunkX}-{chunkZ}"] = tag; } } } using var outputStream = File.CreateText(@"/home/hbecher/Téléchargements/a.snbt"); // SNbt.Serialize(outputStream, allOfTheShite, new() { Style = SNbt.SerializationStyle.Indented }); JsonNbt.ToJson(outputStream, allOfTheShite); } }