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); } }
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); }
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); }