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
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
index 619f5c11ae8e21b060b52b60d681db6dd9cb5816..88d140a03b6f28070b2f78588ee5ce4d5ac3cf0f 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@ -41,264 +21,6 @@ index 619f5c11ae8e21b060b52b60d681db6dd9cb5816..88d140a03b6f28070b2f78588ee5ce4d
+ 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
new file mode 100644
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
index 0c82b270c7095c7e4666a8078ecc7142503795c4..0583d7ee24f694fbf5138dfae9f7b8c8e4225ab3 100644
index 0c82b270c7095c7e4666a8078ecc7142503795c4..2d7f0eb7df62d1c26ccf19cf61595227e19aa562 100644
--- a/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
private final Long2ByteMap chunkTypeCache;
private final Queue<Runnable> unloadQueue;
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()
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.regionManagers.add(this.dataRegionManager);
// 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() {
@@ -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) {
+ return;
+ }
+ int chunkX = (int)Math.floor(entity.getX()) >> 4;
+ int chunkZ = (int)Math.floor(entity.getZ()) >> 4;
+ 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];
+ }
+ }
@ -610,21 +370,17 @@ index f0dac1f596911eb2109192ef16a619f8ae71d1f7..07b616d9d7cde77c001f5c627daef073
this.naturalSpawnChunkCounter.runAllUpdates();
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
index 7b391d6ab84eeaed7bdd27ea70d5e3f9690a0abf..d9405456f61b954f9b6fa2fa7939fc3a36ec6fc6 100644
index 7b391d6ab84eeaed7bdd27ea70d5e3f9690a0abf..0d380bba07c5c7b6b25fa2ce554418ef8ba9fdb1 100644
--- a/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");
this.level.timings.countNaturalMobs.startTiming(); // Paper - timings
int l = this.distanceManager.getNaturalSpawnChunkCount();
- NaturalSpawner.SpawnState spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap));
+ // Paper start - per player mob spawning
+ NaturalSpawner.SpawnState spawnercreature_d; // moved down
+ if (this.chunkMap.playerMobDistanceMap != null) {
+ // update distance map
+ this.level.timings.playerMobDistanceMapUpdate.startTiming();
+ this.chunkMap.playerMobDistanceMap.update(this.level.players, this.distanceManager.getSimulationDistance());
+ this.level.timings.playerMobDistanceMapUpdate.stopTiming();
+ if ((this.spawnFriendlies || this.spawnEnemies) && this.chunkMap.playerMobDistanceMap != null) { // don't count mobs when animals and monsters are disabled
+ // re-set mob counts
+ for (ServerPlayer player : this.level.players) {
+ 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.
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
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
@@ -65,7 +65,13 @@ public final class NaturalSpawner {
@ -684,7 +440,7 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
}
- if (entity instanceof Mob) {
+ if (localmobcapcalculator != null && entity instanceof Mob) {
+ if (localmobcapcalculator != null && entity instanceof Mob) { // Paper
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;
}
@ -709,8 +465,15 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
+
+ if (world.paperConfig.perPlayerMobSpawns) {
+ int minDiff = Integer.MAX_VALUE;
+ for (net.minecraft.server.level.ServerPlayer entityplayer : world.getChunkSource().chunkMap.playerMobDistanceMap.getPlayersInRange(chunk.getPos())) {
+ minDiff = Math.min(limit - world.getChunkSource().chunkMap.getMobCountNear(entityplayer, enumcreaturetype), minDiff);
+ final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<net.minecraft.server.level.ServerPlayer> inRange = world.getChunkSource().chunkMap.playerMobDistanceMap.getObjectsInRange(chunk.getPos());
+ 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;
+ }
@ -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();
}
@ -750,7 +513,7 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
}
@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;
while (k < 3) {
@@ -249,14 +289,14 @@ public final class NaturalSpawner {
@@ -249,14 +296,14 @@ public final class NaturalSpawner {
// Paper start
Boolean doSpawning = isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2);
if (doSpawning == null) {
@ -790,7 +553,7 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
}
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;
++k1;
runner.run(entityinsentient, chunk);
@ -808,7 +571,7 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
}
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) {
@@ -572,7 +618,7 @@ public final class NaturalSpawner {
@@ -572,7 +625,7 @@ public final class NaturalSpawner {
MobCategory enumcreaturetype = entitytypes.getCategory();
this.mobCategoryCounts.addTo(enumcreaturetype, 1);
@ -825,7 +588,7 @@ index 6f63f471c2c9a3b85c6fc92bdee31a5ff9714ff5..3a9e20bdf445c019e60a814ea6fc2677
}
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;
// 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.
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
+++ 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) {
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
index 27c304d66ecf0bb8d7b5b4343ca207880e14711b..6f851c24a67d1b3a349790b0d60f45b23ff93bc6 100644
index ed4b4c3d3d991716078d5f008bf4665e76b30f33..4cb7e63b433b8d4a02c2d193a2596e51ddab2779 100644
--- a/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();
do {

View File

@ -25,7 +25,7 @@ This successfully fixed a reoccurring and highly reproduceable crash
for heightmaps.
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
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -174,6 +174,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@ -36,7 +36,7 @@ index 6f851c24a67d1b3a349790b0d60f45b23ff93bc6..4566af37c76cb3a2fe6441451a444a5a
// Paper start - distance maps
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);
});
}, (runnable) -> {
@ -46,10 +46,10 @@ index 6f851c24a67d1b3a349790b0d60f45b23ff93bc6..4566af37c76cb3a2fe6441451a444a5a
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
index 5b6381858418ceca4fe40ef329e050538e980cdb..66dfe3d79fa3273a2bab64193f73f2b38002c18c 100644
index 19c44eae78802c9fe0479cdc32f21156dc9b9d45..02516d4a6ee08908765f5bc84b14560754a67680 100644
--- a/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
}
} finally {

View File

@ -28,10 +28,10 @@ receives a deterministic result, and should no longer require 1 tick
delays anymore.
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
+++ 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();
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
index 49e612fc0fc4ec991d821d0aa4b41f488dd9f832..62a8482b73796f2c6b76c0e039cb21e799bc9416 100644
index 5f576e6b749e36a4729439930f48e2b1cdddef16..20818ae001a0a1bcf570041468bea33b88fda4ac 100644
--- a/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) {
org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
if (player != this.entity) {

View File

@ -37,10 +37,10 @@ index 74d674b2684b0db4aa6c183edc6091d53e9ee882..626bcbc6dd013260c3f8b38a1d14e7ba
// CraftBukkit start
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
+++ 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
// Paper start - distance maps
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());
// 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
}
// 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) {
-
+ // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
+ this.playerMobSpawnMap.remove(player);
+ this.playerChunkTickRangeMap.remove(player);
+ // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
}
void updateMaps(ServerPlayer player) {
// Paper start - per player mob spawning
if (this.playerMobDistanceMap != null) {
this.playerMobDistanceMap.remove(player);
@@ -202,6 +218,7 @@ 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
+ this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
}
// Paper end
// Paper start
@@ -266,6 +282,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper start - per player mob spawning
if (this.playerMobDistanceMap != null) {
this.playerMobDistanceMap.update(player, chunkX, chunkZ, this.distanceManager.getSimulationDistance());
@@ -281,6 +298,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.regionManagers.add(this.dataRegionManager);
// 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
+ 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,
@ -118,7 +122,7 @@ index 62a8482b73796f2c6b76c0e039cb21e799bc9416..87b612c25f865af4c8da72c761b70094
}
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 {
if (holder != null) {
holder.setTicketLevel(level);
@ -126,7 +130,7 @@ index 62a8482b73796f2c6b76c0e039cb21e799bc9416..87b612c25f865af4c8da72c761b70094
}
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);
}
@ -269,7 +273,7 @@ index f11e9421d393ef5a04f24c78a1214359710cc2f8..3865146697051e01a778414064425ea0
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
index 50f3be85039c698bb2f73116a397d6ddaeea6dbd..b10ed9f87e58983863864161457cd415bb782bfd 100644
index 02516d4a6ee08908765f5bc84b14560754a67680..b327bd2f48166a4a0c831b0209695fe5935f6a68 100644
--- a/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 {
@ -310,7 +314,7 @@ index 50f3be85039c698bb2f73116a397d6ddaeea6dbd..b10ed9f87e58983863864161457cd415
LevelData worlddata = this.level.getLevelData();
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
Collections.shuffle(list);
@ -327,7 +331,7 @@ index 50f3be85039c698bb2f73116a397d6ddaeea6dbd..b10ed9f87e58983863864161457cd415
Iterator iterator1 = list.iterator();
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;
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.
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
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -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.network.ServerPlayerConnection;
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 playerChunkTickRangeMap;
// Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
@ -52,9 +52,11 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
+ // Paper end - use distance map to optimise entity tracker
// 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
}
// Paper start - per player mob spawning
@@ -203,6 +229,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
void removePlayerFromDistanceMaps(ServerPlayer 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);
@ -63,7 +65,7 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
// Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
this.playerMobSpawnMap.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 chunkZ = MCUtil.getChunkCoordinate(player.getZ());
// 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
this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
}
// Paper end
@@ -282,6 +321,45 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper start - per player mob spawning
if (this.playerMobDistanceMap != null) {
@@ -298,6 +337,45 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.regionManagers.add(this.dataRegionManager);
// 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
+ this.playerEntityTrackerTrackMaps = new com.destroystokyo.paper.util.misc.PlayerAreaMap[TRACKING_RANGE_TYPES.length];
+ this.entityTrackerTrackRanges = new int[TRACKING_RANGE_TYPES.length];
@ -124,7 +126,7 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
// Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
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,
@@ -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) {
@ -143,7 +145,7 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
int i = SectionPos.blockToSectionCoord(player.getBlockX());
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
this.entityMap.put(entity.getId(), playerchunkmap_entitytracker);
@ -152,7 +154,7 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
if (entity instanceof ServerPlayer) {
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
}
@ -190,7 +192,7 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
List<ServerPlayer> list = Lists.newArrayList();
List<ServerPlayer> list1 = this.level.players();
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());
List<Entity> list = Lists.newArrayList();
List<Entity> list1 = Lists.newArrayList();
@ -234,7 +236,7 @@ index 87b612c25f865af4c8da72c761b70094fb89c4cb..2534cae6f1b369843808aac91931bdc8
Iterator iterator;
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);
}

