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 );
            }
        }
示例#3
0
        public byte[] Load( Stream stream, Game game, out int width, out int height, out int length )
        {
            GZipHeaderReader gsHeader = new GZipHeaderReader();
            while( !gsHeader.ReadHeader( stream ) ) { }

            using( DeflateStream gs = new DeflateStream( stream, CompressionMode.Decompress ) ) {
                reader = new BinaryReader( gs );
                if( reader.ReadByte() != (byte)NbtTagType.Compound )
                    throw new InvalidDataException( "Nbt file must start with Tag_Compound" );
                this.game = game;
                map = game.World;
                file = new NbtFile( reader );

                NbtTag root = file.ReadTag( (byte)NbtTagType.Compound, true );
                NbtCompound children = (NbtCompound)root.Value;
                if( children.ContainsKey( "Metadata" ) )
                    ParseMetadata( children );

                NbtCompound spawn = (NbtCompound)children["Spawn"].Value;
                LocalPlayer p = game.LocalPlayer;
                p.Spawn.X = (short)spawn["X"].Value;
                p.Spawn.Y = (short)spawn["Y"].Value;
                p.Spawn.Z = (short)spawn["Z"].Value;
                if( spawn.ContainsKey( "H" ) )
                    p.SpawnYaw = (float)Utils.PackedToDegrees( (byte)spawn["H"].Value );
                if( spawn.ContainsKey( "P" ) )
                    p.SpawnPitch = (float)Utils.PackedToDegrees( (byte)spawn["P"].Value );

                map.Uuid = new Guid( (byte[])children["UUID"].Value );
                width = (short)children["X"].Value;
                height = (short)children["Y"].Value;
                length = (short)children["Z"].Value;

                // Older versions incorrectly multiplied spawn coords by * 32, so we check for that.
                if( p.Spawn.X < 0 || p.Spawn.X >= width || p.Spawn.Y < 0 ||
                   p.Spawn.Y >= height || p.Spawn.Z < 0 || p.Spawn.Z >= length ) {
                    p.Spawn.X /= 32; p.Spawn.Y /= 32; p.Spawn.Z /= 32;
                }
                return (byte[])children["BlockArray"].Value;
            }
        }
示例#4
0
        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);

                                #if USE16_BIT
                WriteBlocks(nbt, Utils.UInt16sToUInt8s(map.blocks));
                                #else
                WriteBlocks(nbt, map.blocks);
                                #endif
                WriteBlockData(nbt, map.blocks.Length);

                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);
            }
        }
示例#5
0
        public bool LoadChunk(ref Chunk chunk, string path)
        {
            try {
                using (FileStream fs = File.OpenRead(path)) {
                    GZipHeaderReader gsheader = new GZipHeaderReader();
                    while (!gsheader.ReadHeader(fs))
                    {
                    }

                    using (DeflateStream gs = new DeflateStream(fs, CompressionMode.Decompress)) {
                        BinaryReader reader = new BinaryReader(gs);
                        if (reader.ReadByte() != (byte)NbtTagType.Compound)
                        {
                            throw new InvalidDataException("Nbt file must start with Tag_Compound");
                        }
                        NbtFile file = new NbtFile(reader);

                        NbtTag      root     = file.ReadTag((byte)NbtTagType.Compound, true);
                        NbtCompound children = (NbtCompound)root.Value;
                        if (children.ContainsKey("Level"))
                        {
                            NbtCompound levelChildren = (NbtCompound)children["Level"].Value;
                            chunk.blocks = (byte[])levelChildren["Blocks"].Value;
                            int    size     = 16 * 128 * 16;
                            int    halfSize = size / 2;
                            byte[] data     = (byte[])levelChildren["Data"].Value;
                            chunk.metadata  = new NibbleSlice(data, 0, halfSize);
                            chunk.populated = ((byte)levelChildren["TerrainPopulated"].Value != 0);
                            return(true);
                        }
                    }
                }
            } catch (Exception ex) {
                ErrorHandler.LogError("loading chunk", ex);
                game.Chat.Add("Failed to load chunk.");
                return(false);
            }
            return(false);
        }
示例#6
0
        public void Save( Stream stream, Game game )
        {
            using( GZipStream wrapper = new GZipStream( stream, CompressionMode.Compress ) ) {
                writer = new BinaryWriter( wrapper );
                nbt = new NbtFile( writer );
                this.game = game;
                map = game.World;

                nbt.Write( NbtTagType.Compound ); nbt.Write( "ClassicWorld" );

                nbt.Write( NbtTagType.Int8 );
                nbt.Write( "FormatVersion" ); nbt.WriteInt8( 1 );

                nbt.Write( NbtTagType.Int8Array );
                nbt.Write( "UUID" ); nbt.WriteInt32( 16 );
                nbt.WriteBytes( map.Uuid.ToByteArray() );

                nbt.Write( NbtTagType.Int16 );
                nbt.Write( "X" ); nbt.WriteInt16( (short)map.Width );

                nbt.Write( NbtTagType.Int16 );
                nbt.Write( "Y" ); nbt.WriteInt16( (short)map.Height );

                nbt.Write( NbtTagType.Int16 );
                nbt.Write( "Z" ); nbt.WriteInt16( (short)map.Length );

                WriteSpawnCompoundTag();

                nbt.Write( NbtTagType.Int8Array );
                nbt.Write( "BlockArray" ); nbt.WriteInt32( map.blocks.Length );
                nbt.WriteBytes( map.blocks );

                WriteMetadata();

                nbt.Write( NbtTagType.End );
            }
        }
示例#7
0
        public void Save(Stream stream, Game game)
        {
            using (GZipStream wrapper = new GZipStream(stream, CompressionMode.Compress)) {
                writer    = new BinaryWriter(wrapper);
                nbt       = new NbtFile(writer);
                this.game = game;
                map       = game.World;

                nbt.Write(NbtTagType.Compound); nbt.Write("ClassicWorld");

                nbt.Write(NbtTagType.Int8);
                nbt.Write("FormatVersion"); nbt.WriteUInt8(1);

                nbt.Write(NbtTagType.Int8Array);
                nbt.Write("UUID"); nbt.WriteInt32(16);
                nbt.WriteBytes(map.Uuid.ToByteArray());

                nbt.Write(NbtTagType.Int16);
                nbt.Write("X"); nbt.WriteInt16((short)map.Width);

                nbt.Write(NbtTagType.Int16);
                nbt.Write("Y"); nbt.WriteInt16((short)map.Height);

                nbt.Write(NbtTagType.Int16);
                nbt.Write("Z"); nbt.WriteInt16((short)map.Length);

                WriteSpawnCompoundTag();

                nbt.Write(NbtTagType.Int8Array);
                nbt.Write("BlockArray"); nbt.WriteInt32(map.blocks1.Length);
                nbt.WriteBytes(map.blocks1);

                WriteMetadata();

                nbt.Write(NbtTagType.End);
            }
        }
        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 );
            }
        }