summaryrefslogtreecommitdiffstats
path: root/nms-patches/ChunkRegionLoader.patch
blob: bf874a1b7759088319a87b50cc977ad651d2d3d5 (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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
--- a/net/minecraft/server/ChunkRegionLoader.java
+++ b/net/minecraft/server/ChunkRegionLoader.java
@@ -19,29 +19,47 @@
 
     private static final Logger a = LogManager.getLogger();
     private final Map<ChunkCoordIntPair, NBTTagCompound> b = Maps.newConcurrentMap();
-    private final Set<ChunkCoordIntPair> c = Collections.newSetFromMap(Maps.newConcurrentMap());
+    // CraftBukkit
+    // private final Set<ChunkCoordIntPair> c = Collections.newSetFromMap(Maps.newConcurrentMap());
     private final File d;
     private final DataConverterManager e;
-    private boolean f;
+    // private boolean f;
+    // CraftBukkit
 
     public ChunkRegionLoader(File file, DataConverterManager dataconvertermanager) {
         this.d = file;
         this.e = dataconvertermanager;
     }
 
+    // CraftBukkit start - Add async variant, provide compatibility
     @Nullable
     public Chunk a(World world, int i, int j) throws IOException {
+        Object[] data = loadChunk(world, i, j);
+        if (data != null) {
+            Chunk chunk = (Chunk) data[0];
+            NBTTagCompound nbttagcompound = (NBTTagCompound) data[1];
+            loadEntities(chunk, nbttagcompound.getCompound("Level"), world);
+            return chunk;
+        }
+
+        return null;
+    }
+
+    public Object[] loadChunk(World world, int i, int j) throws IOException {
+        // CraftBukkit end
         ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j);
         NBTTagCompound nbttagcompound = (NBTTagCompound) this.b.get(chunkcoordintpair);
 
         if (nbttagcompound == null) {
-            DataInputStream datainputstream = RegionFileCache.d(this.d, i, j);
+            // CraftBukkit start
+            nbttagcompound = RegionFileCache.d(this.d, i, j);
 
-            if (datainputstream == null) {
+            if (nbttagcompound == null) {
                 return null;
             }
 
-            nbttagcompound = this.e.a((DataConverterType) DataConverterTypes.CHUNK, NBTCompressedStreamTools.a(datainputstream));
+            nbttagcompound = this.e.a((DataConverterType) DataConverterTypes.CHUNK, nbttagcompound);
+            // CraftBukkit end
         }
 
         return this.a(world, i, j, nbttagcompound);
@@ -55,7 +73,7 @@
     }
 
     @Nullable
-    protected Chunk a(World world, int i, int j, NBTTagCompound nbttagcompound) {
+    protected Object[] a(World world, int i, int j, NBTTagCompound nbttagcompound) { // CraftBukkit - return Chunk -> Object[]
         if (!nbttagcompound.hasKeyOfType("Level", 10)) {
             ChunkRegionLoader.a.error("Chunk file at {},{} is missing level data, skipping", Integer.valueOf(i), Integer.valueOf(j));
             return null;
@@ -72,10 +90,28 @@
                     ChunkRegionLoader.a.error("Chunk file at {},{} is in the wrong location; relocating. (Expected {}, {}, got {}, {})", Integer.valueOf(i), Integer.valueOf(j), Integer.valueOf(i), Integer.valueOf(j), Integer.valueOf(chunk.locX), Integer.valueOf(chunk.locZ));
                     nbttagcompound1.setInt("xPos", i);
                     nbttagcompound1.setInt("zPos", j);
+
+                    // CraftBukkit start - Have to move tile entities since we don't load them at this stage
+                    NBTTagList tileEntities = nbttagcompound.getCompound("Level").getList("TileEntities", 10);
+                    if (tileEntities != null) {
+                        for (int te = 0; te < tileEntities.size(); te++) {
+                            NBTTagCompound tileEntity = (NBTTagCompound) tileEntities.get(te);
+                            int x = tileEntity.getInt("x") - chunk.locX * 16;
+                            int z = tileEntity.getInt("z") - chunk.locZ * 16;
+                            tileEntity.setInt("x", i * 16 + x);
+                            tileEntity.setInt("z", j * 16 + z);
+                        }
+                    }
+                    // CraftBukkit end
                     chunk = this.a(world, nbttagcompound1);
                 }
 
-                return chunk;
+                // CraftBukkit start
+                Object[] data = new Object[2];
+                data[0] = chunk;
+                data[1] = nbttagcompound;
+                return data;
+                // CraftBukkit end
             }
         }
     }