View File

@ -165,7 +165,7 @@ index 626bcbc6dd013260c3f8b38a1d14e7ba35dc1e01..9e96b0465717bfa761289c255fd8d2f1
for (int i = 0; i < this.futures.length(); ++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
index 2534cae6f1b369843808aac91931bdc845bbacb1..74187951dc906e72904788ff0b42adc263b790bc 100644
index d358bca3aa0407ede113b4ca6243043f75202267..326a3b312d3446b813e325867f852e0cf6786945 100644
--- a/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
@ -176,7 +176,7 @@ index 2534cae6f1b369843808aac91931bdc845bbacb1..74187951dc906e72904788ff0b42adc2
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.mutable.MutableObject;
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) {
if (flush) {
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;
@ -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);
}
@ -264,7 +264,7 @@ index 2534cae6f1b369843808aac91931bdc845bbacb1..74187951dc906e72904788ff0b42adc2
this.lightEngine.updateChunkStatus(ichunkaccess.getPos());
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);
chunk.setUnsaved(false);
@ -272,7 +272,7 @@ index 2534cae6f1b369843808aac91931bdc845bbacb1..74187951dc906e72904788ff0b42adc2
}
// 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()) {
return false;
} else {
@ -281,7 +281,7 @@ index 2534cae6f1b369843808aac91931bdc845bbacb1..74187951dc906e72904788ff0b42adc2
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
index 1115df1f148bcb079edb9eb397de3fab725bf83b..3ebe6d4a87eac760d65ea335d683742a06c6c580 100644
index b327bd2f48166a4a0c831b0209695fe5935f6a68..73b1018b0aca377ed0ff188e74040cef57036b0b 100644
--- a/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 {

View File

@ -360,7 +360,7 @@ index 9e96b0465717bfa761289c255fd8d2f1df1be3d8..87271552aa85626f22f7f8569c8fb48f
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
index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892cb8adc4b8 100644
index 326a3b312d3446b813e325867f852e0cf6786945..3e6cc16ff6f6c7993b15bd807257c0554afb6c77 100644
--- a/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
@ -371,7 +371,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
public ChunkGenerator generator;
public final Supplier<DimensionDataStorage> overworldDataStorage;
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.generator = chunkGenerator;
this.mainThreadExecutor = mainThreadExecutor;
@ -387,7 +387,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
ProcessorMailbox<Runnable> threadedmailbox = ProcessorMailbox.create(executor, "worldgen");
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
public void updatePlayerMobTypeMap(Entity entity) {
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();
int j = centerChunk.x;
int k = centerChunk.z;
@ -433,7 +433,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
for (int l = -margin; l <= margin; ++l) {
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);
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = playerchunk.getOrScheduleFuture(chunkstatus, this);
@ -448,7 +448,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
list1.add(playerchunk);
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) {
return this.scheduleChunkLoad(chunkcoordintpair);
} else {
@ -469,7 +469,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
if (optional.isPresent() && ((ChunkAccess) optional.get()).getStatus().isOrAfter(requiredStatus)) {
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 {
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);
@ -507,7 +507,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
return ret;
// 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);
return CompletableFuture.completedFuture(Either.right(playerchunk_failure));
});
@ -519,7 +519,7 @@ index 74187951dc906e72904788ff0b42adc263b790bc..0d01fc498d09c5e11d8d173ca98d892c
}
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();
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
index 84dc1e94b4f7b8315d8422634dd49b1f85044d18..451d5e9b5906e662a0c2e04b407068ea49d1089e 100644
index cd81e7844c985d7d0f0930faa96478af6a7f6cd4..1744f4983b24a87f3861ebd5d68120cfce904934 100644
--- a/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 {
@ -711,7 +711,7 @@ index 84dc1e94b4f7b8315d8422634dd49b1f85044d18..451d5e9b5906e662a0c2e04b407068ea
Ticket<ChunkPos> ticket = new Ticket<>(TicketType.FORCED, 31, pos);
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
index 3ebe6d4a87eac760d65ea335d683742a06c6c580..42cecd0f072505c80b65ccf26e5d838750d21e28 100644
index 73b1018b0aca377ed0ff188e74040cef57036b0b..3b0e254f569576a6193750811c06f1c102a2aeac 100644
--- a/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 {

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) {
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
index 0d01fc498d09c5e11d8d173ca98d892cb8adc4b8..b44f1dc663dc3c081ec85941a2cd73e522e3c348 100644
index 3e6cc16ff6f6c7993b15bd807257c0554afb6c77..a737fb56fef791f53ed3b0252e5a0369c22bcc7d 100644
--- a/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 (LevelChunk) list.get(list.size() / 2);
});
@ -66,7 +66,7 @@ index 0d01fc498d09c5e11d8d173ca98d892cb8adc4b8..b44f1dc663dc3c081ec85941a2cd73e5
}
@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();
});
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