aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches-Unmapped/0355-ChunkMapDistance-CME.patch
blob: 148847522f64aea23a8104cef504bc877018d2a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Wed, 29 May 2019 04:01:22 +0100
Subject: [PATCH] ChunkMapDistance CME


diff --git a/src/main/java/net/minecraft/server/level/ChunkMapDistance.java b/src/main/java/net/minecraft/server/level/ChunkMapDistance.java
index 6ef404ee29ddc79aeca534a58ec182e0e8b1b6c8..961257ebc28a8b4753faf3c2d5b6abaea4ffc0dd 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMapDistance.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMapDistance.java
@@ -39,7 +39,16 @@ public abstract class ChunkMapDistance {
     private final ChunkMapDistance.a ticketLevelTracker = new ChunkMapDistance.a();
     private final ChunkMapDistance.b f = new ChunkMapDistance.b(8);
     private final ChunkMapDistance.c g = new ChunkMapDistance.c(33);
-    private final Set<PlayerChunk> pendingChunkUpdates = Sets.newHashSet();
+    // Paper start use a queue, but still keep unique requirement
+    public final java.util.Queue<PlayerChunk> pendingChunkUpdates = new java.util.ArrayDeque<PlayerChunk>() {
+        @Override
+        public boolean add(PlayerChunk o) {
+            if (o.isUpdateQueued) return true;
+            o.isUpdateQueued = true;
+            return super.add(o);
+        }
+    };
+    // Paper end
     private final ChunkTaskQueueSorter i;
     private final Mailbox<ChunkTaskQueueSorter.a<Runnable>> j;
     private final Mailbox<ChunkTaskQueueSorter.b> k;
@@ -100,26 +109,14 @@ public abstract class ChunkMapDistance {
             ;
         }
 
+        // Paper start
         if (!this.pendingChunkUpdates.isEmpty()) {
-            // CraftBukkit start
-            // Iterate pending chunk updates with protection against concurrent modification exceptions
-            java.util.Iterator<PlayerChunk> iter = this.pendingChunkUpdates.iterator();
-            int expectedSize = this.pendingChunkUpdates.size();
-            do {
-                PlayerChunk playerchunk = iter.next();
-                iter.remove();
-                expectedSize--;
-
-                playerchunk.a(playerchunkmap);
-
-                // Reset iterator if set was modified using add()
-                if (this.pendingChunkUpdates.size() != expectedSize) {
-                    expectedSize = this.pendingChunkUpdates.size();
-                    iter = this.pendingChunkUpdates.iterator();
-                }
-            } while (iter.hasNext());
-            // CraftBukkit end
-
+            while(!this.pendingChunkUpdates.isEmpty()) {
+                PlayerChunk remove = this.pendingChunkUpdates.remove();
+                remove.isUpdateQueued = false;
+                remove.a(playerchunkmap);
+            }
+            // Paper end
             return true;
         } else {
             if (!this.l.isEmpty()) {
@@ -373,7 +370,7 @@ public abstract class ChunkMapDistance {
             ObjectIterator objectiterator = this.a.long2ByteEntrySet().iterator();
 
             while (objectiterator.hasNext()) {
-                it.unimi.dsi.fastutil.longs.Long2ByteMap.Entry it_unimi_dsi_fastutil_longs_long2bytemap_entry = (it.unimi.dsi.fastutil.longs.Long2ByteMap.Entry) objectiterator.next();
+                Long2ByteMap.Entry it_unimi_dsi_fastutil_longs_long2bytemap_entry = (Long2ByteMap.Entry) objectiterator.next(); // Paper - decompile fix
                 byte b0 = it_unimi_dsi_fastutil_longs_long2bytemap_entry.getByteValue();
                 long j = it_unimi_dsi_fastutil_longs_long2bytemap_entry.getLongKey();
 
diff --git a/src/main/java/net/minecraft/server/level/PlayerChunk.java b/src/main/java/net/minecraft/server/level/PlayerChunk.java
index 7dea5e783ce2a1f8ddd2b3ab7a19e03a56c36ba1..2c3d9a5d118cc4f3b5e78daf943911bb7386488a 100644
--- a/src/main/java/net/minecraft/server/level/PlayerChunk.java
+++ b/src/main/java/net/minecraft/server/level/PlayerChunk.java
@@ -45,6 +45,7 @@ public class PlayerChunk {
     private static final CompletableFuture<Either<Chunk, PlayerChunk.Failure>> UNLOADED_CHUNK_FUTURE = CompletableFuture.completedFuture(PlayerChunk.UNLOADED_CHUNK);
     private static final List<ChunkStatus> CHUNK_STATUSES = ChunkStatus.a();
     private static final PlayerChunk.State[] CHUNK_STATES = PlayerChunk.State.values();
+    boolean isUpdateQueued = false; // Paper
     private final AtomicReferenceArray<CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>>> statusFutures;
     private volatile CompletableFuture<Either<Chunk, PlayerChunk.Failure>> fullChunkFuture; private int fullChunkCreateCount; private volatile boolean isFullChunkReady; // Paper - cache chunk ticking stage
     private volatile CompletableFuture<Either<Chunk, PlayerChunk.Failure>> tickingFuture; private volatile boolean isTickingReady; // Paper - cache chunk ticking stage