From 243cfdf6b551171c0fa378b7c6f477ab21746337 Mon Sep 17 00:00:00 2001
From: Nassim Jahnke <nassim@njahnke.dev>
Date: Mon, 2 Aug 2021 10:00:31 +0200
Subject: [PATCH] Don't not shuffle visible chunks (#6283)

---
 patches/server/MC-Utils.patch                      | 14 --------------
 ...unk-Tasks-Speed-up-processing-of-chunk-lo.patch |  5 ++---
 ...ayerChunkMap-memory-use-for-visibleChunks.patch | 14 +++++++-------
 ...imize-isOutsideRange-to-use-distance-maps.patch | 12 ++++++------
 .../PlayerNaturallySpawnCreaturesEvent.patch       |  8 ++++----
 patches/server/Timings-v2.patch                    |  7 ++++---
 6 files changed, 23 insertions(+), 37 deletions(-)

diff --git a/patches/server/MC-Utils.patch b/patches/server/MC-Utils.patch
index a41a24b7d8..b43b7aac9b 100644
--- a/patches/server/MC-Utils.patch
+++ b/patches/server/MC-Utils.patch
@@ -3300,20 +3300,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      @Override
      public ChunkAccess getChunk(int x, int z, ChunkStatus leastStatus, boolean create) {
 @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
- 
-             this.lastSpawnState = spawnercreature_d;
-             this.level.getProfiler().pop();
--            List<ChunkHolder> list = Lists.newArrayList(this.chunkMap.getChunks());
--
--            Collections.shuffle(list);
--            list.forEach((playerchunk) -> {
-+            //List<PlayerChunk> list = Lists.newArrayList(this.playerChunkMap.f()); // Paper
-+            //Collections.shuffle(list); // Paper
-+            this.chunkMap.getChunks().forEach((playerchunk) -> { // Paper - no... just no...
-                 Optional<LevelChunk> optional = ((Either) playerchunk.getTickingChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left();
- 
-                 if (optional.isPresent()) {
-@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
              }
  
              this.level.getProfiler().popPush("broadcast");
diff --git a/patches/server/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch b/patches/server/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch
index d6f6b1dbb2..6aab9210d4 100644
--- a/patches/server/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch
+++ b/patches/server/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch
@@ -170,11 +170,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              };
              // Paper end
              this.level.timings.chunkTicks.startTiming(); // Paper
--            this.chunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping
-+            final int[] chunksTicked = {0}; this.chunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping
++            final int[] chunksTicked = {0}; // Paper
+             list.forEach((playerchunk) -> {
                  Optional<LevelChunk> optional = ((Either) playerchunk.getTickingChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left();
  
-                 if (optional.isPresent()) {
 @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
                          chunk.setInhabitedTime(chunk.getInhabitedTime() + j);
                          if (flag1 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunk.getPos()) && !this.chunkMap.isOutsideOfRange(chunkcoordintpair, true)) { // Spigot
diff --git a/patches/server/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch b/patches/server/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch
index 166fc2a0bb..ada2cc60d0 100644
--- a/patches/server/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch
+++ b/patches/server/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch
@@ -237,14 +237,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
 +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
 @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
-             };
-             // Paper end
-             this.level.timings.chunkTicks.startTiming(); // Paper
--            this.chunkMap.getChunks().forEach((playerchunk) -> { // Paper - no... just no...
-+            this.chunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping
-                 Optional<LevelChunk> optional = ((Either) playerchunk.getTickingChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left();
  
-                 if (optional.isPresent()) {
+             this.lastSpawnState = spawnercreature_d;
+             this.level.getProfiler().pop();
+-            List<ChunkHolder> list = Lists.newArrayList(this.chunkMap.getChunks());
++            List<ChunkHolder> list = Lists.newArrayList(this.chunkMap.visibleChunkMap.values()); // Paper
+ 
+             Collections.shuffle(list);
+             //Paper start - call player naturally spawn event
 diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
diff --git a/patches/server/Optimize-isOutsideRange-to-use-distance-maps.patch b/patches/server/Optimize-isOutsideRange-to-use-distance-maps.patch
index a47b584574..b995ed2cd2 100644
--- a/patches/server/Optimize-isOutsideRange-to-use-distance-maps.patch
+++ b/patches/server/Optimize-isOutsideRange-to-use-distance-maps.patch
@@ -333,9 +333,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              int k = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING);
              boolean flag2 = level.ticksPerAnimalSpawns != 0L && worlddata.getGameTime() % level.ticksPerAnimalSpawns == 0L; // CraftBukkit
 @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
-             this.level.getProfiler().pop();
-             //List<PlayerChunk> list = Lists.newArrayList(this.playerChunkMap.f()); // Paper
-             //Collections.shuffle(list); // Paper
+             List<ChunkHolder> list = Lists.newArrayList(this.chunkMap.visibleChunkMap.values()); // Paper
+ 
+             Collections.shuffle(list);
 -            //Paper start - call player naturally spawn event
 -            int chunkRange = level.spigotConfig.mobSpawnRange;
 -            chunkRange = (chunkRange > level.spigotConfig.viewDistance) ? (byte) level.spigotConfig.viewDistance : chunkRange;
@@ -345,10 +345,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -                entityPlayer.playerNaturallySpawnedEvent.callEvent();
 -            };
 -            // Paper end
-+            // Paper - moved up
++            // Paper - moved natural spawn event up
              this.level.timings.chunkTicks.startTiming(); // Paper
-             final int[] chunksTicked = {0}; this.chunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping
-                 Optional<LevelChunk> optional = ((Either) playerchunk.getTickingChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left();
+             final int[] chunksTicked = {0}; // Paper
+             list.forEach((playerchunk) -> {
 @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
                      LevelChunk chunk = (LevelChunk) optional.get();
                      ChunkPos chunkcoordintpair = chunk.getPos();
diff --git a/patches/server/PlayerNaturallySpawnCreaturesEvent.patch b/patches/server/PlayerNaturallySpawnCreaturesEvent.patch
index f6ae8ee3de..2d51e0fbf2 100644
--- a/patches/server/PlayerNaturallySpawnCreaturesEvent.patch
+++ b/patches/server/PlayerNaturallySpawnCreaturesEvent.patch
@@ -40,9 +40,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
 +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
 @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
-             this.level.getProfiler().pop();
-             //List<PlayerChunk> list = Lists.newArrayList(this.playerChunkMap.f()); // Paper
-             //Collections.shuffle(list); // Paper
+             List<ChunkHolder> list = Lists.newArrayList(this.chunkMap.getChunks());
+ 
+             Collections.shuffle(list);
 +            //Paper start - call player naturally spawn event
 +            int chunkRange = level.spigotConfig.mobSpawnRange;
 +            chunkRange = (chunkRange > level.spigotConfig.viewDistance) ? (byte) level.spigotConfig.viewDistance : chunkRange;
@@ -53,7 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            };
 +            // Paper end
              this.level.timings.chunkTicks.startTiming(); // Paper
-             this.chunkMap.getChunks().forEach((playerchunk) -> { // Paper - no... just no...
+             list.forEach((playerchunk) -> {
                  Optional<LevelChunk> optional = ((Either) playerchunk.getTickingChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left();
 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
diff --git a/patches/server/Timings-v2.patch b/patches/server/Timings-v2.patch
index f0d805042d..bcfc37e99d 100644
--- a/patches/server/Timings-v2.patch
+++ b/patches/server/Timings-v2.patch
@@ -1187,10 +1187,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
              this.lastSpawnState = spawnercreature_d;
              this.level.getProfiler().pop();
-             //List<PlayerChunk> list = Lists.newArrayList(this.playerChunkMap.f()); // Paper
-             //Collections.shuffle(list); // Paper
+             List<ChunkHolder> list = Lists.newArrayList(this.chunkMap.getChunks());
+ 
+             Collections.shuffle(list);
 +            this.level.timings.chunkTicks.startTiming(); // Paper
-             this.chunkMap.getChunks().forEach((playerchunk) -> { // Paper - no... just no...
+             list.forEach((playerchunk) -> {
                  Optional<LevelChunk> optional = ((Either) playerchunk.getTickingChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left();
  
 @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {