Use AreaMap for per-player mob spawning (#7235)

This commit is contained in:
Jason 2022-01-02 11:06:08 -08:00 committed by GitHub
parent 19bc612483
commit 79dd62ae62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
264 changed files with 207 additions and 457 deletions

View File

@ -4,26 +4,6 @@ Date: Mon, 19 Aug 2019 01:27:58 +0500
Subject: [PATCH] implement optional per player mob spawns Subject: [PATCH] implement optional per player mob spawns
diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java
index fe79c0add4f7cb18d487c5bb9415c40c5b551ea2..8d9ddad1879e7616d980ca70de8aecacaa86db35 100644
--- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java
+++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java
@@ -57,6 +57,7 @@ public class WorldTimingsHandler {
public final Timing miscMobSpawning;
+ public final Timing playerMobDistanceMapUpdate;
public final Timing poiUnload;
public final Timing chunkUnload;
@@ -121,6 +122,7 @@ public class WorldTimingsHandler {
miscMobSpawning = Timings.ofSafe(name + "Mob spawning - Misc");
+ playerMobDistanceMapUpdate = Timings.ofSafe(name + "Per Player Mob Spawning - Distance Map Update");
poiUnload = Timings.ofSafe(name + "Chunk unload - POI");
chunkUnload = Timings.ofSafe(name + "Chunk unload - Chunk");
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 619f5c11ae8e21b060b52b60d681db6dd9cb5816..88d140a03b6f28070b2f78588ee5ce4d5ac3cf0f 100644 index 619f5c11ae8e21b060b52b60d681db6dd9cb5816..88d140a03b6f28070b2f78588ee5ce4d5ac3cf0f 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@ -41,264 +21,6 @@ index 619f5c11ae8e21b060b52b60d681db6dd9cb5816..88d140a03b6f28070b2f78588ee5ce4d
+ perPlayerMobSpawns = getBoolean("per-player-mob-spawns", true); + perPlayerMobSpawns = getBoolean("per-player-mob-spawns", true);
+ } + }
} }
diff --git a/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java b/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java
new file mode 100644
index 0000000000000000000000000000000000000000..72063ba7fb0d04594043cb07034590d597c3d77e
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java
@@ -0,0 +1,252 @@
+package com.destroystokyo.paper.util;
+
+import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
+import java.util.List;
+import java.util.Map;
+import net.minecraft.core.SectionPos;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.level.ChunkPos;
+import org.spigotmc.AsyncCatcher;
+import java.util.HashMap;
+
+/** @author Spottedleaf */
+public final class PlayerMobDistanceMap {
+
+ private static final PooledHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> EMPTY_SET = new PooledHashSets.PooledObjectLinkedOpenHashSet<>();
+
+ private final Map<ServerPlayer, SectionPos> players = new HashMap<>();
+ // we use linked for better iteration.
+ private final Long2ObjectOpenHashMap<PooledHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer>> playerMap = new Long2ObjectOpenHashMap<>(32, 0.5f);
+ private int viewDistance;
+
+ private final PooledHashSets<ServerPlayer> pooledHashSets = new PooledHashSets<>();
+
+ public PooledHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> getPlayersInRange(final ChunkPos chunkPos) {
+ return this.getPlayersInRange(chunkPos.x, chunkPos.z);
+ }
+
+ public PooledHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> getPlayersInRange(final int chunkX, final int chunkZ) {
+ return this.playerMap.getOrDefault(ChunkPos.asLong(chunkX, chunkZ), EMPTY_SET);
+ }
+
+ public void update(final List<ServerPlayer> currentPlayers, final int newViewDistance) {
+ AsyncCatcher.catchOp("Distance map update");
+ final ObjectLinkedOpenHashSet<ServerPlayer> gone = new ObjectLinkedOpenHashSet<>(this.players.keySet());
+
+ final int oldViewDistance = this.viewDistance;
+ this.viewDistance = newViewDistance;
+
+ for (final ServerPlayer player : currentPlayers) {
+ if (player.isSpectator() || !player.affectsSpawning) {
+ continue; // will be left in 'gone' (or not added at all)
+ }
+
+ gone.remove(player);
+
+ final SectionPos newPosition = player.getLastSectionPos();
+ final SectionPos oldPosition = this.players.put(player, newPosition);
+
+ if (oldPosition == null) {
+ this.addNewPlayer(player, newPosition, newViewDistance);
+ } else {
+ this.updatePlayer(player, oldPosition, newPosition, oldViewDistance, newViewDistance);
+ }
+ //this.validatePlayer(player, newViewDistance); // debug only
+ }
+
+ for (final ServerPlayer player : gone) {
+ final SectionPos oldPosition = this.players.remove(player);
+ if (oldPosition != null) {
+ this.removePlayer(player, oldPosition, oldViewDistance);
+ }
+ }
+ }
+
+ // expensive op, only for debug
+ private void validatePlayer(final ServerPlayer player, final int viewDistance) {
+ int entiesGot = 0;
+ int expectedEntries = (2 * viewDistance + 1);
+ expectedEntries *= expectedEntries;
+
+ final SectionPos currPosition = player.getLastSectionPos();
+
+ final int centerX = currPosition.getX();
+ final int centerZ = currPosition.getZ();
+
+ for (final Long2ObjectLinkedOpenHashMap.Entry<PooledHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer>> entry : this.playerMap.long2ObjectEntrySet()) {
+ final long key = entry.getLongKey();
+ final PooledHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> map = entry.getValue();
+
+ if (map.referenceCount == 0) {
+ throw new IllegalStateException("Invalid map");
+ }
+
+ if (map.set.contains(player)) {
+ ++entiesGot;
+
+ final int chunkX = ChunkPos.getX(key);
+ final int chunkZ = ChunkPos.getZ(key);
+
+ final int dist = Math.max(Math.abs(chunkX - centerX), Math.abs(chunkZ - centerZ));
+
+ if (dist > viewDistance) {
+ throw new IllegalStateException("Expected view distance " + viewDistance + ", got " + dist);
+ }
+ }
+ }
+
+ if (entiesGot != expectedEntries) {
+ throw new IllegalStateException("Expected " + expectedEntries + ", got " + entiesGot);
+ }
+ }
+
+ private void addPlayerTo(final ServerPlayer player, final int chunkX, final int chunkZ) {
+ this.playerMap.compute(ChunkPos.asLong(chunkX, chunkZ), (final Long key, final PooledHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> players) -> {
+ if (players == null) {
+ return player.cachedSingleMobDistanceMap;
+ } else {
+ return PlayerMobDistanceMap.this.pooledHashSets.findMapWith(players, player);
+ }
+ });
+ }
+
+ private void removePlayerFrom(final ServerPlayer player, final int chunkX, final int chunkZ) {
+ this.playerMap.compute(ChunkPos.asLong(chunkX, chunkZ), (final Long keyInMap, final PooledHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> players) -> {
+ return PlayerMobDistanceMap.this.pooledHashSets.findMapWithout(players, player); // rets null instead of an empty map
+ });
+ }
+
+ private void updatePlayer(final ServerPlayer player, final SectionPos oldPosition, final SectionPos newPosition, final int oldViewDistance, final int newViewDistance) {
+ final int toX = newPosition.getX();
+ final int toZ = newPosition.getZ();
+ final int fromX = oldPosition.getX();
+ final int fromZ = oldPosition.getZ();
+
+ final int dx = toX - fromX;
+ final int dz = toZ - fromZ;
+
+ final int totalX = Math.abs(fromX - toX);
+ final int totalZ = Math.abs(fromZ - toZ);
+
+ if (Math.max(totalX, totalZ) > (2 * oldViewDistance)) {
+ // teleported?
+ this.removePlayer(player, oldPosition, oldViewDistance);
+ this.addNewPlayer(player, newPosition, newViewDistance);
+ return;
+ }
+
+ // x axis is width
+ // z axis is height
+ // right refers to the x axis of where we moved
+ // top refers to the z axis of where we moved
+
+ if (oldViewDistance == newViewDistance) {
+ // same view distance
+
+ // used for relative positioning
+ final int up = 1 | (dz >> (Integer.SIZE - 1)); // 1 if dz >= 0, -1 otherwise
+ final int right = 1 | (dx >> (Integer.SIZE - 1)); // 1 if dx >= 0, -1 otherwise
+
+ // The area excluded by overlapping the two view distance squares creates four rectangles:
+ // Two on the left, and two on the right. The ones on the left we consider the "removed" section
+ // and on the right the "added" section.
+ // https://i.imgur.com/MrnOBgI.png is a reference image. Note that the outside border is not actually
+ // exclusive to the regions they surround.
+
+ // 4 points of the rectangle
+ int maxX; // exclusive
+ int minX; // inclusive
+ int maxZ; // exclusive
+ int minZ; // inclusive
+
+ if (dx != 0) {
+ // handle right addition
+
+ maxX = toX + (oldViewDistance * right) + right; // exclusive
+ minX = fromX + (oldViewDistance * right) + right; // inclusive
+ maxZ = fromZ + (oldViewDistance * up) + up; // exclusive
+ minZ = toZ - (oldViewDistance * up); // inclusive
+
+ for (int currX = minX; currX != maxX; currX += right) {
+ for (int currZ = minZ; currZ != maxZ; currZ += up) {
+ this.addPlayerTo(player, currX, currZ);
+ }
+ }
+ }
+
+ if (dz != 0) {
+ // handle up addition
+
+ maxX = toX + (oldViewDistance * right) + right; // exclusive
+ minX = toX - (oldViewDistance * right); // inclusive
+ maxZ = toZ + (oldViewDistance * up) + up; // exclusive
+ minZ = fromZ + (oldViewDistance * up) + up; // inclusive
+
+ for (int currX = minX; currX != maxX; currX += right) {
+ for (int currZ = minZ; currZ != maxZ; currZ += up) {
+ this.addPlayerTo(player, currX, currZ);
+ }
+ }
+ }
+
+ if (dx != 0) {
+ // handle left removal
+
+ maxX = toX - (oldViewDistance * right); // exclusive
+ minX = fromX - (oldViewDistance * right); // inclusive
+ maxZ = fromZ + (oldViewDistance * up) + up; // exclusive
+ minZ = toZ - (oldViewDistance * up); // inclusive
+
+ for (int currX = minX; currX != maxX; currX += right) {
+ for (int currZ = minZ; currZ != maxZ; currZ += up) {
+ this.removePlayerFrom(player, currX, currZ);
+ }
+ }
+ }
+
+ if (dz != 0) {
+ // handle down removal
+
+ maxX = fromX + (oldViewDistance * right) + right; // exclusive
+ minX = fromX - (oldViewDistance * right); // inclusive
+ maxZ = toZ - (oldViewDistance * up); // exclusive
+ minZ = fromZ - (oldViewDistance * up); // inclusive
+
+ for (int currX = minX; currX != maxX; currX += right) {
+ for (int currZ = minZ; currZ != maxZ; currZ += up) {
+ this.removePlayerFrom(player, currX, currZ);
+ }
+ }
+ }
+ } else {
+ // different view distance
+ // for now :)
+ this.removePlayer(player, oldPosition, oldViewDistance);
+ this.addNewPlayer(player, newPosition, newViewDistance);
+ }
+ }
+
+ private void removePlayer(final ServerPlayer player, final SectionPos position, final int viewDistance) {
+ final int x = position.getX();
+ final int z = position.getZ();
+
+ for (int xoff = -viewDistance; xoff <= viewDistance; ++xoff) {
+ for (int zoff = -viewDistance; zoff <= viewDistance; ++zoff) {
+ this.removePlayerFrom(player, x + xoff, z + zoff);
+ }
+ }
+ }
+
+ private void addNewPlayer(final ServerPlayer player, final SectionPos position, final int viewDistance) {
+ final int x = position.getX();
+ final int z = position.getZ();
+
+ for (int xoff = -viewDistance; xoff <= viewDistance; ++xoff) {
+ for (int zoff = -viewDistance; zoff <= viewDistance; ++zoff) {
+ this.addPlayerTo(player, x + xoff, z + zoff);
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/util/PooledHashSets.java b/src/main/java/com/destroystokyo/paper/util/PooledHashSets.java diff --git a/src/main/java/com/destroystokyo/paper/util/PooledHashSets.java b/src/main/java/com/destroystokyo/paper/util/PooledHashSets.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..11de56afaf059b00fa5bec293516bcdce7c4b2b9 index 0000000000000000000000000000000000000000..11de56afaf059b00fa5bec293516bcdce7c4b2b9
@ -547,26 +269,58 @@ index 0000000000000000000000000000000000000000..11de56afaf059b00fa5bec293516bcdc
+ } + }
+} +}
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 0c82b270c7095c7e4666a8078ecc7142503795c4..0583d7ee24f694fbf5138dfae9f7b8c8e4225ab3 100644 index 0c82b270c7095c7e4666a8078ecc7142503795c4..2d7f0eb7df62d1c26ccf19cf61595227e19aa562 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -151,6 +151,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -151,6 +151,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
private final Long2ByteMap chunkTypeCache; private final Long2ByteMap chunkTypeCache;
private final Queue<Runnable> unloadQueue; private final Queue<Runnable> unloadQueue;
int viewDistance; int viewDistance;
+ public final com.destroystokyo.paper.util.PlayerMobDistanceMap playerMobDistanceMap; // Paper + public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobDistanceMap; // Paper
// CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback() // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback()
public final CallbackExecutor callbackExecutor = new CallbackExecutor(); public final CallbackExecutor callbackExecutor = new CallbackExecutor();
@@ -263,6 +264,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -180,16 +181,31 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
int chunkX = MCUtil.getChunkCoordinate(player.getX());
int chunkZ = MCUtil.getChunkCoordinate(player.getZ());
// Note: players need to be explicitly added to distance maps before they can be updated
+ // Paper start - per player mob spawning
+ if (this.playerMobDistanceMap != null) {
+ this.playerMobDistanceMap.add(player, chunkX, chunkZ, this.distanceManager.getSimulationDistance());
+ }
+ // Paper end - per player mob spawning
}
void removePlayerFromDistanceMaps(ServerPlayer player) {
+ // Paper start - per player mob spawning
+ if (this.playerMobDistanceMap != null) {
+ this.playerMobDistanceMap.remove(player);
+ }
+ // Paper end - per player mob spawning
}
void updateMaps(ServerPlayer player) {
int chunkX = MCUtil.getChunkCoordinate(player.getX());
int chunkZ = MCUtil.getChunkCoordinate(player.getZ());
// Note: players need to be explicitly added to distance maps before they can be updated
+ // Paper start - per player mob spawning
+ if (this.playerMobDistanceMap != null) {
+ this.playerMobDistanceMap.update(player, chunkX, chunkZ, this.distanceManager.getSimulationDistance());
+ }
+ // Paper end - per player mob spawning
}
// Paper end
// Paper start
@@ -263,6 +279,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.dataRegionManager = new io.papermc.paper.chunk.SingleThreadChunkRegionManager(this.level, 2, (1.0 / 3.0), 1, 6, "Data", DataRegionData::new, DataRegionSectionData::new); this.dataRegionManager = new io.papermc.paper.chunk.SingleThreadChunkRegionManager(this.level, 2, (1.0 / 3.0), 1, 6, "Data", DataRegionData::new, DataRegionSectionData::new);
this.regionManagers.add(this.dataRegionManager); this.regionManagers.add(this.dataRegionManager);
// Paper end // Paper end
+ this.playerMobDistanceMap = this.level.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper + this.playerMobDistanceMap = this.level.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets) : null; // Paper
} }
protected ChunkGenerator generator() { protected ChunkGenerator generator() {
@@ -280,6 +282,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -280,6 +297,31 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}); });
} }
@ -575,11 +329,17 @@ index 0c82b270c7095c7e4666a8078ecc7142503795c4..0583d7ee24f694fbf5138dfae9f7b8c8
+ if (!this.level.paperConfig.perPlayerMobSpawns) { + if (!this.level.paperConfig.perPlayerMobSpawns) {
+ return; + return;
+ } + }
+ int chunkX = (int)Math.floor(entity.getX()) >> 4;
+ int chunkZ = (int)Math.floor(entity.getZ()) >> 4;
+ int index = entity.getType().getCategory().ordinal(); + int index = entity.getType().getCategory().ordinal();
+ +
+ for (ServerPlayer player : this.playerMobDistanceMap.getPlayersInRange(chunkX, chunkZ)) { + final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> inRange = this.playerMobDistanceMap.getObjectsInRange(entity.chunkPosition());
+ if (inRange == null) {
+ return;
+ }
+ final Object[] backingSet = inRange.getBackingSet();
+ for (int i = 0; i < backingSet.length; i++) {
+ if (!(backingSet[i] instanceof final ServerPlayer player)) {
+ continue;
+ }
+ ++player.mobCounts[index]; + ++player.mobCounts[index];
+ } + }
+ } + }
@ -610,21 +370,17 @@ index f0dac1f596911eb2109192ef16a619f8ae71d1f7..07b616d9d7cde77c001f5c627daef073
this.naturalSpawnChunkCounter.runAllUpdates(); this.naturalSpawnChunkCounter.runAllUpdates();
return this.naturalSpawnChunkCounter.chunks.size(); return this.naturalSpawnChunkCounter.chunks.size();
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 7b391d6ab84eeaed7bdd27ea70d5e3f9690a0abf..d9405456f61b954f9b6fa2fa7939fc3a36ec6fc6 100644 index 7b391d6ab84eeaed7bdd27ea70d5e3f9690a0abf..0d380bba07c5c7b6b25fa2ce554418ef8ba9fdb1 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -916,7 +916,22 @@ public class ServerChunkCache extends ChunkSource { @@ -916,7 +916,18 @@ public class ServerChunkCache extends ChunkSource {
gameprofilerfiller.push("naturalSpawnCount"); gameprofilerfiller.push("naturalSpawnCount");
this.level.timings.countNaturalMobs.startTiming(); // Paper - timings this.level.timings.countNaturalMobs.startTiming(); // Paper - timings
int l = this.distanceManager.getNaturalSpawnChunkCount(); int l = this.distanceManager.getNaturalSpawnChunkCount();
- NaturalSpawner.SpawnState spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap)); - NaturalSpawner.SpawnState spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap));
+ // Paper start - per player mob spawning + // Paper start - per player mob spawning
+ NaturalSpawner.SpawnState spawnercreature_d; // moved down + NaturalSpawner.SpawnState spawnercreature_d; // moved down
+ if (this.chunkMap.playerMobDistanceMap != null) { + if ((this.spawnFriendlies || this.spawnEnemies) && this.chunkMap.playerMobDistanceMap != null) { // don't count mobs when animals and monsters are disabled
+ // update distance map
+ this.level.timings.playerMobDistanceMapUpdate.startTiming();
+ this.chunkMap.playerMobDistanceMap.update(this.level.players, this.distanceManager.getSimulationDistance());
+ this.level.timings.playerMobDistanceMapUpdate.stopTiming();
+ // re-set mob counts + // re-set mob counts
+ for (ServerPlayer player : this.level.players) { + for (ServerPlayer player : this.level.players) {
+ Arrays.fill(player.mobCounts, 0); + Arrays.fill(player.mobCounts, 0);
@ -662,7 +418,7 @@ index b193f8dfbe7b61c919ad5eb452d29885982e25e4..01b9edc8aaf472650f171f1b88229807
// Yes, this doesn't match Vanilla, but it's the best we can do for now. // Yes, this doesn't match Vanilla, but it's the best we can do for now.
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc267758df10ed 100644 index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..c0fb5d445ed18fbf52df2be754eab0d8fb6e9239 100644
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
@@ -65,7 +65,13 @@ public final class NaturalSpawner { @@ -65,7 +65,13 @@ public final class NaturalSpawner {
@ -684,7 +440,7 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
} }
- if (entity instanceof Mob) { - if (entity instanceof Mob) {
+ if (localmobcapcalculator != null && entity instanceof Mob) { + if (localmobcapcalculator != null && entity instanceof Mob) { // Paper
localmobcapcalculator.addMob(chunk.getPos(), enumcreaturetype); localmobcapcalculator.addMob(chunk.getPos(), enumcreaturetype);
} }
@ -697,7 +453,7 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
}); });
} }
} }
@@ -169,13 +180,30 @@ public final class NaturalSpawner { @@ -169,13 +180,37 @@ public final class NaturalSpawner {
continue; continue;
} }
@ -709,8 +465,15 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
+ +
+ if (world.paperConfig.perPlayerMobSpawns) { + if (world.paperConfig.perPlayerMobSpawns) {
+ int minDiff = Integer.MAX_VALUE; + int minDiff = Integer.MAX_VALUE;
+ for (net.minecraft.server.level.ServerPlayer entityplayer : world.getChunkSource().chunkMap.playerMobDistanceMap.getPlayersInRange(chunk.getPos())) { + final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<net.minecraft.server.level.ServerPlayer> inRange = world.getChunkSource().chunkMap.playerMobDistanceMap.getObjectsInRange(chunk.getPos());
+ minDiff = Math.min(limit - world.getChunkSource().chunkMap.getMobCountNear(entityplayer, enumcreaturetype), minDiff); + if (inRange != null) {
+ final Object[] backingSet = inRange.getBackingSet();
+ for (int k = 0; k < backingSet.length; k++) {
+ if (!(backingSet[k] instanceof final net.minecraft.server.level.ServerPlayer player)) {
+ continue;
+ }
+ minDiff = Math.min(limit - world.getChunkSource().chunkMap.getMobCountNear(player, enumcreaturetype), minDiff);
+ }
+ } + }
+ difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff; + difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff;
+ } + }
@ -730,7 +493,7 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
} }
} }
@@ -183,12 +211,18 @@ public final class NaturalSpawner { @@ -183,12 +218,18 @@ public final class NaturalSpawner {
world.getProfiler().pop(); world.getProfiler().pop();
} }
@ -750,7 +513,7 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
} }
@VisibleForDebug @VisibleForDebug
@@ -199,15 +233,21 @@ public final class NaturalSpawner { @@ -199,15 +240,21 @@ public final class NaturalSpawner {
}); });
} }
@ -773,7 +536,7 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
int k = 0; int k = 0;
while (k < 3) { while (k < 3) {
@@ -249,14 +289,14 @@ public final class NaturalSpawner { @@ -249,14 +296,14 @@ public final class NaturalSpawner {
// Paper start // Paper start
Boolean doSpawning = isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2); Boolean doSpawning = isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2);
if (doSpawning == null) { if (doSpawning == null) {
@ -790,7 +553,7 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
} }
entityinsentient.moveTo(d0, (double) i, d1, world.random.nextFloat() * 360.0F, 0.0F); entityinsentient.moveTo(d0, (double) i, d1, world.random.nextFloat() * 360.0F, 0.0F);
@@ -268,10 +308,15 @@ public final class NaturalSpawner { @@ -268,10 +315,15 @@ public final class NaturalSpawner {
++j; ++j;
++k1; ++k1;
runner.run(entityinsentient, chunk); runner.run(entityinsentient, chunk);
@ -808,7 +571,7 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
} }
if (entityinsentient.isMaxGroupSizeReached(k1)) { if (entityinsentient.isMaxGroupSizeReached(k1)) {
@@ -293,6 +338,7 @@ public final class NaturalSpawner { @@ -293,6 +345,7 @@ public final class NaturalSpawner {
} }
} }
@ -816,7 +579,7 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
} }
private static boolean isRightDistanceToPlayerAndSpawnPoint(ServerLevel world, ChunkAccess chunk, BlockPos.MutableBlockPos pos, double squaredDistance) { private static boolean isRightDistanceToPlayerAndSpawnPoint(ServerLevel world, ChunkAccess chunk, BlockPos.MutableBlockPos pos, double squaredDistance) {
@@ -572,7 +618,7 @@ public final class NaturalSpawner { @@ -572,7 +625,7 @@ public final class NaturalSpawner {
MobCategory enumcreaturetype = entitytypes.getCategory(); MobCategory enumcreaturetype = entitytypes.getCategory();
this.mobCategoryCounts.addTo(enumcreaturetype, 1); this.mobCategoryCounts.addTo(enumcreaturetype, 1);
@ -825,7 +588,7 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
} }
public int getSpawnableChunkCount() { public int getSpawnableChunkCount() {
@@ -588,6 +634,7 @@ public final class NaturalSpawner { @@ -588,6 +641,7 @@ public final class NaturalSpawner {
int i = limit * this.spawnableChunkCount / NaturalSpawner.MAGIC_NUMBER; int i = limit * this.spawnableChunkCount / NaturalSpawner.MAGIC_NUMBER;
// CraftBukkit end // CraftBukkit end

View File

@ -7,10 +7,10 @@ Suspected case would be around the technique used in .stopRiding
Stack will identify any causer of this and warn instead of crashing. Stack will identify any causer of this and warn instead of crashing.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 0583d7ee24f694fbf5138dfae9f7b8c8e4225ab3..27c304d66ecf0bb8d7b5b4343ca207880e14711b 100644 index 2d7f0eb7df62d1c26ccf19cf61595227e19aa562..ed4b4c3d3d991716078d5f008bf4665e76b30f33 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1539,6 +1539,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1560,6 +1560,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
public void addEntity(Entity entity) { public void addEntity(Entity entity) {
org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot

View File

@ -262,10 +262,10 @@ index 049eb5693dc98e1d0ec3bd88c73a41fdb2f59bff..0716aaf29f9d76240a0de4ca02daba44
} }
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 27c304d66ecf0bb8d7b5b4343ca207880e14711b..6f851c24a67d1b3a349790b0d60f45b23ff93bc6 100644 index ed4b4c3d3d991716078d5f008bf4665e76b30f33..4cb7e63b433b8d4a02c2d193a2596e51ddab2779 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -514,6 +514,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -535,6 +535,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
MutableBoolean mutableboolean = new MutableBoolean(); MutableBoolean mutableboolean = new MutableBoolean();
do { do {

View File

@ -25,7 +25,7 @@ This successfully fixed a reoccurring and highly reproduceable crash
for heightmaps. for heightmaps.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 6f851c24a67d1b3a349790b0d60f45b23ff93bc6..4566af37c76cb3a2fe6441451a444a5a3c9914f9 100644 index 4cb7e63b433b8d4a02c2d193a2596e51ddab2779..9396d1164355aa3f10a8e5adad4813be808c0ffb 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -174,6 +174,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -174,6 +174,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@ -36,7 +36,7 @@ index 6f851c24a67d1b3a349790b0d60f45b23ff93bc6..4566af37c76cb3a2fe6441451a444a5a
// Paper start - distance maps // Paper start - distance maps
private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>(); private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>();
@@ -954,7 +955,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -975,7 +976,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return Either.left(chunk); return Either.left(chunk);
}); });
}, (runnable) -> { }, (runnable) -> {
@ -46,10 +46,10 @@ index 6f851c24a67d1b3a349790b0d60f45b23ff93bc6..4566af37c76cb3a2fe6441451a444a5a
completablefuture1.thenAcceptAsync((either) -> { completablefuture1.thenAcceptAsync((either) -> {
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 5b6381858418ceca4fe40ef329e050538e980cdb..66dfe3d79fa3273a2bab64193f73f2b38002c18c 100644 index 19c44eae78802c9fe0479cdc32f21156dc9b9d45..02516d4a6ee08908765f5bc84b14560754a67680 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -1144,6 +1144,7 @@ public class ServerChunkCache extends ChunkSource { @@ -1140,6 +1140,7 @@ public class ServerChunkCache extends ChunkSource {
return super.pollTask() || execChunkTask; // Paper return super.pollTask() || execChunkTask; // Paper
} }
} finally { } finally {

View File

@ -28,10 +28,10 @@ receives a deterministic result, and should no longer require 1 tick
delays anymore. delays anymore.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 4566af37c76cb3a2fe6441451a444a5a3c9914f9..49e612fc0fc4ec991d821d0aa4b41f488dd9f832 100644 index 9396d1164355aa3f10a8e5adad4813be808c0ffb..5f576e6b749e36a4729439930f48e2b1cdddef16 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1548,6 +1548,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1569,6 +1569,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
.printStackTrace(); .printStackTrace();
return; return;
} }

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Reduce allocation of Vec3D by entity tracker
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 49e612fc0fc4ec991d821d0aa4b41f488dd9f832..62a8482b73796f2c6b76c0e039cb21e799bc9416 100644 index 5f576e6b749e36a4729439930f48e2b1cdddef16..20818ae001a0a1bcf570041468bea33b88fda4ac 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1826,9 +1826,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1847,9 +1847,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
public void updatePlayer(ServerPlayer player) { public void updatePlayer(ServerPlayer player) {
org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
if (player != this.entity) { if (player != this.entity) {

View File

@ -37,10 +37,10 @@ index 74d674b2684b0db4aa6c183edc6091d53e9ee882..626bcbc6dd013260c3f8b38a1d14e7ba
// CraftBukkit start // CraftBukkit start
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 62a8482b73796f2c6b76c0e039cb21e799bc9416..87b612c25f865af4c8da72c761b70094fb89c4cb 100644 index 7f8c82f2f50934bcc2eacd40a5fbd93d5dae68f6..745b8c16600ba106907302daa9630abdce6807b0 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -177,21 +177,37 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -177,11 +177,23 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
final CallbackExecutor chunkLoadConversionCallbackExecutor = new CallbackExecutor(); // Paper final CallbackExecutor chunkLoadConversionCallbackExecutor = new CallbackExecutor(); // Paper
// Paper start - distance maps // Paper start - distance maps
private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>(); private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>();
@ -61,28 +61,32 @@ index 62a8482b73796f2c6b76c0e039cb21e799bc9416..87b612c25f865af4c8da72c761b70094
int chunkZ = MCUtil.getChunkCoordinate(player.getZ()); int chunkZ = MCUtil.getChunkCoordinate(player.getZ());
// Note: players need to be explicitly added to distance maps before they can be updated // Note: players need to be explicitly added to distance maps before they can be updated
+ this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning + this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
} // Paper start - per player mob spawning
if (this.playerMobDistanceMap != null) {
this.playerMobDistanceMap.add(player, chunkX, chunkZ, this.distanceManager.getSimulationDistance());
@@ -191,6 +203,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
void removePlayerFromDistanceMaps(ServerPlayer player) { void removePlayerFromDistanceMaps(ServerPlayer player) {
-
+ // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning + // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
+ this.playerMobSpawnMap.remove(player); + this.playerMobSpawnMap.remove(player);
+ this.playerChunkTickRangeMap.remove(player); + this.playerChunkTickRangeMap.remove(player);
+ // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning + // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
} // Paper start - per player mob spawning
if (this.playerMobDistanceMap != null) {
void updateMaps(ServerPlayer player) { this.playerMobDistanceMap.remove(player);
@@ -202,6 +218,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
int chunkX = MCUtil.getChunkCoordinate(player.getX()); int chunkX = MCUtil.getChunkCoordinate(player.getX());
int chunkZ = MCUtil.getChunkCoordinate(player.getZ()); int chunkZ = MCUtil.getChunkCoordinate(player.getZ());
// Note: players need to be explicitly added to distance maps before they can be updated // Note: players need to be explicitly added to distance maps before they can be updated
+ this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning + this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
} // Paper start - per player mob spawning
// Paper end if (this.playerMobDistanceMap != null) {
// Paper start this.playerMobDistanceMap.update(player, chunkX, chunkZ, this.distanceManager.getSimulationDistance());
@@ -266,6 +282,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -281,6 +298,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.regionManagers.add(this.dataRegionManager); this.regionManagers.add(this.dataRegionManager);
// Paper end // Paper end
this.playerMobDistanceMap = this.level.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper this.playerMobDistanceMap = this.level.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets) : null; // Paper
+ // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning + // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
+ this.playerChunkTickRangeMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets, + this.playerChunkTickRangeMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets,
+ (ServerPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ, + (ServerPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
@ -118,7 +122,7 @@ index 62a8482b73796f2c6b76c0e039cb21e799bc9416..87b612c25f865af4c8da72c761b70094
} }
protected ChunkGenerator generator() { protected ChunkGenerator generator() {
@@ -466,6 +514,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -487,6 +536,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} else { } else {
if (holder != null) { if (holder != null) {
holder.setTicketLevel(level); holder.setTicketLevel(level);
@ -126,7 +130,7 @@ index 62a8482b73796f2c6b76c0e039cb21e799bc9416..87b612c25f865af4c8da72c761b70094
} }
if (holder != null) { if (holder != null) {
@@ -1310,43 +1359,48 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1331,43 +1381,48 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return this.anyPlayerCloseEnoughForSpawning(pos, false); return this.anyPlayerCloseEnoughForSpawning(pos, false);
} }
@ -269,7 +273,7 @@ index f11e9421d393ef5a04f24c78a1214359710cc2f8..3865146697051e01a778414064425ea0
public String getDebugStatus() { public String getDebugStatus() {
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 50f3be85039c698bb2f73116a397d6ddaeea6dbd..b10ed9f87e58983863864161457cd415bb782bfd 100644 index 02516d4a6ee08908765f5bc84b14560754a67680..b327bd2f48166a4a0c831b0209695fe5935f6a68 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -881,6 +881,37 @@ public class ServerChunkCache extends ChunkSource { @@ -881,6 +881,37 @@ public class ServerChunkCache extends ChunkSource {
@ -310,7 +314,7 @@ index 50f3be85039c698bb2f73116a397d6ddaeea6dbd..b10ed9f87e58983863864161457cd415
LevelData worlddata = this.level.getLevelData(); LevelData worlddata = this.level.getLevelData();
ProfilerFiller gameprofilerfiller = this.level.getProfiler(); ProfilerFiller gameprofilerfiller = this.level.getProfiler();
@@ -928,15 +959,7 @@ public class ServerChunkCache extends ChunkSource { @@ -924,15 +955,7 @@ public class ServerChunkCache extends ChunkSource {
boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit
Collections.shuffle(list); Collections.shuffle(list);
@ -327,7 +331,7 @@ index 50f3be85039c698bb2f73116a397d6ddaeea6dbd..b10ed9f87e58983863864161457cd415
Iterator iterator1 = list.iterator(); Iterator iterator1 = list.iterator();
while (iterator1.hasNext()) { while (iterator1.hasNext()) {
@@ -944,9 +967,9 @@ public class ServerChunkCache extends ChunkSource { @@ -940,9 +963,9 @@ public class ServerChunkCache extends ChunkSource {
LevelChunk chunk1 = chunkproviderserver_a.chunk; LevelChunk chunk1 = chunkproviderserver_a.chunk;
ChunkPos chunkcoordintpair = chunk1.getPos(); ChunkPos chunkcoordintpair = chunk1.getPos();

View File

@ -6,7 +6,7 @@ Subject: [PATCH] Use distance map to optimise entity tracker
Use the distance map to find candidate players for tracking. Use the distance map to find candidate players for tracking.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc845bbacb1 100644 index 4796e60ade3b576dbe0fe79bc9f0be6085dc7cc8..d358bca3aa0407ede113b4ca6243043f75202267 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -67,6 +67,7 @@ import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket; @@ -67,6 +67,7 @@ import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket;
@ -17,7 +17,7 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
import net.minecraft.server.level.progress.ChunkProgressListener; import net.minecraft.server.level.progress.ChunkProgressListener;
import net.minecraft.server.network.ServerPlayerConnection; import net.minecraft.server.network.ServerPlayerConnection;
import net.minecraft.util.CsvOutput; import net.minecraft.util.CsvOutput;
@@ -188,15 +189,45 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -188,10 +189,35 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobSpawnMap; // this map is absent from updateMaps since it's controlled at the start of the chunkproviderserver tick public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobSpawnMap; // this map is absent from updateMaps since it's controlled at the start of the chunkproviderserver tick
public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerChunkTickRangeMap; public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerChunkTickRangeMap;
// Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
@ -52,9 +52,11 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
+ // Paper end - use distance map to optimise entity tracker + // Paper end - use distance map to optimise entity tracker
// Note: players need to be explicitly added to distance maps before they can be updated // Note: players need to be explicitly added to distance maps before they can be updated
this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
} // Paper start - per player mob spawning
@@ -203,6 +229,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
void removePlayerFromDistanceMaps(ServerPlayer player) { void removePlayerFromDistanceMaps(ServerPlayer player) {
+ // Paper start - use distance map to optimise tracker + // Paper start - use distance map to optimise tracker
+ for (int i = 0, len = TRACKING_RANGE_TYPES.length; i < len; ++i) { + for (int i = 0, len = TRACKING_RANGE_TYPES.length; i < len; ++i) {
+ this.playerEntityTrackerTrackMaps[i].remove(player); + this.playerEntityTrackerTrackMaps[i].remove(player);
@ -63,7 +65,7 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
// Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
this.playerMobSpawnMap.remove(player); this.playerMobSpawnMap.remove(player);
this.playerChunkTickRangeMap.remove(player); this.playerChunkTickRangeMap.remove(player);
@@ -207,6 +238,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -218,6 +249,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
int chunkX = MCUtil.getChunkCoordinate(player.getX()); int chunkX = MCUtil.getChunkCoordinate(player.getX());
int chunkZ = MCUtil.getChunkCoordinate(player.getZ()); int chunkZ = MCUtil.getChunkCoordinate(player.getZ());
// Note: players need to be explicitly added to distance maps before they can be updated // Note: players need to be explicitly added to distance maps before they can be updated
@ -76,12 +78,12 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
+ } + }
+ // Paper end - use distance map to optimise entity tracker + // Paper end - use distance map to optimise entity tracker
this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
} // Paper start - per player mob spawning
// Paper end if (this.playerMobDistanceMap != null) {
@@ -282,6 +321,45 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -298,6 +337,45 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.regionManagers.add(this.dataRegionManager); this.regionManagers.add(this.dataRegionManager);
// Paper end // Paper end
this.playerMobDistanceMap = this.level.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper this.playerMobDistanceMap = this.level.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets) : null; // Paper
+ // Paper start - use distance map to optimise entity tracker + // Paper start - use distance map to optimise entity tracker
+ this.playerEntityTrackerTrackMaps = new com.destroystokyo.paper.util.misc.PlayerAreaMap[TRACKING_RANGE_TYPES.length]; + this.playerEntityTrackerTrackMaps = new com.destroystokyo.paper.util.misc.PlayerAreaMap[TRACKING_RANGE_TYPES.length];
+ this.entityTrackerTrackRanges = new int[TRACKING_RANGE_TYPES.length]; + this.entityTrackerTrackRanges = new int[TRACKING_RANGE_TYPES.length];
@ -124,7 +126,7 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
// Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
this.playerChunkTickRangeMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets, this.playerChunkTickRangeMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets,
(ServerPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ, (ServerPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
@@ -1482,17 +1560,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1504,17 +1582,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} }
public void move(ServerPlayer player) { public void move(ServerPlayer player) {
@ -143,7 +145,7 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
int i = SectionPos.blockToSectionCoord(player.getBlockX()); int i = SectionPos.blockToSectionCoord(player.getBlockX());
int j = SectionPos.blockToSectionCoord(player.getBlockZ()); int j = SectionPos.blockToSectionCoord(player.getBlockZ());
@@ -1619,7 +1687,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1641,7 +1709,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
this.entityMap.put(entity.getId(), playerchunkmap_entitytracker); this.entityMap.put(entity.getId(), playerchunkmap_entitytracker);
@ -152,7 +154,7 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
if (entity instanceof ServerPlayer) { if (entity instanceof ServerPlayer) {
ServerPlayer entityplayer = (ServerPlayer) entity; ServerPlayer entityplayer = (ServerPlayer) entity;
@@ -1663,7 +1731,37 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1685,7 +1753,37 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
entity.tracker = null; // Paper - We're no longer tracked entity.tracker = null; // Paper - We're no longer tracked
} }
@ -190,7 +192,7 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
List<ServerPlayer> list = Lists.newArrayList(); List<ServerPlayer> list = Lists.newArrayList();
List<ServerPlayer> list1 = this.level.players(); List<ServerPlayer> list1 = this.level.players();
ObjectIterator objectiterator = this.entityMap.values().iterator(); ObjectIterator objectiterator = this.entityMap.values().iterator();
@@ -1739,23 +1837,31 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1761,23 +1859,31 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
DebugPackets.sendPoiPacketsForChunk(this.level, chunk.getPos()); DebugPackets.sendPoiPacketsForChunk(this.level, chunk.getPos());
List<Entity> list = Lists.newArrayList(); List<Entity> list = Lists.newArrayList();
List<Entity> list1 = Lists.newArrayList(); List<Entity> list1 = Lists.newArrayList();
@ -234,7 +236,7 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
Iterator iterator; Iterator iterator;
Entity entity1; Entity entity1;
@@ -1831,6 +1937,42 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1853,6 +1959,42 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.lastSectionPos = SectionPos.of(entity); this.lastSectionPos = SectionPos.of(entity);
} }

View File

@ -165,7 +165,7 @@ index 626bcbc6dd013260c3f8b38a1d14e7ba35dc1e01..9e96b0465717bfa761289c255fd8d2f1
for (int i = 0; i < this.futures.length(); ++i) { for (int i = 0; i < this.futures.length(); ++i) {
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = (CompletableFuture) this.futures.get(i); CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = (CompletableFuture) this.futures.get(i);
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 2534cae6f1b369843808aac91931bdc845bbacb1..74187951dc906e72904788ff0b42adc263b790bc 100644 index d358bca3aa0407ede113b4ca6243043f75202267..326a3b312d3446b813e325867f852e0cf6786945 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -101,6 +101,7 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureMana @@ -101,6 +101,7 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureMana
@ -176,7 +176,7 @@ index 2534cae6f1b369843808aac91931bdc845bbacb1..74187951dc906e72904788ff0b42adc2
import org.apache.commons.lang3.mutable.MutableBoolean; import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.mutable.MutableObject; import org.apache.commons.lang3.mutable.MutableObject;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@@ -636,6 +637,64 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -658,6 +659,64 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} }
@ -241,7 +241,7 @@ index 2534cae6f1b369843808aac91931bdc845bbacb1..74187951dc906e72904788ff0b42adc2
protected void saveAllChunks(boolean flush) { protected void saveAllChunks(boolean flush) {
if (flush) { if (flush) {
List<ChunkHolder> list = (List) this.visibleChunkMap.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList()); List<ChunkHolder> list = (List) this.visibleChunkMap.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList());
@@ -729,13 +788,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -751,13 +810,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} }
int l = 0; int l = 0;
@ -256,7 +256,7 @@ index 2534cae6f1b369843808aac91931bdc845bbacb1..74187951dc906e72904788ff0b42adc2
} }
@@ -773,6 +826,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -795,6 +848,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.level.unload(chunk); this.level.unload(chunk);
} }
@ -264,7 +264,7 @@ index 2534cae6f1b369843808aac91931bdc845bbacb1..74187951dc906e72904788ff0b42adc2
this.lightEngine.updateChunkStatus(ichunkaccess.getPos()); this.lightEngine.updateChunkStatus(ichunkaccess.getPos());
this.lightEngine.tryScheduleUpdate(); this.lightEngine.tryScheduleUpdate();
@@ -1170,6 +1224,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1192,6 +1246,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
asyncSaveData, chunk); asyncSaveData, chunk);
chunk.setUnsaved(false); chunk.setUnsaved(false);
@ -272,7 +272,7 @@ index 2534cae6f1b369843808aac91931bdc845bbacb1..74187951dc906e72904788ff0b42adc2
} }
// Paper end // Paper end
@@ -1179,6 +1234,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1201,6 +1256,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
if (!chunk.isUnsaved()) { if (!chunk.isUnsaved()) {
return false; return false;
} else { } else {
@ -281,7 +281,7 @@ index 2534cae6f1b369843808aac91931bdc845bbacb1..74187951dc906e72904788ff0b42adc2
ChunkPos chunkcoordintpair = chunk.getPos(); ChunkPos chunkcoordintpair = chunk.getPos();
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 1115df1f148bcb079edb9eb397de3fab725bf83b..3ebe6d4a87eac760d65ea335d683742a06c6c580 100644 index b327bd2f48166a4a0c831b0209695fe5935f6a68..73b1018b0aca377ed0ff188e74040cef57036b0b 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -825,6 +825,15 @@ public class ServerChunkCache extends ChunkSource { @@ -825,6 +825,15 @@ public class ServerChunkCache extends ChunkSource {

View File

@ -360,7 +360,7 @@ index 9e96b0465717bfa761289c255fd8d2f1df1be3d8..87271552aa85626f22f7f8569c8fb48f
return this.isEntityTickingReady; return this.isEntityTickingReady;
} }
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892cb8adc4b8 100644 index 326a3b312d3446b813e325867f852e0cf6786945..3e6cc16ff6f6c7993b15bd807257c0554afb6c77 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -128,6 +128,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -128,6 +128,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@ -371,7 +371,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
public ChunkGenerator generator; public ChunkGenerator generator;
public final Supplier<DimensionDataStorage> overworldDataStorage; public final Supplier<DimensionDataStorage> overworldDataStorage;
private final PoiManager poiManager; private final PoiManager poiManager;
@@ -299,6 +300,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -315,6 +316,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.level = world; this.level = world;
this.generator = chunkGenerator; this.generator = chunkGenerator;
this.mainThreadExecutor = mainThreadExecutor; this.mainThreadExecutor = mainThreadExecutor;
@ -387,7 +387,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
ProcessorMailbox<Runnable> threadedmailbox = ProcessorMailbox.create(executor, "worldgen"); ProcessorMailbox<Runnable> threadedmailbox = ProcessorMailbox.create(executor, "worldgen");
Objects.requireNonNull(mainThreadExecutor); Objects.requireNonNull(mainThreadExecutor);
@@ -410,6 +420,37 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -426,6 +436,37 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}); });
} }
@ -425,7 +425,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
// Paper start // Paper start
public void updatePlayerMobTypeMap(Entity entity) { public void updatePlayerMobTypeMap(Entity entity) {
if (!this.level.paperConfig.perPlayerMobSpawns) { if (!this.level.paperConfig.perPlayerMobSpawns) {
@@ -514,6 +555,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -536,6 +577,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
List<ChunkHolder> list1 = new ArrayList(); List<ChunkHolder> list1 = new ArrayList();
int j = centerChunk.x; int j = centerChunk.x;
int k = centerChunk.z; int k = centerChunk.z;
@ -433,7 +433,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
for (int l = -margin; l <= margin; ++l) { for (int l = -margin; l <= margin; ++l) {
for (int i1 = -margin; i1 <= margin; ++i1) { for (int i1 = -margin; i1 <= margin; ++i1) {
@@ -532,6 +574,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -554,6 +596,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
ChunkStatus chunkstatus = (ChunkStatus) distanceToStatus.apply(j1); ChunkStatus chunkstatus = (ChunkStatus) distanceToStatus.apply(j1);
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = playerchunk.getOrScheduleFuture(chunkstatus, this); CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = playerchunk.getOrScheduleFuture(chunkstatus, this);
@ -448,7 +448,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
list1.add(playerchunk); list1.add(playerchunk);
list.add(completablefuture); list.add(completablefuture);
@@ -866,11 +916,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -888,11 +938,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
if (requiredStatus == ChunkStatus.EMPTY) { if (requiredStatus == ChunkStatus.EMPTY) {
return this.scheduleChunkLoad(chunkcoordintpair); return this.scheduleChunkLoad(chunkcoordintpair);
} else { } else {
@ -469,7 +469,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
if (optional.isPresent() && ((ChunkAccess) optional.get()).getStatus().isOrAfter(requiredStatus)) { if (optional.isPresent() && ((ChunkAccess) optional.get()).getStatus().isOrAfter(requiredStatus)) {
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = requiredStatus.load(this.level, this.structureManager, this.lightEngine, (ichunkaccess) -> { CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = requiredStatus.load(this.level, this.structureManager, this.lightEngine, (ichunkaccess) -> {
@@ -882,6 +940,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -904,6 +962,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} else { } else {
return this.scheduleChunkGeneration(holder, requiredStatus); return this.scheduleChunkGeneration(holder, requiredStatus);
} }
@ -477,7 +477,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
} }
} }
@@ -938,14 +997,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -960,14 +1019,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}; };
CompletableFuture<CompoundTag> chunkSaveFuture = this.level.asyncChunkTaskManager.getChunkSaveFuture(pos.x, pos.z); CompletableFuture<CompoundTag> chunkSaveFuture = this.level.asyncChunkTaskManager.getChunkSaveFuture(pos.x, pos.z);
@ -507,7 +507,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
return ret; return ret;
// Paper end // Paper end
} }
@@ -997,7 +1066,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1019,7 +1088,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.releaseLightTicket(chunkcoordintpair); this.releaseLightTicket(chunkcoordintpair);
return CompletableFuture.completedFuture(Either.right(playerchunk_failure)); return CompletableFuture.completedFuture(Either.right(playerchunk_failure));
}); });
@ -519,7 +519,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
} }
protected void releaseLightTicket(ChunkPos pos) { protected void releaseLightTicket(ChunkPos pos) {
@@ -1081,7 +1153,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1103,7 +1175,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
long i = chunkHolder.getPos().toLong(); long i = chunkHolder.getPos().toLong();
Objects.requireNonNull(chunkHolder); Objects.requireNonNull(chunkHolder);
@ -529,7 +529,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
} }
diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java
index 84dc1e94b4f7b8315d8422634dd49b1f85044d18..451d5e9b5906e662a0c2e04b407068ea49d1089e 100644 index cd81e7844c985d7d0f0930faa96478af6a7f6cd4..1744f4983b24a87f3861ebd5d68120cfce904934 100644
--- a/src/main/java/net/minecraft/server/level/DistanceManager.java --- a/src/main/java/net/minecraft/server/level/DistanceManager.java
+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java
@@ -113,6 +113,7 @@ public abstract class DistanceManager { @@ -113,6 +113,7 @@ public abstract class DistanceManager {
@ -711,7 +711,7 @@ index 84dc1e94b4f7b8315d8422634dd49b1f85044d18..451d5e9b5906e662a0c2e04b407068ea
Ticket<ChunkPos> ticket = new Ticket<>(TicketType.FORCED, 31, pos); Ticket<ChunkPos> ticket = new Ticket<>(TicketType.FORCED, 31, pos);
long i = pos.toLong(); long i = pos.toLong();
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 3ebe6d4a87eac760d65ea335d683742a06c6c580..42cecd0f072505c80b65ccf26e5d838750d21e28 100644 index 73b1018b0aca377ed0ff188e74040cef57036b0b..3b0e254f569576a6193750811c06f1c102a2aeac 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -601,6 +601,26 @@ public class ServerChunkCache extends ChunkSource { @@ -601,6 +601,26 @@ public class ServerChunkCache extends ChunkSource {

View File

@ -54,10 +54,10 @@ index 87271552aa85626f22f7f8569c8fb48fe4b30bf3..80aae4303e011dad13ce818136f0383e
public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) { public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) {
this.futures = new AtomicReferenceArray(ChunkHolder.CHUNK_STATUSES.size()); this.futures = new AtomicReferenceArray(ChunkHolder.CHUNK_STATUSES.size());
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 0d01fc498d09c5e11d8d173ca98d892cb8adc4b8..b44f1dc663dc3c081ec85941a2cd73e522e3c348 100644 index 3e6cc16ff6f6c7993b15bd807257c0554afb6c77..a737fb56fef791f53ed3b0252e5a0369c22bcc7d 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -633,7 +633,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -655,7 +655,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return either.mapLeft((list) -> { return either.mapLeft((list) -> {
return (LevelChunk) list.get(list.size() / 2); return (LevelChunk) list.get(list.size() / 2);
}); });
@ -66,7 +66,7 @@ index 0d01fc498d09c5e11d8d173ca98d892cb8adc4b8..b44f1dc663dc3c081ec85941a2cd73e5
} }
@Nullable @Nullable
@@ -1037,6 +1037,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1059,6 +1059,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return "chunkGenerate " + requiredStatus.getName(); return "chunkGenerate " + requiredStatus.getName();
}); });
Executor executor = (runnable) -> { Executor executor = (runnable) -> {

View File

@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Beech Horn <beechhorn@gmail.com>
Date: Fri, 14 Feb 2020 19:39:59 +0000
Subject: [PATCH] Skip distance map update when spawning disabled.
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 1ff2d926ca5de9334b1e5aa5defb73d7fbc1c3af..8e87cc36b57bc5e8f8eb5583e02bbede4eb9ce54 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -966,7 +966,7 @@ public class ServerChunkCache extends ChunkSource {
int l = this.distanceManager.getNaturalSpawnChunkCount();
// Paper start - per player mob spawning
NaturalSpawner.SpawnState spawnercreature_d; // moved down
- if (this.chunkMap.playerMobDistanceMap != null) {
+ if ((this.spawnFriendlies || this.spawnEnemies) && this.chunkMap.playerMobDistanceMap != null) { // don't update when animals and monsters are disabled
// update distance map
this.level.timings.playerMobDistanceMapUpdate.startTiming();
this.chunkMap.playerMobDistanceMap.update(this.level.players, this.distanceManager.getSimulationDistance());

Some files were not shown because too many files have changed in this diff Show More