129 lines
4.0 KiB
C#
Executable File
129 lines
4.0 KiB
C#
Executable File
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<byte> 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);
|
|
}
|
|
}
|