示例#1
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.SpawnRotY = (float)Utils.PackedToDegrees((byte)spawn["H"].Value);
                }
                if (spawn.ContainsKey("P"))
                {
                    p.SpawnHeadX = (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);
            }
        }
示例#2
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);
        }
示例#3
0
        public unsafe NbtTag ReadTag(byte typeId, bool readTagName)
        {
            NbtTag tag = default(NbtTag);

            if (typeId == 0)
            {
                tag.TagId = NbtTagType.Invalid; return(tag);
            }

            tag.Name  = readTagName ? ReadString() : null;
            tag.TagId = (NbtTagType)typeId;
            switch ((NbtTagType)typeId)
            {
            case NbtTagType.Int8:
                tag.Value = reader.ReadByte(); break;

            case NbtTagType.Int16:
                tag.Value = ReadInt16(); break;

            case NbtTagType.Int32:
                tag.Value = ReadInt32(); break;

            case NbtTagType.Int64:
                tag.Value = ReadInt64(); break;

            case NbtTagType.Real32:
                int temp32 = ReadInt32();
                tag.Value = *((float *)&temp32); break;

            case NbtTagType.Real64:
                long temp64 = ReadInt64();
                tag.Value = *((double *)&temp64); break;

            case NbtTagType.Int8Array:
                tag.Value = reader.ReadBytes(ReadInt32()); break;

            case NbtTagType.String:
                tag.Value = ReadString(); break;

            case NbtTagType.List:
                NbtList list = new NbtList();
                list.ChildTagId     = (NbtTagType)reader.ReadByte();
                list.ChildrenValues = new object[ReadInt32()];
                for (int i = 0; i < list.ChildrenValues.Length; i++)
                {
                    list.ChildrenValues[i] = ReadTag((byte)list.ChildTagId, false).Value;
                }
                tag.Value = list; break;

            case NbtTagType.Compound:
                Dictionary <string, NbtTag> children = new Dictionary <string, NbtTag>();
                NbtTag child;
                while ((child = ReadTag(reader.ReadByte(), true)).TagId != NbtTagType.Invalid)
                {
                    children[child.Name] = child;
                }
                tag.Value = children; break;

            case NbtTagType.Int32Array:
                int[] array = new int[ReadInt32()];
                for (int i = 0; i < array.Length; i++)
                {
                    array[i] = ReadInt32();
                }
                tag.Value = array; break;

            default:
                throw new InvalidDataException("Unrecognised tag id: " + typeId);
            }
            return(tag);
        }