public override NbtCompound GetCompound() { Compound["x"] = new NbtInt("x", Coordinates.X); Compound["y"] = new NbtInt("y", Coordinates.Y); Compound["z"] = new NbtInt("z", Coordinates.Z); return Compound; }
/// <summary> Creates a copy of given NbtInt tag. </summary> /// <param name="other"> Tag to copy. May not be <c>null</c>. </param> /// <exception cref="ArgumentNullException"> <paramref name="other"/> is <c>null</c>. </exception> public NbtInt([NotNull] NbtInt other) { if (other == null) { throw new ArgumentNullException("other"); } name = other.name; Value = other.Value; }
internal override bool ReadTag(NbtBinaryReader readStream) { if (readStream.Selector != null && !readStream.Selector(this)) { SkipTag(readStream); return(false); } ListType = readStream.ReadTagType(); int length = readStream.ReadInt32(); if (length < 0) { throw new NbtFormatException("Negative list size given."); } for (int i = 0; i < length; i++) { NbtTag newTag; switch (ListType) { case NbtTagType.Byte: newTag = new NbtByte(); break; case NbtTagType.Short: newTag = new NbtShort(); break; case NbtTagType.Int: newTag = new NbtInt(); break; case NbtTagType.Long: newTag = new NbtLong(); break; case NbtTagType.Float: newTag = new NbtFloat(); break; case NbtTagType.Double: newTag = new NbtDouble(); break; case NbtTagType.ByteArray: newTag = new NbtByteArray(); break; case NbtTagType.String: newTag = new NbtString(); break; case NbtTagType.List: newTag = new NbtList(); break; case NbtTagType.Compound: newTag = new NbtCompound(); break; case NbtTagType.IntArray: newTag = new NbtIntArray(); break; default: // should never happen, since ListType is checked beforehand throw new NbtFormatException("Unsupported tag type found in a list: " + ListType); } newTag.Parent = this; if (newTag.ReadTag(readStream)) { tags.Add(newTag); } } return(true); }
internal override void SkipTag(NbtBinaryReader readStream) { while (true) { NbtTagType nextTag = readStream.ReadTagType(); NbtTag newTag; switch (nextTag) { case NbtTagType.End: return; case NbtTagType.Byte: newTag = new NbtByte(); break; case NbtTagType.Short: newTag = new NbtShort(); break; case NbtTagType.Int: newTag = new NbtInt(); break; case NbtTagType.Long: newTag = new NbtLong(); break; case NbtTagType.Float: newTag = new NbtFloat(); break; case NbtTagType.Double: newTag = new NbtDouble(); break; case NbtTagType.ByteArray: newTag = new NbtByteArray(); break; case NbtTagType.String: newTag = new NbtString(); break; case NbtTagType.List: newTag = new NbtList(); break; case NbtTagType.Compound: newTag = new NbtCompound(); break; case NbtTagType.IntArray: newTag = new NbtIntArray(); break; case NbtTagType.LongArray: newTag = new NbtLongArray(); break; default: throw new NbtFormatException("Unsupported tag type found in NBT_Compound: " + nextTag); } readStream.SkipString(); newTag.SkipTag(readStream); } }
internal override bool ReadTag(NbtBinaryReader readStream) { if (Parent != null && readStream.Selector != null && !readStream.Selector(this)) { SkipTag(readStream); return(false); } while (true) { NbtTagType nextTag = readStream.ReadTagType(); NbtTag newTag; switch (nextTag) { case NbtTagType.End: return(true); case NbtTagType.Byte: newTag = new NbtByte(); break; case NbtTagType.Short: newTag = new NbtShort(); break; case NbtTagType.Int: newTag = new NbtInt(); break; case NbtTagType.Long: newTag = new NbtLong(); break; case NbtTagType.Float: newTag = new NbtFloat(); break; case NbtTagType.Double: newTag = new NbtDouble(); break; case NbtTagType.ByteArray: newTag = new NbtByteArray(); break; case NbtTagType.String: newTag = new NbtString(); break; case NbtTagType.List: newTag = new NbtList(); break; case NbtTagType.Compound: newTag = new NbtCompound(); break; case NbtTagType.IntArray: newTag = new NbtIntArray(); break; case NbtTagType.LongArray: newTag = new NbtLongArray(); break; default: throw new NbtFormatException("Unsupported tag type found in NBT_Compound: " + nextTag); } newTag.Parent = this; newTag.Name = readStream.ReadString(); if (newTag.ReadTag(readStream)) { // ReSharper disable AssignNullToNotNullAttribute // newTag.Name is never null tags.Add(newTag.Name, newTag); // ReSharper restore AssignNullToNotNullAttribute } } }
public static ChunkColumn GetChunk(ChunkCoordinates coordinates, string basePath, IWorldProvider generator, int yoffset) { int width = 32; int depth = 32; int rx = coordinates.X >> 5; int rz = coordinates.Z >> 5; string filePath = Path.Combine(basePath, string.Format(@"region\r.{0}.{1}.mca", rx, rz)); if (!File.Exists(filePath)) return generator.GenerateChunkColumn(coordinates); using (var regionFile = File.OpenRead(filePath)) { byte[] buffer = new byte[8192]; regionFile.Read(buffer, 0, 8192); int xi = (coordinates.X%width); if (xi < 0) xi += 32; int zi = (coordinates.Z%depth); if (zi < 0) zi += 32; int tableOffset = (xi + zi*width)*4; regionFile.Seek(tableOffset, SeekOrigin.Begin); byte[] offsetBuffer = new byte[4]; regionFile.Read(offsetBuffer, 0, 3); Array.Reverse(offsetBuffer); int offset = BitConverter.ToInt32(offsetBuffer, 0) << 4; int length = regionFile.ReadByte(); if (offset == 0 || length == 0) { return generator.GenerateChunkColumn(coordinates); } regionFile.Seek(offset, SeekOrigin.Begin); byte[] waste = new byte[4]; regionFile.Read(waste, 0, 4); int compressionMode = regionFile.ReadByte(); var nbt = new NbtFile(); nbt.LoadFromStream(regionFile, NbtCompression.ZLib); NbtTag dataTag = nbt.RootTag["Level"]; NbtList sections = dataTag["Sections"] as NbtList; ChunkColumn chunk = new ChunkColumn { x = coordinates.X, z = coordinates.Z, biomeId = dataTag["Biomes"].ByteArrayValue }; for (int i = 0; i < chunk.biomeId.Length; i++) { if (chunk.biomeId[i] > 22) chunk.biomeId[i] = 0; } if (chunk.biomeId.Length > 256) throw new Exception(); // This will turn into a full chunk column foreach (NbtTag sectionTag in sections) { int sy = sectionTag["Y"].ByteValue*16; byte[] blocks = sectionTag["Blocks"].ByteArrayValue; byte[] data = sectionTag["Data"].ByteArrayValue; NbtTag addTag = sectionTag["Add"]; byte[] adddata = new byte[2048]; if (addTag != null) adddata = addTag.ByteArrayValue; byte[] blockLight = sectionTag["BlockLight"].ByteArrayValue; byte[] skyLight = sectionTag["SkyLight"].ByteArrayValue; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { int yi = sy + y - yoffset; if (yi < 0 || yi >= 128) continue; int anvilIndex = y*16*16 + z*16 + x; int blockId = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8); // Anvil to PE friendly converstion if (blockId == 125) blockId = 5; else if (blockId == 126) blockId = 158; else if (blockId == 75) blockId = 50; else if (blockId == 76) blockId = 50; else if (blockId == 123) blockId = 89; else if (blockId == 124) blockId = 89; else if (blockId == 152) blockId = 73; else if (_ignore.BinarySearch(blockId) >= 0) blockId = 0; else if (_gaps.BinarySearch(blockId) >= 0) { Debug.WriteLine("Missing material: " + blockId); blockId = 133; } if (blockId > 255) blockId = 41; if (yi == 127 && blockId != 0) blockId = 30; if (yi == 0 && (blockId == 8 || blockId == 9 /*|| blockId == 0*/)) blockId = 7; //if (blockId != 0) blockId = 41; chunk.SetBlock(x, yi, z, (byte) blockId); chunk.SetMetadata(x, yi, z, Nibble4(data, anvilIndex)); chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex)); chunk.SetSkylight(x, yi, z, Nibble4(skyLight, anvilIndex)); } } } } NbtList entities = dataTag["Entities"] as NbtList; NbtList blockEntities = dataTag["TileEntities"] as NbtList; if (blockEntities != null) { foreach (var nbtTag in blockEntities) { var blockEntityTag = (NbtCompound) nbtTag; string entityId = blockEntityTag["id"].StringValue; int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue - yoffset; int z = blockEntityTag["z"].IntValue; blockEntityTag["y"] = new NbtInt("y", y); BlockEntity blockEntity = BlockEntityFactory.GetBlockEntityById(entityId); if (blockEntity != null) { blockEntityTag.Name = string.Empty; chunk.SetBlockEntity(new BlockCoordinates(x, y, z), blockEntityTag); } } } NbtList tileTicks = dataTag["TileTicks"] as NbtList; chunk.isDirty = false; return chunk; } }
public ChunkColumn GetChunk(int X, int Z) { var width = 32; var depth = 32; var rx = X >> 5; var rz = Z >> 5; var filePath = Path.Combine(_basePath, string.Format(@"region\r.{0}.{1}.mca", rx, rz)); if (!File.Exists(filePath)) return _backEndGenerator.GenerateChunkColumn(new Vector2(X, Z)); using (var regionFile = File.OpenRead(filePath)) { var buffer = new byte[8192]; regionFile.Read(buffer, 0, 8192); var xi = (X%width); if (xi < 0) xi += 32; var zi = (Z%depth); if (zi < 0) zi += 32; var tableOffset = (xi + zi*width)*4; regionFile.Seek(tableOffset, SeekOrigin.Begin); var offsetBuffer = new byte[4]; regionFile.Read(offsetBuffer, 0, 3); Array.Reverse(offsetBuffer); var offset = BitConverter.ToInt32(offsetBuffer, 0) << 4; var length = regionFile.ReadByte(); //if (offset == 0 || length == 0) return _backEndGenerator.GenerateChunkColumn(new Vector2(X, Z)); if (offset == 0 || length == 0) { return _backEndGenerator.GenerateChunkColumn(new Vector2(X,Z)); } regionFile.Seek(offset, SeekOrigin.Begin); var waste = new byte[4]; regionFile.Read(waste, 0, 4); var compressionMode = regionFile.ReadByte(); var nbt = new NbtFile(); nbt.LoadFromStream(regionFile, NbtCompression.ZLib); var dataTag = nbt.RootTag["Level"]; var sections = dataTag["Sections"] as NbtList; var chunk = new ChunkColumn { X = X, Z = Z, BiomeId = dataTag["Biomes"].ByteArrayValue }; for (var i = 0; i < chunk.BiomeId.Length; i++) { if (chunk.BiomeId[i] > 22) chunk.BiomeId[i] = 0; } if (chunk.BiomeId.Length > 256) throw new Exception(); // This will turn into a full chunk column foreach (var sectionTag in sections) { var sy = sectionTag["Y"].ByteValue*16; var blocks = sectionTag["Blocks"].ByteArrayValue; var data = sectionTag["Data"].ByteArrayValue; var addTag = sectionTag["Add"]; var adddata = new byte[2048]; if (addTag != null) adddata = addTag.ByteArrayValue; var blockLight = sectionTag["BlockLight"].ByteArrayValue; var skyLight = sectionTag["SkyLight"].ByteArrayValue; for (var x = 0; x < 16; x++) { for (var z = 0; z < 16; z++) { for (var y = 0; y < 16; y++) { var yi = sy + y - _waterOffsetY; if (yi < 0 || yi >= 256) continue; var anvilIndex = y*16*16 + z*16 + x; var blockId = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8); var b = BlockFactory.GetBlockById((ushort) blockId); b.Metadata = Nibble4(data, anvilIndex); chunk.SetBlock(x, yi, z, b); chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex)); chunk.SetSkylight(x, yi, z, Nibble4(skyLight, anvilIndex)); } } } } var entities = dataTag["Entities"] as NbtList; var tileEntities = dataTag["TileEntities"] as NbtList; if (tileEntities != null) { foreach (var nbtTag in tileEntities) { var blockEntityTag = (NbtCompound)nbtTag; string entityId = blockEntityTag["id"].StringValue; int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue - _waterOffsetY; int z = blockEntityTag["z"].IntValue; blockEntityTag["y"] = new NbtInt("y", y); TileEntity blockEntity = TileEntityFactory.GetBlockEntityById(entityId); if (blockEntity != null) { blockEntityTag.Name = string.Empty; chunk.SetBlockEntity(new Vector3(x, y, z), blockEntityTag); } } } var tileTicks = dataTag["TileTicks"] as NbtList; chunk.IsDirty = false; return chunk; } }