mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-11-12 13:34:47 +01:00
Put 3D biome code in spigot 1.18 - still working on grass shading...
This commit is contained in:
parent
983a2a4390
commit
37fd064434
@ -1,5 +1,6 @@
|
||||
package org.dynmap.common;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -9,7 +10,7 @@ import org.dynmap.hdmap.HDBlockModels;
|
||||
/* Generic biome mapping */
|
||||
public class BiomeMap {
|
||||
public static final int NO_INDEX = -2;
|
||||
private static BiomeMap[] biome_by_index = new BiomeMap[1025];
|
||||
private static BiomeMap[] biome_by_index = new BiomeMap[256];
|
||||
private static Map<String, BiomeMap> biome_by_rl = new HashMap<String, BiomeMap>();
|
||||
public static final BiomeMap NULL = new BiomeMap(-1, "NULL", 0.5, 0.5, 0xFFFFFF, 0, 0, null);
|
||||
|
||||
@ -37,7 +38,7 @@ public class BiomeMap {
|
||||
public static final BiomeMap JUNGLE = new BiomeMap(21, "JUNGLE", 1.2, 0.9, "minecraft:jungle");
|
||||
public static final BiomeMap JUNGLE_HILLS = new BiomeMap(22, "JUNGLE_HILLS", 1.2, 0.9, "minecraft:jungle_hills");
|
||||
|
||||
public static final int LAST_WELL_KNOWN = 22;
|
||||
public static final int LAST_WELL_KNOWN = 175;
|
||||
|
||||
private double tmp;
|
||||
private double rain;
|
||||
@ -128,7 +129,7 @@ public class BiomeMap {
|
||||
}
|
||||
|
||||
static {
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
for (int i = 0; i < 256; i++) {
|
||||
BiomeMap bm = BiomeMap.byBiomeID(i);
|
||||
if (bm == null) {
|
||||
bm = new BiomeMap(i, "BIOME_" + i);
|
||||
@ -145,6 +146,20 @@ public class BiomeMap {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void resizeIfNeeded(int idx) {
|
||||
if ((idx >= biome_by_index.length) ) {
|
||||
int oldlen = biome_by_index.length;
|
||||
biome_by_index = Arrays.copyOf(biome_by_index, biome_by_index.length * 3 / 2);
|
||||
for (int i = oldlen; i < biome_by_index.length; i++) {
|
||||
if (biome_by_index[i] == null) {
|
||||
BiomeMap bm = new BiomeMap(i, "BIOME_" + i);
|
||||
bm.isDef = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BiomeMap(int idx, String id, double tmp, double rain, int waterColorMultiplier, int grassmult, int foliagemult, String rl) {
|
||||
/* Clamp values : we use raw values from MC code, which are clamped during color mapping only */
|
||||
setTemperature(tmp);
|
||||
@ -159,9 +174,20 @@ public class BiomeMap {
|
||||
id = id + "_" + idx;
|
||||
}
|
||||
this.id = id;
|
||||
// If index is NO_INDEX, find one after the well known ones
|
||||
if (idx == NO_INDEX) {
|
||||
idx = LAST_WELL_KNOWN + 1;
|
||||
while (true) {
|
||||
resizeIfNeeded(idx);
|
||||
if (biome_by_index[idx].isDef) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
idx++; /* Insert one after ID value - null is zero index */
|
||||
this.index = idx;
|
||||
if (idx >= 0) {
|
||||
resizeIfNeeded(idx);
|
||||
biome_by_index[idx] = this;
|
||||
}
|
||||
this.resourcelocation = rl;
|
||||
|
@ -36,8 +36,6 @@ public abstract class GenericMapChunkCache extends MapChunkCache {
|
||||
private boolean isempty = true;
|
||||
private int snapcnt;
|
||||
private GenericChunk[] snaparray; /* Index = (x-x_min) + ((z-z_min)*x_dim) */
|
||||
private byte[][] sameneighborbiomecnt;
|
||||
private BiomeMap[][] biomemap;
|
||||
private boolean[][] isSectionNotEmpty; /* Indexed by snapshot index, then by section index */
|
||||
|
||||
private static final BlockStep unstep[] = { BlockStep.X_MINUS, BlockStep.Y_MINUS, BlockStep.Z_MINUS,
|
||||
@ -64,8 +62,6 @@ public abstract class GenericMapChunkCache extends MapChunkCache {
|
||||
x_base = x_min << 4;
|
||||
z_base = z_min << 4;
|
||||
|
||||
biomePrep();
|
||||
|
||||
initialize(x0, y0, z0);
|
||||
worldheight = dw.worldheight;
|
||||
ymin = dw.minY;
|
||||
@ -113,100 +109,46 @@ public abstract class GenericMapChunkCache extends MapChunkCache {
|
||||
}
|
||||
}
|
||||
|
||||
private void biomePrep() {
|
||||
if (sameneighborbiomecnt != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int x_size = x_dim << 4;
|
||||
int z_size = (z_max - z_min + 1) << 4;
|
||||
sameneighborbiomecnt = new byte[x_size][];
|
||||
biomemap = new BiomeMap[x_size][];
|
||||
|
||||
for (int i = 0; i < x_size; i++) {
|
||||
sameneighborbiomecnt[i] = new byte[z_size];
|
||||
biomemap[i] = new BiomeMap[z_size];
|
||||
}
|
||||
|
||||
for (int i = 0; i < x_size; i++) {
|
||||
for (int j = 0; j < z_size; j++) {
|
||||
if (j == 0)
|
||||
initialize(i + x_base, 64, z_base);
|
||||
else
|
||||
stepPosition(BlockStep.Z_PLUS);
|
||||
|
||||
BiomeMap bm = snap.getBiome(bx, y, bz);
|
||||
|
||||
biomemap[i][j] = bm;
|
||||
int cnt = 0;
|
||||
|
||||
if (i > 0) {
|
||||
if (bm == biomemap[i - 1][j]) /* Same as one to left */
|
||||
{
|
||||
cnt++;
|
||||
sameneighborbiomecnt[i - 1][j]++;
|
||||
}
|
||||
|
||||
if ((j > 0) && (bm == biomemap[i - 1][j - 1])) {
|
||||
cnt++;
|
||||
sameneighborbiomecnt[i - 1][j - 1]++;
|
||||
}
|
||||
|
||||
if ((j < (z_size - 1)) && (bm == biomemap[i - 1][j + 1])) {
|
||||
cnt++;
|
||||
sameneighborbiomecnt[i - 1][j + 1]++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((j > 0) && (biomemap[i][j] == biomemap[i][j - 1])) /* Same as one to above */
|
||||
{
|
||||
cnt++;
|
||||
sameneighborbiomecnt[i][j - 1]++;
|
||||
}
|
||||
|
||||
sameneighborbiomecnt[i][j] = (byte) cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final BiomeMap getBiome() {
|
||||
try {
|
||||
return biomemap[x - x_base][z - z_base];
|
||||
return snap.getBiome(bx, y, bz);
|
||||
} catch (Exception ex) {
|
||||
return BiomeMap.NULL;
|
||||
}
|
||||
}
|
||||
|
||||
private final BiomeMap getBiomeRel(int dx, int dz) {
|
||||
int nx = x + dx;
|
||||
int nz = z + dz;
|
||||
int nchunkindex = ((nx >> 4) - x_min) + (((nz >> 4) - z_min) * x_dim);
|
||||
if ((nchunkindex >= snapcnt) || (nchunkindex < 0)) {
|
||||
return BiomeMap.NULL;
|
||||
} else {
|
||||
return snaparray[chunkindex].getBiome(nx, y, nz);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getSmoothGrassColorMultiplier(int[] colormap) {
|
||||
int mult = 0xFFFFFF;
|
||||
|
||||
try {
|
||||
int rx = x - x_base;
|
||||
int rz = z - z_base;
|
||||
BiomeMap bm = biomemap[rx][rz];
|
||||
|
||||
if (sameneighborbiomecnt[rx][rz] >= (byte) 8) /* All neighbors same? */
|
||||
{
|
||||
mult = bm.getModifiedGrassMultiplier(colormap[bm.biomeLookup()]);
|
||||
} else {
|
||||
int raccum = 0;
|
||||
int gaccum = 0;
|
||||
int baccum = 0;
|
||||
|
||||
for (int xoff = -1; xoff < 2; xoff++) {
|
||||
for (int zoff = -1; zoff < 2; zoff++) {
|
||||
bm = biomemap[rx + xoff][rz + zoff];
|
||||
int cnt = 0;
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
for (int dz = -1; dz <= 1; dz++) {
|
||||
BiomeMap bm = getBiomeRel(dx, dz);
|
||||
int rmult = bm.getModifiedGrassMultiplier(colormap[bm.biomeLookup()]);
|
||||
raccum += (rmult >> 16) & 0xFF;
|
||||
gaccum += (rmult >> 8) & 0xFF;
|
||||
baccum += rmult & 0xFF;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9);
|
||||
}
|
||||
mult = ((raccum / cnt) << 16) | ((gaccum / cnt) << 8) | (baccum / cnt);
|
||||
} catch (Exception x) {
|
||||
//Log.info("getSmoothGrassColorMultiplier() error: " + x);
|
||||
mult = 0xFFFFFF;
|
||||
@ -221,30 +163,21 @@ public abstract class GenericMapChunkCache extends MapChunkCache {
|
||||
int mult = 0xFFFFFF;
|
||||
|
||||
try {
|
||||
int rx = x - x_base;
|
||||
int rz = z - z_base;
|
||||
BiomeMap bm = biomemap[rx][rz];
|
||||
|
||||
if (sameneighborbiomecnt[rx][rz] >= (byte) 8) /* All neighbors same? */
|
||||
{
|
||||
mult = bm.getModifiedFoliageMultiplier(colormap[bm.biomeLookup()]);
|
||||
} else {
|
||||
int raccum = 0;
|
||||
int gaccum = 0;
|
||||
int baccum = 0;
|
||||
|
||||
for (int xoff = -1; xoff < 2; xoff++) {
|
||||
for (int zoff = -1; zoff < 2; zoff++) {
|
||||
bm = biomemap[rx + xoff][rz + zoff];
|
||||
int cnt = 0;
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
for (int dz = -1; dz <= 1; dz++) {
|
||||
BiomeMap bm = getBiomeRel(dx, dz);
|
||||
int rmult = bm.getModifiedFoliageMultiplier(colormap[bm.biomeLookup()]);
|
||||
raccum += (rmult >> 16) & 0xFF;
|
||||
gaccum += (rmult >> 8) & 0xFF;
|
||||
baccum += rmult & 0xFF;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9);
|
||||
}
|
||||
mult = ((raccum / cnt) << 16) | ((gaccum / cnt) << 8) | (baccum / cnt);
|
||||
} catch (Exception x) {
|
||||
//Log.info("getSmoothFoliageColorMultiplier() error: " + x);
|
||||
mult = 0xFFFFFF;
|
||||
@ -259,41 +192,26 @@ public abstract class GenericMapChunkCache extends MapChunkCache {
|
||||
int mult = 0xFFFFFF;
|
||||
|
||||
try {
|
||||
int rx = x - x_base;
|
||||
int rz = z - z_base;
|
||||
BiomeMap bm = biomemap[rx][rz];
|
||||
|
||||
if (sameneighborbiomecnt[rx][rz] >= (byte) 8) /* All neighbors same? */
|
||||
{
|
||||
if (bm == BiomeMap.SWAMPLAND) {
|
||||
mult = swampmap[bm.biomeLookup()];
|
||||
} else {
|
||||
mult = colormap[bm.biomeLookup()];
|
||||
}
|
||||
} else {
|
||||
int raccum = 0;
|
||||
int gaccum = 0;
|
||||
int baccum = 0;
|
||||
|
||||
for (int xoff = -1; xoff < 2; xoff++) {
|
||||
for (int zoff = -1; zoff < 2; zoff++) {
|
||||
bm = biomemap[rx + xoff][rz + zoff];
|
||||
int cnt = 0;
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
for (int dz = -1; dz <= 1; dz++) {
|
||||
BiomeMap bm = getBiomeRel(dx, dz);
|
||||
int rmult;
|
||||
|
||||
if (bm == BiomeMap.SWAMPLAND) {
|
||||
rmult = swampmap[bm.biomeLookup()];
|
||||
} else {
|
||||
rmult = colormap[bm.biomeLookup()];
|
||||
}
|
||||
|
||||
raccum += (rmult >> 16) & 0xFF;
|
||||
gaccum += (rmult >> 8) & 0xFF;
|
||||
baccum += rmult & 0xFF;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9);
|
||||
}
|
||||
mult = ((raccum / cnt) << 16) | ((gaccum / cnt) << 8) | (baccum / cnt);
|
||||
} catch (Exception x) {
|
||||
//Log.info("getSmoothColorMultiplier() error: " + x);
|
||||
mult = 0xFFFFFF;
|
||||
@ -307,30 +225,21 @@ public abstract class GenericMapChunkCache extends MapChunkCache {
|
||||
public final int getSmoothWaterColorMultiplier() {
|
||||
int multv;
|
||||
try {
|
||||
int rx = x - x_base;
|
||||
int rz = z - z_base;
|
||||
BiomeMap bm = biomemap[rx][rz];
|
||||
|
||||
if (sameneighborbiomecnt[rx][rz] >= (byte) 8) /* All neighbors same? */
|
||||
{
|
||||
multv = bm.getWaterColorMult();
|
||||
} else {
|
||||
int raccum = 0;
|
||||
int gaccum = 0;
|
||||
int baccum = 0;
|
||||
|
||||
for (int xoff = -1; xoff < 2; xoff++) {
|
||||
for (int zoff = -1; zoff < 2; zoff++) {
|
||||
bm = biomemap[rx + xoff][rz + zoff];
|
||||
int mult = bm.getWaterColorMult();
|
||||
raccum += (mult >> 16) & 0xFF;
|
||||
gaccum += (mult >> 8) & 0xFF;
|
||||
baccum += mult & 0xFF;
|
||||
int cnt = 0;
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
for (int dz = -1; dz <= 1; dz++) {
|
||||
BiomeMap bm = getBiomeRel(dx, dz);
|
||||
int rmult = bm.getWaterColorMult();
|
||||
raccum += (rmult >> 16) & 0xFF;
|
||||
gaccum += (rmult >> 8) & 0xFF;
|
||||
baccum += rmult & 0xFF;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
multv = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9);
|
||||
}
|
||||
multv = ((raccum / cnt) << 16) | ((gaccum / cnt) << 8) | (baccum / cnt);
|
||||
} catch (Exception x) {
|
||||
//Log.info("getSmoothWaterColorMultiplier(nomap) error: " + x);
|
||||
|
||||
@ -346,30 +255,21 @@ public abstract class GenericMapChunkCache extends MapChunkCache {
|
||||
int mult = 0xFFFFFF;
|
||||
|
||||
try {
|
||||
int rx = x - x_base;
|
||||
int rz = z - z_base;
|
||||
BiomeMap bm = biomemap[rx][rz];
|
||||
|
||||
if (sameneighborbiomecnt[rx][rz] >= (byte) 8) /* All neighbors same? */
|
||||
{
|
||||
mult = colormap[bm.biomeLookup()];
|
||||
} else {
|
||||
int raccum = 0;
|
||||
int gaccum = 0;
|
||||
int baccum = 0;
|
||||
|
||||
for (int xoff = -1; xoff < 2; xoff++) {
|
||||
for (int zoff = -1; zoff < 2; zoff++) {
|
||||
bm = biomemap[rx + xoff][rz + zoff];
|
||||
int cnt = 0;
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
for (int dz = -1; dz <= 1; dz++) {
|
||||
BiomeMap bm = getBiomeRel(dx, dz);
|
||||
int rmult = colormap[bm.biomeLookup()];
|
||||
raccum += (rmult >> 16) & 0xFF;
|
||||
gaccum += (rmult >> 8) & 0xFF;
|
||||
baccum += rmult & 0xFF;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9);
|
||||
}
|
||||
mult = ((raccum / cnt) << 16) | ((gaccum / cnt) << 8) | (baccum / cnt);
|
||||
} catch (Exception x) {
|
||||
//Log.info("getSmoothWaterColorMultiplier() error: " + x);
|
||||
mult = 0xFFFFFF;
|
||||
|
@ -62,7 +62,9 @@ import java.util.Map;
|
||||
* Helper for isolation of bukkit version specific issues
|
||||
*/
|
||||
public class BukkitVersionHelperSpigot118 extends BukkitVersionHelper {
|
||||
|
||||
public BukkitVersionHelperSpigot118() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,7 +193,7 @@ public class BukkitVersionHelperSpigot118 extends BukkitVersionHelper {
|
||||
*/
|
||||
@Override
|
||||
public MapChunkCache getChunkCache(BukkitWorld dw, List<DynmapChunk> chunks) {
|
||||
MapChunkCache118 c = new MapChunkCache118();
|
||||
MapChunkCache118 c = new MapChunkCache118(gencache);
|
||||
c.setChunks(dw, chunks);
|
||||
return c;
|
||||
}
|
||||
@ -437,4 +439,9 @@ public class BukkitVersionHelperSpigot118 extends BukkitVersionHelper {
|
||||
CraftWorld cw = (CraftWorld) w;
|
||||
return cw.getMinHeight();
|
||||
}
|
||||
@Override
|
||||
public boolean useGenericCache() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,11 +6,16 @@ import org.bukkit.block.Biome;
|
||||
import org.bukkit.craftbukkit.v1_18_R1.CraftWorld;
|
||||
import org.dynmap.DynmapChunk;
|
||||
import org.dynmap.DynmapCore;
|
||||
import org.dynmap.bukkit.helper.BukkitWorld;
|
||||
import org.dynmap.bukkit.helper.AbstractMapChunkCache;
|
||||
import org.dynmap.bukkit.helper.BukkitVersionHelper;
|
||||
import org.dynmap.bukkit.helper.SnapshotCache;
|
||||
import org.dynmap.bukkit.helper.SnapshotCache.SnapshotRec;
|
||||
import org.dynmap.common.BiomeMap;
|
||||
import org.dynmap.common.chunk.GenericChunk;
|
||||
import org.dynmap.common.chunk.GenericChunkCache;
|
||||
import org.dynmap.common.chunk.GenericChunkSection;
|
||||
import org.dynmap.common.chunk.GenericMapChunkCache;
|
||||
import org.dynmap.renderer.DynmapBlockState;
|
||||
import org.dynmap.utils.DataBitsPacked;
|
||||
import org.dynmap.utils.DynIntHashMap;
|
||||
@ -28,186 +33,67 @@ import net.minecraft.world.level.chunk.Chunk;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread
|
||||
*/
|
||||
public class MapChunkCache118 extends AbstractMapChunkCache {
|
||||
|
||||
public static class NBTSnapshot implements Snapshot {
|
||||
private static interface Section {
|
||||
public DynmapBlockState getBlockType(int x, int y, int z);
|
||||
public int getBlockSkyLight(int x, int y, int z);
|
||||
public int getBlockEmittedLight(int x, int y, int z);
|
||||
public boolean isEmpty();
|
||||
public int getBiome(int x, int y, int z);
|
||||
}
|
||||
private final int x, z;
|
||||
private final Section[] section;
|
||||
private final int sectionOffset;
|
||||
private final int[] hmap; // Height map
|
||||
private final int[] biome;
|
||||
private final Object[] biomebase;
|
||||
private final long captureFulltime;
|
||||
private final int sectionCnt;
|
||||
private final long inhabitedTicks;
|
||||
|
||||
private static final int BLOCKS_PER_SECTION = 16 * 16 * 16;
|
||||
private static final int BIOMES_PER_SECTION = 4 * 4 * 4;
|
||||
private static final int COLUMNS_PER_CHUNK = 16 * 16;
|
||||
private static final byte[] emptyData = new byte[BLOCKS_PER_SECTION / 2];
|
||||
private static final byte[] fullData = new byte[BLOCKS_PER_SECTION / 2];
|
||||
|
||||
static
|
||||
{
|
||||
Arrays.fill(fullData, (byte)0xFF);
|
||||
}
|
||||
|
||||
private static byte[] dataCopy(byte[] v) {
|
||||
if (Arrays.equals(v, emptyData))
|
||||
return emptyData;
|
||||
else if (Arrays.equals(v, fullData))
|
||||
return fullData;
|
||||
else
|
||||
return v.clone();
|
||||
}
|
||||
|
||||
private static class EmptySection implements Section {
|
||||
@Override
|
||||
public DynmapBlockState getBlockType(int x, int y, int z) {
|
||||
return DynmapBlockState.AIR;
|
||||
}
|
||||
@Override
|
||||
public int getBlockSkyLight(int x, int y, int z) {
|
||||
return 15;
|
||||
}
|
||||
@Override
|
||||
public int getBlockEmittedLight(int x, int y, int z) {
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public int getBiome(int x, int y, int z) {
|
||||
return BiomeMap.PLAINS.getBiomeID();
|
||||
}
|
||||
}
|
||||
|
||||
private static final EmptySection empty_section = new EmptySection();
|
||||
|
||||
private static class StdSection implements Section {
|
||||
DynmapBlockState[] states;
|
||||
byte[] skylight;
|
||||
byte[] emitlight;
|
||||
int[] biomes;
|
||||
|
||||
public StdSection() {
|
||||
states = new DynmapBlockState[BLOCKS_PER_SECTION];
|
||||
Arrays.fill(states, DynmapBlockState.AIR);
|
||||
biomes = new int[BIOMES_PER_SECTION];
|
||||
skylight = emptyData;
|
||||
emitlight = emptyData;
|
||||
}
|
||||
@Override
|
||||
public DynmapBlockState getBlockType(int x, int y, int z) {
|
||||
return states[((y & 0xF) << 8) | (z << 4) | x];
|
||||
}
|
||||
@Override
|
||||
public int getBlockSkyLight(int x, int y, int z) {
|
||||
int off = ((y & 0xF) << 7) | (z << 3) | (x >> 1);
|
||||
return (skylight[off] >> (4 * (x & 1))) & 0xF;
|
||||
}
|
||||
@Override
|
||||
public int getBlockEmittedLight(int x, int y, int z)
|
||||
{
|
||||
int off = ((y & 0xF) << 7) | (z << 3) | (x >> 1);
|
||||
return (emitlight[off] >> (4 * (x & 1))) & 0xF;
|
||||
}
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public int getBiome(int x, int y, int z) {
|
||||
int off = (((y & 0xF) >> 2) << 4) | ((z >> 2) << 2) | (x >> 2);
|
||||
return biomes[off];
|
||||
}
|
||||
}
|
||||
public class MapChunkCache118 extends GenericMapChunkCache {
|
||||
private World w;
|
||||
/**
|
||||
* Construct empty chunk snapshot
|
||||
*
|
||||
* @param x
|
||||
* @param z
|
||||
* Construct empty cache
|
||||
*/
|
||||
public NBTSnapshot(int worldheight, int x, int z, long captime, long inhabitedTime)
|
||||
{
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
this.captureFulltime = captime;
|
||||
this.biome = new int[COLUMNS_PER_CHUNK];
|
||||
this.biomebase = new Object[COLUMNS_PER_CHUNK];
|
||||
this.sectionCnt = worldheight / 16;
|
||||
/* Allocate arrays indexed by section */
|
||||
this.section = new Section[this.sectionCnt+1];
|
||||
this.sectionOffset = 0;
|
||||
/* Fill with empty data */
|
||||
for (int i = 0; i <= this.sectionCnt; i++) {
|
||||
this.section[i] = empty_section;
|
||||
public MapChunkCache118(GenericChunkCache cc) {
|
||||
super(cc);
|
||||
init();
|
||||
}
|
||||
|
||||
/* Create empty height map */
|
||||
this.hmap = new int[16 * 16];
|
||||
|
||||
this.inhabitedTicks = inhabitedTime;
|
||||
private GenericChunk parseChunkFromNBT(NBTTagCompound nbt) {
|
||||
if ((nbt != null) && nbt.e("Level")) {
|
||||
nbt = nbt.p("Level");
|
||||
}
|
||||
|
||||
public NBTSnapshot(NBTTagCompound nbt, int worldheight) {
|
||||
this.x = nbt.h("xPos");
|
||||
this.z = nbt.h("zPos");
|
||||
this.captureFulltime = 0;
|
||||
this.hmap = nbt.n("HeightMap");
|
||||
this.sectionCnt = worldheight / 16;
|
||||
if (nbt == null) return null;
|
||||
// Start generic chunk builder
|
||||
GenericChunk.Builder bld = new GenericChunk.Builder(dw.minY, dw.worldheight);
|
||||
bld.coords(nbt.h("xPos"), nbt.h("zPos"));
|
||||
if (nbt.e("InhabitedTime")) {
|
||||
this.inhabitedTicks = nbt.i("InhabitedTime");
|
||||
bld.inhabitedTicks(nbt.i("InhabitedTime"));
|
||||
}
|
||||
else {
|
||||
this.inhabitedTicks = 0;
|
||||
// Check for 2D or old 3D biome data from chunk level: need these when we build old sections
|
||||
List<BiomeMap[]> old3d = null; // By section, then YZX list
|
||||
BiomeMap[] old2d = null;
|
||||
if (nbt.e("Biomes")) {
|
||||
int[] bb = nbt.n("Biomes");
|
||||
if (bb != null) {
|
||||
// If v1.15+ format
|
||||
if (bb.length > 256) {
|
||||
old3d = new ArrayList<BiomeMap[]>();
|
||||
// Get 4 x 4 x 4 list for each section
|
||||
for (int sect = 0; sect < (bb.length / 64); sect++) {
|
||||
BiomeMap smap[] = new BiomeMap[64];
|
||||
for (int i = 0; i < 64; i++) {
|
||||
smap[i] = BiomeMap.byBiomeID(bb[sect*64 + i]);
|
||||
}
|
||||
/* Allocate arrays indexed by section */
|
||||
LinkedList<Section> sections = new LinkedList<Section>();
|
||||
int sectoff = 0; // Default to zero
|
||||
int sectcnt = 0;
|
||||
/* Fill with empty data */
|
||||
for (int i = 0; i <= this.sectionCnt; i++) {
|
||||
sections.add(empty_section);
|
||||
sectcnt++;
|
||||
old3d.add(smap);
|
||||
}
|
||||
//System.out.println("nbt.keys()=" + nbt.d().toString());
|
||||
StdSection lastsectwithbiome = null;
|
||||
}
|
||||
else { // Else, older chunks
|
||||
old2d = new BiomeMap[256];
|
||||
for (int i = 0; i < bb.length; i++) {
|
||||
old2d[i] = BiomeMap.byBiomeID(bb[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Start section builder
|
||||
GenericChunkSection.Builder sbld = new GenericChunkSection.Builder();
|
||||
/* Get sections */
|
||||
|
||||
NBTTagList sect = nbt.e("sections") ? nbt.c("sections", 10) : nbt.c("Sections", 10);
|
||||
for (int i = 0; i < sect.size(); i++) {
|
||||
NBTTagCompound sec = sect.a(i);
|
||||
int secnum = sec.h("Y");
|
||||
// Beyond end - extend up
|
||||
while (secnum >= (sectcnt - sectoff)) {
|
||||
sections.addLast(empty_section); // Pad with empty
|
||||
sectcnt++;
|
||||
}
|
||||
// Negative - see if we need to extend sectionOffset
|
||||
while ((secnum + sectoff) < 0) {
|
||||
sections.addFirst(empty_section); // Pad with empty
|
||||
sectoff++;
|
||||
sectcnt++;
|
||||
}
|
||||
//System.out.println("section(" + secnum + ")=" + sec.toString());
|
||||
// Create normal section to initialize
|
||||
StdSection cursect = new StdSection();
|
||||
sections.set(secnum + sectoff, cursect);
|
||||
DynmapBlockState[] states = cursect.states;
|
||||
|
||||
DynmapBlockState[] palette = null;
|
||||
// If we've got palette and block states list, process non-empty section
|
||||
if (sec.b("Palette", 9) && sec.b("BlockStates", 12)) {
|
||||
@ -246,16 +132,18 @@ public class MapChunkCache118 extends AbstractMapChunkCache {
|
||||
if (bitsperblock > 8) { // Not palette
|
||||
for (int j = 0; j < 4096; j++) {
|
||||
int v = (dbp != null) ? dbp.getAt(j) : db.a(j);
|
||||
states[j] = DynmapBlockState.getStateByGlobalIndex(v);
|
||||
sbld.xyzBlockState(j & 0xF, (j & 0xF00) >> 8, (j & 0xF0) >> 4, DynmapBlockState.getStateByGlobalIndex(v));
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int j = 0; j < 4096; j++) {
|
||||
int v = (dbp != null) ? dbp.getAt(j) : db.a(j);
|
||||
states[j] = (v < palette.length) ? palette[v] : DynmapBlockState.AIR;
|
||||
DynmapBlockState bs = (v < palette.length) ? palette[v] : DynmapBlockState.AIR;
|
||||
sbld.xyzBlockState(j & 0xF, (j & 0xF00) >> 8, (j & 0xF0) >> 4, bs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (sec.e("block_states")) { // 1.18
|
||||
NBTTagCompound block_states = sec.p("block_states");
|
||||
// If we've block state data, process non-empty section
|
||||
@ -297,23 +185,23 @@ public class MapChunkCache118 extends AbstractMapChunkCache {
|
||||
if (bitsperblock > 8) { // Not palette
|
||||
for (int j = 0; j < 4096; j++) {
|
||||
int v = db != null ? db.a(j) : dbp.getAt(j);
|
||||
states[j] = DynmapBlockState.getStateByGlobalIndex(v);
|
||||
sbld.xyzBlockState(j & 0xF, (j & 0xF00) >> 8, (j & 0xF0) >> 4, DynmapBlockState.getStateByGlobalIndex(v));
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int j = 0; j < 4096; j++) {
|
||||
int v = db != null ? db.a(j) : dbp.getAt(j);
|
||||
states[j] = (v < palette.length) ? palette[v] : DynmapBlockState.AIR;
|
||||
DynmapBlockState bs = (v < palette.length) ? palette[v] : DynmapBlockState.AIR;
|
||||
sbld.xyzBlockState(j & 0xF, (j & 0xF00) >> 8, (j & 0xF0) >> 4, bs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sec.e("BlockLight")) {
|
||||
cursect.emitlight = dataCopy(sec.m("BlockLight"));
|
||||
sbld.emittedLight(sec.m("BlockLight"));
|
||||
}
|
||||
if (sec.e("SkyLight")) {
|
||||
cursect.skylight = dataCopy(sec.m("SkyLight"));
|
||||
sbld.skyLight(sec.m("SkyLight"));
|
||||
}
|
||||
// If section biome palette
|
||||
if (sec.e("biomes")) {
|
||||
@ -325,120 +213,80 @@ public class MapChunkCache118 extends AbstractMapChunkCache {
|
||||
bdata = new SimpleBitStorage(bdataPacked.length, 64, bdataPacked);
|
||||
for (int j = 0; j < 64; j++) {
|
||||
int b = bdata != null ? bdata.a(j) : 0;
|
||||
cursect.biomes[j] = b < bpalette.size() ? BiomeMap.byBiomeResourceLocation(bpalette.j(b)).getBiomeID() : -1;
|
||||
sbld.xyzBiome(j & 0x3, (j & 0x30) >> 4, (j & 0xC) >> 2, BiomeMap.byBiomeResourceLocation(bpalette.j(b)));
|
||||
}
|
||||
// Favor the Y=64 version
|
||||
if ((secnum == 4) || (lastsectwithbiome == null)) {
|
||||
lastsectwithbiome = cursect;
|
||||
}
|
||||
else { // Else, apply legacy biomes
|
||||
if (old3d != null) {
|
||||
BiomeMap m[] = old3d.get(secnum);
|
||||
if (m != null) {
|
||||
for (int j = 0; j < 64; j++) {
|
||||
sbld.xyzBiome(j & 0x3, (j & 0x30) >> 4, (j & 0xC) >> 2, m[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Get biome data */
|
||||
this.biome = new int[COLUMNS_PER_CHUNK];
|
||||
this.biomebase = new Object[COLUMNS_PER_CHUNK];
|
||||
Object[] bbl = BukkitVersionHelper.helper.getBiomeBaseList();
|
||||
if (nbt.e("Biomes")) {
|
||||
int[] bb = nbt.n("Biomes");
|
||||
if (bb != null) {
|
||||
// If v1.15+ format
|
||||
if (bb.length > COLUMNS_PER_CHUNK) {
|
||||
// For now, just pad the grid with the first 16
|
||||
for (int i = 0; i < COLUMNS_PER_CHUNK; i++) {
|
||||
int off = ((i >> 4) & 0xC) + ((i >> 2) & 0x3);
|
||||
int bv = bb[off + 64]; // Offset to y=64
|
||||
if (bv < 0) bv = 0;
|
||||
this.biome[i] = bv;
|
||||
this.biomebase[i] = bbl[bv];
|
||||
}
|
||||
}
|
||||
else { // Else, older chunks
|
||||
for (int i = 0; i < bb.length; i++) {
|
||||
int bv = bb[i];
|
||||
if (bv < 0) bv = 0;
|
||||
this.biome[i] = bv;
|
||||
this.biomebase[i] = bbl[bv];
|
||||
else if (old2d != null) {
|
||||
for (int j = 0; j < 256; j++) {
|
||||
sbld.xzBiome(j & 0xF, (j & 0xF0) >> 4, old2d[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Finish and add section
|
||||
bld.addSection(secnum, sbld.build());
|
||||
sbld.reset();
|
||||
}
|
||||
else { // Make up 2D version for now
|
||||
if (lastsectwithbiome != null) {
|
||||
// For now, just pad the grid with the first 16
|
||||
for (int i = 0; i < COLUMNS_PER_CHUNK; i++) {
|
||||
int off = ((i >> 4) & 0xC) + ((i >> 2) & 0x3);
|
||||
int bv = lastsectwithbiome.biomes[off]; // Offset to y=64
|
||||
if (bv < 0) bv = 0;
|
||||
this.biome[i] = bv;
|
||||
this.biomebase[i] = bbl[bv];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Finalize sections array
|
||||
this.section = sections.toArray(new Section[sections.size()]);
|
||||
this.sectionOffset = sectoff;
|
||||
return bld.build();
|
||||
}
|
||||
|
||||
public int getX()
|
||||
{
|
||||
return x;
|
||||
// Load generic chunk from existing and already loaded chunk
|
||||
protected GenericChunk getLoadedChunk(DynmapChunk chunk) {
|
||||
CraftWorld cw = (CraftWorld) w;
|
||||
NBTTagCompound nbt = null;
|
||||
if (cw.isChunkLoaded(chunk.x, chunk.z)) {
|
||||
Chunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z);
|
||||
if ((c != null) && c.o) { // c.loaded
|
||||
nbt = ChunkRegionLoader.a(cw.getHandle(), c);
|
||||
}
|
||||
if (nbt.e("Level")) {
|
||||
nbt = nbt.p("Level");
|
||||
}
|
||||
if (nbt != null) {
|
||||
String stat = nbt.l("Status");
|
||||
ChunkStatus cs = ChunkStatus.a(stat);
|
||||
if ((stat == null) || (!cs.b(ChunkStatus.l))) { // ChunkStatus.LIGHT
|
||||
nbt = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return parseChunkFromNBT(nbt);
|
||||
}
|
||||
// Load generic chunk from unloaded chunk
|
||||
protected GenericChunk loadChunk(DynmapChunk chunk) {
|
||||
CraftWorld cw = (CraftWorld) w;
|
||||
NBTTagCompound nbt = null;
|
||||
ChunkCoordIntPair cc = new ChunkCoordIntPair(chunk.x, chunk.z);
|
||||
try {
|
||||
nbt = cw.getHandle().k().a.f(cc); // playerChunkMap
|
||||
} catch (IOException iox) {
|
||||
}
|
||||
if (nbt != null) {
|
||||
// See if we have Level - unwrap this if so
|
||||
if (nbt.e("Level")) {
|
||||
nbt = nbt.p("Level");
|
||||
}
|
||||
if (nbt != null) {
|
||||
String stat = nbt.l("Status");
|
||||
if ((stat == null) || (stat.equals("full") == false)) {
|
||||
nbt = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return parseChunkFromNBT(nbt);
|
||||
}
|
||||
|
||||
public int getZ()
|
||||
{
|
||||
return z;
|
||||
}
|
||||
|
||||
public DynmapBlockState getBlockType(int x, int y, int z)
|
||||
{
|
||||
int idx = (y >> 4) + sectionOffset;
|
||||
if ((idx < 0) || (idx >= section.length)) return DynmapBlockState.AIR;
|
||||
return section[idx].getBlockType(x, y, z);
|
||||
}
|
||||
|
||||
public int getBlockSkyLight(int x, int y, int z)
|
||||
{
|
||||
int idx = (y >> 4) + sectionOffset;
|
||||
if ((idx < 0) || (idx >= section.length)) return 15;
|
||||
return section[idx].getBlockSkyLight(x, y, z);
|
||||
}
|
||||
|
||||
public int getBlockEmittedLight(int x, int y, int z)
|
||||
{
|
||||
int idx = (y >> 4) + sectionOffset;
|
||||
if ((idx < 0) || (idx >= section.length)) return 0;
|
||||
return section[idx].getBlockEmittedLight(x, y, z);
|
||||
}
|
||||
|
||||
public int getHighestBlockYAt(int x, int z)
|
||||
{
|
||||
return hmap[z << 4 | x];
|
||||
}
|
||||
|
||||
public final long getCaptureFullTime()
|
||||
{
|
||||
return captureFulltime;
|
||||
}
|
||||
|
||||
public boolean isSectionEmpty(int sy)
|
||||
{
|
||||
int idx = sy + sectionOffset;
|
||||
if ((idx < 0) || (idx >= section.length)) return true;
|
||||
return section[idx].isEmpty();
|
||||
}
|
||||
|
||||
public long getInhabitedTicks() {
|
||||
return inhabitedTicks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome(int x, int z) {
|
||||
return AbstractMapChunkCache.getBiomeByID(biome[z << 4 | x]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getBiomeBaseFromSnapshot() {
|
||||
return this.biomebase;
|
||||
}
|
||||
public void setChunks(BukkitWorld dw, List<DynmapChunk> chunks) {
|
||||
this.w = dw.getWorld();
|
||||
super.setChunks(dw, chunks);
|
||||
}
|
||||
|
||||
private NBTTagCompound fetchLoadedChunkNBT(World w, int x, int z) {
|
||||
@ -464,155 +312,4 @@ public class MapChunkCache118 extends AbstractMapChunkCache {
|
||||
}
|
||||
return nbt;
|
||||
}
|
||||
|
||||
private NBTTagCompound loadChunkNBT(World w, int x, int z) {
|
||||
//.info("loadChunkNBT(" + w.getName() + "," + x + "," + z);
|
||||
CraftWorld cw = (CraftWorld) w;
|
||||
NBTTagCompound nbt = null;
|
||||
ChunkCoordIntPair cc = new ChunkCoordIntPair(x, z);
|
||||
try {
|
||||
nbt = cw.getHandle().k().a.f(cc); // playerChunkMap
|
||||
} catch (IOException iox) {
|
||||
}
|
||||
if (nbt != null) {
|
||||
// See if we have Level - unwrap this if so
|
||||
if (nbt.e("Level")) {
|
||||
nbt = nbt.p("Level");
|
||||
}
|
||||
if (nbt != null) {
|
||||
String stat = nbt.l("Status");
|
||||
if ((stat == null) || (stat.equals("full") == false)) {
|
||||
nbt = null;
|
||||
if ((stat == null) || stat.equals("") && DynmapCore.migrateChunks()) {
|
||||
Chunk c = cw.getHandle().getChunkIfLoaded(x, z);
|
||||
if (c != null) {
|
||||
nbt = fetchLoadedChunkNBT(w, x, z);
|
||||
cw.getHandle().a(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Snapshot wrapChunkSnapshot(ChunkSnapshot css) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
// Load chunk snapshots
|
||||
@Override
|
||||
public int loadChunks(int max_to_load) {
|
||||
if(dw.isLoaded() == false)
|
||||
return 0;
|
||||
int cnt = 0;
|
||||
if(iterator == null)
|
||||
iterator = chunks.listIterator();
|
||||
|
||||
DynmapCore.setIgnoreChunkLoads(true);
|
||||
// Load the required chunks.
|
||||
while((cnt < max_to_load) && iterator.hasNext()) {
|
||||
long startTime = System.nanoTime();
|
||||
DynmapChunk chunk = iterator.next();
|
||||
boolean vis = true;
|
||||
if(visible_limits != null) {
|
||||
vis = false;
|
||||
for(VisibilityLimit limit : visible_limits) {
|
||||
if (limit.doIntersectChunk(chunk.x, chunk.z)) {
|
||||
vis = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(vis && (hidden_limits != null)) {
|
||||
for(VisibilityLimit limit : hidden_limits) {
|
||||
if (limit.doIntersectChunk(chunk.x, chunk.z)) {
|
||||
vis = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Check if cached chunk snapshot found */
|
||||
Snapshot ss = null;
|
||||
long inhabited_ticks = 0;
|
||||
DynIntHashMap tileData = null;
|
||||
int idx = (chunk.x-x_min) + (chunk.z - z_min)*x_dim;
|
||||
SnapshotRec ssr = SnapshotCache.sscache.getSnapshot(dw.getName(), chunk.x, chunk.z, blockdata, biome, biomeraw, highesty);
|
||||
if(ssr != null) {
|
||||
inhabited_ticks = ssr.inhabitedTicks;
|
||||
if(!vis) {
|
||||
if(hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN)
|
||||
ss = STONE;
|
||||
else if(hidestyle == HiddenChunkStyle.FILL_OCEAN)
|
||||
ss = OCEAN;
|
||||
else
|
||||
ss = EMPTY;
|
||||
}
|
||||
else {
|
||||
ss = ssr.ss;
|
||||
}
|
||||
snaparray[idx] = ss;
|
||||
snaptile[idx] = ssr.tileData;
|
||||
inhabitedTicks[idx] = inhabited_ticks;
|
||||
|
||||
endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT);
|
||||
continue;
|
||||
}
|
||||
// Fetch NTB for chunk if loaded
|
||||
NBTTagCompound nbt = fetchLoadedChunkNBT(w, chunk.x, chunk.z);
|
||||
boolean did_load = false;
|
||||
if (nbt == null) {
|
||||
// Load NTB for chunk, if it exists
|
||||
nbt = loadChunkNBT(w, chunk.x, chunk.z);
|
||||
did_load = true;
|
||||
}
|
||||
if (nbt != null) {
|
||||
NBTSnapshot nss = new NBTSnapshot(nbt, w.getMaxHeight());
|
||||
ss = nss;
|
||||
inhabited_ticks = nss.getInhabitedTicks();
|
||||
if(!vis) {
|
||||
if(hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN)
|
||||
ss = STONE;
|
||||
else if(hidestyle == HiddenChunkStyle.FILL_OCEAN)
|
||||
ss = OCEAN;
|
||||
else
|
||||
ss = EMPTY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ss = EMPTY;
|
||||
}
|
||||
ssr = new SnapshotRec();
|
||||
ssr.ss = ss;
|
||||
ssr.inhabitedTicks = inhabited_ticks;
|
||||
ssr.tileData = tileData;
|
||||
SnapshotCache.sscache.putSnapshot(dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty);
|
||||
snaparray[idx] = ss;
|
||||
snaptile[idx] = ssr.tileData;
|
||||
inhabitedTicks[idx] = inhabited_ticks;
|
||||
if (nbt == null)
|
||||
endChunkLoad(startTime, ChunkStats.UNGENERATED_CHUNKS);
|
||||
else if (did_load)
|
||||
endChunkLoad(startTime, ChunkStats.UNLOADED_CHUNKS);
|
||||
else
|
||||
endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS);
|
||||
cnt++;
|
||||
}
|
||||
DynmapCore.setIgnoreChunkLoads(false);
|
||||
|
||||
if(iterator.hasNext() == false) { /* If we're done */
|
||||
isempty = true;
|
||||
/* Fill missing chunks with empty dummy chunk */
|
||||
for(int i = 0; i < snaparray.length; i++) {
|
||||
if(snaparray[i] == null)
|
||||
snaparray[i] = EMPTY;
|
||||
else if(snaparray[i] != EMPTY)
|
||||
isempty = false;
|
||||
}
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.dynmap.DynmapChunk;
|
||||
import org.dynmap.Log;
|
||||
import org.dynmap.common.chunk.GenericChunkCache;
|
||||
import org.dynmap.renderer.DynmapBlockState;
|
||||
import org.dynmap.utils.MapChunkCache;
|
||||
import org.dynmap.utils.Polygon;
|
||||
@ -20,6 +21,8 @@ import org.dynmap.utils.Polygon;
|
||||
public abstract class BukkitVersionHelper {
|
||||
public static BukkitVersionHelper helper = null;
|
||||
|
||||
public static GenericChunkCache gencache;
|
||||
|
||||
public static DynmapBlockState[] stateByID;
|
||||
|
||||
protected boolean isBlockIdNeeded() {
|
||||
@ -218,4 +221,7 @@ public abstract class BukkitVersionHelper {
|
||||
if (subtitle != null) p.sendMessage(subtitle);
|
||||
}
|
||||
}
|
||||
public boolean useGenericCache() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -385,7 +385,7 @@ public class DynmapPlugin {
|
||||
if (rl != null) { // If resource location, lookup by this
|
||||
bmap = BiomeMap.byBiomeResourceLocation(rl);
|
||||
}
|
||||
if (bmap == BiomeMap.NULL) {
|
||||
else {
|
||||
bmap = BiomeMap.byBiomeID(i);
|
||||
}
|
||||
if (bmap.isDefault()) {
|
||||
|
@ -1400,7 +1400,7 @@ public class DynmapPlugin
|
||||
if (rl != null) { // If resource location, lookup by this
|
||||
bmap = BiomeMap.byBiomeResourceLocation(rl);
|
||||
}
|
||||
if (bmap == BiomeMap.NULL) {
|
||||
else {
|
||||
bmap = BiomeMap.byBiomeID(i);
|
||||
}
|
||||
if (bmap.isDefault()) { // If matched default, replace with new one
|
||||
|
@ -101,6 +101,7 @@ import org.dynmap.common.BiomeMap;
|
||||
import org.dynmap.common.DynmapCommandSender;
|
||||
import org.dynmap.common.DynmapPlayer;
|
||||
import org.dynmap.common.DynmapServerInterface;
|
||||
import org.dynmap.common.chunk.GenericChunkCache;
|
||||
import org.dynmap.common.DynmapListenerManager.EventType;
|
||||
import org.dynmap.hdmap.HDMap;
|
||||
import org.dynmap.markers.MarkerAPI;
|
||||
@ -435,12 +436,17 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
}
|
||||
@Override
|
||||
public double getCacheHitRate() {
|
||||
return SnapshotCache.sscache.getHitRate();
|
||||
return helper.useGenericCache() ? BukkitVersionHelper.gencache.getHitRate() : SnapshotCache.sscache.getHitRate();
|
||||
}
|
||||
@Override
|
||||
public void resetCacheStats() {
|
||||
if (helper.useGenericCache()) {
|
||||
BukkitVersionHelper.gencache.resetStats();
|
||||
}
|
||||
else {
|
||||
SnapshotCache.sscache.resetStats();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public DynmapWorld getWorldByName(String wname) {
|
||||
return DynmapPlugin.this.getWorldByName(wname);
|
||||
@ -828,7 +834,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
if (rl != null) { // If resource location, lookup by this
|
||||
bmap = BiomeMap.byBiomeResourceLocation(rl);
|
||||
}
|
||||
if (bmap == BiomeMap.NULL) {
|
||||
else {
|
||||
bmap = BiomeMap.byBiomeID(i);
|
||||
}
|
||||
if (bmap.isDefault()) {
|
||||
@ -1009,7 +1015,12 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
return;
|
||||
}
|
||||
playerList = core.playerList;
|
||||
if (helper.useGenericCache()) {
|
||||
BukkitVersionHelper.gencache = new GenericChunkCache(core.getSnapShotCacheSize(), core.useSoftRefInSnapShotCache());
|
||||
}
|
||||
else {
|
||||
SnapshotCache.sscache = new SnapshotCache(core.getSnapShotCacheSize(), core.useSoftRefInSnapShotCache());
|
||||
}
|
||||
|
||||
/* Get map manager from core */
|
||||
mapManager = core.getMapManager();
|
||||
@ -1047,6 +1058,10 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
SnapshotCache.sscache.cleanup();
|
||||
SnapshotCache.sscache = null;
|
||||
}
|
||||
if (BukkitVersionHelper.gencache != null) {
|
||||
BukkitVersionHelper.gencache.cleanup();
|
||||
BukkitVersionHelper.gencache = null;
|
||||
}
|
||||
Log.info("Disabled");
|
||||
}
|
||||
|
||||
@ -1101,13 +1116,13 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
@Override
|
||||
public final int triggerRenderOfVolume(String wid, int minx, int miny, int minz,
|
||||
int maxx, int maxy, int maxz) {
|
||||
SnapshotCache.sscache.invalidateSnapshot(wid, minx, miny, minz, maxx, maxy, maxz);
|
||||
invalidateSnapshot(wid, minx, miny, minz, maxx, maxy, maxz);
|
||||
return core.triggerRenderOfVolume(wid, minx, miny, minz, maxx, maxy, maxz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int triggerRenderOfBlock(String wid, int x, int y, int z) {
|
||||
SnapshotCache.sscache.invalidateSnapshot(wid, x, y, z);
|
||||
invalidateSnapshot(wid, x, y, z);
|
||||
return core.triggerRenderOfBlock(wid, x, y, z);
|
||||
}
|
||||
|
||||
@ -1233,7 +1248,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
if(btt.typeid == 9) btt.typeid = 8;
|
||||
if((bt != btt.typeid) || (btt.data != w.getBlockAt(loc).getData())) {
|
||||
String wn = getWorld(w).getName();
|
||||
SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), btt.trigger);
|
||||
}
|
||||
}
|
||||
@ -1279,6 +1294,23 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
private boolean onblockgrow;
|
||||
private boolean onblockredstone;
|
||||
|
||||
private void invalidateSnapshot(String wn, int x, int y, int z) {
|
||||
if (helper.useGenericCache()) {
|
||||
BukkitVersionHelper.gencache.invalidateSnapshot(wn, x, y, z);
|
||||
}
|
||||
else {
|
||||
SnapshotCache.sscache.invalidateSnapshot(wn, x, y, z);
|
||||
}
|
||||
}
|
||||
private void invalidateSnapshot(String wname, int minx, int miny, int minz, int maxx, int maxy, int maxz) {
|
||||
if (helper.useGenericCache()) {
|
||||
BukkitVersionHelper.gencache.invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz);
|
||||
}
|
||||
else {
|
||||
SnapshotCache.sscache.invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerEvents() {
|
||||
|
||||
// To trigger rendering.
|
||||
@ -1300,7 +1332,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
public void onBlockPlace(BlockPlaceEvent event) {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockplace");
|
||||
}
|
||||
};
|
||||
@ -1315,7 +1347,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
if(b == null) return; /* Stupid mod workaround */
|
||||
Location loc = b.getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockbreak");
|
||||
}
|
||||
};
|
||||
@ -1328,7 +1360,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
public void onLeavesDecay(LeavesDecayEvent event) {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
if(onleaves) {
|
||||
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "leavesdecay");
|
||||
}
|
||||
@ -1343,7 +1375,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
public void onBlockBurn(BlockBurnEvent event) {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
if(onburn) {
|
||||
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockburn");
|
||||
}
|
||||
@ -1409,14 +1441,14 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
}
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
|
||||
SnapshotCache.sscache.invalidateSnapshot(wn, x, y, z);
|
||||
invalidateSnapshot(wn, x, y, z);
|
||||
if(onpiston)
|
||||
mapManager.touch(wn, x, y, z, "pistonretract");
|
||||
for(int i = 0; i < 2; i++) {
|
||||
x += dir.getModX();
|
||||
y += dir.getModY();
|
||||
z += dir.getModZ();
|
||||
SnapshotCache.sscache.invalidateSnapshot(wn, x, y, z);
|
||||
invalidateSnapshot(wn, x, y, z);
|
||||
mapManager.touch(wn, x, y, z, "pistonretract");
|
||||
}
|
||||
}
|
||||
@ -1433,14 +1465,14 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
}
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
|
||||
SnapshotCache.sscache.invalidateSnapshot(wn, x, y, z);
|
||||
invalidateSnapshot(wn, x, y, z);
|
||||
if(onpiston)
|
||||
mapManager.touch(wn, x, y, z, "pistonretract");
|
||||
for(int i = 0; i < 1+event.getLength(); i++) {
|
||||
x += dir.getModX();
|
||||
y += dir.getModY();
|
||||
z += dir.getModZ();
|
||||
SnapshotCache.sscache.invalidateSnapshot(wn, x, y, z);
|
||||
invalidateSnapshot(wn, x, y, z);
|
||||
mapManager.touch(wn, x, y, z, "pistonretract");
|
||||
}
|
||||
}
|
||||
@ -1454,7 +1486,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
public void onBlockSpread(BlockSpreadEvent event) {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockspread");
|
||||
}
|
||||
};
|
||||
@ -1467,7 +1499,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
public void onBlockForm(BlockFormEvent event) {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockform");
|
||||
}
|
||||
};
|
||||
@ -1480,7 +1512,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
public void onBlockFade(BlockFadeEvent event) {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfade");
|
||||
}
|
||||
};
|
||||
@ -1495,7 +1527,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
public void onBlockGrow(BlockGrowEvent event) {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockgrow");
|
||||
}
|
||||
};
|
||||
@ -1508,7 +1540,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
public void onBlockRedstone(BlockRedstoneEvent event) {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockredstone");
|
||||
}
|
||||
};
|
||||
@ -1565,7 +1597,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
if(z < minz) minz = z;
|
||||
if(z > maxz) maxz = z;
|
||||
}
|
||||
SnapshotCache.sscache.invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz);
|
||||
invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz);
|
||||
if(onexplosion) {
|
||||
mapManager.touchVolume(wname, minx, miny, minz, maxx, maxy, maxz, "entityexplode");
|
||||
}
|
||||
@ -1612,7 +1644,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
if(z < minz) minz = z;
|
||||
if(z > maxz) maxz = z;
|
||||
}
|
||||
SnapshotCache.sscache.invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz);
|
||||
invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz);
|
||||
if(onstructuregrow) {
|
||||
mapManager.touchVolume(wname, minx, miny, minz, maxx, maxy, maxz, "structuregrow");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user