Use distance map to optimise entity tracker / Misc Utils

Use the distance map to find candidate players for tracking.

This also ports a few utility changes from Tuinity
This commit is contained in:
Spottedleaf 2020-05-06 03:44:47 -04:00
parent 444dd5a0c6
commit fbe8958237
67 changed files with 802 additions and 358 deletions

View file

@ -19,7 +19,7 @@ index 2ac396dd17..3043b87cf7 100644
if (bukkitEntity == null) {
bukkitEntity = CraftEntity.getEntity(world.getServer(), this);
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 175734b50c..2c7e611663 100644
index 7804cc0f6a..4ee26ff08f 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -52,7 +52,7 @@ index 2f57c7bc76..a1c33c525c 100644
public boolean captureBlockStates = false;
public boolean captureTreeGeneration = false;
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 4cbf390ce0..6ce7f77a5e 100644
index 25e2a6580a..02d9c754b1 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -49,7 +49,7 @@ index 0000000000..f699ce18ca
+ }
+}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 56d740fcad..39e77f8248 100644
index 687e609cab..8f3eee5ea8 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@
@ -121,7 +121,7 @@ index c9c2b00251..1422503e11 100644
}
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index d49f456f73..a79e4cef4a 100644
index eece2f689c..6374bf8785 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {

View file

@ -5,7 +5,7 @@ Subject: [PATCH] Add phantom creative and insomniac controls
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 88a45e517c..fc189ebc96 100644
index 3c0468bc44..bfb52d75c7 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig {

View file

@ -9,7 +9,7 @@ This should hopefully avoid duplicate entities ever being created
if the entity was to end up in 2 different chunk slices
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 803afed60d..80b5013d95 100644
index 6a40dddf46..0afa8a7ebd 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {

View file

@ -14,7 +14,7 @@ Use an ArrayDeque to store this Queue
We make sure to also implement a pattern that is recursion safe too.
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 3f4a3205a4..aabb9220db 100644
index a06c0327df..e08a3bd96c 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {

View file

@ -1181,7 +1181,7 @@ index 0000000000..37093419cf
+ }
+}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 4b77934c39..9ce9542b80 100644
index af0d6aff4d..472d3a4c03 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {
@ -1550,7 +1550,7 @@ index 040d4b41ea..f1620ba80e 100644
this.a(new PacketPlayOutMultiBlockChange(this.dirtyCount, this.dirtyBlocks, chunk), false);
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index c9c25cdb8e..9c627bf3b4 100644
index 9171785ad5..eb29d0e956 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {

View file

@ -3099,7 +3099,7 @@ index f1620ba80e..74e6b8b973 100644
completablefuture = (CompletableFuture) this.statusFutures.get(i);
if (completablefuture != null) {
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 9c627bf3b4..19603343b2 100644
index eb29d0e956..43abdb47fd 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -3983,7 +3983,7 @@ index c999f8c9bf..b59ef1a633 100644
HAS_SPACE(VillagePlaceRecord::d), IS_OCCUPIED(VillagePlaceRecord::e), ANY((villageplacerecord) -> {
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index e3913952d9..3db0ad0a46 100644
index 8561f96b9a..c0476f69e4 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -14,7 +14,7 @@ And since minecart hoppers are used _very_ rarely near we can avoid alot of sear
Combined, this adds up a lot.
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 9ce9542b80..a23dfeb63d 100644
index 472d3a4c03..42eede6781 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {

View file

@ -30,7 +30,7 @@ index 6ef0e1399e..5872e6b171 100644
+ }
}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 7ddf6592f7..d1761ff3c4 100644
index 4b162a768e..6694d0e36c 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {

View file

@ -102,7 +102,7 @@ index 3868572aed..ae77805f71 100644
@Override
public void a(ChunkCoordIntPair chunkcoordintpair) {
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index f9ee9afe3a..389c9d03a1 100644
index 081df240f3..ce506e0e12 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -6,7 +6,7 @@ Subject: [PATCH] Delay unsafe actions until after entity ticking is done
This will help prevent many cases of unregistering entities during entity ticking
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index dc01fb494d..d13dc8fce9 100644
index 9b5f24c262..b3785775ec 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -10,7 +10,7 @@ larger than the keep loaded range.
By skipping this, we avoid potential for a large spike on server start.
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index a16a8c10a2..50886c1374 100644
index aa9c903aa8..d51af68a92 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {

View file

@ -7,7 +7,7 @@ Causes sync chunk loads and who knows what all else.
This is safe because Spectators are skipped in unloaded chunks too in vanilla.
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index c6474aa0f8..a16a8c10a2 100644
index 900631ebe0..aa9c903aa8 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {

View file

@ -81,7 +81,7 @@ index 4ba72275b9..572679e4d1 100644
+ }
}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index f47ed1947e..7bcdbe713d 100644
index 8e9ddca049..165cb994e8 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {
@ -105,7 +105,7 @@ index 030c9992eb..fd6dad8437 100644
this.uniqueID = uuid;
this.am = this.uniqueID.toString();
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 2c7e611663..3c237b259e 100644
index 4ee26ff08f..1d255ce383 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@
@ -197,7 +197,7 @@ index 2c7e611663..3c237b259e 100644
ChunkCoordIntPair chunkcoordintpair = playerchunk.i();
CompletableFuture<Either<List<IChunkAccess>, PlayerChunk.Failure>> completablefuture = this.a(chunkcoordintpair, 1, (i) -> {
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index e34ea3d098..f9ee9afe3a 100644
index 6da2392915..081df240f3 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ package net.minecraft.server;

View file

@ -23,7 +23,7 @@ index 00df89d650..0dbe2dce11 100644
private boolean locked = false;
@Override
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 9b9e242432..f80c80957a 100644
index 5173731dc5..3fc25183ca 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -5,7 +5,7 @@ Subject: [PATCH] Entity AddTo/RemoveFrom World Events
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 9d0edf5382..fd42f34004 100644
index 3769f0533d..f8d1cb0231 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -101,7 +101,7 @@ index 5406f4c40f..d778eac45d 100644
if (i >= 0 && i < this.list.size()) {
NBTBase nbtbase = (NBTBase) this.list.get(i);
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 6810d49b17..450b414298 100644
index 38a71bca2f..351825ebec 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -72,7 +72,7 @@ index e9908cd01f..7745e70d2d 100644
});
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 43565dd92c..f7a1fad9c1 100644
index a75034079b..955003d5f8 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -10,7 +10,7 @@ Adds an option to control the force mode of the particle.
This adds a new Builder API which is much friendlier to use.
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index eb99f3a967..da391e945c 100644
index 7417725363..60f936f2e5 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -37,7 +37,7 @@ index c2e4e4f6f1..78a8a3cc68 100644
}
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 6fa70eb08d..0e652625bb 100644
index 22550f74df..cc400a9a84 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {

View file

@ -8,7 +8,7 @@ Vanilla will double add Spider Jockeys to the world, so ignore already added.
Also add debug if something else tries to, and abort before world gets bad state
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 40c9cba760..3004270455 100644
index 6271fb2092..3508fd7084 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -28,7 +28,7 @@ receives a deterministic result, and should no longer require 1 tick
delays anymore.
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index c108a38018..a48e113b53 100644
index bf2ba0548d..45df816980 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
@ -40,7 +40,7 @@ index c108a38018..a48e113b53 100644
// CraftBukkit end
public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 0e652625bb..3f4a3205a4 100644
index cc400a9a84..a06c0327df 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {

View file

@ -132,7 +132,7 @@ index 3d255b1964..040d4b41ea 100644
public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> getStatusFutureUnchecked(ChunkStatus chunkstatus) {
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 4682dca9de..405f57874e 100644
index 4f5b516144..1d517fd1ae 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {

View file

@ -19,7 +19,7 @@ This change ensures the chunks are always loaded when entities are
added to the world, or a valid entity moves between chunks.
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index f7a1fad9c1..e34ea3d098 100644
index 955003d5f8..6da2392915 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -15,7 +15,7 @@ Combine that with a buggy detail of the previous implementation of
the Dupe UUID patch, then this was the likely source of the "Ghost entities"
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index f80c80957a..3f8f40018d 100644
index 3fc25183ca..9fbe8fa1b2 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -23,7 +23,7 @@ index b839769cea..5acad8e44f 100644
MutablePair<Integer, Map<ChunkCoordIntPair, Integer>> info = list.computeIfAbsent(key, k -> MutablePair.of(0, Maps.newHashMap()));
ChunkCoordIntPair chunk = new ChunkCoordIntPair(e.getChunkX(), e.getChunkZ());
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 80b5013d95..f47ed1947e 100644
index 0afa8a7ebd..8e9ddca049 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {
@ -63,7 +63,7 @@ index 838aa7da69..35d22ec027 100644
public float getBukkitYaw() {
return this.yaw;
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 87762b1725..8d292604c3 100644
index d1424325d5..f071b61195 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -197,7 +197,7 @@ index 04b97cec29..568fbbd5f2 100644
private void d(int i) {
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index fb7bbe8744..6fa70eb08d 100644
index db5a35598d..22550f74df 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {

View file

@ -5,7 +5,7 @@ Subject: [PATCH] Implement Mob Goal API
diff --git a/pom.xml b/pom.xml
index bc8438ae1..0c0051f7f 100644
index bc8438ae1a..0c0051f7f2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -0,0 +0,0 @@
@ -24,7 +24,7 @@ index bc8438ae1..0c0051f7f 100644
<repositories>
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java
new file mode 100644
index 000000000..d6ee94107
index 0000000000..d6ee941078
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java
@@ -0,0 +0,0 @@
@ -359,7 +359,7 @@ index 000000000..d6ee94107
+}
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/PaperCustomGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/PaperCustomGoal.java
new file mode 100644
index 000000000..8e4dc2708
index 0000000000..8e4dc2708d
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/PaperCustomGoal.java
@@ -0,0 +0,0 @@
@ -417,7 +417,7 @@ index 000000000..8e4dc2708
+}
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java b/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java
new file mode 100644
index 000000000..d9df0236e
index 0000000000..d9df0236e8
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java
@@ -0,0 +0,0 @@
@ -659,7 +659,7 @@ index 000000000..d9df0236e
+}
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/PaperVanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/PaperVanillaGoal.java
new file mode 100644
index 000000000..263e8c65b
index 0000000000..263e8c65b9
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/PaperVanillaGoal.java
@@ -0,0 +0,0 @@
@ -727,7 +727,7 @@ index 000000000..263e8c65b
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java
index 9df0006c1..b3329c6fc 100644
index 9df0006c1a..b3329c6fcd 100644
--- a/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java
+++ b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java
@@ -0,0 +0,0 @@ public final class OptimizedSmallEnumSet<E extends Enum<E>> {
@ -740,7 +740,7 @@ index 9df0006c1..b3329c6fc 100644
+ }
}
diff --git a/src/main/java/net/minecraft/server/PathfinderGoal.java b/src/main/java/net/minecraft/server/PathfinderGoal.java
index 93009d83f..2dfbecf39 100644
index 93009d83f0..2dfbecf390 100644
--- a/src/main/java/net/minecraft/server/PathfinderGoal.java
+++ b/src/main/java/net/minecraft/server/PathfinderGoal.java
@@ -0,0 +0,0 @@ public abstract class PathfinderGoal {
@ -776,7 +776,7 @@ index 93009d83f..2dfbecf39 100644
this.goalTypes.clear();
this.goalTypes.addAllUnchecked(enumset);
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
index 84d2abbcb..a68fc11ec 100644
index 84d2abbcb9..a68fc11ec6 100644
--- a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
+++ b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
@@ -0,0 +0,0 @@ public class PathfinderGoalSelector {
@ -815,7 +815,7 @@ index 84d2abbcb..a68fc11ec 100644
return this.d.stream().filter(PathfinderGoalWrapped::g);
}
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java b/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java
index 1b800c558..dee4e2bea 100644
index 1b800c558f..dee4e2beac 100644
--- a/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java
+++ b/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java
@@ -0,0 +0,0 @@ import javax.annotation.Nullable;
@ -830,7 +830,7 @@ index 1b800c558..dee4e2bea 100644
public PathfinderGoalWrapped(int i, PathfinderGoal pathfindergoal) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 1647c0975..b89f99a66 100644
index 1647c09756..b89f99a66f 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
@ -847,7 +847,7 @@ index 1647c0975..b89f99a66 100644
}
diff --git a/src/test/java/com/destroystokyo/paper/entity/ai/VanillaMobGoalTest.java b/src/test/java/com/destroystokyo/paper/entity/ai/VanillaMobGoalTest.java
new file mode 100644
index 000000000..83d34761d
index 0000000000..83d34761d9
--- /dev/null
+++ b/src/test/java/com/destroystokyo/paper/entity/ai/VanillaMobGoalTest.java
@@ -0,0 +0,0 @@

View file

@ -98,7 +98,7 @@ index c4d4334305..7df24be46e 100644
protected static final DataWatcherObject<NBTTagCompound> bs = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p);
protected static final DataWatcherObject<NBTTagCompound> bt = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p);
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 0c0224d1eb..c108a38018 100644
index f453ccdb02..bf2ba0548d 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -0,0 +0,0 @@ package net.minecraft.server;
@ -154,7 +154,7 @@ index 8faebf9efe..4da6371381 100644
return this.e;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index e76f2b9c7f..3515b72682 100644
index 6672feaf51..dcbda5b35a 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -0,0 +0,0 @@
@ -176,7 +176,7 @@ index e76f2b9c7f..3515b72682 100644
import net.minecraft.server.EnumChatFormat;
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
public void setViewDistance(int viewDistance) {
throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement"); // TODO
throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement (There are per world view distances though!)"); // TODO
}
+
+ @Override

View file

@ -102,7 +102,7 @@ index a56ac3da80..2f1be1995d 100644
for ( org.bukkit.map.MapCursor cursor : render.cursors) {
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 6f66c38650..40c9cba760 100644
index f46da0e8a0..6271fb2092 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -14,12 +14,12 @@ light engine on shutdown...
The queue size only puts a cap on max loss, doesn't solve that problem.
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 659a011e97..88a45e517c 100644
index 803be76772..3c0468bc44 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
private void trackerUpdateDistance() {
trackerUpdateDistance = getDouble("tracker-update-distance", trackerUpdateDistance);
private void zombieVillagerInfectionChance() {
zombieVillagerInfectionChance = getDouble("zombie-villager-infection-chance", zombieVillagerInfectionChance);
}
+
+ public int lightQueueSize = 20;

View file

@ -114,7 +114,7 @@ index a61815c794..5ae0927c14 100644
PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(cserver.getPlayer(entityplayer), "\u00A7e" + entityplayer.getName() + " left the game");
cserver.getPluginManager().callEvent(playerQuitEvent);
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index da391e945c..c5b4218b44 100644
index 60f936f2e5..7c1a748c9b 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -69,7 +69,7 @@ index 7c518983a9..bdb534deb4 100644
--this.lifeTicks;
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 09176e6040..43565dd92c 100644
index ad779650ed..a75034079b 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -18,7 +18,7 @@ index 324fd07bce..01330045c0 100644
public void setPositionRotation(BlockPosition blockposition, float f, float f1) {
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index a48e113b53..0f9bca8b8b 100644
index 45df816980..48bbaec4b6 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {

View file

@ -248,7 +248,7 @@ index 0000000000..59868f37d1
+}
diff --git a/src/main/java/com/destroystokyo/paper/util/map/QueuedChangesMapLong2Object.java b/src/main/java/com/destroystokyo/paper/util/map/QueuedChangesMapLong2Object.java
new file mode 100644
index 0000000000..07685b6bd5
index 0000000000..7bab31a312
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/util/map/QueuedChangesMapLong2Object.java
@@ -0,0 +0,0 @@
@ -300,10 +300,18 @@ index 0000000000..07685b6bd5
+ return this.updatingMap.get(k);
+ }
+
+ public boolean updatingContainsKey(final long k) {
+ return this.updatingMap.containsKey(k);
+ }
+
+ public V getVisible(final long k) {
+ return this.visibleMap.get(k);
+ }
+
+ public boolean visibleContainsKey(final long k) {
+ return this.visibleMap.containsKey(k);
+ }
+
+ public V getVisibleAsync(final long k) {
+ long readlock;
+ V ret = null;
@ -326,6 +334,28 @@ index 0000000000..07685b6bd5
+ return ret;
+ }
+
+ public boolean visibleContainsKeyAsync(final long k) {
+ long readlock;
+ boolean ret = false;
+
+ do {
+ readlock = this.updatingMapSeqLock.acquireRead();
+
+ try {
+ ret = this.visibleMap.containsKey(k);
+ } catch (final Throwable thr) {
+ if (thr instanceof ThreadDeath) {
+ throw (ThreadDeath)thr;
+ }
+ // ignore...
+ continue;
+ }
+
+ } while (!this.updatingMapSeqLock.tryReleaseRead(readlock));
+
+ return ret;
+ }
+
+ public Long2ObjectLinkedOpenHashMap<V> getVisibleMap() {
+ return this.visibleMap;
+ }
@ -1065,7 +1095,7 @@ index 0000000000..c3b936f54b
+}
diff --git a/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java
new file mode 100644
index 0000000000..f625da9f09
index 0000000000..c71ed11834
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java
@@ -0,0 +0,0 @@
@ -1148,27 +1178,57 @@ index 0000000000..f625da9f09
+ return this.areaMap.size();
+ }
+
+ public final void update(final E object, final int chunkX, final int chunkZ, final int viewDistance) {
+ public final void addOrUpdate(final E object, final int chunkX, final int chunkZ, final int viewDistance) {
+ final int oldViewDistance = this.objectToViewDistance.put(object, viewDistance);
+ final long newPos = MCUtil.getCoordinateKey(chunkX, chunkZ);
+ final long oldPos = this.objectToLastCoordinate.put(object, newPos);
+
+ if (oldViewDistance == -1) {
+ this.objectToLastCoordinate.put(object, newPos);
+ this.addObject(object, chunkX, chunkZ, Integer.MIN_VALUE, Integer.MIN_VALUE, viewDistance);
+ this.addObjectCallback(object, chunkX, chunkZ, viewDistance);
+ } else {
+ final long oldPos = this.objectToLastCoordinate.put(object, newPos);
+ this.updateObject(object, oldPos, newPos, oldViewDistance, viewDistance);
+ this.updateObjectCallback(object, oldPos, newPos, oldViewDistance, viewDistance);
+ }
+ //this.validate(object, viewDistance);
+ }
+
+ // called after the distance map updates
+ protected void addObjectCallback(final E object, final int chunkX, final int chunkZ, final int viewDistance) {}
+ public final boolean update(final E object, final int chunkX, final int chunkZ, final int viewDistance) {
+ final int oldViewDistance = this.objectToViewDistance.replace(object, viewDistance);
+ if (oldViewDistance == -1) {
+ return false;
+ } else {
+ final long newPos = MCUtil.getCoordinateKey(chunkX, chunkZ);
+ final long oldPos = this.objectToLastCoordinate.put(object, newPos);
+ this.updateObject(object, oldPos, newPos, oldViewDistance, viewDistance);
+ this.updateObjectCallback(object, oldPos, newPos, oldViewDistance, viewDistance);
+ }
+ //this.validate(object, viewDistance);
+ return true;
+ }
+
+ // called after the distance map updates
+ protected void updateObjectCallback(final E Object, final long oldPosition, final long newPosition, final int oldViewDistance, final int newViewDistance) {}
+
+ public final boolean add(final E object, final int chunkX, final int chunkZ, final int viewDistance) {
+ final int oldViewDistance = this.objectToViewDistance.putIfAbsent(object, viewDistance);
+ if (oldViewDistance != -1) {
+ return false;
+ }
+
+ final long newPos = MCUtil.getCoordinateKey(chunkX, chunkZ);
+ this.objectToLastCoordinate.put(object, newPos);
+ this.addObject(object, chunkX, chunkZ, Integer.MIN_VALUE, Integer.MIN_VALUE, viewDistance);
+ this.addObjectCallback(object, chunkX, chunkZ, viewDistance);
+
+ //this.validate(object, viewDistance);
+
+ return true;
+ }
+
+ // called after the distance map updates
+ protected void addObjectCallback(final E object, final int chunkX, final int chunkZ, final int viewDistance) {}
+
+ public final boolean remove(final E object) {
+ final long position = this.objectToLastCoordinate.removeLong(object);
+ final int viewDistance = this.objectToViewDistance.removeInt(object);
@ -2015,6 +2075,197 @@ index 0000000000..e51104e65a
+ }
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/util/pooled/PooledObjects.java b/src/main/java/com/destroystokyo/paper/util/pooled/PooledObjects.java
new file mode 100644
index 0000000000..d4325f1f11
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/util/pooled/PooledObjects.java
@@ -0,0 +0,0 @@
+package com.destroystokyo.paper.util.pooled;
+
+import org.apache.commons.lang3.mutable.MutableInt;
+import java.util.ArrayDeque;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.locks.ReentrantLock;
+
+public final class PooledObjects<E> {
+
+ public static final PooledObjects<MutableInt> POOLED_MUTABLE_INTEGERS = new PooledObjects<>(new PooledObjectHandler<MutableInt>() {
+ @Override
+ public MutableInt createNew() {
+ return new MutableInt();
+ }
+
+ @Override
+ public void onAcquire(final MutableInt value) {}
+
+ @Override
+ public void onRelease(final MutableInt value) {}
+ }, 200, -1);
+
+ private final PooledObjectHandler<E> handler;
+ private final int maxPoolSize;
+ private final int expectingThreads;
+
+ private final IsolatedPool<E> mainPool;
+ // use these under contention
+ private final IsolatedPool<E>[] contendedPools;
+
+ public PooledObjects(final PooledObjectHandler<E> handler, final int maxPoolSize, int expectingThreads) {
+ if (handler == null) {
+ throw new NullPointerException("Handler must not be null");
+ }
+ if (maxPoolSize <= 0) {
+ throw new IllegalArgumentException("Max pool size must be greater-than 0");
+ }
+ if (expectingThreads <= 0) {
+ expectingThreads = Runtime.getRuntime().availableProcessors();
+ }
+
+ this.handler = handler;
+ this.maxPoolSize = maxPoolSize;
+ this.expectingThreads = expectingThreads;
+ this.mainPool = new IsolatedPool<>(handler, maxPoolSize);
+ final IsolatedPool<E>[] contendedPools = new IsolatedPool[2 * expectingThreads];
+
+ for (int i = 0; i < contendedPools.length; ++i) {
+ contendedPools[i] = new IsolatedPool<>(handler, Math.max(1, maxPoolSize / 2));
+ }
+
+ this.contendedPools = contendedPools;
+ }
+
+ // Taken from
+ // https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
+ // https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/blob/master/2016/06/25/fastrange.c
+ // Original license is public domain
+ public static int fastRandomBounded(final long randomInteger, final long limit) {
+ // randomInteger must be [0, pow(2, 32))
+ // limit must be [0, pow(2, 32))
+ return (int)((randomInteger * limit) >>> 32);
+ }
+
+ public E acquire() {
+ E ret;
+ PooledObjects.IsolatedPool<E> pooled = this.mainPool;
+ int lastIndex = -1;
+ while ((ret = pooled.tryAcquireUncontended()) == null) {
+ int index;
+ while (lastIndex == (index = fastRandomBounded(ThreadLocalRandom.current().nextInt() & 0xFFFFFFFFL, this.contendedPools.length)));
+ lastIndex = index;
+ pooled = this.contendedPools[index];
+ }
+
+ return ret;
+ }
+
+ public void release(final E value) {
+ PooledObjects.IsolatedPool<E> pooled = this.mainPool;
+ int lastIndex = -1;
+ while (!pooled.tryReleaseUncontended(value)) {
+ int index;
+ while (lastIndex == (index = fastRandomBounded(ThreadLocalRandom.current().nextInt() & 0xFFFFFFFFL, this.contendedPools.length)));
+ lastIndex = index;
+ pooled = this.contendedPools[index];
+ }
+ }
+
+ /** This object is restricted from interacting with any pool */
+ static interface PooledObjectHandler<E> {
+
+ /**
+ * Must return a non-null object
+ */
+ E createNew();
+
+ void onAcquire(final E value);
+
+ void onRelease(final E value);
+ }
+
+ protected static class IsolatedPool<E> {
+
+ protected final PooledObjectHandler<E> handler;
+
+ // We use arraydeque as it doesn't create garbage per element...
+ protected final ArrayDeque<E> pool;
+ protected final int maxPoolSize;
+
+ protected final ReentrantLock lock = new ReentrantLock();
+
+ public IsolatedPool(final PooledObjectHandler<E> handler, final int maxPoolSize) {
+ this.handler = handler;
+ this.pool = new ArrayDeque<>();
+ this.maxPoolSize = maxPoolSize;
+ }
+
+ protected E acquireOrCreateNoLock() {
+ E ret;
+
+ ret = this.pool.poll();
+
+ if (ret == null) {
+ ret = this.handler.createNew();
+ }
+ this.handler.onAcquire(ret);
+
+ return ret;
+ }
+
+ public E tryAcquireUncontended() {
+ if (!this.lock.tryLock()) {
+ return null;
+ }
+ try {
+ return this.acquireOrCreateNoLock();
+ } finally {
+ this.lock.unlock();
+ }
+ }
+
+ public E acquire() {
+ this.lock.lock();
+ try {
+ return this.acquireOrCreateNoLock();
+ } finally {
+ this.lock.unlock();
+ }
+ }
+
+ protected void releaseNoLock(final E value) {
+ if (this.pool.size() >= this.maxPoolSize) {
+ this.handler.onRelease(value);
+ return; // can't accept, we're at capacity
+ }
+
+ this.pool.add(value);
+ this.handler.onRelease(value);
+ }
+
+ public boolean tryReleaseUncontended(final E value) {
+ if (!this.lock.tryLock()) {
+ return false;
+ }
+
+ try {
+ this.releaseNoLock(value);
+ } finally {
+ this.lock.unlock();
+ }
+
+ return true;
+ }
+
+ public void release(final E value) {
+ this.lock.lock();
+ try {
+ this.releaseNoLock(value);
+ } finally {
+ this.lock.unlock();
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java
new file mode 100644
index 0000000000..9df0006c1a
@ -2136,7 +2387,7 @@ index 1cf97cefc9..2040f18349 100644
return this.d.containsKey(iblockstate);
}
diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
index c88a62f6b7..5dbd3e60fe 100644
index c88a62f6b7..f8ac39e1b0 100644
--- a/src/main/java/net/minecraft/server/BlockPosition.java
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali
@ -2156,6 +2407,14 @@ index c88a62f6b7..5dbd3e60fe 100644
public BlockPosition immutableCopy() {
return this;
}
@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali
super(i, j, k);
}
+ public static BlockPosition.PooledBlockPosition acquire() { return r(); } // Paper - OBFHELPER
public static BlockPosition.PooledBlockPosition r() {
return f(0, 0, 0);
}
@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali
return this.d;
}
@ -2191,7 +2450,7 @@ index c88a62f6b7..5dbd3e60fe 100644
this.d = i;
}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 55373cae07..c50fe1c245 100644
index 55373cae07..b39ce329aa 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ import org.apache.logging.log4j.Logger;
@ -2256,27 +2515,41 @@ index 55373cae07..c50fe1c245 100644
+ if (chunk == null) {
+ throw new IllegalArgumentException("Chunk must be non-null, neighbour: (" + relativeX + "," + relativeZ + "), chunk: " + this.loc);
+ }
+ final long before = this.neighbourChunksLoadedBitset;
+ final int index = getNeighbourIndex(relativeX, relativeZ);
+ this.loadedNeighbourChunks[index] = chunk;
+ this.neighbourChunksLoadedBitset |= (1L << index);
+ this.onNeighbourChange(before, this.neighbourChunksLoadedBitset);
+ }
+
+ public final void setNeighbourUnloaded(final int relativeX, final int relativeZ) {
+ final long before = this.neighbourChunksLoadedBitset;
+ final int index = getNeighbourIndex(relativeX, relativeZ);
+ this.loadedNeighbourChunks[index] = null;
+ this.neighbourChunksLoadedBitset &= ~(1L << index);
+ this.onNeighbourChange(before, this.neighbourChunksLoadedBitset);
+ }
+
+ public final void resetNeighbours() {
+ final long before = this.neighbourChunksLoadedBitset;
+ this.neighbourChunksLoadedBitset = 0L;
+ java.util.Arrays.fill(this.loadedNeighbourChunks, null);
+ this.onNeighbourChange(before, 0L);
+ }
+
+ protected void onNeighbourChange(final long bitsetBefore, final long bitsetAfter) {
+
+ }
+
+ public final boolean areNeighboursLoaded(final int radius) {
+ return Chunk.areNeighboursLoaded(this.neighbourChunksLoadedBitset, radius);
+ }
+
+ public static boolean areNeighboursLoaded(final long bitset, final int radius) {
+ // index = relativeX + (relativeZ * (NEIGHBOUR_CACHE_RADIUS * 2 + 1)) + (NEIGHBOUR_CACHE_RADIUS + NEIGHBOUR_CACHE_RADIUS * ((NEIGHBOUR_CACHE_RADIUS * 2 + 1)))
+ switch (radius) {
+ case 0: {
+ return this.loadedTicketLevel;
+ return (bitset & (1L << getNeighbourIndex(0, 0))) != 0;
+ }
+ case 1: {
+ long mask = 0L;
@ -2285,7 +2558,7 @@ index 55373cae07..c50fe1c245 100644
+ mask |= (1L << getNeighbourIndex(dx, dz));
+ }
+ }
+ return (this.neighbourChunksLoadedBitset & mask) == mask;
+ return (bitset & mask) == mask;
+ }
+ case 2: {
+ long mask = 0L;
@ -2294,7 +2567,7 @@ index 55373cae07..c50fe1c245 100644
+ mask |= (1L << getNeighbourIndex(dx, dz));
+ }
+ }
+ return (this.neighbourChunksLoadedBitset & mask) == mask;
+ return (bitset & mask) == mask;
+ }
+ case 3: {
+ long mask = 0L;
@ -2303,7 +2576,7 @@ index 55373cae07..c50fe1c245 100644
+ mask |= (1L << getNeighbourIndex(dx, dz));
+ }
+ }
+ return (this.neighbourChunksLoadedBitset & mask) == mask;
+ return (bitset & mask) == mask;
+ }
+
+ default:
@ -3704,7 +3977,7 @@ index 5c5bf010d0..6e9f402fb0 100644
}
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 7ad30548e2..93d838ec2d 100644
index 7ad30548e2..b505244516 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -3715,26 +3988,19 @@ index 7ad30548e2..93d838ec2d 100644
+ private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<EntityPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>();
+
+ void addPlayerToDistanceMaps(EntityPlayer player) {
+ this.updateMaps(player);
+
+
+
+ int chunkX = MCUtil.getChunkCoordinate(player.locX());
+ int chunkZ = MCUtil.getChunkCoordinate(player.locZ());
+ // Note: players need to be explicitly added to distance maps before they can be updated
+ }
+
+ void removePlayerFromDistanceMaps(EntityPlayer player) {
+
+
+
+
+ }
+
+ void updateMaps(EntityPlayer player) {
+ int chunkX = MCUtil.getChunkCoordinate(player.locX());
+ int chunkZ = MCUtil.getChunkCoordinate(player.locZ());
+
+
+
+
+ // Note: players need to be explicitly added to distance maps before they can be updated
+ }
+
+
@ -3743,6 +4009,37 @@ index 7ad30548e2..93d838ec2d 100644
public PlayerChunkMap(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, IAsyncTaskHandler<Runnable> iasynctaskhandler, ILightAccess ilightaccess, ChunkGenerator<?> chunkgenerator, WorldLoadListener worldloadlistener, Supplier<WorldPersistentData> supplier, int i) {
super(new File(worldserver.getWorldProvider().getDimensionManager().a(file), "region"), datafixer);
this.visibleChunks = this.updatingChunks.clone();
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
};
}
+ // Paper start
+ public final int getEffectiveViewDistance() {
+ // TODO this needs to be checked on update
+ // Mojang currently sets it to +1 of the configured view distance. So subtract one to get the one we really want.
+ return this.viewDistance - 1;
+ }
+ // Paper end
+
private CompletableFuture<Either<List<IChunkAccess>, PlayerChunk.Failure>> a(ChunkCoordIntPair chunkcoordintpair, int i, IntFunction<ChunkStatus> intfunction) {
List<CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>>> list = Lists.newArrayList();
int j = chunkcoordintpair.x;
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
if (!flag1) {
this.chunkDistanceManager.a(SectionPosition.a((Entity) entityplayer), entityplayer);
}
+ this.addPlayerToDistanceMaps(entityplayer); // Paper - distance maps
} else {
SectionPosition sectionposition = entityplayer.K();
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
if (!flag2) {
this.chunkDistanceManager.b(sectionposition, entityplayer);
}
+ this.removePlayerFromDistanceMaps(entityplayer); // Paper - distance maps
}
for (int k = i - this.viewDistance; k <= i + this.viewDistance; ++k) {
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
}
@ -3961,26 +4258,6 @@ index 2e1eabba14..2a4fa455ff 100644
Fluid fluid = this.getFluid(blockposition);
return this.setTypeAndData(blockposition, fluid.getBlockData(), 3 | (flag ? 64 : 0));
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index d5014abc9d..8a5ac6f69b 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {
}
this.registerEntity(entityplayer);
+ this.getChunkProvider().playerChunkMap.addPlayerToDistanceMaps(entityplayer); // Paper - distance maps
}
// CraftBukkit start
@@ -0,0 +0,0 @@ public class WorldServer extends World {
EntityPlayer entityplayer = (EntityPlayer) entity;
this.players.remove(entityplayer);
+ this.getChunkProvider().playerChunkMap.removePlayerFromDistanceMaps(entityplayer); // Paper - distance maps
}
this.getScoreboard().a(entity);
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
index e181df6f4d..4a9132c701 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java

View file

@ -5,7 +5,7 @@ Subject: [PATCH] Make targetSize more aggressive in the chunk unload queue
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index a79e4cef4a..a851997e5f 100644
index 6374bf8785..0edba59675 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {

View file

@ -6,7 +6,7 @@ Subject: [PATCH] Mark chunk dirty anytime entities change to guarantee it
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index e66bbb7ee3..803afed60d 100644
index 87d68a3e21..6a40dddf46 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {

View file

@ -5,7 +5,7 @@ Subject: [PATCH] Mark entities as being ticked when notifying navigation
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 6654b91998..e3913952d9 100644
index 5d1fa08f69..8561f96b9a 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -226,7 +226,7 @@ index 77adc64e30..3c25436f15 100644
// Spigot Start
CrashReport crashreport;
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 532aba2a5d..dc01fb494d 100644
index 2a7a47c670..9b5f24c262 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -8,7 +8,7 @@ faster on its own, however removing the try catch makes it
easier to inline due to code size
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 2e3db1a755..d802acef71 100644
index 65882f4632..696634ebf5 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {

View file

@ -11,7 +11,7 @@ Less crammed entities are likely to show significantly less benefit.
Effectively, this patch optimises crammed entity situations.
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index d802acef71..09137d8785 100644
index 696634ebf5..00dd21205d 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {
@ -133,7 +133,7 @@ index 0dbe2dce11..324fd07bce 100644
this.id = Entity.entityCount.incrementAndGet();
this.passengers = Lists.newArrayList();
diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java
index af10fc36e0..2887cb14e4 100644
index 5bf99e0028..aecdaacfc7 100644
--- a/src/main/java/net/minecraft/server/EntityEnderDragon.java
+++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java
@@ -0,0 +0,0 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {

View file

@ -99,7 +99,7 @@ index 6d351f0979..a44f65f40d 100644
@Override
diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
index e76528f199..e650a2e48d 100644
index db7ba12fd4..9010359fbd 100644
--- a/src/main/java/net/minecraft/server/BlockPosition.java
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali
@ -111,7 +111,7 @@ index e76528f199..e650a2e48d 100644
return this.d(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ());
}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index a23dfeb63d..2e3db1a755 100644
index 42eede6781..65882f4632 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {
@ -376,7 +376,7 @@ index 0c23fc89d7..de9f49b884 100644
public boolean isSavingDisabled() {
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 62fabb7ad5..9a2b4fa7a2 100644
index c348e3e500..fcbc9f2913 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -76,7 +76,7 @@ index d9941b38ca..71ab65e00f 100644
List<PlayerChunk> allChunks = new ArrayList<>(visibleChunks.values());
List<EntityPlayer> players = world.players;
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 7647b804fa..fb7bbe8744 100644
index e22ef19534..db5a35598d 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {

View file

@ -31,7 +31,7 @@ index a3b5793e48..71089442c1 100644
public BaseBlockPosition(int i, int j, int k) {
this.a = i;
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 39e77f8248..7ddf6592f7 100644
index 8f3eee5ea8..4b162a768e 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {

View file

@ -19,7 +19,7 @@ index 8cf3076f4e..721eceeffc 100644
+ }
}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index d1761ff3c4..e66bbb7ee3 100644
index 6694d0e36c..87d68a3e21 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {

View file

@ -7,7 +7,7 @@ I hope to look at this more in-depth soon. It appears doable.
However this should not block the update.
diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java
index 6a4ccaeb0f..af10fc36e0 100644
index 6a4ccaeb0f..5bf99e0028 100644
--- a/src/main/java/net/minecraft/server/EntityEnderDragon.java
+++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java
@@ -0,0 +0,0 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
@ -15,7 +15,7 @@ index 6a4ccaeb0f..af10fc36e0 100644
// this.world.b(1028, new BlockPosition(this), 0);
// Paper start
- //int viewDistance = ((WorldServer) this.world).spigotConfig.viewDistance * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API
+ int viewDistance = ((WorldServer) this.world).spigotConfig.viewDistance * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API
+ int viewDistance = this.world.getWorld().getViewDistance() * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API
for (EntityPlayer player : ((WorldServer)world).getPlayers()) {
- final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch
+ //final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch
@ -23,7 +23,7 @@ index 6a4ccaeb0f..af10fc36e0 100644
double deltaX = this.locX() - player.locX();
double deltaZ = this.locZ() - player.locZ();
diff --git a/src/main/java/net/minecraft/server/EntityWither.java b/src/main/java/net/minecraft/server/EntityWither.java
index 2e95069c19..8977c3516b 100644
index 2e95069c19..2f466af4d5 100644
--- a/src/main/java/net/minecraft/server/EntityWither.java
+++ b/src/main/java/net/minecraft/server/EntityWither.java
@@ -0,0 +0,0 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
@ -31,7 +31,7 @@ index 2e95069c19..8977c3516b 100644
// this.world.b(1023, new BlockPosition(this), 0);
// Paper start
- //int viewDistance = ((WorldServer) this.world).spigotConfig.viewDistance * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API
+ int viewDistance = ((WorldServer) this.world).spigotConfig.viewDistance * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API
+ int viewDistance = this.world.getWorld().getViewDistance() * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API
for (EntityPlayer player : ((WorldServer)world).getPlayers()) {
- final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch
+ //final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch
@ -39,7 +39,7 @@ index 2e95069c19..8977c3516b 100644
double deltaX = this.locX() - player.locX();
double deltaZ = this.locZ() - player.locZ();
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 6e3bcfe2cd..e76f2b9c7f 100644
index 6e3bcfe2cd..6672feaf51 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@ -49,12 +49,12 @@ index 6e3bcfe2cd..e76f2b9c7f 100644
+
+ @Override
+ public int getViewDistance() {
+ throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement"); // TODO
+ throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement (There are per world view distances though!)"); // TODO
+ }
+
+ @Override
+ public void setViewDistance(int viewDistance) {
+ throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement"); // TODO
+ throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement (There are per world view distances though!)"); // TODO
+ }
// Paper end

View file

@ -10,7 +10,7 @@ When not per player it will use the Vanilla mechanic of one delay per
world and the world age for the start day.
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index e93176d8f2..659a011e97 100644
index 7ca67a4aa5..803be76772 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
@ -36,7 +36,7 @@ index e93176d8f2..659a011e97 100644
private void entitiesTargetWithFollowRange() {
entitiesTargetWithFollowRange = getBoolean("entities-target-with-follow-range", entitiesTargetWithFollowRange);
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 9da6ed85fa..c6474aa0f8 100644
index cf837bdb3b..900631ebe0 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {

View file

@ -48,7 +48,7 @@ index bf32997c42..88692d9eae 100644
public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> cachedSingleHashSet; // Paper
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index a851997e5f..175734b50c 100644
index 0edba59675..7804cc0f6a 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {

View file

@ -7,7 +7,7 @@ Suspected case would be around the technique used in .stopRiding
Stack will identify any causer of this and warn instead of crashing.
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 8f477767b9..7647b804fa 100644
index 73bfebb837..e22ef19534 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -26,7 +26,7 @@ index 8f477767b9..7647b804fa 100644
if (!(entity instanceof EntityLightning)) {
EntityTypes<?> entitytypes = entity.getEntityType();
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 3f8f40018d..532aba2a5d 100644
index 9fbe8fa1b2..2a7a47c670 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -80,7 +80,7 @@ index 13d99de2cd..f54572773c 100644
public static ChunkStatus.Type a(@Nullable NBTTagCompound nbttagcompound) {
if (nbttagcompound != null) {
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 6ce7f77a5e..87762b1725 100644
index 02d9c754b1..d1424325d5 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -5,7 +5,7 @@ Subject: [PATCH] Prevent opening inventories when frozen
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 50886c1374..0c0224d1eb 100644
index d51af68a92..f453ccdb02 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {

View file

@ -8,7 +8,7 @@ These are a critical sign that somethin went wrong, and you've lost some data...
We should kind of know about these things you know.
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index c5b4218b44..4cbf390ce0 100644
index 7c1a748c9b..25e2a6580a 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -1,211 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: froobynooby <froobynooby@froobworld.com>
Date: Thu, 20 Feb 2020 15:50:49 +0930
Subject: [PATCH] Reduce entity tracker updates on move
With this patch, for each player we keep track of a set of
entities that the player is tracking. This is used to split
the entity tracker update logic in the movePlayer method in
PlayerChunkMap in to two parts:
* Full update: Run through all entity trackers and update them
* Partial update: Run through all entity trackers for entities
the player is already tracking and update them
Partial updates will always take less time than full updates,
usually by a considerable amount if players and entities are
spread out over the map. Assuming they are evenly spread,
and given there are x many players, it would be expected to
take 1/x the time of a full update.
Full updates are only run if the following conditions are met:
* It has been 20 ticks since the last full update
* The player has moved over set distance since the last full
update (distance is configurable)
The motivation for the first condition is that the client
sends the server its position once a second, which calls
movePlayer, so at a minimum we want to be sending the player
an updated set of entities it can see every second.
The motivation for the second condition is that looping
through every entity in world to check if it is now within
the tracking range after the player has moved 0.1 blocks is
largely unnecessary. Checking only after the player has moved
1 or 2 blocks is far better for performance, and very unlikely
to give any noticeable side effects.
In testing, this has reduced the time taken for movement
packet processing by up to 4x. Packet processing for movement
packets often show up as a major contributor to TPS loss in
servers with large player counts
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 7ca67a4aa5..e93176d8f2 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
private void zombieVillagerInfectionChance() {
zombieVillagerInfectionChance = getDouble("zombie-villager-infection-chance", zombieVillagerInfectionChance);
}
+
+ public double trackerUpdateDistance = 1;
+ private void trackerUpdateDistance() {
+ trackerUpdateDistance = getDouble("tracker-update-distance", trackerUpdateDistance);
+ }
}
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index cf837bdb3b..9da6ed85fa 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
public final int[] mobCounts = new int[ENUMCREATURETYPE_TOTAL_ENUMS]; // Paper
public final com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> cachedSingleMobDistanceMap;
// Paper end
+ // Paper start - Reduce entity tracker updates on move
+ public Vec3D lastTrackedPosition = new Vec3D(0, 0, 0);
+ public long lastTrackedTick;
+ // Paper end
// CraftBukkit start
public String displayName;
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 043ba702d7..8f477767b9 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
+ // Paper end
+
+ // Paper start - Reduce entity tracker updates on move
+ private double trackerUpdateDistanceSquared;
+ private final Int2ObjectMap<Int2ObjectMap<PlayerChunkMap.EntityTracker>> playerTrackedEntities = new Int2ObjectOpenHashMap<>();
+ private final Int2ObjectMap<Queue<Integer>> playerTrackedEntitiesRemoveQueue = new Int2ObjectOpenHashMap<>();
+
+ void flushRemoveQueue(EntityPlayer entityplayer) {
+ Queue<Integer> removeQueue = getPlayerTrackedEntityMapRemoveQueue(entityplayer.getId());
+ Int2ObjectMap<PlayerChunkMap.EntityTracker> entityMap = getPlayerTrackedEntityMap(entityplayer.getId());
+ for (Integer id = removeQueue.poll(); id != null; id = removeQueue.poll()) {
+ entityMap.remove(id);
+ }
+ }
+
+ void flushRemoveQueues() {
+ for (Int2ObjectMap.Entry<Queue<Integer>> entry : playerTrackedEntitiesRemoveQueue.int2ObjectEntrySet()) {
+ Int2ObjectMap<EntityTracker> entityMap = getPlayerTrackedEntityMap(entry.getKey());
+ Queue<Integer> removeQueue = entry.getValue();
+ for (Integer id = removeQueue.poll(); id != null; id = removeQueue.poll()) {
+ entityMap.remove(id);
+ }
+ }
+ }
+
+ Int2ObjectMap<EntityTracker> getPlayerTrackedEntityMap(int id) {
+ return playerTrackedEntities.computeIfAbsent(id, i -> new Int2ObjectOpenHashMap<>());
+ }
+
+ Queue<Integer> getPlayerTrackedEntityMapRemoveQueue(int id) {
+ return playerTrackedEntitiesRemoveQueue.computeIfAbsent(id, i -> new java.util.ArrayDeque<>());
+ }
+
// Paper end
public PlayerChunkMap(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, IAsyncTaskHandler<Runnable> iasynctaskhandler, ILightAccess ilightaccess, ChunkGenerator<?> chunkgenerator, WorldLoadListener worldloadlistener, Supplier<WorldPersistentData> supplier, int i) {
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.m = new VillagePlace(new File(this.w, "poi"), datafixer, this.world); // Paper
this.setViewDistance(i);
this.playerMobDistanceMap = this.world.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper
+ this.trackerUpdateDistanceSquared = Math.pow(this.world.paperConfig.trackerUpdateDistance, 2); // Paper
}
public void updatePlayerMobTypeMap(Entity entity) {
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
public void movePlayer(EntityPlayer entityplayer) {
- ObjectIterator objectiterator = this.trackedEntities.values().iterator();
+ // Paper start
+ // ObjectIterator objectiterator = this.trackedEntities.values().iterator();
+ ObjectIterator objectiterator;
+ if (MinecraftServer.currentTick - entityplayer.lastTrackedTick >= 20
+ || entityplayer.lastTrackedPosition.distanceSquared(entityplayer.getPositionVector()) >= trackerUpdateDistanceSquared) {
+ entityplayer.lastTrackedPosition = entityplayer.getPositionVector();
+ entityplayer.lastTrackedTick = MinecraftServer.currentTick;
+ objectiterator = this.trackedEntities.values().iterator(); // Update all entity trackers
+ } else {
+ objectiterator = getPlayerTrackedEntityMap(entityplayer.getId()).values().iterator(); // Only update entity trackers for already tracked entities
+ }
+ // Paper end
while (objectiterator.hasNext()) {
PlayerChunkMap.EntityTracker playerchunkmap_entitytracker = (PlayerChunkMap.EntityTracker) objectiterator.next();
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
playerchunkmap_entitytracker.updatePlayer(entityplayer);
}
}
+ flushRemoveQueues(); // Paper
int i = MathHelper.floor(entityplayer.locX()) >> 4;
int j = MathHelper.floor(entityplayer.locZ()) >> 4;
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
playerchunkmap_entitytracker.clear(entityplayer);
}
+ // Paper start
+ playerTrackedEntities.remove(entityplayer.getId());
+ playerTrackedEntitiesRemoveQueue.remove(entityplayer.getId());
+ // Paper end
}
PlayerChunkMap.EntityTracker playerchunkmap_entitytracker1 = (PlayerChunkMap.EntityTracker) this.trackedEntities.remove(entity.getId());
if (playerchunkmap_entitytracker1 != null) {
playerchunkmap_entitytracker1.a();
+ // Paper start
+ for (EntityPlayer player : playerchunkmap_entitytracker1.trackedPlayers) {
+ getPlayerTrackedEntityMap(player.getId()).remove(playerchunkmap_entitytracker1.tracker.getId());
+ }
+ // Paper end
}
entity.tracker = null; // Paper - We're no longer tracked
}
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
world.timings.tracker2.stopTiming(); // Paper
}
-
+ flushRemoveQueues(); // Paper
}
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
}
}
+ flushRemoveQueue(entityplayer); // Paper
Iterator iterator;
Entity entity1;
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot
if (this.trackedPlayers.remove(entityplayer)) {
this.trackerEntry.a(entityplayer);
+ getPlayerTrackedEntityMap(entityplayer.getId()).remove(this.tracker.getId()); // Paper
}
}
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
if (flag1 && this.trackedPlayerMap.putIfAbsent(entityplayer, true) == null) { // Paper
this.trackerEntry.b(entityplayer);
+ getPlayerTrackedEntityMap(entityplayer.getId()).put(this.tracker.getId(), this); // Paper
}
} else if (this.trackedPlayers.remove(entityplayer)) {
this.trackerEntry.a(entityplayer);
+ getPlayerTrackedEntityMapRemoveQueue(entityplayer.getId()).add(this.tracker.getId()); // Paper
}
}
--

View file

@ -5,7 +5,7 @@ Subject: [PATCH] Remove invalid mob spawner tile entities
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 4cd353b253..56d740fcad 100644
index 352bb787fd..687e609cab 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {

View file

@ -67,7 +67,7 @@ index aaedbaf4d7..0e8d31babd 100644
}
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index fd42f34004..6f66c38650 100644
index f8d1cb0231..f46da0e8a0 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -77,7 +77,7 @@ index a75e0ec54e..a13fd9b340 100644
this.c();
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 5e31b65e16..d49f456f73 100644
index 65134c8777..eece2f689c 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {

View file

@ -46,7 +46,7 @@ index 5ae0927c14..6b67201852 100644
double d5 = d1 - entityplayer.locY();
double d6 = d2 - entityplayer.locZ();
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 8d292604c3..09176e6040 100644
index f071b61195..ad779650ed 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -110,7 +110,7 @@ index 71089442c1..c439a8d019 100644
return (int) (f + f1 + f2);
}
diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
index 5dbd3e60fe..e9ea232a78 100644
index f8ac39e1b0..0ab2b23440 100644
--- a/src/main/java/net/minecraft/server/BlockPosition.java
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali

View file

@ -6,7 +6,7 @@ Subject: [PATCH] Store counts for each Entity/Block Entity Type
Opens door for future patches to optimize performance
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 061384b012..2b6fe2e01d 100644
index 4d7dc71474..a144f4ef56 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {

View file

@ -8,7 +8,7 @@ This enables us a fast reference to the entities current chunk instead
of having to look it up by hashmap lookups.
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index c50fe1c245..061384b012 100644
index b39ce329aa..4d7dc71474 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {

View file

@ -343,7 +343,7 @@ index cd72a9c845..5de881371a 100644
private final float frictionFactor;
private final float f;
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 2b6fe2e01d..4cd353b253 100644
index a144f4ef56..352bb787fd 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {
@ -934,7 +934,7 @@ index b4a0bd7951..67bdd57747 100644
this.methodProfiler.exit();
}
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 93d838ec2d..5e31b65e16 100644
index b505244516..65134c8777 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@
@ -1260,7 +1260,7 @@ index 2a4fa455ff..f572c5f227 100644
CrashReport crashreport = CrashReport.a(throwable, "Ticking entity");
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being ticked");
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 8a5ac6f69b..6810d49b17 100644
index d5014abc9d..38a71bca2f 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@

View file

@ -8,7 +8,7 @@ Sets tracking range of watermobs to animals instead of misc and simplifies code
Also ignores Enderdragon, defaulting it to Mojang's setting
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index a7b981f299..043ba702d7 100644
index 0fd1d6b3e6..73bfebb837 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {

View file

@ -7,7 +7,7 @@ The cache should contain the chunk status when saving. If not it
will load it.
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 405f57874e..c9c25cdb8e 100644
index 1d517fd1ae..9171785ad5 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {

View file

@ -0,0 +1,378 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Tue, 5 May 2020 20:18:05 -0700
Subject: [PATCH] Use distance map to optimise entity tracker
Use the distance map to find candidate players for tracking.
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 14ba037c1d..8820e4b650 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
}
// Paper end
+ // Paper start - optimise entity tracking
+ final org.spigotmc.TrackingRange.TrackingRangeType trackingRangeType = org.spigotmc.TrackingRange.getTrackingRangeType(this);
+
+ boolean isLegacyTrackingEntity = false;
+
+ public final void setLegacyTrackingEntity(final boolean isLegacyTrackingEntity) {
+ this.isLegacyTrackingEntity = isLegacyTrackingEntity;
+ }
+
+ final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> getPlayersInTrackRange() {
+ return ((WorldServer)this.world).getChunkProvider().playerChunkMap.playerEntityTrackerTrackMaps[this.trackingRangeType.ordinal()]
+ .getObjectsInRange(MCUtil.getCoordinateKey(this));
+ }
+ // Paper end - optimise entity tracking
+
public Entity(EntityTypes<?> entitytypes, World world) {
this.id = Entity.entityCount.incrementAndGet();
this.passengers = Lists.newArrayList();
diff --git a/src/main/java/net/minecraft/server/EntityTrackerEntry.java b/src/main/java/net/minecraft/server/EntityTrackerEntry.java
index 3a88c9a670..6d3b34ead9 100644
--- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java
+++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java
@@ -0,0 +0,0 @@ public class EntityTrackerEntry {
this.r = entity.onGround;
}
+ public final void tick() { this.a(); } // Paper - OBFHELPER
public void a() {
List<Entity> list = this.tracker.getPassengers();
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index e08a3bd96c..a780cf5b45 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
// Paper start - distance maps
private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<EntityPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>();
+ // Paper start - use distance map to optimise tracker
+ public static boolean isLegacyTrackingEntity(Entity entity) {
+ return entity.isLegacyTrackingEntity;
+ }
+
+ // inlined EnumMap, TrackingRange.TrackingRangeType
+ static final org.spigotmc.TrackingRange.TrackingRangeType[] TRACKING_RANGE_TYPES = org.spigotmc.TrackingRange.TrackingRangeType.values();
+ final com.destroystokyo.paper.util.misc.PlayerAreaMap[] playerEntityTrackerTrackMaps;
+ final int[] entityTrackerTrackRanges;
+ // Paper end - use distance map to optimise tracker
void addPlayerToDistanceMaps(EntityPlayer player) {
int chunkX = MCUtil.getChunkCoordinate(player.locX());
int chunkZ = MCUtil.getChunkCoordinate(player.locZ());
// Note: players need to be explicitly added to distance maps before they can be updated
+ // Paper start - use distance map to optimise entity tracker
+ for (int i = 0, len = TRACKING_RANGE_TYPES.length; i < len; ++i) {
+ com.destroystokyo.paper.util.misc.PlayerAreaMap trackMap = this.playerEntityTrackerTrackMaps[i];
+ int trackRange = this.entityTrackerTrackRanges[i];
+
+ trackMap.add(player, chunkX, chunkZ, Math.min(trackRange, this.getEffectiveViewDistance()));
+ }
+ // Paper end - use distance map to optimise entity tracker
}
void removePlayerFromDistanceMaps(EntityPlayer player) {
-
+ // Paper start - use distance map to optimise tracker
+ for (int i = 0, len = TRACKING_RANGE_TYPES.length; i < len; ++i) {
+ this.playerEntityTrackerTrackMaps[i].remove(player);
+ }
+ // Paper end - use distance map to optimise tracker
}
void updateMaps(EntityPlayer player) {
int chunkX = MCUtil.getChunkCoordinate(player.locX());
int chunkZ = MCUtil.getChunkCoordinate(player.locZ());
// Note: players need to be explicitly added to distance maps before they can be updated
+ // Paper start - use distance map to optimise entity tracker
+ for (int i = 0, len = TRACKING_RANGE_TYPES.length; i < len; ++i) {
+ com.destroystokyo.paper.util.misc.PlayerAreaMap trackMap = this.playerEntityTrackerTrackMaps[i];
+ int trackRange = this.entityTrackerTrackRanges[i];
+
+ trackMap.update(player, chunkX, chunkZ, Math.min(trackRange, this.getEffectiveViewDistance()));
+ }
+ // Paper end - use distance map to optimise entity tracker
}
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.m = new VillagePlace(new File(this.w, "poi"), datafixer, this.world); // Paper
this.setViewDistance(i);
this.playerMobDistanceMap = this.world.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper
+ // Paper start - use distance map to optimise entity tracker
+ this.playerEntityTrackerTrackMaps = new com.destroystokyo.paper.util.misc.PlayerAreaMap[TRACKING_RANGE_TYPES.length];
+ this.entityTrackerTrackRanges = new int[TRACKING_RANGE_TYPES.length];
+
+ org.spigotmc.SpigotWorldConfig spigotWorldConfig = this.world.spigotConfig;
+
+ for (int ordinal = 0, len = TRACKING_RANGE_TYPES.length; ordinal < len; ++ordinal) {
+ org.spigotmc.TrackingRange.TrackingRangeType trackingRangeType = TRACKING_RANGE_TYPES[ordinal];
+ int configuredSpigotValue;
+ switch (trackingRangeType) {
+ case PLAYER:
+ configuredSpigotValue = spigotWorldConfig.playerTrackingRange;
+ break;
+ case ANIMAL:
+ configuredSpigotValue = spigotWorldConfig.animalTrackingRange;
+ break;
+ case MONSTER:
+ configuredSpigotValue = spigotWorldConfig.monsterTrackingRange;
+ break;
+ case MISC:
+ configuredSpigotValue = spigotWorldConfig.miscTrackingRange;
+ break;
+ case OTHER:
+ configuredSpigotValue = spigotWorldConfig.otherTrackingRange;
+ break;
+ case ENDERDRAGON:
+ configuredSpigotValue = 10 * 16; // default is 10 chunk range // TODO check on update
+ break;
+ default:
+ throw new IllegalStateException("Missing case for enum " + trackingRangeType);
+ }
+
+ int trackRange = (configuredSpigotValue >>> 4) + ((configuredSpigotValue & 15) != 0 ? 1 : 0);
+ this.entityTrackerTrackRanges[ordinal] = trackRange;
+
+ this.playerEntityTrackerTrackMaps[ordinal] = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets);
+ }
+ // Paper end - use distance map to optimise entity tracker
}
public void updatePlayerMobTypeMap(Entity entity) {
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
public void movePlayer(EntityPlayer entityplayer) {
- ObjectIterator objectiterator = this.trackedEntities.values().iterator();
-
- while (objectiterator.hasNext()) {
- PlayerChunkMap.EntityTracker playerchunkmap_entitytracker = (PlayerChunkMap.EntityTracker) objectiterator.next();
-
- if (playerchunkmap_entitytracker.tracker == entityplayer) {
- playerchunkmap_entitytracker.track(this.world.getPlayers());
- } else {
- playerchunkmap_entitytracker.updatePlayer(entityplayer);
- }
- }
+ // Paper - delay this logic for the entity tracker tick, no need to duplicate it
int i = MathHelper.floor(entityplayer.locX()) >> 4;
int j = MathHelper.floor(entityplayer.locZ()) >> 4;
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker);
- playerchunkmap_entitytracker.track(this.world.getPlayers());
+ playerchunkmap_entitytracker.updatePlayers(entity.getPlayersInTrackRange()); // Paper - don't search all players
if (entity instanceof EntityPlayer) {
EntityPlayer entityplayer = (EntityPlayer) entity;
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
entity.tracker = null; // Paper - We're no longer tracked
}
+ // Paper start - optimised tracker
+ private final void processTrackQueue() {
+ this.world.timings.tracker1.startTiming();
+ try {
+ Entity[] entities = this.world.loadedEntities.getRawData();
+ for (int i = 0, len = this.world.loadedEntities.size(); i < len; ++i) {
+ Entity tracked = entities[i];
+ // update tracker entry
+ EntityTracker tracker = this.trackedEntities.get(tracked.getId());
+ if (tracker == null) {
+ continue;
+ }
+ tracker.updatePlayers(tracked.getPlayersInTrackRange());
+ }
+ } finally {
+ this.world.timings.tracker1.stopTiming();
+ }
+
+
+ this.world.timings.tracker2.startTiming();
+ try {
+ Entity[] entities = this.world.loadedEntities.getRawData();
+ for (int i = 0, len = this.world.loadedEntities.size(); i < len; ++i) {
+ Entity tracked = entities[i];
+ EntityTracker tracker = this.trackedEntities.get(tracked.getId());
+ if (tracker != null) {
+ tracker.trackerEntry.tick();
+ }
+ }
+ } finally {
+ this.world.timings.tracker2.stopTiming();
+ }
+ }
+ // Paper end - optimised tracker
+
protected void g() {
+ // Paper start - optimized tracker
+ if (true) {
+ this.processTrackQueue();
+ return;
+ }
+ // Paper end - optimized tracker
List<EntityPlayer> list = Lists.newArrayList();
List<EntityPlayer> list1 = this.world.getPlayers();
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
PacketDebug.a(this.world, chunk.getPos());
List<Entity> list = Lists.newArrayList();
List<Entity> list1 = Lists.newArrayList();
- ObjectIterator objectiterator = this.trackedEntities.values().iterator();
+ // Paper start - optimise entity tracker
+ // use the chunk entity list, not the whole trackedEntities map...
+ Entity[] entities = chunk.entities.getRawData();
+ for (int i = 0, size = chunk.entities.size(); i < size; ++i) {
+ Entity entity = entities[i];
+ if (entity == entityplayer) {
+ continue;
+ }
+ PlayerChunkMap.EntityTracker tracker = this.trackedEntities.get(entity.getId());
+ if (tracker != null) { // dumb plugins... move on...
+ tracker.updatePlayer(entityplayer);
+ }
- while (objectiterator.hasNext()) {
- PlayerChunkMap.EntityTracker playerchunkmap_entitytracker = (PlayerChunkMap.EntityTracker) objectiterator.next();
- Entity entity = playerchunkmap_entitytracker.tracker;
+ // keep the vanilla logic here - this is REQUIRED or else passengers and their vehicles disappear!
+ // (and god knows what the leash thing is)
- if (entity != entityplayer && entity.chunkX == chunk.getPos().x && entity.chunkZ == chunk.getPos().z) {
- playerchunkmap_entitytracker.updatePlayer(entityplayer);
- if (entity instanceof EntityInsentient && ((EntityInsentient) entity).getLeashHolder() != null) {
- list.add(entity);
- }
+ if (entity instanceof EntityInsentient && ((EntityInsentient)entity).getLeashHolder() != null) {
+ list.add(entity);
+ }
- if (!entity.getPassengers().isEmpty()) {
- list1.add(entity);
- }
+ if (!entity.getPassengers().isEmpty()) {
+ list1.add(entity);
}
}
+ // Paper end - optimise entity tracker
Iterator iterator;
Entity entity1;
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
public class EntityTracker {
- private final EntityTrackerEntry trackerEntry;
+ final EntityTrackerEntry trackerEntry; // Paper - private -> package private
private final Entity tracker;
private final int trackingDistance;
private SectionPosition e;
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.e = SectionPosition.a(entity);
}
+ // Paper start - use distance map to optimise tracker
+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> lastTrackerCandidates;
+
+ final void updatePlayers(com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> newTrackerCandidates) {
+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> oldTrackerCandidates = this.lastTrackerCandidates;
+ this.lastTrackerCandidates = newTrackerCandidates;
+
+ if (newTrackerCandidates != null) {
+ Object[] rawData = newTrackerCandidates.getBackingSet();
+ for (int i = 0, len = rawData.length; i < len; ++i) {
+ Object raw = rawData[i];
+ if (!(raw instanceof EntityPlayer)) {
+ continue;
+ }
+ EntityPlayer player = (EntityPlayer)raw;
+ this.updatePlayer(player);
+ }
+ }
+
+ if (oldTrackerCandidates == newTrackerCandidates) {
+ // this is likely the case.
+ // means there has been no range changes, so we can just use the above for tracking.
+ return;
+ }
+
+ // stuff could have been removed, so we need to check the trackedPlayers set
+ // for players that were removed
+
+ for (EntityPlayer player : this.trackedPlayers.toArray(new EntityPlayer[0])) { // avoid CME
+ if (newTrackerCandidates == null || !newTrackerCandidates.contains(player)) {
+ this.updatePlayer(player);
+ }
+ }
+ }
+ // Paper end - use distance map to optimise tracker
+
public boolean equals(Object object) {
return object instanceof PlayerChunkMap.EntityTracker ? ((PlayerChunkMap.EntityTracker) object).tracker.getId() == this.tracker.getId() : false;
}
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
int j = entity.getEntityType().getChunkRange() * 16;
j = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, j); // Paper
- if (j > i) {
+ if (j < i) { // Paper - we need the lowest range thanks to the fact that our tracker doesn't account for passenger logic
i = j;
}
}
diff --git a/src/main/java/org/spigotmc/TrackingRange.java b/src/main/java/org/spigotmc/TrackingRange.java
index 765bdaf9b5..43b5ed8e39 100644
--- a/src/main/java/org/spigotmc/TrackingRange.java
+++ b/src/main/java/org/spigotmc/TrackingRange.java
@@ -0,0 +0,0 @@ public class TrackingRange
return config.otherTrackingRange;
}
}
+
+ // Paper start - optimise entity tracking
+ // copied from above, TODO check on update
+ public static TrackingRangeType getTrackingRangeType(Entity entity)
+ {
+ if ( entity instanceof EntityPlayer )
+ {
+ return TrackingRangeType.PLAYER;
+ // Paper start - Simplify and set water mobs to animal tracking range
+ }
+ switch (entity.activationType) {
+ case RAIDER:
+ case MONSTER:
+ return TrackingRangeType.MONSTER;
+ case WATER:
+ case ANIMAL:
+ return TrackingRangeType.ANIMAL;
+ case MISC:
+ }
+ if ( entity instanceof EntityItemFrame || entity instanceof EntityPainting || entity instanceof EntityItem || entity instanceof EntityExperienceOrb )
+ // Paper end
+ {
+ return TrackingRangeType.MISC;
+ } else
+ {
+ if (entity instanceof EntityEnderDragon) return TrackingRangeType.ENDERDRAGON; // Paper - enderdragon is exempt
+ return TrackingRangeType.OTHER;
+ }
+ }
+
+ public static enum TrackingRangeType {
+ PLAYER,
+ ANIMAL,
+ MONSTER,
+ MISC,
+ OTHER,
+ ENDERDRAGON;
+ }
+ // Paper end - optimise entity tracking
}
--

View file

@ -5,7 +5,7 @@ Subject: [PATCH] Validate PickItem Packet and kick for invalid
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
index 376f7f8f0b..a33289749c 100644
index a180df220e..02bda8bee4 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn {

View file

@ -643,7 +643,7 @@ index 8427ee2ee8..0f04bcc8b7 100644
return this.bb;
}
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 19603343b2..a7b981f299 100644
index 43abdb47fd..0fd1d6b3e6 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -755,7 +755,7 @@ index fdac5bb3a2..58bbf2f9d2 100644
@Nullable
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index f9aed78188..fd8ca2a510 100644
index 731f6a8320..38c5b721bf 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {

View file

@ -29,7 +29,7 @@ index 071e5e7f72..4867615215 100644
+ }
}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 7bcdbe713d..4b77934c39 100644
index 165cb994e8..af0d6aff4d 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {
@ -175,7 +175,7 @@ index a640cb3845..3d255b1964 100644
public void a(ProtoChunkExtension protochunkextension) {
for (int i = 0; i < this.statusFutures.length(); ++i) {
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 6122d19ccf..4682dca9de 100644
index 34f470779f..4f5b516144 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -261,7 +261,7 @@ index 6122d19ccf..4682dca9de 100644
return PlayerChunk.getChunkState(playerchunk.getTicketLevel());
});
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 389c9d03a1..62c2275098 100644
index ce506e0e12..ad5e538b24 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {