From c86a3f7a5877acb5406147923ac48d91c2f6e7d4 Mon Sep 17 00:00:00 2001 From: Gero Date: Sun, 28 Nov 2021 11:54:00 +1100 Subject: [PATCH] #959: Fix World#refreshChunk --- .../org/bukkit/craftbukkit/CraftWorld.java | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index b409580b6..f98312b64 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -22,11 +22,13 @@ import java.util.UUID; import java.util.function.Predicate; import java.util.stream.Collectors; import net.minecraft.core.BlockPosition; +import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; import net.minecraft.network.protocol.game.PacketPlayOutCustomSoundEffect; import net.minecraft.network.protocol.game.PacketPlayOutUpdateTime; import net.minecraft.network.protocol.game.PacketPlayOutWorldEvent; import net.minecraft.resources.MinecraftKey; import net.minecraft.server.level.ChunkMapDistance; +import net.minecraft.server.level.EntityPlayer; import net.minecraft.server.level.PlayerChunk; import net.minecraft.server.level.Ticket; import net.minecraft.server.level.TicketType; @@ -292,21 +294,22 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean refreshChunk(int x, int z) { - if (!isChunkLoaded(x, z)) { - return false; - } + PlayerChunk playerChunk = world.getChunkSource().chunkMap.visibleChunkMap.get(ChunkCoordIntPair.asLong(x, z)); + if (playerChunk == null) return false; - int px = x << 4; - int pz = z << 4; + playerChunk.getTickingChunkFuture().thenAccept(either -> { + either.left().ifPresent(chunk -> { + List playersInRange = playerChunk.playerProvider.getPlayers(playerChunk.getPos(), false); + if (playersInRange.isEmpty()) return; - // If there are more than 64 updates to a chunk at once, it will update all 'touched' sections within the chunk - // And will include biome data if all sections have been 'touched' - // This flags 65 blocks distributed across all the sections of the chunk, so that everything is sent, including biomes - int height = getMaxHeight() / 16; - for (int idx = 0; idx < 64; idx++) { - world.sendBlockUpdated(new BlockPosition(px + (idx / height), ((idx % height) * 16), pz), Blocks.AIR.defaultBlockState(), Blocks.STONE.defaultBlockState(), 3); - } - world.sendBlockUpdated(new BlockPosition(px + 15, (height * 16) - 1, pz + 15), Blocks.AIR.defaultBlockState(), Blocks.STONE.defaultBlockState(), 3); + ClientboundLevelChunkWithLightPacket refreshPacket = new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), null, null, true); + for (EntityPlayer player : playersInRange) { + if (player.connection == null) continue; + + player.connection.send(refreshPacket); + } + }); + }); return true; }