public byte[] Load( Stream stream, Game game, out int width, out int height, out int length )
        {
            byte[] map = null;
            width = 0;
            height = 0;
            length = 0;
            LocalPlayer p = game.LocalPlayer;
            p.Spawn = Vector3.Zero;
            GZipHeaderReader gsHeader = new GZipHeaderReader();
            while( !gsHeader.ReadHeader( stream ) ) { }

            using( DeflateStream gs = new DeflateStream( stream, CompressionMode.Decompress ) ) {
                reader = new BinaryReader( gs );
                ClassDescription obj = ReadData();
                for( int i = 0; i < obj.Fields.Length; i++ ) {
                    FieldDescription field = obj.Fields[i];
                    if( field.FieldName == "width" )
                        width = (int)field.Value;
                    else if( field.FieldName == "height" )
                        length = (int)field.Value;
                    else if( field.FieldName == "depth" )
                        height = (int)field.Value;
                    else if( field.FieldName == "blocks" )
                        map = (byte[])field.Value;
                    else if( field.FieldName == "xSpawn" )
                        p.Spawn.X = (int)field.Value;
                    else if( field.FieldName == "ySpawn" )
                        p.Spawn.Y = (int)field.Value;
                    else if( field.FieldName == "zSpawn" )
                        p.Spawn.Z = (int)field.Value;
                }
            }
            return map;
        }
        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 ) ) {
                BinaryReader r = new BinaryReader( gs );
                ushort header = r.ReadUInt16();

                width = header == Version ? r.ReadUInt16() : header;
                length = r.ReadUInt16();
                height = r.ReadUInt16();

                LocalPlayer p = game.LocalPlayer;
                p.Spawn.X = r.ReadUInt16();
                p.Spawn.Z = r.ReadUInt16();
                p.Spawn.Y = r.ReadUInt16();
                p.SpawnYaw = (float)Utils.PackedToDegrees( r.ReadByte() );
                p.SpawnPitch = (float)Utils.PackedToDegrees( r.ReadByte() );

                if( header == Version )
                    r.ReadUInt16(); // pervisit and perbuild perms
                byte[] blocks = new byte[width * height * length];
                int read = gs.Read( blocks, 0, blocks.Length );
                ConvertPhysicsBlocks( blocks );

                if( gs.ReadByte() != 0xBD ) return blocks;
                ReadCustomBlocks( gs, width, height, length, blocks );
                return blocks;
            }
        }
Example #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;
            }
        }
Example #4
0
        internal void HandleLevelDataChunk()
        {
            // Workaround for some servers that send LevelDataChunk before LevelInit
            // due to their async packet sending behaviour.
            if (gzipStream == null)
            {
                HandleLevelInit();
            }
            int usedLength = reader.ReadInt16();

            gzippedMap.Position = 0;
            gzippedMap.Offset   = reader.index;
            gzippedMap.SetLength(usedLength);

            if (gzipHeader.done || gzipHeader.ReadHeader(gzippedMap))
            {
                if (mapSizeIndex < 4)
                {
                    mapSizeIndex += gzipStream.Read(mapSize, mapSizeIndex, 4 - mapSizeIndex);
                }

                if (mapSizeIndex == 4)
                {
                    if (map == null)
                    {
                        int size = mapSize[0] << 24 | mapSize[1] << 16 | mapSize[2] << 8 | mapSize[3];
                        map = new byte[size];
                    }
                    mapIndex += gzipStream.Read(map, mapIndex, map.Length - mapIndex);
                }
            }

            reader.Skip(1025);               // also skip progress since we calculate client side
            float progress = map == null ? 0 : (float)mapIndex / map.Length;

            game.WorldEvents.RaiseMapLoading(progress);
        }