Use AreaMap for per-player mob spawning (#7235)
This commit is contained in:
parent
19bc612483
commit
79dd62ae62
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) -> {
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue