--- a/net/minecraft/server/PlayerChunk.java +++ b/net/minecraft/server/PlayerChunk.java @@ -8,32 +8,48 @@ import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +// CraftBukkit Start +import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor; +// CraftBukkit end public class PlayerChunk { private static final Logger a = LogManager.getLogger(); private final PlayerChunkMap playerChunkMap; - private final List c = Lists.newArrayList(); + public final List c = Lists.newArrayList(); // CraftBukkit - public private final ChunkCoordIntPair location; private final short[] dirtyBlocks = new short[64]; @Nullable - private Chunk chunk; + public Chunk chunk; // CraftBukkit - public private int dirtyCount; private int h; private long i; private boolean done; + // CraftBukkit start - add fields + private boolean loadInProgress = false; + private Runnable loadedRunnable = new Runnable() { + public void run() { + loadInProgress = false; + PlayerChunk.this.chunk = PlayerChunk.this.playerChunkMap.getWorld().getChunkProviderServer().getOrLoadChunkAt(location.x, location.z); + } + }; + // CraftBukkit end + public PlayerChunk(PlayerChunkMap playerchunkmap, int i, int j) { this.playerChunkMap = playerchunkmap; this.location = new ChunkCoordIntPair(i, j); - this.chunk = playerchunkmap.getWorld().getChunkProviderServer().getOrLoadChunkAt(i, j); + // CraftBukkit start + loadInProgress = true; + this.chunk = playerchunkmap.getWorld().getChunkProviderServer().getChunkAt(i, j, loadedRunnable, false); + // CraftBukkit end } public ChunkCoordIntPair a() { return this.location; } - public void a(EntityPlayer entityplayer) { + public void a(final EntityPlayer entityplayer) { // CraftBukkit - added final to argument if (this.c.contains(entityplayer)) { PlayerChunk.a.debug("Failed to add player. {} already is in chunk {}, {}", new Object[] { entityplayer, Integer.valueOf(this.location.x), Integer.valueOf(this.location.z)}); } else { @@ -42,15 +58,32 @@ } this.c.add(entityplayer); + // CraftBukkit start - use async chunk io + // if (this.done) { + // this.sendChunk(entityplayer); + // } if (this.done) { this.sendChunk(entityplayer); } + // CraftBukkit end } } public void b(EntityPlayer entityplayer) { if (this.c.contains(entityplayer)) { + // CraftBukkit start - If we haven't loaded yet don't load the chunk just so we can clean it up + if (!this.done) { + this.c.remove(entityplayer); + + if (this.c.isEmpty()) { + ChunkIOExecutor.dropQueuedChunkLoad(this.playerChunkMap.getWorld(), this.location.x, this.location.z, this.loadedRunnable); + this.playerChunkMap.b(this); + } + + return; + } + // CraftBukkit end if (this.done) { entityplayer.playerConnection.sendPacket(new PacketPlayOutUnloadChunk(this.location.x, this.location.z)); } @@ -67,11 +100,18 @@ if (this.chunk != null) { return true; } else { + /* CraftBukkit start if (flag) { this.chunk = this.playerChunkMap.getWorld().getChunkProviderServer().getChunkAt(this.location.x, this.location.z); } else { this.chunk = this.playerChunkMap.getWorld().getChunkProviderServer().getOrLoadChunkAt(this.location.x, this.location.z); } + */ + if (!loadInProgress) { + loadInProgress = true; + this.chunk = playerChunkMap.getWorld().getChunkProviderServer().getChunkAt(this.location.x, this.location.z, loadedRunnable, flag); + } + // CraftBukkit end return this.chunk != null; }