1
0
Files
named-binary-tag/Test/Program.cs
2024-03-15 14:44:21 +01:00

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);
}
}