2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								From: Spottedleaf <Spottedleaf@users.noreply.github.com>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Date: Tue, 5 May 2020 20:40:53 -0700
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 18:18:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Subject: [PATCH] Optimize anyPlayerCloseEnoughForSpawning to use distance maps
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Use a distance map to find the players in range quickly
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public class ChunkHolder {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     boolean isUpdateQueued = false; // Paper
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     private final ChunkMap chunkMap; // Paper
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-28 15:46:53 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+    // Paper start - optimise anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								+    // cached here to avoid a map lookup
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+    com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> playersInMobSpawnRange;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+    com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> playersInChunkTickRange;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 09:44:46 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+    void onChunkAdd() {
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								+        long key = net.minecraft.server.MCUtil.getCoordinateKey(this.pos);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        this.playersInMobSpawnRange = this.chunkMap.playerMobSpawnMap.getObjectsInRange(key);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        this.playersInChunkTickRange = this.chunkMap.playerChunkTickRangeMap.getObjectsInRange(key);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+    }
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 09:44:46 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+    void onChunkRemove() {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        this.playersInMobSpawnRange = null;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        this.playersInChunkTickRange = null;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+    }
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-28 15:46:53 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+    // Paper end - optimise anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         this.futures = new AtomicReferenceArray(ChunkHolder.CHUNK_STATUSES.size());
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         this.fullChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public class ChunkHolder {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         this.setTicketLevel(level);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         this.changedBlocksPerSection = new ShortSet[world.getSectionsCount()];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         this.chunkMap = (ChunkMap)playersWatchingChunkProvider; // Paper
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 09:44:46 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+        this.onChunkAdd(); // Paper - optimise anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								     }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     // 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ 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<>();
							 
						 
					
						
							
								
									
										
										
										
											2021-11-28 15:46:53 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+    // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								+    // A note about the naming used here:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+    // Previously, mojang used a "spawn range" of 8 for controlling both ticking and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+    // mob spawn range. However, spigot makes the spawn range configurable by
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+    // checking if the chunk is in the tick range (8) and the spawn range
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+    // obviously this means a spawn range > 8 cannot be implemented
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+    // these maps are named after spigot's uses
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+    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;
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-28 15:46:53 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+    // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     void addPlayerToDistanceMaps(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
							 
						 
					
						
							
								
									
										
										
										
											2021-12-31 13:59:34 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+        this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-02 11:06:08 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								         // Paper start - per player mob spawning
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         if (this.playerMobDistanceMap != null) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             this.playerMobDistanceMap.add(player, chunkX, chunkZ, this.distanceManager.getSimulationDistance());
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     void removePlayerFromDistanceMaps(ServerPlayer player) {
							 
						 
					
						
							
								
									
										
										
										
											2022-01-02 11:06:08 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-28 15:46:53 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+        // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								+        this.playerMobSpawnMap.remove(player);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        this.playerChunkTickRangeMap.remove(player);
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-28 15:46:53 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+        // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-02 11:06:08 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								         // Paper start - per player mob spawning
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         if (this.playerMobDistanceMap != null) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             this.playerMobDistanceMap.remove(player);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								         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
							 
						 
					
						
							
								
									
										
										
										
											2021-11-28 15:46:53 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+        this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-02 11:06:08 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								         // Paper start - per player mob spawning
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         if (this.playerMobDistanceMap != null) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             this.playerMobDistanceMap.update(player, chunkX, chunkZ, this.distanceManager.getSimulationDistance());
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         this.regionManagers.add(this.dataRegionManager);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         // Paper end
							 
						 
					
						
							
								
									
										
										
										
											2022-01-02 11:06:08 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								         this.playerMobDistanceMap = this.level.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets) : null; // Paper
							 
						 
					
						
							
								
									
										
										
										
											2021-11-28 15:46:53 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+        // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								+        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,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+             com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> newState) -> {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                ChunkHolder playerChunk = ChunkMap.this.getUpdatingChunkIfPresent(MCUtil.getCoordinateKey(rangeX, rangeZ));
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                if (playerChunk != null) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                    playerChunk.playersInChunkTickRange = newState;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            },
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            (ServerPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+             com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> newState) -> {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                ChunkHolder playerChunk = ChunkMap.this.getUpdatingChunkIfPresent(MCUtil.getCoordinateKey(rangeX, rangeZ));
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                if (playerChunk != null) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                    playerChunk.playersInChunkTickRange = newState;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            });
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        this.playerMobSpawnMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            (ServerPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+             com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> newState) -> {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                ChunkHolder playerChunk = ChunkMap.this.getUpdatingChunkIfPresent(MCUtil.getCoordinateKey(rangeX, rangeZ));
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                if (playerChunk != null) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                    playerChunk.playersInMobSpawnRange = newState;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            },
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            (ServerPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+             com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> newState) -> {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                ChunkHolder playerChunk = ChunkMap.this.getUpdatingChunkIfPresent(MCUtil.getCoordinateKey(rangeX, rangeZ));
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                if (playerChunk != null) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                    playerChunk.playersInMobSpawnRange = newState;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            });
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-28 15:46:53 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+        // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								     }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     protected ChunkGenerator generator() {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 09:44:46 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                 holder = (ChunkHolder) this.pendingUnloads.remove(pos);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 if (holder != null) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                     holder.setTicketLevel(level);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                    holder.onChunkAdd(); // Paper - optimise anyPlayerCloseEnoughForSpawning - PUT HERE AFTER RE-ADDING ONLY
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 } else {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                     holder = new ChunkHolder(new ChunkPos(pos), level, this.level, this.lightEngine, this.queueSorter, this);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                     // Paper start
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             ChunkHolder playerchunk = (ChunkHolder) this.updatingChunkMap.remove(j);
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-18 09:44:46 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								             if (playerchunk != null) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                playerchunk.onChunkRemove(); // Paper
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 this.pendingUnloads.put(j, playerchunk);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 this.modified = true;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 this.scheduleUnload(j, playerchunk); // Paper - Move up - don't leak chunks
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         return this.anyPlayerCloseEnoughForSpawning(pos, false);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-    boolean anyPlayerCloseEnoughForSpawning(ChunkPos chunkcoordintpair, boolean reducedRange) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        int chunkRange = level.spigotConfig.mobSpawnRange;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        chunkRange = (chunkRange > level.spigotConfig.viewDistance) ? (byte) level.spigotConfig.viewDistance : chunkRange;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        chunkRange = (chunkRange > 8) ? 8 : chunkRange;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        final int finalChunkRange = chunkRange; // Paper for lambda below
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        //double blockRange = (reducedRange) ? Math.pow(chunkRange << 4, 2) : 16384.0D; // Paper - use from event
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        double blockRange = 16384.0D; // Paper
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        // Spigot end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        long i = chunkcoordintpair.toLong();
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-28 15:46:53 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+    // Paper start - optimise anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								+    final boolean anyPlayerCloseEnoughForSpawning(ChunkPos chunkcoordintpair, boolean reducedRange) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        return this.anyPlayerCloseEnoughForSpawning(this.getUpdatingChunkIfPresent(chunkcoordintpair.toLong()), chunkcoordintpair, reducedRange);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+    }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        if (!this.distanceManager.hasPlayersNearby(i)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+    final boolean anyPlayerCloseEnoughForSpawning(ChunkHolder playerchunk, ChunkPos chunkcoordintpair, boolean reducedRange) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        // this function is so hot that removing the map lookup call can have an order of magnitude impact on its performance
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        // tested and confirmed via System.nanoTime()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> playersInRange = reducedRange ? playerchunk.playersInMobSpawnRange : playerchunk.playersInChunkTickRange;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        if (playersInRange == null) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             return false;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        } else {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-            Iterator iterator = this.playerMap.getPlayers(i).iterator();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-            ServerPlayer entityplayer;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        Object[] backingSet = playersInRange.getBackingSet();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-            do {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-                if (!iterator.hasNext()) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-                    return false;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        if (reducedRange) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            for (int i = 0, len = backingSet.length; i < len; ++i) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                Object raw = backingSet[i];
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                if (!(raw instanceof ServerPlayer player)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                    continue;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-                entityplayer = (ServerPlayer) iterator.next();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-                // Paper start - add PlayerNaturallySpawnCreaturesEvent
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-                com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-                blockRange = 16384.0D;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-                if (reducedRange) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-                    event = entityplayer.playerNaturallySpawnedEvent;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-                    if (event == null || event.isCancelled()) return false;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-                    blockRange = (double) ((event.getSpawnRadius() << 4) * (event.getSpawnRadius() << 4));
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                // don't check spectator and whatnot, already handled by mob spawn map update
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 18:18:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+                if (euclideanDistanceSquared(chunkcoordintpair, player) < player.lastEntitySpawnRadiusSquared) {
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								+                    return true; // in range
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-                // Paper end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-            } while (!this.playerIsCloseEnoughForSpawning(entityplayer, chunkcoordintpair, blockRange)); // Spigot
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-            return true;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        } else {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            final double range = (DistanceManager.MOB_SPAWN_RANGE * 16) * (DistanceManager.MOB_SPAWN_RANGE * 16);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            // before spigot, mob spawn range was actually mob spawn range + tick range, but it was split
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            for (int i = 0, len = backingSet.length; i < len; ++i) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                Object raw = backingSet[i];
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                if (!(raw instanceof ServerPlayer player)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                    continue;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                // don't check spectator and whatnot, already handled by mob spawn map update
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 18:18:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+                if (euclideanDistanceSquared(chunkcoordintpair, player) < range) {
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								+                    return true; // in range
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        // no players in range
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        return false;
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-28 15:46:53 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+        // Paper end - optimise anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								     }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     public List<ServerPlayer> getPlayersCloseForSpawning(ChunkPos pos) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								--- a/src/main/java/net/minecraft/server/level/DistanceManager.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public abstract class DistanceManager {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     final Long2ObjectMap<ObjectSet<ServerPlayer>> playersPerChunk = new Long2ObjectOpenHashMap();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     public final Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> tickets = new Long2ObjectOpenHashMap();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     private final DistanceManager.ChunkTicketTracker ticketTracker = new DistanceManager.ChunkTicketTracker();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-    private final DistanceManager.FixedPlayerDistanceChunkTracker naturalSpawnChunkCounter = new DistanceManager.FixedPlayerDistanceChunkTracker(8);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+    public static final int MOB_SPAWN_RANGE = 8; // private final ChunkMapDistance.b f = new ChunkMapDistance.b(8); // Paper - no longer used
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     private final TickingTracker tickingTicketsTracker = new TickingTracker();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     private final DistanceManager.PlayerTicketTracker playerTicketManager = new DistanceManager.PlayerTicketTracker(33);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     // Paper start use a queue, but still keep unique requirement
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public abstract class DistanceManager {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     protected abstract ChunkHolder updateChunkScheduling(long pos, int level, @Nullable ChunkHolder holder, int k);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     public boolean runAllUpdates(ChunkMap chunkStorage) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        this.naturalSpawnChunkCounter.runAllUpdates();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        //this.f.a(); // Paper - no longer used
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         this.tickingTicketsTracker.runAllUpdates();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         this.playerTicketManager.runAllUpdates();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         int i = Integer.MAX_VALUE - this.ticketTracker.runDistanceUpdates(Integer.MAX_VALUE);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public abstract class DistanceManager {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         ((ObjectSet) this.playersPerChunk.computeIfAbsent(i, (j) -> {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             return new ObjectOpenHashSet();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         })).add(player);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        this.naturalSpawnChunkCounter.update(i, 0, true);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        //this.f.update(i, 0, true); // Paper - no longer used
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         this.playerTicketManager.update(i, 0, true);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         this.tickingTicketsTracker.addTicket(TicketType.PLAYER, chunkcoordintpair, this.getPlayerTicketLevel(), chunkcoordintpair);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public abstract class DistanceManager {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         if (objectset != null) objectset.remove(player); // Paper - some state corruption happens here, don't crash, clean up gracefully.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         if (objectset == null || objectset.isEmpty()) { // Paper
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             this.playersPerChunk.remove(i);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-            this.naturalSpawnChunkCounter.update(i, Integer.MAX_VALUE, false);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            //this.f.update(i, Integer.MAX_VALUE, false); // Paper - no longer used
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             this.playerTicketManager.update(i, Integer.MAX_VALUE, false);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             this.tickingTicketsTracker.removeTicket(TicketType.PLAYER, chunkcoordintpair, this.getPlayerTicketLevel(), chunkcoordintpair);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public abstract class DistanceManager {
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-02 15:05:08 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     // Paper end
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     public int getNaturalSpawnChunkCount() {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        this.naturalSpawnChunkCounter.runAllUpdates();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        return this.naturalSpawnChunkCounter.chunks.size();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        // Paper start - use distance map to implement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        // note: this is the spawn chunk count
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        return this.chunkMap.playerChunkTickRangeMap.size();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        // Paper end - use distance map to implement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     public boolean hasPlayersNearby(long chunkPos) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        this.naturalSpawnChunkCounter.runAllUpdates();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-        return this.naturalSpawnChunkCounter.chunks.containsKey(chunkPos);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        // Paper start - use distance map to implement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        // note: this is the is spawn chunk method
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        return this.chunkMap.playerChunkTickRangeMap.getObjectsInRange(chunkPos) != null;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+        // Paper end - use distance map to implement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 12:08:44 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         if (flag) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             this.chunkMap.tick();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         } else {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            // Paper start - optimize isOutisdeRange
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            ChunkMap playerChunkMap = this.chunkMap;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            for (ServerPlayer player : this.level.players) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                if (!player.affectsSpawning || player.isSpectator()) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                    playerChunkMap.playerMobSpawnMap.remove(player);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                    continue;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                int viewDistance = this.chunkMap.getEffectiveViewDistance();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                // copied and modified from isOutisdeRange
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                int chunkRange = level.spigotConfig.mobSpawnRange;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                chunkRange = (chunkRange > viewDistance) ? (byte)viewDistance : chunkRange;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                chunkRange = (chunkRange > DistanceManager.MOB_SPAWN_RANGE) ? DistanceManager.MOB_SPAWN_RANGE : chunkRange;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(player.getBukkitEntity(), (byte)chunkRange);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                event.callEvent();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                if (event.isCancelled() || event.getSpawnRadius() < 0 || playerChunkMap.playerChunkTickRangeMap.getLastViewDistance(player) == -1) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                    playerChunkMap.playerMobSpawnMap.remove(player);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                    continue;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                int range = Math.min(event.getSpawnRadius(), 32); // limit to max view distance
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                int chunkX = net.minecraft.server.MCUtil.getChunkCoordinate(player.getX());
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                int chunkZ = net.minecraft.server.MCUtil.getChunkCoordinate(player.getZ());
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                playerChunkMap.playerMobSpawnMap.addOrUpdate(player, chunkX, chunkZ, range);
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-28 15:46:53 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+                player.lastEntitySpawnRadiusSquared = (double)((range << 4) * (range << 4)); // used in anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 12:08:44 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+                player.playerNaturallySpawnedEvent = event;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            // Paper end - optimize isOutisdeRange
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             LevelData worlddata = this.level.getLevelData();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             ProfilerFiller gameprofilerfiller = this.level.getProfiler();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-05 06:00:13 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								             Collections.shuffle(list);
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								-            // Paper start - call player naturally spawn event
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-            int chunkRange = level.spigotConfig.mobSpawnRange;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-            chunkRange = (chunkRange > level.spigotConfig.viewDistance) ? (byte) level.spigotConfig.viewDistance : chunkRange;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-            chunkRange = Math.min(chunkRange, 8);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-            for (ServerPlayer entityPlayer : this.level.players()) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-                entityPlayer.playerNaturallySpawnedEvent = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityPlayer.getBukkitEntity(), (byte) chunkRange);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-                entityPlayer.playerNaturallySpawnedEvent.callEvent();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-            };
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-            // Paper end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            // Paper - moved natural spawn event up
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             Iterator iterator1 = list.iterator();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             while (iterator1.hasNext()) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 LevelChunk chunk1 = chunkproviderserver_a.chunk;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 ChunkPos chunkcoordintpair = chunk1.getPos();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								-                if (this.level.isPositionEntityTicking(chunkcoordintpair) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkcoordintpair)) {
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-28 15:46:53 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+                if (this.level.isPositionEntityTicking(chunkcoordintpair) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkproviderserver_a.holder, chunkcoordintpair, false)) { // Paper - optimise anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                     chunk1.incrementInhabitedTime(j);
							 
						 
					
						
							
								
									
										
										
										
											2021-11-28 15:46:53 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								-                    if (flag2 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkcoordintpair, true)) { // Spigot
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+                    if (flag2 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkproviderserver_a.holder, chunkcoordintpair, true)) { // Spigot // Paper - optimise anyPlayerCloseEnoughForSpawning
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 10:19:05 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                         NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                     }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     // CraftBukkit end
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+    public double lastEntitySpawnRadiusSquared; // Paper - optimise isOutsideRange, this field is in blocks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> cachedSingleHashSet; // Paper
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile) {