@@ -98,7 +134,9 @@
     }
 
     protected void a(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) {
-        if (!this.c.contains(chunkcoordintpair)) {
+        // CraftBukkit
+        // if (!this.c.contains(chunkcoordintpair))
+        {
             this.b.put(chunkcoordintpair, nbttagcompound);
         }
 
@@ -106,20 +144,32 @@
     }
 
     public boolean a() {
-        if (this.b.isEmpty()) {
-            if (this.f) {
+        // CraftBukkit start
+        return this.processSaveQueueEntry(false);
+    }
+
+    private synchronized boolean processSaveQueueEntry(boolean logCompletion) {
+        Iterator<Map.Entry<ChunkCoordIntPair, NBTTagCompound>> iter = this.b.entrySet().iterator();
+        if (!iter.hasNext()) {
+            if (logCompletion) {
+                // CraftBukkit end
                 ChunkRegionLoader.a.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", this.d.getName());
             }
 
             return false;
         } else {
-            ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) this.b.keySet().iterator().next();
+            // CraftBukkit start
+            Map.Entry<ChunkCoordIntPair, NBTTagCompound> entry = iter.next();
+            ChunkCoordIntPair chunkcoordintpair = entry.getKey();
+            NBTTagCompound nbttagcompound = entry.getValue();
+            // CraftBukkit end
 
             boolean flag;
 
             try {
-                this.c.add(chunkcoordintpair);
-                NBTTagCompound nbttagcompound = (NBTTagCompound) this.b.remove(chunkcoordintpair);
+                // this.c.add(chunkcoordintpair);
+                // NBTTagCompound nbttagcompound = (NBTTagCompound) this.b.remove(chunkcoordintpair);
+                // CraftBukkit
 
                 if (nbttagcompound != null) {
                     try {
@@ -131,7 +181,7 @@
 
                 flag = true;
             } finally {
-                this.c.remove(chunkcoordintpair);
+                this.b.remove(chunkcoordintpair, nbttagcompound); // CraftBukkit
             }
 
             return flag;
@@ -139,10 +189,14 @@
     }
 
     private void b(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException {
-        DataOutputStream dataoutputstream = RegionFileCache.e(this.d, chunkcoordintpair.x, chunkcoordintpair.z);
+        // CraftBukkit start
+        RegionFileCache.e(this.d, chunkcoordintpair.x, chunkcoordintpair.z, nbttagcompound);
 
+        /*
         NBTCompressedStreamTools.a(nbttagcompound, (DataOutput) dataoutputstream);
         dataoutputstream.close();
+        */
+        // CraftBukkit end
     }
 
     public void b(World world, Chunk chunk) throws IOException {}
@@ -151,15 +205,16 @@
 
     public void c() {
         try {
-            this.f = true;
+            // this.f = true; // CraftBukkit
 
             while (true) {
-                if (this.a()) {
+                if (this.processSaveQueueEntry(true)) { // CraftBukkit
                     continue;
                 }
+                break; // CraftBukkit - Fix infinite loop when saving chunks
             }
         } finally {
-            this.f = false;
+            // this.f = false; // CraftBukkit
         }
 
     }
@@ -334,6 +389,13 @@
             chunk.a(nbttagcompound.getByteArray("Biomes"));
         }
 
+        // CraftBukkit start - End this method here and split off entity loading to another method
+        return chunk;
+    }
+
+    public void loadEntities(Chunk chunk, NBTTagCompound nbttagcompound, World world) {
+        // CraftBukkit end
+
         NBTTagList nbttaglist1 = nbttagcompound.getList("Entities", 10);
 
         for (int l = 0; l < nbttaglist1.size(); ++l) {
@@ -371,7 +433,7 @@
             }
         }
 
-        return chunk;
+        // return chunk; // CraftBukkit
     }
 
     @Nullable
@@ -399,14 +461,20 @@
     }
 
     @Nullable
+    // CraftBukkit start
     public static Entity a(NBTTagCompound nbttagcompound, World world, double d0, double d1, double d2, boolean flag) {
+        return spawnEntity(nbttagcompound, world, d0, d1, d2, flag, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT);
+    }
+
+    public static Entity spawnEntity(NBTTagCompound nbttagcompound, World world, double d0, double d1, double d2, boolean flag, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
+        // CraftBukkit end
         Entity entity = a(nbttagcompound, world);
 
         if (entity == null) {
             return null;
         } else {
             entity.setPositionRotation(d0, d1, d2, entity.yaw, entity.pitch);
-            if (flag && !world.addEntity(entity)) {
+            if (flag && !world.addEntity(entity, spawnReason)) { // CraftBukkit
                 return null;
             } else {
                 if (nbttagcompound.hasKeyOfType("Passengers", 9)) {
@@ -435,8 +503,14 @@
         }
     }
 
+    // CraftBukkit start
     public static void a(Entity entity, World world) {
-        if (world.addEntity(entity) && entity.isVehicle()) {
+        a(entity, world, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT);
+    }
+
+    public static void a(Entity entity, World world, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) {
+        if (world.addEntity(entity, reason) && entity.isVehicle()) {
+            // CraftBukkit end
             Iterator iterator = entity.bF().iterator();
 
             while (iterator.hasNext()) {