summaryrefslogtreecommitdiffstats
path: root/nms-patches/ChunkRegionLoader.patch
blob: d20b674453bbd1090c40d07ab3cb2f3f4d13327f (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
--- /home/matt/mc-dev-private//net/minecraft/server/ChunkRegionLoader.java	2015-03-16 19:44:31.166833062 +0000
+++ src/main/java/net/minecraft/server/ChunkRegionLoader.java	2015-03-16 19:44:31.166833062 +0000
@@ -25,7 +25,39 @@
         this.e = file;
     }
 
+    // CraftBukkit start
+    public boolean chunkExists(World world, int i, int j) {
+        ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j);
+
+        synchronized (this.d) {
+            if (this.c.contains(chunkcoordintpair)) {
+                for (int k = 0; k < this.b.size(); ++k) {
+                    if (((PendingChunkToSave) this.b.get(k)).a.equals(chunkcoordintpair)) {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return RegionFileCache.a(this.e, i, j).chunkExists(i & 31, j & 31);
+    }
+    // CraftBukkit end
+
+    // CraftBukkit start - Add async variant, provide compatibility
     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
         NBTTagCompound nbttagcompound = null;
         ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j);
         Object object = this.d;
@@ -54,7 +86,7 @@
         return this.a(world, i, j, nbttagcompound);
     }
 
-    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 " + i + "," + j + " is missing level data, skipping");
             return null;
@@ -71,10 +103,28 @@
                     ChunkRegionLoader.a.error("Chunk file at " + i + "," + j + " is in the wrong location; relocating. (Expected " + i + ", " + j + ", got " + chunk.locX + ", " + 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
             }
         }
     }
@@ -308,7 +358,26 @@
                 int k1 = l >> 4 & 15;
                 int l1 = nibblearray1 != null ? nibblearray1.a(i1, j1, k1) : 0;
 
-                achar[l] = (char) (l1 << 12 | (abyte[l] & 255) << 4 | nibblearray.a(i1, j1, k1));
+                // CraftBukkit start - fix broken blocks
+                // achar[l] = (char) (l1 << 12 | (abyte[l] & 255) << 4 | nibblearray.a(i1, j1, k1));
+
+                int ex =  l1;
+                int id = (abyte[l] & 255);
+                int data = nibblearray.a(i1, j1, k1);
+                int packed = ex << 12 | id << 4 | data;
+                if (Block.d.a(packed) == null) {
+                    Block block = Block.getById(ex << 8 | id);
+                    if (block != null) {
+                        try {
+                            data = block.toLegacyData(block.fromLegacyData(data));
+                        } catch (Exception ignored) {
+                            data = block.toLegacyData(block.getBlockData());
+                        }
+                        packed = ex << 12 | id << 4 | data;
+                    }
+                }
+                achar[l] = (char) packed;
+                // CraftBukkit end
             }
 
             chunksection.a(achar);
@@ -326,6 +395,17 @@
             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) {
+        // moved from Chunk.<init>
+        for (int k = 0; k < chunk.entitySlices.length; ++k) {
+            chunk.entitySlices[k] = new EntitySlice(Entity.class);
+        }
+        // CraftBukkit end
+
         NBTTagList nbttaglist1 = nbttagcompound.getList("Entities", 10);
 
         if (nbttaglist1 != null) {
@@ -384,7 +464,7 @@
             }
         }
 
-        return chunk;
+        // return chunk; // CraftBukkit
     }
 
     static class PendingChunkToSave {