ClassiCube/ClassicalSharp/Map/Formats/MapSchematic.Exporter.cs
2016-06-11 15:29:45 +10:00

73 lines
2.1 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 );
}
}
}
}