A tag containing a single signed 32-bit integer.
Наследование: NbtTag
		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;
		}
Пример #2
0
 /// <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;
 }
Пример #3
0
        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);
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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
                }
            }
        }
Пример #6
0
        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;
            }
        }
Пример #7
0
        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;
            }
        }