ClassiCube/ClassicalSharp/Map/Formats/MapSchematic.Exporter.cs
2016-11-27 14:50:45 +11:00

73 lines
2.0 KiB
C#

// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
using System;
using System.IO;
using System.IO.Compression;
namespace ClassicalSharp.Map {
public sealed class MapSchematicExporter : IMapFormatExporter {
public void Save(Stream stream, Game game) {
using (GZipStream wrapper = new GZipStream(stream, CompressionMode.Compress)) {
BinaryWriter writer = new BinaryWriter(wrapper);
NbtFile nbt = new NbtFile(writer);
World map = game.World;
nbt.Write(NbtTagType.Compound); nbt.Write("Schematic");
nbt.Write(NbtTagType.String);
nbt.Write("Materials"); nbt.Write("Classic");
nbt.Write(NbtTagType.Int16);
nbt.Write("Width"); nbt.WriteInt16((short)map.Width);
nbt.Write(NbtTagType.Int16);
nbt.Write("Height"); nbt.WriteInt16((short)map.Height);
nbt.Write(NbtTagType.Int16);
nbt.Write("Length"); nbt.WriteInt16((short)map.Length);
WriteBlocks(nbt, map.blocks);
WriteBlockData(nbt, map.blocks);
nbt.Write(NbtTagType.List);
nbt.Write("Entities");
nbt.Write(NbtTagType.Compound); nbt.WriteInt32(0);
nbt.Write(NbtTagType.List);
nbt.Write("TileEntities");
nbt.Write(NbtTagType.Compound); nbt.WriteInt32(0);
nbt.Write(NbtTagType.End);
}
}
void WriteBlocks(NbtFile nbt, byte[] blocks) {
const int chunkSize = 64 * 1024 * 32;
nbt.Write(NbtTagType.Int8Array);
nbt.Write("Blocks");
nbt.WriteInt32(blocks.Length);
for (int i = 0; i < blocks.Length; i += chunkSize) {
int count = Math.Min(chunkSize, blocks.Length - i);
nbt.WriteBytes(blocks, i, count);
}
}
void WriteBlockData(NbtFile nbt, byte[] blocks) {
const int chunkSize = 64 * 1024;
byte[] chunk = new byte[chunkSize];
nbt.Write(NbtTagType.Int8Array);
nbt.Write("Data");
nbt.WriteInt32(blocks.Length);
for (int i = 0; i < blocks.Length; i += chunkSize) {
// All 0 so we can skip this.
int count = Math.Min(chunkSize, blocks.Length - i);
nbt.WriteBytes(chunk, 0, count);
}
}
}
}