Improved workaround for 1.14 chunk load problems

This commit is contained in:
Mike Primm 2019-05-11 16:45:10 -05:00
parent c1902a2a9b
commit fb24299a05

View File

@ -1,6 +1,12 @@
package org.dynmap.bukkit.helper.v114;
import org.bukkit.block.Biome;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashMap;
import org.bukkit.ChunkSnapshot;
import org.bukkit.World;
import org.dynmap.bukkit.helper.AbstractMapChunkCache;
@ -64,13 +70,14 @@ public class MapChunkCache114 extends AbstractMapChunkCache {
public Snapshot wrapChunkSnapshot(ChunkSnapshot css) {
return new WrappedSnapshot(css);
}
@Override
public boolean loadChunkNoGenerate(World w, int x, int z) {
boolean generated = true;
// Check one in each direction: see if all are generated
for (int xx = x-4; xx <= x+4; xx++) {
for (int zz = z-4; zz <= z+4; zz++) {
if (w.isChunkGenerated(xx, zz) == false) {
for (int xx = x-3; xx <= x+3; xx++) {
for (int zz = z-3; zz <= z+3; zz++) {
if (isChunkGenerated(w, xx, zz) == false) {
generated = false;
break;
}
@ -82,4 +89,52 @@ public class MapChunkCache114 extends AbstractMapChunkCache {
}
return rslt;
}
private static class CacheRec {
long timestamp;
long[] blockmap; // ( bit = 1 at blockmap[z] & (1 << x))
}
private static HashMap<String, CacheRec> regioncache = new HashMap<String, CacheRec>();
private static long CACHE_TIMEOUT = 15000L; // 15 second cache
private static boolean isChunkGenerated(World w, int x, int z) {
String fn = String.format("%s/region/r.%d.%d.mca", w.getWorldFolder().getPath(), (x >> 5), (z >> 5));
CacheRec rec = regioncache.get(fn);
long ts = System.currentTimeMillis();
if ((rec == null) || (rec.timestamp < ts)) {
if (rec == null) {
rec = new CacheRec();
rec.blockmap = new long[32];
}
rec.timestamp = ts + CACHE_TIMEOUT;
RandomAccessFile raf = null;
byte[] dat = new byte[4096];
try {
raf = new RandomAccessFile(fn, "r");
raf.seek(0);
raf.read(dat);
} catch (IOException iox) {
} finally {
if (raf != null) {
try {
raf.close();
} catch (IOException iox) {
}
}
}
// Build cache map
for (int zz = 0; zz < 32; zz++) {
long val = 0;
for (int xx = 0; xx < 32; xx++) {
int off = 4*((zz << 5) + xx);
int v = dat[off] | dat[off+1] | dat[off+2] | dat[off+3];
if (v != 0)
val |= (1L << xx);
}
rec.blockmap[zz] = val;
}
regioncache.put(fn, rec);
}
return (rec.blockmap[z & 31] & (1L << (x & 31))) != 0;
}
}