diff options
Diffstat (limited to 'nms-patches/PlayerChunkMap.patch')
-rw-r--r-- | nms-patches/PlayerChunkMap.patch | 173 |
1 files changed, 118 insertions, 55 deletions
diff --git a/nms-patches/PlayerChunkMap.patch b/nms-patches/PlayerChunkMap.patch index 70c02c14..d7899e7d 100644 --- a/nms-patches/PlayerChunkMap.patch +++ b/nms-patches/PlayerChunkMap.patch @@ -1,6 +1,6 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/PlayerChunkMap.java 2014-11-28 17:43:43.321707430 +0000 -+++ src/main/java/net/minecraft/server/PlayerChunkMap.java 2014-11-28 17:38:19.000000000 +0000 -@@ -7,17 +7,24 @@ +--- /home/matt/mc-dev-private//net/minecraft/server/PlayerChunkMap.java 2015-02-26 22:40:22.991608135 +0000 ++++ src/main/java/net/minecraft/server/PlayerChunkMap.java 2015-02-26 22:40:22.991608135 +0000 +@@ -7,17 +7,26 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -8,18 +8,20 @@ +import java.util.Collections; +import java.util.Queue; +import java.util.LinkedList; ++import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor; ++import java.util.HashMap; +// CraftBukkit end + public class PlayerChunkMap { private static final Logger a = LogManager.getLogger(); private final WorldServer world; - private final List managedPlayers = Lists.newArrayList(); - private final LongHashMap d = new LongHashMap(); -- private final List e = Lists.newArrayList(); -- private final List f = Lists.newArrayList(); -+ private final Queue e = new java.util.concurrent.ConcurrentLinkedQueue(); // CraftBukkit ArrayList -> ConcurrentLinkedQueue -+ private final Queue f = new java.util.concurrent.ConcurrentLinkedQueue(); // CraftBukkit ArrayList -> ConcurrentLinkedQueue + private final List<EntityPlayer> managedPlayers = Lists.newArrayList(); + private final LongHashMap<PlayerChunkMap.PlayerChunk> d = new LongHashMap(); +- private final List<PlayerChunkMap.PlayerChunk> e = Lists.newArrayList(); +- private final List<PlayerChunkMap.PlayerChunk> f = Lists.newArrayList(); ++ private final Queue<PlayerChunkMap.PlayerChunk> e = new java.util.concurrent.ConcurrentLinkedQueue<PlayerChunkMap.PlayerChunk>(); // CraftBukkit ArrayList -> ConcurrentLinkedQueue ++ private final Queue<PlayerChunkMap.PlayerChunk> f = new java.util.concurrent.ConcurrentLinkedQueue<PlayerChunkMap.PlayerChunk>(); // CraftBukkit ArrayList -> ConcurrentLinkedQueue private int g; private long h; private final int[][] i = new int[][] { { 1, 0}, { 0, 1}, { -1, 0}, { 0, -1}}; @@ -27,36 +29,33 @@ public PlayerChunkMap(WorldServer worldserver) { this.world = worldserver; -@@ -35,28 +42,39 @@ - +@@ -36,26 +45,37 @@ if (i - this.h > 8000L) { this.h = i; -- + - for (j = 0; j < this.f.size(); ++j) { -- playerchunk = (PlayerChunk) this.f.get(j); -+ +- playerchunkmap_playerchunk = (PlayerChunkMap.PlayerChunk) this.f.get(j); + // CraftBukkit start - Use iterator + java.util.Iterator iterator = this.f.iterator(); + while (iterator.hasNext()) { -+ playerchunk = (PlayerChunk) iterator.next(); - playerchunk.b(); - playerchunk.a(); ++ playerchunkmap_playerchunk = (PlayerChunk) iterator.next(); + playerchunkmap_playerchunk.b(); + playerchunkmap_playerchunk.a(); } } else { - for (j = 0; j < this.e.size(); ++j) { -- playerchunk = (PlayerChunk) this.e.get(j); +- playerchunkmap_playerchunk = (PlayerChunkMap.PlayerChunk) this.e.get(j); + java.util.Iterator iterator = this.e.iterator(); -+ + while (iterator.hasNext()) { -+ playerchunk = (PlayerChunk) iterator.next(); - playerchunk.b(); ++ playerchunkmap_playerchunk = (PlayerChunk) iterator.next(); + playerchunkmap_playerchunk.b(); + iterator.remove(); + // CraftBukkit end } } - this.e.clear(); -+ // this.e.clear(); // CraftBukkit - Removals are already covered ++ // this.e.clear(); //CraftBukkit - Removals are already covered if (this.managedPlayers.isEmpty()) { + if (!wasNotEmpty) return; // CraftBukkit - Only do unload when we go from non-empty to empty WorldProvider worldprovider = this.world.worldProvider; @@ -69,54 +68,50 @@ + } else { + wasNotEmpty = true; } -- + // CraftBukkit end - } - public boolean a(int i, int j) { -@@ -77,6 +95,16 @@ + } - return playerchunk; +@@ -78,6 +98,16 @@ + return playerchunkmap_playerchunk; } -+ + + // CraftBukkit start - add method + public final boolean isChunkInUse(int x, int z) { + PlayerChunk pi = a(x, z, false); + if (pi != null) { -+ return (PlayerChunk.b(pi).size() > 0); ++ return (pi.b.size() > 0); + } + return false; + } + // CraftBukkit end - ++ public void flagDirty(BlockPosition blockposition) { int i = blockposition.getX() >> 4; -@@ -95,13 +123,22 @@ - + int j = blockposition.getZ() >> 4; +@@ -96,11 +126,20 @@ entityplayer.d = entityplayer.locX; entityplayer.e = entityplayer.locZ; -+ + + // CraftBukkit start - Load nearby chunks first + List<ChunkCoordIntPair> chunkList = new LinkedList<ChunkCoordIntPair>(); - ++ for (int k = i - this.g; k <= i + this.g; ++k) { for (int l = j - this.g; l <= j + this.g; ++l) { - this.a(k, l, true).a(entityplayer); + chunkList.add(new ChunkCoordIntPair(k, l)); } } -- + + Collections.sort(chunkList, new ChunkCoordComparator(entityplayer)); -+ for (ChunkCoordIntPair pair : chunkList) { ++ for (ChunkCoordIntPair pair : chunkList) { + this.a(pair.x, pair.z, true).a(entityplayer); + } + // CraftBukkit end -+ + this.managedPlayers.add(entityplayer); this.b(entityplayer); - } -@@ -188,12 +225,13 @@ +@@ -188,12 +227,13 @@ int i1 = this.g; int j1 = i - k; int k1 = j - l; @@ -131,17 +126,17 @@ } if (!this.a(l1 - j1, i2 - k1, i, j, i1)) { -@@ -209,6 +247,17 @@ +@@ -209,6 +249,17 @@ this.b(entityplayer); entityplayer.d = entityplayer.locX; entityplayer.e = entityplayer.locZ; -+ -+ // CraftBukkit start - send nearest chunks first ++ ++ // CraftBukkit start - send nearest chunks first + Collections.sort(chunksToLoad, new ChunkCoordComparator(entityplayer)); -+ for (ChunkCoordIntPair pair : chunksToLoad) { ++ for (ChunkCoordIntPair pair : chunksToLoad) { + this.a(pair.x, pair.z, true).a(entityplayer); + } -+ ++ + if (j1 > 1 || j1 < -1 || k1 > 1 || k1 < -1) { + Collections.sort(entityplayer.chunkCoordIntPairQueue, new ChunkCoordComparator(entityplayer)); + } @@ -149,20 +144,88 @@ } } } -@@ -274,11 +323,54 @@ - return playerchunkmap.d; - } +@@ -271,12 +322,22 @@ + private int f; + private long g; -- static List c(PlayerChunkMap playerchunkmap) { -+ static Queue c(PlayerChunkMap playerchunkmap) { // CraftBukkit List -> Queue - return playerchunkmap.f; - } ++ // CraftBukkit start - add fields ++ private final HashMap<EntityPlayer, Runnable> players = new HashMap<EntityPlayer, Runnable>(); ++ private boolean loaded = false; ++ private Runnable loadedRunnable = new Runnable() { ++ public void run() { ++ PlayerChunk.this.loaded = true; ++ } ++ }; ++ // CraftBukkit end ++ + public PlayerChunk(int i, int j) { + this.location = new ChunkCoordIntPair(i, j); +- PlayerChunkMap.this.a().chunkProviderServer.getChunkAt(i, j); ++ PlayerChunkMap.this.a().chunkProviderServer.getChunkAt(i, j, loadedRunnable); // CraftBukkit + } + +- public void a(EntityPlayer entityplayer) { ++ public void a(final EntityPlayer entityplayer) { // CraftBukkit - added final to argument + if (this.b.contains(entityplayer)) { + PlayerChunkMap.a.debug("Failed to add player. {} already is in chunk {}, {}", new Object[] { entityplayer, Integer.valueOf(this.location.x), Integer.valueOf(this.location.z)}); + } else { +@@ -285,18 +346,50 @@ + } + + this.b.add(entityplayer); +- entityplayer.chunkCoordIntPairQueue.add(this.location); ++ // CraftBukkit start - use async chunk io ++ Runnable playerRunnable; ++ if (this.loaded) { ++ playerRunnable = null; ++ entityplayer.chunkCoordIntPairQueue.add(this.location); ++ } else { ++ playerRunnable = new Runnable() { ++ public void run() { ++ entityplayer.chunkCoordIntPairQueue.add(PlayerChunk.this.location); ++ } ++ }; ++ PlayerChunkMap.this.a().chunkProviderServer.getChunkAt(this.location.x, this.location.z, playerRunnable); ++ } ++ ++ this.players.put(entityplayer, playerRunnable); ++ // CraftBukkit end + } + } + + public void b(EntityPlayer entityplayer) { + if (this.b.contains(entityplayer)) { ++ // CraftBukkit start - If we haven't loaded yet don't load the chunk just so we can clean it up ++ if (!this.loaded) { ++ ChunkIOExecutor.dropQueuedChunkLoad(PlayerChunkMap.this.a(), this.location.x, this.location.z, this.players.get(entityplayer)); ++ this.b.remove(entityplayer); ++ this.players.remove(entityplayer); ++ ++ if (this.b.isEmpty()) { ++ ChunkIOExecutor.dropQueuedChunkLoad(PlayerChunkMap.this.a(), this.location.x, this.location.z, this.loadedRunnable); ++ long i = (long) this.location.x + 2147483647L | (long) this.location.z + 2147483647L << 32; ++ PlayerChunkMap.this.d.remove(i); ++ PlayerChunkMap.this.f.remove(this); ++ } ++ ++ return; ++ } ++ // CraftBukkit end + Chunk chunk = PlayerChunkMap.this.world.getChunkAt(this.location.x, this.location.z); + + if (chunk.isReady()) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutMapChunk(chunk, true, 0)); + } + ++ this.players.remove(entityplayer); // CraftBukkit + this.b.remove(entityplayer); + entityplayer.chunkCoordIntPairQueue.remove(this.location); + if (this.b.isEmpty()) { +@@ -421,4 +514,47 @@ -- static List d(PlayerChunkMap playerchunkmap) { -+ static Queue d(PlayerChunkMap playerchunkmap) { // CraftBukkit List -> Queue - return playerchunkmap.e; + } } -+ ++ + // CraftBukkit start - Sorter to load nearby chunks first + private static class ChunkCoordComparator implements java.util.Comparator<ChunkCoordIntPair> { + private int x; |