1
0
forked from xjboss/KCauldronX
KCauldronX/patches/net/minecraft/server/management/PlayerManager.java.patch
Sergey Shatunov 5aaf6c5cbf ChunkManager implementation
ChunkManager optimize chunks handling in small and big worlds

Small worlds gets benefits with using int-object map instead long-object (in area -32768...32767 by x and z)

Large worlds gets benefits by using efficient map by Colt project, which a little (3-6%) slower in writing, but greatly faster
(400-500% from Java's HashMap and 150-180% from Trove's maps) on reading.
2016-02-10 19:17:47 +07:00

114 lines
4.9 KiB
Diff

--- ../src-base/minecraft/net/minecraft/server/management/PlayerManager.java
+++ ../src-work/minecraft/net/minecraft/server/management/PlayerManager.java
@@ -18,14 +18,19 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+//CraftBukkit start
+import java.util.Collections;
+import java.util.Queue;
+// CraftBukkit end
+
public class PlayerManager
{
private static final Logger field_152627_a = LogManager.getLogger();
private final WorldServer theWorldServer;
private final List players = new ArrayList();
private final LongHashMap playerInstances = new LongHashMap();
- private final List chunkWatcherWithPlayers = new ArrayList();
- private final List playerInstanceList = new ArrayList();
+ private final Queue chunkWatcherWithPlayers = new java.util.concurrent.ConcurrentLinkedQueue(); // CraftBukkit ArrayList -> ConcurrentLinkedQueue
+ private final Queue playerInstanceList = new java.util.concurrent.ConcurrentLinkedQueue(); // CraftBukkit ArrayList -> ConcurrentLinkedQueue
private int playerViewRadius;
private long previousTotalWorldTime;
private final int[][] xzDirectionsConst = new int[][] {{1, 0}, {0, 1}, { -1, 0}, {0, -1}};
@@ -37,6 +42,14 @@
this.func_152622_a(p_i1176_1_.func_73046_m().getConfigurationManager().getViewDistance());
}
+ // Cauldron start - vanilla compatibility
+ public PlayerManager(WorldServer p_i1176_1_, int viewDistance /* Spigot */)
+ {
+ this.theWorldServer = p_i1176_1_;
+ this.func_152622_a(viewDistance); // Spigot
+ }
+ // Cauldron end
+
public WorldServer getWorldServer()
{
return this.theWorldServer;
@@ -51,27 +64,38 @@
if (i - this.previousTotalWorldTime > 8000L)
{
this.previousTotalWorldTime = i;
+ // CraftBukkit start - Use iterator
+ java.util.Iterator iterator = this.playerInstanceList.iterator();
- for (j = 0; j < this.playerInstanceList.size(); ++j)
+ while (iterator.hasNext())
{
- playerinstance = (PlayerManager.PlayerInstance)this.playerInstanceList.get(j);
+ playerinstance = (PlayerManager.PlayerInstance)iterator.next();
playerinstance.sendChunkUpdate();
playerinstance.processChunk();
}
}
else
{
- for (j = 0; j < this.chunkWatcherWithPlayers.size(); ++j)
+ java.util.Iterator iterator = this.chunkWatcherWithPlayers.iterator();
+
+ while (iterator.hasNext())
{
- playerinstance = (PlayerManager.PlayerInstance)this.chunkWatcherWithPlayers.get(j);
+ playerinstance = (PlayerManager.PlayerInstance)iterator.next();
playerinstance.sendChunkUpdate();
+ iterator.remove();
+ // CraftBukkit end
}
}
- this.chunkWatcherWithPlayers.clear();
+ // this.chunkWatcherWithPlayers.clear(); // CraftBukkit - Removals are already covered
if (this.players.isEmpty())
{
+ if (this.theWorldServer.loadedEntityList.size() == 0 || this.theWorldServer.theChunkProviderServer.chunkManager.size() == 0)
+ {
+ return; // CraftBukkit - Only do unload when we go from non-empty to empty
+ }
+
WorldProvider worldprovider = this.theWorldServer.provider;
if (!worldprovider.canRespawnHere())
@@ -102,6 +126,20 @@
return playerinstance;
}
+ // CraftBukkit start
+ public final boolean isChunkInUse(int x, int z)
+ {
+ PlayerManager.PlayerInstance pi = getOrCreateChunkWatcher(x, z, false);
+
+ if (pi != null)
+ {
+ return (pi.playersWatchingChunk.size() > 0);
+ }
+
+ return false;
+ }
+ // CraftBukkit end
+
public void markBlockForUpdate(int p_151250_1_, int p_151250_2_, int p_151250_3_)
{
int l = p_151250_1_ >> 4;
@@ -541,7 +579,7 @@
{
i = this.chunkLocation.chunkXPos * 16;
j = this.chunkLocation.chunkZPos * 16;
- this.sendToAllPlayersWatchingChunk(new S21PacketChunkData(PlayerManager.this.theWorldServer.getChunkFromChunkCoords(this.chunkLocation.chunkXPos, this.chunkLocation.chunkZPos), false, this.flagsYAreasToUpdate));
+ this.sendToAllPlayersWatchingChunk(new S21PacketChunkData(PlayerManager.this.theWorldServer.getChunkFromChunkCoords(this.chunkLocation.chunkXPos, this.chunkLocation.chunkZPos), (this.flagsYAreasToUpdate == 0xFFFF), this.flagsYAreasToUpdate)); // CraftBukkit - send everything (including biome) if all sections flagged
// Forge: Grabs ALL tile entities is costly on a modded server, only send needed ones
for (k = 0; false && k < 16; ++k)