Beispiel #1
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);
            }
        }
Beispiel #2
0
        public void GetEntitysInChunk(int chunkX, int chunkZ)
        {
            foreach (var player in Level.GetOnlinePlayers)
            {
                if (player == this)
                {
                    continue;
                }

                var x = (int)player.KnownPosition.X >> 4;
                var z = (int)player.KnownPosition.Z >> 4;
                if (chunkX == x && chunkZ == z)
                {
                    new SpawnPlayer(Wrapper)
                    {
                        Player = player
                    }.Write();
                }
            }

            foreach (var entity in Level.Entities)
            {
                var x = (int)entity.KnownPosition.X >> 4;
                var z = (int)entity.KnownPosition.Z >> 4;
                if (chunkX == x && chunkZ == z)
                {
                    new SpawnObject(Wrapper)
                    {
                        X = entity.KnownPosition.X, Y = entity.KnownPosition.Y, Z = entity.KnownPosition.Z, EntityId = entity.EntityId, Type = (ObjectType)entity.EntityTypeId, Yaw = entity.KnownPosition.Yaw, Pitch = entity.KnownPosition.Pitch
                    }.Write();
                }
            }

            ChunkColumn chunk = Level.Generator.GenerateChunkColumn(new Vector2(chunkX, chunkZ));

            foreach (var raw in chunk.TileEntities)
            {
                var nbt = raw.Value;
                if (nbt == null)
                {
                    continue;
                }

                string id    = null;
                var    idTag = nbt.Get("id");
                if (idTag != null)
                {
                    id = idTag.StringValue;
                }

                if (string.IsNullOrEmpty(id))
                {
                    continue;
                }

                var tileEntity = TileEntityFactory.GetBlockEntityById(id);
                tileEntity.Coordinates = raw.Key;
                tileEntity.SetCompound(nbt);

                if (tileEntity.Id == "Sign")
                {
                    var sign = (SignTileEntity)tileEntity;
                    new UpdateSign(Wrapper)
                    {
                        SignCoordinates = sign.Coordinates,
                        Line1           = sign.Line1,
                        Line2           = sign.Line2,
                        Line3           = sign.Line3,
                        Line4           = sign.Line4,
                    }.Write();
                }
            }
        }