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