summaryrefslogtreecommitdiffstats
path: root/nms-patches/ChunkProviderServer.patch
blob: aad3ec49d640dfc87de2cd8548ba2fed4a81fa33 (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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
--- a/net/minecraft/server/ChunkProviderServer.java
+++ b/net/minecraft/server/ChunkProviderServer.java
@@ -20,6 +20,11 @@
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
+// CraftBukkit start
+import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor;
+import org.bukkit.event.world.ChunkUnloadEvent;
+// CraftBukkit end
+
 public class ChunkProviderServer implements IChunkProvider {
 
     private static final Logger a = LogManager.getLogger();
@@ -35,7 +40,7 @@
         this.world = worldserver;
         this.chunkLoader = ichunkloader;
         this.chunkGenerator = chunkgenerator;
-        this.f = new ChunkTaskScheduler(2, worldserver, chunkgenerator, ichunkloader, iasynctaskhandler);
+        this.f = new ChunkTaskScheduler(0, worldserver, chunkgenerator, ichunkloader, iasynctaskhandler); // CraftBukkit - very buggy, broken in lots of __subtle__ ways. Same goes for async chunk loading. Also Bukkit API / plugins can't handle async events at all anyway.
         this.g = new SchedulerBatch(this.f);
     }
 
@@ -77,9 +82,10 @@
     @Nullable
     private Chunk loadChunkAt(int i, int j) {
         try {
-            Chunk chunk = this.chunkLoader.a(this.world, i, j, (chunk) -> {
-                chunk.setLastSaved(this.world.getTime());
-                this.chunks.put(ChunkCoordIntPair.a(i, j), chunk);
+            // CraftBukkit - decompile error
+            Chunk chunk = this.chunkLoader.a(this.world, i, j, (chunk1) -> {
+                chunk1.setLastSaved(this.world.getTime());
+                this.chunks.put(ChunkCoordIntPair.a(i, j), chunk1);
             });
 
             if (chunk != null) {
@@ -104,6 +110,12 @@
         }
     }
 
+    // CraftBukkit start
+    public Chunk getChunkIfLoaded(int x, int z) {
+        return chunks.get(ChunkCoordIntPair.a(x, z));
+    }
+    // CraftBukkit end
+
     public Chunk getChunkAt(int i, int j) {
         Chunk chunk = this.getOrLoadChunkAt(i, j);
 
@@ -125,7 +137,7 @@
         synchronized (this.chunks) {
             IChunkAccess ichunkaccess = (IChunkAccess) this.chunks.get(ChunkCoordIntPair.a(i, j));
 
-            return ichunkaccess != null ? ichunkaccess : (IChunkAccess) this.f.c((Object) (new ChunkCoordIntPair(i, j)));
+            return ichunkaccess != null ? ichunkaccess : (IChunkAccess) this.f.c((new ChunkCoordIntPair(i, j))); // CraftBukkit - decompile error
         }
     }
 
@@ -147,10 +159,21 @@
         return this.g.c();
     }
 
+    // CraftBukkit start
     public CompletableFuture<Chunk> generateChunk(int i, int j) {
+        return this.generateChunk(i, j, false);
+    }
+
+    public CompletableFuture<Chunk> generateChunk(int i, int j, boolean force) {
         this.g.b();
-        this.g.a(new ChunkCoordIntPair(i, j));
-        CompletableFuture completablefuture = this.g.c();
+
+        ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j);
+        if (force) {
+            this.f.forcePolluteCache(chunkcoordintpair);
+        }
+        this.g.a(chunkcoordintpair);
+        // CraftBukkit end
+        CompletableFuture<ProtoChunk> completablefuture = this.g.c(); // CraftBukkit - decompile error
 
         return completablefuture.thenApply(this::a);
     }
@@ -268,10 +291,12 @@
                     Chunk chunk = (Chunk) this.chunks.get(olong);
 
                     if (chunk != null && chunk.d) {
-                        chunk.removeEntities();
-                        this.saveChunk(chunk);
-                        this.saveChunkNOP(chunk);
-                        this.chunks.remove(olong);
+                        // CraftBukkit start - move unload logic to own method
+                        if (!unloadChunk(chunk, true)) {
+                            continue;
+                        }
+                        // CraftBukkit end
+
                         ++i;
                     }
                 }
@@ -284,6 +309,40 @@
         return false;
     }
 
+    // CraftBukkit start
+    public boolean unloadChunk(Chunk chunk, boolean save) {
+        ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk, save);
+        this.world.getServer().getPluginManager().callEvent(event);
+        if (event.isCancelled()) {
+            return false;
+        }
+        save = event.isSaveChunk();
+
+        // Update neighbor counts
+        for (int x = -2; x < 3; x++) {
+            for (int z = -2; z < 3; z++) {
+                if (x == 0 && z == 0) {
+                    continue;
+                }
+
+                Chunk neighbor = this.getChunkIfLoaded(chunk.locX + x, chunk.locZ + z);
+                if (neighbor != null) {
+                    neighbor.setNeighborUnloaded(-x, -z);
+                    chunk.setNeighborUnloaded(x, z);
+                }
+            }
+        }
+        // Moved from unloadChunks above
+        chunk.removeEntities();
+        if (save) {
+            this.saveChunk(chunk);
+            this.saveChunkNOP(chunk);
+        }
+        this.chunks.remove(chunk.chunkKey);
+        return true;
+    }
+    // CraftBukkit end
+
     public boolean e() {
         return !this.world.savingDisabled;
     }