From b4920e02466c6950bd558de8dc2da34791562335 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Sun, 5 Aug 2018 14:38:13 -0500 Subject: [PATCH 01/50] Start refactor to support pre-1.13 and 1.13+ --- .../dynmap/bukkit/BukkitVersionHelper.java | 26 +++++ .../dynmap/bukkit/BukkitVersionHelperCB.java | 2 +- .../java/org/dynmap/bukkit/DynmapPlugin.java | 3 + .../org/dynmap/bukkit/NewMapChunkCache.java | 100 ++++++++++-------- 4 files changed, 84 insertions(+), 47 deletions(-) diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java b/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java index be6b5f32..0f2f4e84 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java +++ b/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java @@ -8,6 +8,8 @@ import org.bukkit.ChunkSnapshot; import org.bukkit.World; import org.bukkit.entity.Player; import org.dynmap.Log; +import org.dynmap.renderer.DynmapBlockState; +import org.dynmap.utils.DynIntHashMap; import org.dynmap.utils.Polygon; /** @@ -44,6 +46,9 @@ public abstract class BukkitVersionHelper { } return helper; } + + public static DynIntHashMap stateByID = new DynIntHashMap(); + protected BukkitVersionHelper() { } @@ -148,4 +153,25 @@ public abstract class BukkitVersionHelper { * @param player */ public String getSkinURL(Player player) { return null; } + /** + * Initialize block states (org.dynmap.blockstate.DynmapBlockState) + */ + public void initializeBlockStates() { + String[] blkname = getBlockShortNames(); + // Keep it simple for now - just assume 16 meta states for each + + for (int i = 0; i < blkname.length; i++) { + // Only do defined names, and not "air" + if ((blkname[i] != null) && (!blkname[i].equals("air"))) { + Log.info("block " + blkname[i]); + DynmapBlockState basebs = new DynmapBlockState(null, 0, "minecraft:" + blkname, "meta=0"); + stateByID.put((i << 4), basebs); + for (int m = 1; m < 16; m++) { + DynmapBlockState bs = new DynmapBlockState(basebs, m, "minecraft:" + blkname, "meta=" + m); + stateByID.put((i << 4) + m, bs); + } + } + } + stateByID.put(0, DynmapBlockState.AIR); // Include air block; + } } diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperCB.java b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperCB.java index 2e21a7e1..1f41c2c7 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperCB.java +++ b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperCB.java @@ -13,6 +13,7 @@ import org.bukkit.Server; import org.bukkit.World; import org.dynmap.Log; import org.dynmap.hdmap.HDBlockModels; +import org.dynmap.renderer.DynmapBlockState; import org.dynmap.utils.Polygon; /** @@ -346,5 +347,4 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric { */ @Override public boolean isUnloadChunkBroken() { return isBadUnload; } - } diff --git a/src/main/java/org/dynmap/bukkit/DynmapPlugin.java b/src/main/java/org/dynmap/bukkit/DynmapPlugin.java index af54d3a2..6ef6bcd3 100644 --- a/src/main/java/org/dynmap/bukkit/DynmapPlugin.java +++ b/src/main/java/org/dynmap/bukkit/DynmapPlugin.java @@ -791,6 +791,9 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { if(idx > 0) mcver = mcver.substring(0, idx); } + // Initialize block states + helper.initializeBlockStates(); + /* Load extra biomes, if any */ loadExtraBiomes(mcver); diff --git a/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java b/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java index 9494635a..f1a507cd 100644 --- a/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java +++ b/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java @@ -16,6 +16,7 @@ import org.dynmap.Log; import org.dynmap.bukkit.SnapshotCache.SnapshotRec; import org.dynmap.common.BiomeMap; import org.dynmap.hdmap.HDBlockModels; +import org.dynmap.renderer.DynmapBlockState; import org.dynmap.renderer.RenderPatchFactory; import org.dynmap.utils.DynIntHashMap; import org.dynmap.utils.MapChunkCache; @@ -61,6 +62,10 @@ public class NewMapChunkCache extends MapChunkCache { return (cy << 8) | (cz << 4) | cx; } + private static DynmapBlockState getTypeAt(ChunkSnapshot ss, int x, int y, int z) { + return (DynmapBlockState) BukkitVersionHelper.stateByID.get((ss.getBlockTypeId(x, y, z) << 4) | ss.getBlockData(x, y, z)); + } + /** * Iterator for traversing map chunk cache (base is for non-snapshot) */ @@ -69,8 +74,7 @@ public class NewMapChunkCache extends MapChunkCache { private int x, y, z, chunkindex, bx, bz, off; private ChunkSnapshot snap; private BlockStep laststep; - private int typeid = -1; - private int blkdata = -1; + private DynmapBlockState type = null; private final int worldheight; private final int x_base; private final int z_base; @@ -101,23 +105,17 @@ public class NewMapChunkCache extends MapChunkCache { } laststep = BlockStep.Y_MINUS; if((y >= 0) && (y < worldheight)) - typeid = blkdata = -1; + type = null; else - typeid = blkdata = 0; + type = DynmapBlockState.AIR; } + @Override - public final int getBlockTypeID() { - if(typeid < 0) { - typeid = snap.getBlockTypeId(bx, y, bz); + public final DynmapBlockState getBlockType() { + if (type == null) { + type = getTypeAt(snap, bx, y, bz); } - return typeid; - } - @Override - public final int getBlockData() { - if(blkdata < 0) { - blkdata = snap.getBlockData(bx, y, bz); - } - return blkdata; + return type; } @Override public int getBlockSkyLight() { @@ -373,8 +371,7 @@ public class NewMapChunkCache extends MapChunkCache { */ @Override public final void stepPosition(BlockStep step) { - typeid = -1; - blkdata = -1; + type = null; switch(step.ordinal()) { case 0: x++; @@ -395,7 +392,7 @@ public class NewMapChunkCache extends MapChunkCache { case 1: y++; if(y >= worldheight) { - typeid = blkdata = 0; + type = DynmapBlockState.AIR; } break; case 2: @@ -433,7 +430,7 @@ public class NewMapChunkCache extends MapChunkCache { case 4: y--; if(y < 0) { - typeid = blkdata = 0; + type = DynmapBlockState.AIR; } break; case 5: @@ -479,10 +476,10 @@ public class NewMapChunkCache extends MapChunkCache { laststep = BlockStep.Y_MINUS; this.y = y; if((y < 0) || (y >= worldheight)) { - typeid = blkdata = 0; + type = DynmapBlockState.AIR; } else { - typeid = blkdata = -1; + type = null; } } @Override @@ -498,24 +495,24 @@ public class NewMapChunkCache extends MapChunkCache { return z; } @Override - public final int getBlockTypeIDAt(BlockStep s) { + public final DynmapBlockState getBlockTypeAt(BlockStep s) { if(s == BlockStep.Y_MINUS) { if(y > 0) - return snap.getBlockTypeId(bx, y-1, bz); + return getTypeAt(snap, bx, y-1, bz); } else if(s == BlockStep.Y_PLUS) { if(y < (worldheight-1)) - return snap.getBlockTypeId(bx, y+1, bz); + return getTypeAt(snap, bx, y+1, bz); } else { BlockStep ls = laststep; stepPosition(s); - int tid = snap.getBlockTypeId(bx, y, bz); + DynmapBlockState tid = getTypeAt(snap, bx, y, bz); unstepPosition(); laststep = ls; return tid; } - return 0; + return DynmapBlockState.AIR; } @Override public BlockStep getLastStep() { @@ -557,27 +554,15 @@ public class NewMapChunkCache extends MapChunkCache { return null; } @Override - public int getBlockTypeIDAt(int xoff, int yoff, int zoff) { + public DynmapBlockState getBlockTypeAt(int xoff, int yoff, int zoff) { int xx = this.x + xoff; int yy = this.y + yoff; int zz = this.z + zoff; int idx = ((xx >> 4) - x_min) + (((zz >> 4) - z_min) * x_dim); try { - return snaparray[idx].getBlockTypeId(xx & 0xF, yy, zz & 0xF); + return getTypeAt(snaparray[idx], xx & 0xF, yy, zz & 0xF); } catch (Exception x) { - return 0; - } - } - @Override - public int getBlockDataAt(int xoff, int yoff, int zoff) { - int xx = this.x + xoff; - int yy = this.y + yoff; - int zz = this.z + zoff; - int idx = ((xx >> 4) - x_min) + (((zz >> 4) - z_min) * x_dim); - try { - return snaparray[idx].getBlockData(xx & 0xF, yy, zz & 0xF); - } catch (Exception x) { - return 0; + return DynmapBlockState.AIR; } } @Override @@ -600,6 +585,7 @@ public class NewMapChunkCache extends MapChunkCache { OurEndMapIterator(int x0, int y0, int z0) { super(x0, y0, z0); } + @Override public final int getBlockSkyLight() { return 15; } @@ -609,35 +595,47 @@ public class NewMapChunkCache extends MapChunkCache { */ private static class EmptyChunk implements ChunkSnapshot { /* Need these for interface, but not used */ + @Override public int getX() { return 0; } + @Override public int getZ() { return 0; } + @Override public String getWorldName() { return ""; } + @Override public long getCaptureFullTime() { return 0; } - + @Override public final int getBlockTypeId(int x, int y, int z) { return 0; } + @Override public final int getBlockData(int x, int y, int z) { return 0; } + @Override public final int getBlockSkyLight(int x, int y, int z) { return 15; } + @Override public final int getBlockEmittedLight(int x, int y, int z) { return 0; } + @Override public final int getHighestBlockYAt(int x, int z) { return 0; } + @Override public Biome getBiome(int x, int z) { return null; } + @Override public double getRawBiomeTemperature(int x, int z) { return 0.0; } + @Override public double getRawBiomeRainfall(int x, int z) { return 0.0; } + @Override public boolean isSectionEmpty(int sy) { return true; } @@ -650,32 +648,44 @@ public class NewMapChunkCache extends MapChunkCache { private int fillid; PlainChunk(int fillid) { this.fillid = fillid; } /* Need these for interface, but not used */ + @Override public int getX() { return 0; } + @Override public int getZ() { return 0; } + @Override public String getWorldName() { return ""; } + @Override public Biome getBiome(int x, int z) { return null; } + @Override public double getRawBiomeTemperature(int x, int z) { return 0.0; } + @Override public double getRawBiomeRainfall(int x, int z) { return 0.0; } + @Override public long getCaptureFullTime() { return 0; } - + @Override public final int getBlockTypeId(int x, int y, int z) { if(y < 64) return fillid; return 0; } + @Override public final int getBlockData(int x, int y, int z) { return 0; } + @Override public final int getBlockSkyLight(int x, int y, int z) { if(y < 64) return 0; return 15; } + @Override public final int getBlockEmittedLight(int x, int y, int z) { return 0; } + @Override public final int getHighestBlockYAt(int x, int z) { return 64; } + @Override public boolean isSectionEmpty(int sy) { return (sy < 4); } @@ -833,9 +843,7 @@ public class NewMapChunkCache extends MapChunkCache { int te_z = helper.getTileEntityZ(t); int cx = te_x & 0xF; int cz = te_z & 0xF; - int blkid = ss.getBlockTypeId(cx, te_y, cz); - int blkdat = ss.getBlockData(cx, te_y, cz); - String[] te_fields = HDBlockModels.getTileEntityFieldsNeeded(blkid, blkdat); + String[] te_fields = HDBlockModels.getTileEntityFieldsNeeded(getTypeAt(ss, cx, te_y, cz)); if(te_fields != null) { Object nbtcompound = helper.readTileEntityNBT(t); From 58d5e59616c4314f6ad6b8fe8cb9a8b5f98af773 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Sun, 5 Aug 2018 21:27:18 -0500 Subject: [PATCH 02/50] Get 1.12.2 blockname based textures working --- .../dynmap/bukkit/BukkitVersionHelper.java | 32 ++++++++++++------- .../dynmap/bukkit/BukkitVersionHelperCB.java | 13 ++++++-- .../bukkit/BukkitVersionHelperGlowstone.java | 2 +- .../java/org/dynmap/bukkit/DynmapPlugin.java | 7 ++-- .../org/dynmap/bukkit/NewMapChunkCache.java | 2 +- 5 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java b/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java index 0f2f4e84..6c9d13db 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java +++ b/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java @@ -1,5 +1,6 @@ package org.dynmap.bukkit; +import java.util.Arrays; import java.util.Map; import org.bukkit.Bukkit; @@ -47,7 +48,7 @@ public abstract class BukkitVersionHelper { return helper; } - public static DynIntHashMap stateByID = new DynIntHashMap(); + public static DynmapBlockState[] stateByID = new DynmapBlockState[65536]; protected BukkitVersionHelper() { @@ -121,9 +122,9 @@ public abstract class BukkitVersionHelper { */ public abstract void unloadChunkNoSave(World w, Chunk c, int cx, int cz); /** - * Get block short name list + * Get block name list */ - public abstract String[] getBlockShortNames(); + public abstract String[] getBlockNames(); /** * Get biome name list */ @@ -157,21 +158,28 @@ public abstract class BukkitVersionHelper { * Initialize block states (org.dynmap.blockstate.DynmapBlockState) */ public void initializeBlockStates() { - String[] blkname = getBlockShortNames(); + String[] blkname = getBlockNames(); // Keep it simple for now - just assume 16 meta states for each - + Arrays.fill(stateByID, DynmapBlockState.AIR); for (int i = 0; i < blkname.length; i++) { + if (blkname[i] == null) continue; + String bn = blkname[i]; + if (bn.indexOf(':') < 0) { + bn = "minecraft:" + bn; + } // Only do defined names, and not "air" - if ((blkname[i] != null) && (!blkname[i].equals("air"))) { - Log.info("block " + blkname[i]); - DynmapBlockState basebs = new DynmapBlockState(null, 0, "minecraft:" + blkname, "meta=0"); - stateByID.put((i << 4), basebs); + if (!bn.equals(DynmapBlockState.AIR_BLOCK)) { + DynmapBlockState basebs = new DynmapBlockState(null, 0, bn, "meta=0"); + stateByID[i << 4] = basebs; for (int m = 1; m < 16; m++) { - DynmapBlockState bs = new DynmapBlockState(basebs, m, "minecraft:" + blkname, "meta=" + m); - stateByID.put((i << 4) + m, bs); + DynmapBlockState bs = new DynmapBlockState(basebs, m, bn, "meta=" + m); + stateByID[(i << 4) + m] = bs; } } } - stateByID.put(0, DynmapBlockState.AIR); // Include air block; + for (int gidx = 0; gidx < DynmapBlockState.getGlobalIndexMax(); gidx++) { + DynmapBlockState bs = DynmapBlockState.getStateByGlobalIndex(gidx); + Log.info(gidx + ":" + bs.toString() + ", gidx=" + bs.globalStateIndex + ", sidx=" + bs.stateIndex); + } } } diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperCB.java b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperCB.java index 1f41c2c7..c486ad5f 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperCB.java +++ b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperCB.java @@ -186,18 +186,25 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric { public void unloadChunkNoSave(World w, Chunk c, int cx, int cz) { w.unloadChunk(cx, cz, false, false); } + private String stripBlockString(String bname) { + int idx = bname.indexOf('{'); + if (idx >= 0) bname = bname.substring(idx+1); + idx = bname.indexOf('}'); + if (idx >= 0) bname = bname.substring(0, idx); + return bname; + } /** * Get block short name list */ @Override - public String[] getBlockShortNames() { + public String[] getBlockNames() { try { String[] names = new String[4096]; if (blockbyid != null) { Object[] byid = (Object[])blockbyid.get(nmsblock); for (int i = 0; i < names.length; i++) { if (byid[i] != null) { - names[i] = (String)blockname.get(byid[i]); + names[i] = stripBlockString(byid[i].toString()); } } } @@ -205,7 +212,7 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric { for (int i = 0; i < names.length; i++) { Object blk = blockbyidfunc.invoke(nmsblock, i); if (blk != null) { - names[i] = (String)blockname.get(blk); + names[i] = stripBlockString(blk.toString()); } } } diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGlowstone.java b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGlowstone.java index 8b15753d..a546bad1 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGlowstone.java +++ b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGlowstone.java @@ -140,7 +140,7 @@ public class BukkitVersionHelperGlowstone extends BukkitVersionHelper { } @Override - public String[] getBlockShortNames() { + public String[] getBlockNames() { // TODO Auto-generated method stub return null; } diff --git a/src/main/java/org/dynmap/bukkit/DynmapPlugin.java b/src/main/java/org/dynmap/bukkit/DynmapPlugin.java index 6ef6bcd3..c542fa31 100644 --- a/src/main/java/org/dynmap/bukkit/DynmapPlugin.java +++ b/src/main/java/org/dynmap/bukkit/DynmapPlugin.java @@ -545,11 +545,14 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { @Override public Map getBlockIDMap() { - String[] bsn = helper.getBlockShortNames(); + String[] bsn = helper.getBlockNames(); HashMap map = new HashMap(); for (int i = 0; i < bsn.length; i++) { if (bsn[i] != null) { - map.put(i, "minecraft:" + bsn[i]); + if (bsn[i].indexOf(':') < 0) + map.put(i, "minecraft:" + bsn[i]); + else + map.put(i, bsn[i]); } } return map; diff --git a/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java b/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java index f1a507cd..48970b4c 100644 --- a/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java +++ b/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java @@ -63,7 +63,7 @@ public class NewMapChunkCache extends MapChunkCache { } private static DynmapBlockState getTypeAt(ChunkSnapshot ss, int x, int y, int z) { - return (DynmapBlockState) BukkitVersionHelper.stateByID.get((ss.getBlockTypeId(x, y, z) << 4) | ss.getBlockData(x, y, z)); + return BukkitVersionHelper.stateByID[(ss.getBlockTypeId(x, y, z) << 4) | ss.getBlockData(x, y, z)]; } /** From 654cba2de43368f51ca72edfd72d7813257d8af7 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Wed, 8 Aug 2018 01:39:51 -0500 Subject: [PATCH 03/50] Get 1.13 support building and running a little.... --- core/.gitignore | 2 + core/pom.xml | 177 +++ {src => core/src}/main/assembly/package.xml | 0 .../main/java/org/dynmap/bukkit/Armor.java | 0 .../java/org/dynmap/bukkit/DynmapPlugin.java | 54 +- .../main/java/org/dynmap/bukkit/Helper.java | 44 + .../bukkit/permissions/BukkitPermissions.java | 0 .../permissions/GroupManagerPermissions.java | 0 .../permissions/NijikokunPermissions.java | 0 .../bukkit/permissions/OpPermissions.java | 0 .../bukkit/permissions/PEXPermissions.java | 0 .../permissions/PermBukkitPermissions.java | 0 .../permissions/PermissionProvider.java | 0 .../bukkit/permissions/bPermPermissions.java | 0 .../src}/main/resources/configuration.txt | 0 {src => core/src}/main/resources/plugin.yml | 0 {tools => core/tools}/Biomes.ods | Bin .../tools}/bukkit_formatting_profile.xml | 0 helper/.classpath | 36 + helper/.gitignore | 1 + helper/.project | 23 + .../org.eclipse.core.resources.prefs | 6 + helper/.settings/org.eclipse.jdt.core.prefs | 5 + helper/.settings/org.eclipse.m2e.core.prefs | 4 + helper/pom.xml | 47 + .../bukkit/helper}/BukkitVersionHelper.java | 55 +- .../bukkit/helper}/BukkitVersionHelperCB.java | 25 +- .../helper}/BukkitVersionHelperGeneric.java | 6 +- .../helper}/BukkitVersionHelperGlowstone.java | 2 +- .../dynmap/bukkit/helper}/BukkitWorld.java | 8 +- .../bukkit/helper}/NewMapChunkCache.java | 38 +- .../dynmap/bukkit/helper}/SnapshotCache.java | 5 +- helper113/.classpath | 36 + helper113/.gitignore | 1 + helper113/.project | 23 + .../org.eclipse.core.resources.prefs | 6 + .../.settings/org.eclipse.jdt.core.prefs | 5 + .../.settings/org.eclipse.m2e.core.prefs | 4 + helper113/pom.xml | 50 + .../v113/BukkitVersionHelperSpigot113.java | 130 ++ .../bukkit/helper/v113/MapChunkCache113.java | 1062 +++++++++++++++++ pom.xml | 157 +-- 42 files changed, 1763 insertions(+), 249 deletions(-) create mode 100644 core/.gitignore create mode 100644 core/pom.xml rename {src => core/src}/main/assembly/package.xml (100%) rename {src => core/src}/main/java/org/dynmap/bukkit/Armor.java (100%) rename {src => core/src}/main/java/org/dynmap/bukkit/DynmapPlugin.java (96%) create mode 100644 core/src/main/java/org/dynmap/bukkit/Helper.java rename {src => core/src}/main/java/org/dynmap/bukkit/permissions/BukkitPermissions.java (100%) rename {src => core/src}/main/java/org/dynmap/bukkit/permissions/GroupManagerPermissions.java (100%) rename {src => core/src}/main/java/org/dynmap/bukkit/permissions/NijikokunPermissions.java (100%) rename {src => core/src}/main/java/org/dynmap/bukkit/permissions/OpPermissions.java (100%) rename {src => core/src}/main/java/org/dynmap/bukkit/permissions/PEXPermissions.java (100%) rename {src => core/src}/main/java/org/dynmap/bukkit/permissions/PermBukkitPermissions.java (100%) rename {src => core/src}/main/java/org/dynmap/bukkit/permissions/PermissionProvider.java (100%) rename {src => core/src}/main/java/org/dynmap/bukkit/permissions/bPermPermissions.java (100%) rename {src => core/src}/main/resources/configuration.txt (100%) rename {src => core/src}/main/resources/plugin.yml (100%) rename {tools => core/tools}/Biomes.ods (100%) rename {tools => core/tools}/bukkit_formatting_profile.xml (100%) create mode 100644 helper/.classpath create mode 100644 helper/.gitignore create mode 100644 helper/.project create mode 100644 helper/.settings/org.eclipse.core.resources.prefs create mode 100644 helper/.settings/org.eclipse.jdt.core.prefs create mode 100644 helper/.settings/org.eclipse.m2e.core.prefs create mode 100644 helper/pom.xml rename {src/main/java/org/dynmap/bukkit => helper/src/main/java/org/dynmap/bukkit/helper}/BukkitVersionHelper.java (68%) rename {src/main/java/org/dynmap/bukkit => helper/src/main/java/org/dynmap/bukkit/helper}/BukkitVersionHelperCB.java (95%) rename {src/main/java/org/dynmap/bukkit => helper/src/main/java/org/dynmap/bukkit/helper}/BukkitVersionHelperGeneric.java (99%) rename {src/main/java/org/dynmap/bukkit => helper/src/main/java/org/dynmap/bukkit/helper}/BukkitVersionHelperGlowstone.java (99%) rename {src/main/java/org/dynmap/bukkit => helper/src/main/java/org/dynmap/bukkit/helper}/BukkitWorld.java (97%) rename {src/main/java/org/dynmap/bukkit => helper/src/main/java/org/dynmap/bukkit/helper}/NewMapChunkCache.java (95%) rename {src/main/java/org/dynmap/bukkit => helper/src/main/java/org/dynmap/bukkit/helper}/SnapshotCache.java (98%) create mode 100644 helper113/.classpath create mode 100644 helper113/.gitignore create mode 100644 helper113/.project create mode 100644 helper113/.settings/org.eclipse.core.resources.prefs create mode 100644 helper113/.settings/org.eclipse.jdt.core.prefs create mode 100644 helper113/.settings/org.eclipse.m2e.core.prefs create mode 100644 helper113/pom.xml create mode 100644 helper113/src/main/java/org/dynmap/bukkit/helper/v113/BukkitVersionHelperSpigot113.java create mode 100644 helper113/src/main/java/org/dynmap/bukkit/helper/v113/MapChunkCache113.java diff --git a/core/.gitignore b/core/.gitignore new file mode 100644 index 00000000..c8ee1df6 --- /dev/null +++ b/core/.gitignore @@ -0,0 +1,2 @@ +/target/ +/dependency-reduced-pom.xml diff --git a/core/pom.xml b/core/pom.xml new file mode 100644 index 00000000..b2b4c5ec --- /dev/null +++ b/core/pom.xml @@ -0,0 +1,177 @@ + + 4.0.0 + us.dynmap + dynmap + dynmap + http://github.com/webbukkit/dynmap/ + + GitHub + https://github.com/webbukkit/dynmap/issues + + + + + src/main/resources + true + + *.yml + *.txt + + + + src/main/resources + false + + *.yml + *.txt + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.0.2 + + 1.8 + 1.8 + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.0.0 + + + + org.bstats:* + us.dynmap:dynmap-api:jar:* + us.dynmap:DynmapCore:jar:* + us.dynmap:dynmap-helper:jar:* + us.dynmap:dynmap-helper-113:jar:* + + + + + org.bstats + org.dynmap + + + + + + package + + shade + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar + + + + + + + + + + dynmap-repo + http://repo.mikeprimm.com/ + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + bstats-repo + http://repo.bstats.org/content/repositories/releases/ + + + + + com.nijikokun.bukkit + Permissions + 3.1.6 + + + org.bukkit + bukkit + 1.7.10-R0.1-SNAPSHOT + + + us.dynmap + dynmap-api + 3.0-SNAPSHOT + + + us.dynmap + DynmapCore + 3.0-SNAPSHOT + + + ru.tehkode + PermissionsEx + 1.19.1 + + + de.bananaco + bPermissions + 2.9.1 + + + com.platymuus.bukkit.permissions + PermissionsBukkit + 1.6 + + + org.anjocaido + EssentialsGroupManager + 2.10.1 + + + org.bstats + bstats-bukkit + 1.1 + + + com.googlecode.json-simple + json-simple + 1.1.1 + + + + com.google.code.gson + gson + 2.8.2 + + + us.dynmap + dynmap-helper + 3.0-SNAPSHOT + + + us.dynmap + dynmap-helper-113 + 3.0-SNAPSHOT + + + 3.0-SNAPSHOT + + us.dynmap + dynmap-bukkit + 3.0-SNAPSHOT + .. + + diff --git a/src/main/assembly/package.xml b/core/src/main/assembly/package.xml similarity index 100% rename from src/main/assembly/package.xml rename to core/src/main/assembly/package.xml diff --git a/src/main/java/org/dynmap/bukkit/Armor.java b/core/src/main/java/org/dynmap/bukkit/Armor.java similarity index 100% rename from src/main/java/org/dynmap/bukkit/Armor.java rename to core/src/main/java/org/dynmap/bukkit/Armor.java diff --git a/src/main/java/org/dynmap/bukkit/DynmapPlugin.java b/core/src/main/java/org/dynmap/bukkit/DynmapPlugin.java similarity index 96% rename from src/main/java/org/dynmap/bukkit/DynmapPlugin.java rename to core/src/main/java/org/dynmap/bukkit/DynmapPlugin.java index c542fa31..ab8b2749 100644 --- a/src/main/java/org/dynmap/bukkit/DynmapPlugin.java +++ b/core/src/main/java/org/dynmap/bukkit/DynmapPlugin.java @@ -78,6 +78,9 @@ import org.dynmap.Log; import org.dynmap.MapManager; import org.dynmap.MapType; import org.dynmap.PlayerList; +import org.dynmap.bukkit.helper.BukkitVersionHelper; +import org.dynmap.bukkit.helper.BukkitWorld; +import org.dynmap.bukkit.helper.SnapshotCache; import org.dynmap.bukkit.permissions.BukkitPermissions; import org.dynmap.bukkit.permissions.NijikokunPermissions; import org.dynmap.bukkit.permissions.OpPermissions; @@ -102,7 +105,6 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { private DynmapCore core; private PermissionProvider permissions; private String version; - public SnapshotCache sscache; public PlayerList playerList; private MapManager mapManager; public static DynmapPlugin plugin; @@ -370,11 +372,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { } @Override public double getCacheHitRate() { - return sscache.getHitRate(); + return SnapshotCache.sscache.getHitRate(); } @Override public void resetCacheStats() { - sscache.resetStats(); + SnapshotCache.sscache.resetStats(); } @Override public DynmapWorld getWorldByName(String wname) { @@ -769,7 +771,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onLoad() { Log.setLogger(this.getLogger(), ""); - helper = BukkitVersionHelper.getHelper(); + helper = Helper.getHelper(); pm = this.getServer().getPluginManager(); ModSupportImpl.init(); @@ -885,7 +887,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { return; } playerList = core.playerList; - sscache = new SnapshotCache(core.getSnapShotCacheSize(), core.useSoftRefInSnapShotCache()); + SnapshotCache.sscache = new SnapshotCache(core.getSnapShotCacheSize(), core.useSoftRefInSnapShotCache()); /* Get map manager from core */ mapManager = core.getMapManager(); @@ -919,9 +921,9 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { /* Disable core */ core.disableCore(); - if(sscache != null) { - sscache.cleanup(); - sscache = null; + if(SnapshotCache.sscache != null) { + SnapshotCache.sscache.cleanup(); + SnapshotCache.sscache = null; } Log.info("Disabled"); } @@ -974,13 +976,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) { - sscache.invalidateSnapshot(wid, minx, miny, minz, maxx, maxy, maxz); + SnapshotCache.sscache.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) { - sscache.invalidateSnapshot(wid, x, y, z); + SnapshotCache.sscache.invalidateSnapshot(wid, x, y, z); return core.triggerRenderOfBlock(wid, x, y, z); } @@ -1106,7 +1108,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(); - sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), btt.trigger); } } @@ -1174,7 +1176,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onBlockPlace(BlockPlaceEvent event) { Location loc = event.getBlock().getLocation(); String wn = getWorld(loc.getWorld()).getName(); - sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockplace"); } }; @@ -1189,7 +1191,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(); - sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockbreak"); } }; @@ -1202,7 +1204,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onLeavesDecay(LeavesDecayEvent event) { Location loc = event.getBlock().getLocation(); String wn = getWorld(loc.getWorld()).getName(); - sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); if(onleaves) { mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "leavesdecay"); } @@ -1217,7 +1219,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onBlockBurn(BlockBurnEvent event) { Location loc = event.getBlock().getLocation(); String wn = getWorld(loc.getWorld()).getName(); - sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); if(onburn) { mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockburn"); } @@ -1281,14 +1283,14 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { } String wn = getWorld(loc.getWorld()).getName(); int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ(); - sscache.invalidateSnapshot(wn, x, y, z); + SnapshotCache.sscache.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(); - sscache.invalidateSnapshot(wn, x, y, z); + SnapshotCache.sscache.invalidateSnapshot(wn, x, y, z); mapManager.touch(wn, x, y, z, "pistonretract"); } } @@ -1305,14 +1307,14 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { } String wn = getWorld(loc.getWorld()).getName(); int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ(); - sscache.invalidateSnapshot(wn, x, y, z); + SnapshotCache.sscache.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(); - sscache.invalidateSnapshot(wn, x, y, z); + SnapshotCache.sscache.invalidateSnapshot(wn, x, y, z); mapManager.touch(wn, x, y, z, "pistonretract"); } } @@ -1326,7 +1328,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onBlockSpread(BlockSpreadEvent event) { Location loc = event.getBlock().getLocation(); String wn = getWorld(loc.getWorld()).getName(); - sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockspread"); } }; @@ -1339,7 +1341,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onBlockForm(BlockFormEvent event) { Location loc = event.getBlock().getLocation(); String wn = getWorld(loc.getWorld()).getName(); - sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockform"); } }; @@ -1352,7 +1354,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onBlockFade(BlockFadeEvent event) { Location loc = event.getBlock().getLocation(); String wn = getWorld(loc.getWorld()).getName(); - sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfade"); } }; @@ -1367,7 +1369,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onBlockGrow(BlockGrowEvent event) { Location loc = event.getBlock().getLocation(); String wn = getWorld(loc.getWorld()).getName(); - sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockgrow"); } }; @@ -1380,7 +1382,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onBlockRedstone(BlockRedstoneEvent event) { Location loc = event.getBlock().getLocation(); String wn = getWorld(loc.getWorld()).getName(); - sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + SnapshotCache.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockredstone"); } }; @@ -1437,7 +1439,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { if(z < minz) minz = z; if(z > maxz) maxz = z; } - sscache.invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz); + SnapshotCache.sscache.invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz); if(onexplosion) { mapManager.touchVolume(wname, minx, miny, minz, maxx, maxy, maxz, "entityexplode"); } @@ -1484,7 +1486,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { if(z < minz) minz = z; if(z > maxz) maxz = z; } - sscache.invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz); + SnapshotCache.sscache.invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz); if(onstructuregrow) { mapManager.touchVolume(wname, minx, miny, minz, maxx, maxy, maxz, "structuregrow"); } diff --git a/core/src/main/java/org/dynmap/bukkit/Helper.java b/core/src/main/java/org/dynmap/bukkit/Helper.java new file mode 100644 index 00000000..558b4005 --- /dev/null +++ b/core/src/main/java/org/dynmap/bukkit/Helper.java @@ -0,0 +1,44 @@ +package org.dynmap.bukkit; + +import org.bukkit.Bukkit; +import org.dynmap.Log; +import org.dynmap.bukkit.helper.BukkitVersionHelper; +import org.dynmap.bukkit.helper.BukkitVersionHelperCB; +import org.dynmap.bukkit.helper.BukkitVersionHelperGlowstone; +import org.dynmap.bukkit.helper.v113.BukkitVersionHelperSpigot113; + +public class Helper { + + public static final BukkitVersionHelper getHelper() { + if (BukkitVersionHelper.helper == null) { + String v = Bukkit.getServer().getVersion(); + Log.info("version=" + v); + if (v.contains("MCPC")) { + Log.severe("*********************************************************************************"); + Log.severe("* MCPC-Plus is no longer supported via the Bukkit version of Dynmap. *"); + Log.severe("* Install the appropriate Forge version of Dynmap. *"); + Log.severe("* Add the DynmapCBBridge plugin to enable support for Dynmap-compatible plugins *"); + Log.severe("*********************************************************************************"); + } + else if(v.contains("BukkitForge")) { + Log.severe("*********************************************************************************"); + Log.severe("* BukkitForge is not supported via the Bukkit version of Dynmap. *"); + Log.severe("* Install the appropriate Forge version of Dynmap. *"); + Log.severe("* Add the DynmapCBBridge plugin to enable support for Dynmap-compatible plugins *"); + Log.severe("*********************************************************************************"); + } + else if(Bukkit.getServer().getClass().getName().contains("GlowServer")) { + Log.info("Loading Glowstone support"); + BukkitVersionHelper.helper = new BukkitVersionHelperGlowstone(); + } + else if (v.contains("(MC: 1.13)")) { + BukkitVersionHelper.helper = new BukkitVersionHelperSpigot113(); + } + else { + BukkitVersionHelper.helper = new BukkitVersionHelperCB(); + } + } + return BukkitVersionHelper.helper; + } + +} diff --git a/src/main/java/org/dynmap/bukkit/permissions/BukkitPermissions.java b/core/src/main/java/org/dynmap/bukkit/permissions/BukkitPermissions.java similarity index 100% rename from src/main/java/org/dynmap/bukkit/permissions/BukkitPermissions.java rename to core/src/main/java/org/dynmap/bukkit/permissions/BukkitPermissions.java diff --git a/src/main/java/org/dynmap/bukkit/permissions/GroupManagerPermissions.java b/core/src/main/java/org/dynmap/bukkit/permissions/GroupManagerPermissions.java similarity index 100% rename from src/main/java/org/dynmap/bukkit/permissions/GroupManagerPermissions.java rename to core/src/main/java/org/dynmap/bukkit/permissions/GroupManagerPermissions.java diff --git a/src/main/java/org/dynmap/bukkit/permissions/NijikokunPermissions.java b/core/src/main/java/org/dynmap/bukkit/permissions/NijikokunPermissions.java similarity index 100% rename from src/main/java/org/dynmap/bukkit/permissions/NijikokunPermissions.java rename to core/src/main/java/org/dynmap/bukkit/permissions/NijikokunPermissions.java diff --git a/src/main/java/org/dynmap/bukkit/permissions/OpPermissions.java b/core/src/main/java/org/dynmap/bukkit/permissions/OpPermissions.java similarity index 100% rename from src/main/java/org/dynmap/bukkit/permissions/OpPermissions.java rename to core/src/main/java/org/dynmap/bukkit/permissions/OpPermissions.java diff --git a/src/main/java/org/dynmap/bukkit/permissions/PEXPermissions.java b/core/src/main/java/org/dynmap/bukkit/permissions/PEXPermissions.java similarity index 100% rename from src/main/java/org/dynmap/bukkit/permissions/PEXPermissions.java rename to core/src/main/java/org/dynmap/bukkit/permissions/PEXPermissions.java diff --git a/src/main/java/org/dynmap/bukkit/permissions/PermBukkitPermissions.java b/core/src/main/java/org/dynmap/bukkit/permissions/PermBukkitPermissions.java similarity index 100% rename from src/main/java/org/dynmap/bukkit/permissions/PermBukkitPermissions.java rename to core/src/main/java/org/dynmap/bukkit/permissions/PermBukkitPermissions.java diff --git a/src/main/java/org/dynmap/bukkit/permissions/PermissionProvider.java b/core/src/main/java/org/dynmap/bukkit/permissions/PermissionProvider.java similarity index 100% rename from src/main/java/org/dynmap/bukkit/permissions/PermissionProvider.java rename to core/src/main/java/org/dynmap/bukkit/permissions/PermissionProvider.java diff --git a/src/main/java/org/dynmap/bukkit/permissions/bPermPermissions.java b/core/src/main/java/org/dynmap/bukkit/permissions/bPermPermissions.java similarity index 100% rename from src/main/java/org/dynmap/bukkit/permissions/bPermPermissions.java rename to core/src/main/java/org/dynmap/bukkit/permissions/bPermPermissions.java diff --git a/src/main/resources/configuration.txt b/core/src/main/resources/configuration.txt similarity index 100% rename from src/main/resources/configuration.txt rename to core/src/main/resources/configuration.txt diff --git a/src/main/resources/plugin.yml b/core/src/main/resources/plugin.yml similarity index 100% rename from src/main/resources/plugin.yml rename to core/src/main/resources/plugin.yml diff --git a/tools/Biomes.ods b/core/tools/Biomes.ods similarity index 100% rename from tools/Biomes.ods rename to core/tools/Biomes.ods diff --git a/tools/bukkit_formatting_profile.xml b/core/tools/bukkit_formatting_profile.xml similarity index 100% rename from tools/bukkit_formatting_profile.xml rename to core/tools/bukkit_formatting_profile.xml diff --git a/helper/.classpath b/helper/.classpath new file mode 100644 index 00000000..d58ab93b --- /dev/null +++ b/helper/.classpath @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/helper/.gitignore b/helper/.gitignore new file mode 100644 index 00000000..b83d2226 --- /dev/null +++ b/helper/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/helper/.project b/helper/.project new file mode 100644 index 00000000..34ea69da --- /dev/null +++ b/helper/.project @@ -0,0 +1,23 @@ + + + helper + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/helper/.settings/org.eclipse.core.resources.prefs b/helper/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000..04cfa2c1 --- /dev/null +++ b/helper/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/helper/.settings/org.eclipse.jdt.core.prefs b/helper/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..86260262 --- /dev/null +++ b/helper/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/helper/.settings/org.eclipse.m2e.core.prefs b/helper/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 00000000..14b697b7 --- /dev/null +++ b/helper/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/helper/pom.xml b/helper/pom.xml new file mode 100644 index 00000000..7501d231 --- /dev/null +++ b/helper/pom.xml @@ -0,0 +1,47 @@ + + 4.0.0 + + us.dynmap + dynmap-bukkit + 3.0-SNAPSHOT + .. + + dynmap-helper + us.dynmap + 3.0-SNAPSHOT + + + + org.bukkit + bukkit + 1.7.10-R0.1-SNAPSHOT + + + us.dynmap + dynmap-api + 3.0-SNAPSHOT + + + us.dynmap + DynmapCore + 3.0-SNAPSHOT + + + com.google.code.gson + gson + 2.8.2 + + + + + dynmap-repo + http://repo.mikeprimm.com/ + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + + dynmap-helper + \ No newline at end of file diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java b/helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelper.java similarity index 68% rename from src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java rename to helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelper.java index 6c9d13db..ce3b828f 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java +++ b/helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelper.java @@ -1,54 +1,26 @@ -package org.dynmap.bukkit; +package org.dynmap.bukkit.helper; import java.util.Arrays; +import java.util.List; import java.util.Map; -import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.ChunkSnapshot; import org.bukkit.World; import org.bukkit.entity.Player; +import org.dynmap.DynmapChunk; import org.dynmap.Log; import org.dynmap.renderer.DynmapBlockState; -import org.dynmap.utils.DynIntHashMap; +import org.dynmap.utils.MapChunkCache; import org.dynmap.utils.Polygon; /** * Helper for isolation of bukkit version specific issues */ public abstract class BukkitVersionHelper { - - private static BukkitVersionHelper helper = null; + public static BukkitVersionHelper helper = null; - public static final BukkitVersionHelper getHelper() { - if(helper == null) { - Log.info("version=" + Bukkit.getServer().getVersion()); - if(Bukkit.getServer().getVersion().contains("MCPC")) { - Log.severe("*********************************************************************************"); - Log.severe("* MCPC-Plus is no longer supported via the Bukkit version of Dynmap. *"); - Log.severe("* Install the appropriate Forge version of Dynmap. *"); - Log.severe("* Add the DynmapCBBridge plugin to enable support for Dynmap-compatible plugins *"); - Log.severe("*********************************************************************************"); - } - else if(Bukkit.getServer().getVersion().contains("BukkitForge")) { - Log.severe("*********************************************************************************"); - Log.severe("* BukkitForge is not supported via the Bukkit version of Dynmap. *"); - Log.severe("* Install the appropriate Forge version of Dynmap. *"); - Log.severe("* Add the DynmapCBBridge plugin to enable support for Dynmap-compatible plugins *"); - Log.severe("*********************************************************************************"); - } - else if(Bukkit.getServer().getClass().getName().contains("GlowServer")) { - Log.info("Loading Glowstone support"); - helper = new BukkitVersionHelperGlowstone(); - } - else { - helper = new BukkitVersionHelperCB(); - } - } - return helper; - } - - public static DynmapBlockState[] stateByID = new DynmapBlockState[65536]; + public static DynmapBlockState[] stateByID; protected BukkitVersionHelper() { @@ -160,6 +132,7 @@ public abstract class BukkitVersionHelper { public void initializeBlockStates() { String[] blkname = getBlockNames(); // Keep it simple for now - just assume 16 meta states for each + stateByID = new DynmapBlockState[16*blkname.length]; Arrays.fill(stateByID, DynmapBlockState.AIR); for (int i = 0; i < blkname.length; i++) { if (blkname[i] == null) continue; @@ -182,4 +155,18 @@ public abstract class BukkitVersionHelper { Log.info(gidx + ":" + bs.toString() + ", gidx=" + bs.globalStateIndex + ", sidx=" + bs.stateIndex); } } + /** + * Create chunk cache for given chunks of given world + * @param dw - world + * @param chunks - chunk list + * @return cache + */ + public MapChunkCache getChunkCache(BukkitWorld dw, List chunks) { + NewMapChunkCache c = new NewMapChunkCache(); + c.setChunks(dw, chunks); + return c; + } + public Object[] getBlockIDFieldFromSnapshot(ChunkSnapshot css) { + return null; + } } diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperCB.java b/helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperCB.java similarity index 95% rename from src/main/java/org/dynmap/bukkit/BukkitVersionHelperCB.java rename to helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperCB.java index c486ad5f..cb9a6b94 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperCB.java +++ b/helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperCB.java @@ -1,4 +1,4 @@ -package org.dynmap.bukkit; +package org.dynmap.bukkit.helper; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -13,7 +13,6 @@ import org.bukkit.Server; import org.bukkit.World; import org.dynmap.Log; import org.dynmap.hdmap.HDBlockModels; -import org.dynmap.renderer.DynmapBlockState; import org.dynmap.utils.Polygon; /** @@ -24,7 +23,6 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric { private Class nmsblockarray; private Class nmsmaterial; private Field blockbyid; - private Field blockname; private Field material; private Method blockbyidfunc; // 1.7+ method for getting block by id private Method getworldborder; // 1.8+ method for getting world border @@ -37,8 +35,9 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric { private Method getidbybiome; private boolean isBadUnload = false; - BukkitVersionHelperCB() { - String bukkitver = DynmapPlugin.plugin.getServer().getVersion(); + public BukkitVersionHelperCB() { + + String bukkitver = Bukkit.getServer().getVersion(); String mcver = "1.0.0"; int idx = bukkitver.indexOf("(MC: "); if(idx > 0) { @@ -72,7 +71,6 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric { if (blockbyid == null) { blockbyidfunc = getMethod(nmsblock, new String[] { "getById", "e" }, new Class[] { int.class }); } - blockname = getPrivateField(nmsblock, new String[] { "name", "b" }, String.class); material = getPrivateField(nmsblock, new String[] { "material" }, nmsmaterial); /* Set up biomebase fields */ @@ -87,10 +85,10 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric { biomebasehumi = getPrivateField(biomebase, new String[] { "C" }, float.class); } else { - biomebasetemp = getPrivateField(biomebase, new String[] { "temperature", "F", "C" }, float.class); - biomebasehumi = getPrivateField(biomebase, new String[] { "humidity", "G", "D" }, float.class); + biomebasetemp = getPrivateField(biomebase, new String[] { "temperature", "F", "C", "aO" }, float.class); + biomebasehumi = getPrivateField(biomebase, new String[] { "humidity", "G", "D", "aP" }, float.class); } - biomebaseidstring = getPrivateField(biomebase, new String[] { "y", "af", "ah", "z" }, String.class); + biomebaseidstring = getPrivateField(biomebase, new String[] { "y", "af", "ah", "z", "aS" }, String.class); biomebaseid = getFieldNoFail(biomebase, new String[] { "id" }, int.class); if (biomebaseid == null) { getidbybiome = getMethod(biomebase, new String[] { "a" }, new Class[] { biomebase } ); @@ -115,6 +113,13 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric { if (longhashset != null) { lhs_containskey = getMethod(longhashset, new String[] { "containsKey" }, new Class[] { int.class, int.class }); } + else { + longhashset = getOBCClassNoFail("org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.longs.LongSet"); + if (longhashset != null) { + lhs_containskey = getMethod(longhashset, new String[] { "contains" }, new Class[] { long.class }); + cps_unloadqueue_isSet = true; + } + } } cps_unloadqueue_isSet = false; @@ -131,7 +136,7 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric { /** n.m.s.Chunk */ nmschunk = getNMSClass("net.minecraft.server.Chunk"); nmsc_tileentities = getField(nmschunk, new String[] { "tileEntities" }, Map.class); - nmsc_inhabitedticks = getPrivateFieldNoFail(nmschunk, new String[] { "s", "q", "u", "v", "w" }, long.class); + nmsc_inhabitedticks = getPrivateFieldNoFail(nmschunk, new String[] { "s", "q", "u", "v", "w", "A" }, long.class); if (nmsc_inhabitedticks == null) { Log.info("inhabitedTicks field not found - inhabited shader not functional"); } diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGeneric.java b/helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperGeneric.java similarity index 99% rename from src/main/java/org/dynmap/bukkit/BukkitVersionHelperGeneric.java rename to helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperGeneric.java index 363002c6..9ceca8b0 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGeneric.java +++ b/helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperGeneric.java @@ -1,4 +1,4 @@ -package org.dynmap.bukkit; +package org.dynmap.bukkit.helper; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -37,7 +37,7 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper { private static final Map nullmap = Collections.emptyMap(); /** CraftChunkSnapshot */ - private Class craftchunksnapshot; + protected Class craftchunksnapshot; private Field ccss_biome; /** CraftChunk */ private Class craftchunk; @@ -114,7 +114,7 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper { private Class cma_property; private Method cmaproperty_getvalue; - BukkitVersionHelperGeneric() { + protected BukkitVersionHelperGeneric() { failed = false; /* Look up base classname for bukkit server - tells us OBC package */ obc_package = Bukkit.getServer().getClass().getPackage().getName(); diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGlowstone.java b/helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperGlowstone.java similarity index 99% rename from src/main/java/org/dynmap/bukkit/BukkitVersionHelperGlowstone.java rename to helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperGlowstone.java index a546bad1..eac48097 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGlowstone.java +++ b/helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelperGlowstone.java @@ -1,4 +1,4 @@ -package org.dynmap.bukkit; +package org.dynmap.bukkit.helper; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; diff --git a/src/main/java/org/dynmap/bukkit/BukkitWorld.java b/helper/src/main/java/org/dynmap/bukkit/helper/BukkitWorld.java similarity index 97% rename from src/main/java/org/dynmap/bukkit/BukkitWorld.java rename to helper/src/main/java/org/dynmap/bukkit/helper/BukkitWorld.java index e608f392..ddccd7ae 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitWorld.java +++ b/helper/src/main/java/org/dynmap/bukkit/helper/BukkitWorld.java @@ -1,4 +1,4 @@ -package org.dynmap.bukkit; +package org.dynmap.bukkit.helper; /** * Bukkit specific implementation of DynmapWorld */ @@ -177,9 +177,7 @@ public class BukkitWorld extends DynmapWorld { @Override public MapChunkCache getChunkCache(List chunks) { if(isLoaded()) { - NewMapChunkCache c = new NewMapChunkCache(); - c.setChunks(this, chunks); - return c; + return BukkitVersionHelper.helper.getChunkCache(this, chunks); } else { return null; @@ -244,6 +242,6 @@ public class BukkitWorld extends DynmapWorld { } @Override public Polygon getWorldBorder() { - return DynmapPlugin.plugin.getWorldBorder(world); + return BukkitVersionHelper.helper.getWorldBorder(world); } } diff --git a/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java b/helper/src/main/java/org/dynmap/bukkit/helper/NewMapChunkCache.java similarity index 95% rename from src/main/java/org/dynmap/bukkit/NewMapChunkCache.java rename to helper/src/main/java/org/dynmap/bukkit/helper/NewMapChunkCache.java index 48970b4c..56a1a103 100644 --- a/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java +++ b/helper/src/main/java/org/dynmap/bukkit/helper/NewMapChunkCache.java @@ -1,4 +1,4 @@ -package org.dynmap.bukkit; +package org.dynmap.bukkit.helper; import java.util.ArrayList; import java.util.List; @@ -13,7 +13,7 @@ import org.dynmap.DynmapChunk; import org.dynmap.DynmapCore; import org.dynmap.DynmapWorld; import org.dynmap.Log; -import org.dynmap.bukkit.SnapshotCache.SnapshotRec; +import org.dynmap.bukkit.helper.SnapshotCache.SnapshotRec; import org.dynmap.common.BiomeMap; import org.dynmap.hdmap.HDBlockModels; import org.dynmap.renderer.DynmapBlockState; @@ -50,9 +50,7 @@ public class NewMapChunkCache extends MapChunkCache { private boolean[][] isSectionNotEmpty; /* Indexed by snapshot index, then by section index */ private long[] inhabitedTicks; /* Index = (x-x_min) + ((z-z_min)*x_dim) */ private static final BiomeMap[] nullBiomeMap = { BiomeMap.NULL }; - - private static BukkitVersionHelper helper = BukkitVersionHelper.getHelper(); - + private static final BlockStep unstep[] = { BlockStep.X_MINUS, BlockStep.Y_MINUS, BlockStep.Z_MINUS, BlockStep.X_PLUS, BlockStep.Y_PLUS, BlockStep.Z_PLUS }; @@ -160,7 +158,7 @@ public class NewMapChunkCache extends MapChunkCache { biomebase = nullBiomeMap; } else { - biomebase = helper.getBiomeBaseFromSnapshot(snap); + biomebase = BukkitVersionHelper.helper.getBiomeBaseFromSnapshot(snap); } last_css = snap; } @@ -168,7 +166,7 @@ public class NewMapChunkCache extends MapChunkCache { bm = BiomeMap.NULL; } else if(biomebase != null) { - bm = BiomeMap.byBiomeID(helper.getBiomeBaseID(biomebase[bz << 4 | bx])); + bm = BiomeMap.byBiomeID(BukkitVersionHelper.helper.getBiomeBaseID(biomebase[bz << 4 | bx])); } else { Biome bb = snap.getBiome(bx, bz); @@ -745,7 +743,7 @@ public class NewMapChunkCache extends MapChunkCache { public int loadChunks(int max_to_load) { if(dw.isLoaded() == false) return 0; - Object queue = helper.getUnloadQueue(w); + Object queue = BukkitVersionHelper.helper.getUnloadQueue(w); int cnt = 0; if(iterator == null) @@ -779,7 +777,7 @@ public class NewMapChunkCache extends MapChunkCache { ChunkSnapshot ss = null; long inhabited_ticks = 0; DynIntHashMap tileData = null; - SnapshotRec ssr = DynmapPlugin.plugin.sscache.getSnapshot(dw.getName(), chunk.x, chunk.z, blockdata, biome, biomeraw, highesty); + SnapshotRec ssr = SnapshotCache.sscache.getSnapshot(dw.getName(), chunk.x, chunk.z, blockdata, biome, biomeraw, highesty); if(ssr != null) { ss = ssr.ss; inhabited_ticks = ssr.inhabitedTicks; @@ -803,7 +801,7 @@ public class NewMapChunkCache extends MapChunkCache { boolean didload = false; boolean isunloadpending = false; if (queue != null) { - isunloadpending = helper.isInUnloadQueue(queue, chunk.x, chunk.z); + isunloadpending = BukkitVersionHelper.helper.isInUnloadQueue(queue, chunk.x, chunk.z); } if (isunloadpending) { /* Workaround: can't be pending if not loaded */ wasLoaded = true; @@ -822,7 +820,7 @@ public class NewMapChunkCache extends MapChunkCache { Chunk c = w.getChunkAt(chunk.x, chunk.z); /* Get the chunk */ /* Get inhabited ticks count */ - inhabited_ticks = helper.getInhabitedTicks(c); + inhabited_ticks = BukkitVersionHelper.helper.getInhabitedTicks(c); if(!vis) { if(hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) ss = STONE; @@ -836,20 +834,20 @@ public class NewMapChunkCache extends MapChunkCache { ss = c.getChunkSnapshot(highesty, biome, biomeraw); /* Get tile entity data */ List vals = new ArrayList(); - Map tileents = helper.getTileEntitiesForChunk(c); + Map tileents = BukkitVersionHelper.helper.getTileEntitiesForChunk(c); for(Object t : tileents.values()) { - int te_x = helper.getTileEntityX(t); - int te_y = helper.getTileEntityY(t); - int te_z = helper.getTileEntityZ(t); + int te_x = BukkitVersionHelper.helper.getTileEntityX(t); + int te_y = BukkitVersionHelper.helper.getTileEntityY(t); + int te_z = BukkitVersionHelper.helper.getTileEntityZ(t); int cx = te_x & 0xF; int cz = te_z & 0xF; String[] te_fields = HDBlockModels.getTileEntityFieldsNeeded(getTypeAt(ss, cx, te_y, cz)); if(te_fields != null) { - Object nbtcompound = helper.readTileEntityNBT(t); + Object nbtcompound = BukkitVersionHelper.helper.readTileEntityNBT(t); vals.clear(); for(String id: te_fields) { - Object val = helper.getFieldValue(nbtcompound, id); + Object val = BukkitVersionHelper.helper.getFieldValue(nbtcompound, id); if(val != null) { vals.add(id); vals.add(val); @@ -869,7 +867,7 @@ public class NewMapChunkCache extends MapChunkCache { ssr.ss = ss; ssr.inhabitedTicks = inhabited_ticks; ssr.tileData = tileData; - DynmapPlugin.plugin.sscache.putSnapshot(dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty); + SnapshotCache.sscache.putSnapshot(dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty); } } int chunkIndex = (chunk.x-x_min) + (chunk.z - z_min)*x_dim; @@ -886,12 +884,12 @@ public class NewMapChunkCache extends MapChunkCache { * by the MC base server is 21x21 (or about a 160 block radius). * Also, if we did generate it, need to save it */ if (w.isChunkInUse(chunk.x, chunk.z) == false) { - if (helper.isUnloadChunkBroken()) { + if (BukkitVersionHelper.helper.isUnloadChunkBroken()) { // Give up on broken unloadChunk API - lets see if this works w.unloadChunkRequest(chunk.x, chunk.z); } else { - helper.unloadChunkNoSave(w, c, chunk.x, chunk.z); + BukkitVersionHelper.helper.unloadChunkNoSave(w, c, chunk.x, chunk.z); } } endChunkLoad(startTime, ChunkStats.UNLOADED_CHUNKS); diff --git a/src/main/java/org/dynmap/bukkit/SnapshotCache.java b/helper/src/main/java/org/dynmap/bukkit/helper/SnapshotCache.java similarity index 98% rename from src/main/java/org/dynmap/bukkit/SnapshotCache.java rename to helper/src/main/java/org/dynmap/bukkit/helper/SnapshotCache.java index 377c3464..ef5ce6df 100644 --- a/src/main/java/org/dynmap/bukkit/SnapshotCache.java +++ b/helper/src/main/java/org/dynmap/bukkit/helper/SnapshotCache.java @@ -1,4 +1,4 @@ -package org.dynmap.bukkit; +package org.dynmap.bukkit.helper; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; @@ -12,6 +12,9 @@ import org.bukkit.ChunkSnapshot; import org.dynmap.utils.DynIntHashMap; public class SnapshotCache { + + public static SnapshotCache sscache; + public static class SnapshotRec { public ChunkSnapshot ss; public long inhabitedTicks; diff --git a/helper113/.classpath b/helper113/.classpath new file mode 100644 index 00000000..d58ab93b --- /dev/null +++ b/helper113/.classpath @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/helper113/.gitignore b/helper113/.gitignore new file mode 100644 index 00000000..b83d2226 --- /dev/null +++ b/helper113/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/helper113/.project b/helper113/.project new file mode 100644 index 00000000..e0ce0988 --- /dev/null +++ b/helper113/.project @@ -0,0 +1,23 @@ + + + helper113 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/helper113/.settings/org.eclipse.core.resources.prefs b/helper113/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000..04cfa2c1 --- /dev/null +++ b/helper113/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/helper113/.settings/org.eclipse.jdt.core.prefs b/helper113/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..86260262 --- /dev/null +++ b/helper113/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/helper113/.settings/org.eclipse.m2e.core.prefs b/helper113/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 00000000..14b697b7 --- /dev/null +++ b/helper113/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/helper113/pom.xml b/helper113/pom.xml new file mode 100644 index 00000000..70d29637 --- /dev/null +++ b/helper113/pom.xml @@ -0,0 +1,50 @@ + + 4.0.0 + + us.dynmap + dynmap-bukkit + 3.0-SNAPSHOT + .. + + dynmap-helper-113 + dynmap-helper-1.13 + us.dynmap + + + us.dynmap + dynmap-helper + 3.0-SNAPSHOT + + + us.dynmap + dynmap-api + 3.0-SNAPSHOT + + + us.dynmap + DynmapCore + 3.0-SNAPSHOT + + + org.bukkit + bukkit + 1.13-R0.1-SNAPSHOT + + + org.bukkit + craftbukkit + 1.13-R0.1-SNAPSHOT + + + + + dynmap-repo + http://repo.mikeprimm.com/ + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + 3.0-SNAPSHOT + \ No newline at end of file diff --git a/helper113/src/main/java/org/dynmap/bukkit/helper/v113/BukkitVersionHelperSpigot113.java b/helper113/src/main/java/org/dynmap/bukkit/helper/v113/BukkitVersionHelperSpigot113.java new file mode 100644 index 00000000..f61f9e46 --- /dev/null +++ b/helper113/src/main/java/org/dynmap/bukkit/helper/v113/BukkitVersionHelperSpigot113.java @@ -0,0 +1,130 @@ +package org.dynmap.bukkit.helper.v113; + +import java.lang.reflect.Field; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.ChunkSnapshot; +import org.bukkit.Server; +import org.bukkit.World; +import org.dynmap.DynmapChunk; +import org.dynmap.Log; +import org.dynmap.bukkit.helper.BukkitVersionHelper; +import org.dynmap.bukkit.helper.BukkitVersionHelperCB; +import org.dynmap.bukkit.helper.BukkitWorld; +import org.dynmap.hdmap.HDBlockModels; +import org.dynmap.renderer.DynmapBlockState; +import org.dynmap.utils.MapChunkCache; +import org.dynmap.utils.Polygon; +import org.dynmap.bukkit.helper.v113.MapChunkCache113; +import net.minecraft.server.v1_13_R1.Block; +import net.minecraft.server.v1_13_R1.IBlockData; +import net.minecraft.server.v1_13_R1.IBlockState; + +/** + * Helper for isolation of bukkit version specific issues + */ +public class BukkitVersionHelperSpigot113 extends BukkitVersionHelperCB { + + /** CraftChunkSnapshot */ + protected Class datapalettearray; + private Field blockid_field; + + public BukkitVersionHelperSpigot113() { + datapalettearray = getNMSClass("[Lnet.minecraft.server.DataPaletteBlock;"); + blockid_field = getPrivateField(craftchunksnapshot, new String[] { "blockids" }, datapalettearray); + } + + @Override + public Object[] getBlockIDFieldFromSnapshot(ChunkSnapshot css) { + try { + return (Object[]) blockid_field.get(css); + } catch (IllegalArgumentException e) { + } catch (IllegalAccessException e) { + } + return null; + } + @Override + public void unloadChunkNoSave(World w, Chunk c, int cx, int cz) { + w.unloadChunk(cx, cz, false, false); + } + + private String stripBlockString(String bname) { + int idx = bname.indexOf('{'); + if (idx >= 0) bname = bname.substring(idx+1); + idx = bname.indexOf('}'); + if (idx >= 0) bname = bname.substring(0, idx); + return bname; + } + /** + * Get block short name list + */ + @Override + public String[] getBlockNames() { + int cnt = Block.REGISTRY_ID.a(); + String[] names = new String[cnt]; + for (int i = 0; i < cnt; i++) { + IBlockData bd = Block.getByCombinedId(i); + names[i] = Block.REGISTRY.b(bd.getBlock()).b(); + Log.info(i + ": blk=" + names[i] + ", bd=" + bd.toString()); + } + return names; + } + + public static IdentityHashMap dataToState; + + /** + * Initialize block states (org.dynmap.blockstate.DynmapBlockState) + */ + @Override + public void initializeBlockStates() { + dataToState = new IdentityHashMap(); + HashMap lastBlockState = new HashMap(); + + int cnt = Block.REGISTRY_ID.a(); + // Loop through block data states + for (int i = 0; i < cnt; i++) { + IBlockData bd = Block.getByCombinedId(i); + String bname = Block.REGISTRY.b(bd.getBlock()).toString(); + DynmapBlockState lastbs = lastBlockState.get(bname); // See if we have seen this one + int idx = 0; + if (lastbs != null) { // Yes + idx = lastbs.getStateCount(); // Get number of states so far, since this is next + } + // Build state name + String sb = ""; + String fname = bd.toString(); + int off1 = fname.indexOf('['); + if (off1 >= 0) { + int off2 = fname.indexOf(']'); + sb = fname.substring(off1+1, off2); + } + DynmapBlockState bs = new DynmapBlockState(lastbs, idx, bname, sb); + dataToState.put(bd, bs); + lastBlockState.put(bname, (lastbs == null) ? bs : lastbs); + Log.info(i + ": blk=" + bname + ", idx=" + idx + ", state=" + sb); + } + } + /** + * Create chunk cache for given chunks of given world + * @param dw - world + * @param chunks - chunk list + * @return cache + */ + @Override + public MapChunkCache getChunkCache(BukkitWorld dw, List chunks) { + MapChunkCache113 c = new MapChunkCache113(); + c.setChunks(dw, chunks); + return c; + } +} diff --git a/helper113/src/main/java/org/dynmap/bukkit/helper/v113/MapChunkCache113.java b/helper113/src/main/java/org/dynmap/bukkit/helper/v113/MapChunkCache113.java new file mode 100644 index 00000000..f6a9a250 --- /dev/null +++ b/helper113/src/main/java/org/dynmap/bukkit/helper/v113/MapChunkCache113.java @@ -0,0 +1,1062 @@ +package org.dynmap.bukkit.helper.v113; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +import org.bukkit.World; +import org.bukkit.Chunk; +import org.bukkit.block.Biome; +import org.bukkit.ChunkSnapshot; +import org.dynmap.DynmapChunk; +import org.dynmap.DynmapCore; +import org.dynmap.DynmapWorld; +import org.dynmap.Log; +import org.dynmap.bukkit.helper.BukkitVersionHelper; +import org.dynmap.bukkit.helper.BukkitWorld; +import org.dynmap.bukkit.helper.SnapshotCache; +import org.dynmap.bukkit.helper.SnapshotCache.SnapshotRec; +import org.dynmap.common.BiomeMap; +import org.dynmap.hdmap.HDBlockModels; +import org.dynmap.renderer.DynmapBlockState; +import org.dynmap.renderer.RenderPatchFactory; +import org.dynmap.utils.DynIntHashMap; +import org.dynmap.utils.MapChunkCache; +import org.dynmap.utils.MapIterator; +import org.dynmap.utils.BlockStep; +import org.dynmap.utils.VisibilityLimit; + +import net.minecraft.server.v1_13_R1.DataPaletteBlock; +import net.minecraft.server.v1_13_R1.IBlockData; + +/** + * Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread + */ +public class MapChunkCache113 extends MapChunkCache { + private static boolean init = false; + + private World w; + private DynmapWorld dw; + private int nsect; + private List chunks; + private ListIterator iterator; + private int x_min, x_max, z_min, z_max; + private int x_dim; + private boolean biome, biomeraw, highesty, blockdata; + private HiddenChunkStyle hidestyle = HiddenChunkStyle.FILL_AIR; + private List visible_limits = null; + private List hidden_limits = null; + private boolean isempty = true; + private int snapcnt; + private Snapshot[] snaparray; /* Index = (x-x_min) + ((z-z_min)*x_dim) */ + private DynIntHashMap[] snaptile; + private byte[][] sameneighborbiomecnt; + private BiomeMap[][] biomemap; + private boolean[][] isSectionNotEmpty; /* Indexed by snapshot index, then by section index */ + private long[] inhabitedTicks; /* Index = (x-x_min) + ((z-z_min)*x_dim) */ + private static final BiomeMap[] nullBiomeMap = { BiomeMap.NULL }; + + private static final BlockStep unstep[] = { BlockStep.X_MINUS, BlockStep.Y_MINUS, BlockStep.Z_MINUS, + BlockStep.X_PLUS, BlockStep.Y_PLUS, BlockStep.Z_PLUS }; + + private static BiomeMap[] biome_to_bmap; + + private static final int getIndexInChunk(int cx, int cy, int cz) { + return (cy << 8) | (cz << 4) | cx; + } + + /** + * Iterator for traversing map chunk cache (base is for non-snapshot) + */ + public class OurMapIterator implements MapIterator { + @SuppressWarnings("unused") + private int x, y, z, chunkindex, bx, bz, off; + private Snapshot snap; + private BlockStep laststep; + private DynmapBlockState type = null; + private final int worldheight; + private final int x_base; + private final int z_base; + + OurMapIterator(int x0, int y0, int z0) { + x_base = x_min << 4; + z_base = z_min << 4; + if(biome) + biomePrep(); + initialize(x0, y0, z0); + worldheight = w.getMaxHeight(); + } + + @Override + public final void initialize(int x0, int y0, int z0) { + this.x = x0; + this.y = y0; + this.z = z0; + this.chunkindex = ((x >> 4) - x_min) + (((z >> 4) - z_min) * x_dim); + this.bx = x & 0xF; + this.bz = z & 0xF; + this.off = bx + (bz << 4); + if ((chunkindex >= snapcnt) || (chunkindex < 0)) { + snap = EMPTY; + } + else { + snap = snaparray[chunkindex]; + } + laststep = BlockStep.Y_MINUS; + if((y >= 0) && (y < worldheight)) + type = null; + else + type = DynmapBlockState.AIR; + } + + @Override + public final DynmapBlockState getBlockType() { + if (type == null) { + type = snap.getBlockType(bx, y, bz); + } + return type; + } + @Override + public int getBlockSkyLight() { + try { + return snap.getBlockSkyLight(bx, y, bz); + } catch (ArrayIndexOutOfBoundsException aioobx) { + return 15; + } + } + @Override + public final int getBlockEmittedLight() { + try { + return snap.getBlockEmittedLight(bx, y, bz); + } catch (ArrayIndexOutOfBoundsException aioobx) { + return 0; + } + } + 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]; + } + Snapshot last_css = null; + Object[] biomebase = null; + for(int i = 0; i < x_size; i++) { + for(int j = 0; j < z_size; j++) { + BiomeMap bm; + if (j == 0) { + initialize(i + x_base, 64, z_base); + } + else { + stepPosition(BlockStep.Z_PLUS); + } + if (last_css != snap) { + if ((snap instanceof EmptyChunk) || (snap instanceof PlainChunk)) { + biomebase = nullBiomeMap; + } + else { + biomebase = snap.getBiomeBaseFromSnapshot(); + } + last_css = snap; + } + if (biomebase == nullBiomeMap) { + bm = BiomeMap.NULL; + } + else if(biomebase != null) { + bm = BiomeMap.byBiomeID(BukkitVersionHelper.helper.getBiomeBaseID(biomebase[bz << 4 | bx])); + } + else { + Biome bb = snap.getBiome(bx, bz); + if(bb == null) + bm = BiomeMap.NULL; + else + bm = biome_to_bmap[bb.ordinal()]; + } + 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]; + } catch (Exception ex) { + return BiomeMap.NULL; + } + } + @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 rmult = bm.getModifiedGrassMultiplier(colormap[bm.biomeLookup()]); + raccum += (rmult >> 16) & 0xFF; + gaccum += (rmult >> 8) & 0xFF; + baccum += rmult & 0xFF; + } + } + mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); + } + } catch (Exception x) { + mult = 0xFFFFFF; + } + return mult; + } + @Override + public final int getSmoothFoliageColorMultiplier(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.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 rmult = bm.getModifiedFoliageMultiplier(colormap[bm.biomeLookup()]); + raccum += (rmult >> 16) & 0xFF; + gaccum += (rmult >> 8) & 0xFF; + baccum += rmult & 0xFF; + } + } + mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); + } + } catch (Exception x) { + mult = 0xFFFFFF; + } + return mult; + } + @Override + public final int getSmoothColorMultiplier(int[] colormap, int[] swampmap) { + 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 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; + } + } + mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); + } + } catch (Exception x) { + mult = 0xFFFFFF; + } + return mult; + } + @Override + public final int getSmoothWaterColorMultiplier() { + 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? */ + return bm.getWaterColorMult(); + } + 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; + } + } + return ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); + } catch (Exception x) { + return 0xFFFFFF; + } + } + @Override + public final int getSmoothWaterColorMultiplier(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 = 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 rmult = colormap[bm.biomeLookup()]; + raccum += (rmult >> 16) & 0xFF; + gaccum += (rmult >> 8) & 0xFF; + baccum += rmult & 0xFF; + } + } + mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); + } + } catch (Exception x) { + mult = 0xFFFFFF; + } + return mult; + } + /** + * Step current position in given direction + */ + @Override + public final void stepPosition(BlockStep step) { + type = null; + switch(step.ordinal()) { + case 0: + x++; + bx++; + off++; + if(bx == 16) { /* Next chunk? */ + bx = 0; + off -= 16; + chunkindex++; + if ((chunkindex >= snapcnt) || (chunkindex < 0)) { + snap = EMPTY; + } + else { + snap = snaparray[chunkindex]; + } + } + break; + case 1: + y++; + if(y >= worldheight) { + type = DynmapBlockState.AIR; + } + break; + case 2: + z++; + bz++; + off+=16; + if(bz == 16) { /* Next chunk? */ + bz = 0; + off -= 256; + chunkindex += x_dim; + if ((chunkindex >= snapcnt) || (chunkindex < 0)) { + snap = EMPTY; + } + else { + snap = snaparray[chunkindex]; + } + } + break; + case 3: + x--; + bx--; + off--; + if(bx == -1) { /* Next chunk? */ + bx = 15; + off += 16; + chunkindex--; + if ((chunkindex >= snapcnt) || (chunkindex < 0)) { + snap = EMPTY; + } + else { + snap = snaparray[chunkindex]; + } + } + break; + case 4: + y--; + if(y < 0) { + type = DynmapBlockState.AIR; + } + break; + case 5: + z--; + bz--; + off-=16; + if(bz == -1) { /* Next chunk? */ + bz = 15; + off += 256; + chunkindex -= x_dim; + if ((chunkindex >= snapcnt) || (chunkindex < 0)) { + snap = EMPTY; + } + else { + snap = snaparray[chunkindex]; + } + } + break; + } + laststep = step; + } + /** + * Unstep current position to previous position + */ + @Override + public BlockStep unstepPosition() { + BlockStep ls = laststep; + stepPosition(unstep[ls.ordinal()]); + return ls; + } + /** + * Unstep current position in oppisite director of given step + */ + @Override + public void unstepPosition(BlockStep s) { + stepPosition(unstep[s.ordinal()]); + } + @Override + public final void setY(int y) { + if(y > this.y) + laststep = BlockStep.Y_PLUS; + else + laststep = BlockStep.Y_MINUS; + this.y = y; + if((y < 0) || (y >= worldheight)) { + type = DynmapBlockState.AIR; + } + else { + type = null; + } + } + @Override + public final int getX() { + return x; + } + @Override + public final int getY() { + return y; + } + @Override + public final int getZ() { + return z; + } + @Override + public final DynmapBlockState getBlockTypeAt(BlockStep s) { + if(s == BlockStep.Y_MINUS) { + if(y > 0) + return snap.getBlockType(bx, y-1, bz); + } + else if(s == BlockStep.Y_PLUS) { + if(y < (worldheight-1)) + return snap.getBlockType(bx, y+1, bz); + } + else { + BlockStep ls = laststep; + stepPosition(s); + DynmapBlockState tid = snap.getBlockType(bx, y, bz); + unstepPosition(); + laststep = ls; + return tid; + } + return DynmapBlockState.AIR; + } + @Override + public BlockStep getLastStep() { + return laststep; + } + @Override + public int getWorldHeight() { + return worldheight; + } + @Override + public long getBlockKey() { + return (((chunkindex * worldheight) + y) << 8) | (bx << 4) | bz; + } + @Override + public final boolean isEmptySection() { + try { + return !isSectionNotEmpty[chunkindex][y >> 4]; + } catch (Exception x) { + initSectionData(chunkindex); + return !isSectionNotEmpty[chunkindex][y >> 4]; + } + } + @Override + public RenderPatchFactory getPatchFactory() { + return HDBlockModels.getPatchDefinitionFactory(); + } + @Override + public Object getBlockTileEntityField(String fieldId) { + try { + int idx = getIndexInChunk(bx,y,bz); + Object[] vals = (Object[])snaptile[chunkindex].get(idx); + for (int i = 0; i < vals.length; i += 2) { + if (vals[i].equals(fieldId)) { + return vals[i+1]; + } + } + } catch (Exception x) { + } + return null; + } + @Override + public DynmapBlockState getBlockTypeAt(int xoff, int yoff, int zoff) { + int xx = this.x + xoff; + int yy = this.y + yoff; + int zz = this.z + zoff; + int idx = ((xx >> 4) - x_min) + (((zz >> 4) - z_min) * x_dim); + try { + return snaparray[idx].getBlockType(xx & 0xF, yy, zz & 0xF); + } catch (Exception x) { + return DynmapBlockState.AIR; + } + } + @Override + public Object getBlockTileEntityFieldAt(String fieldId, int xoff, + int yoff, int zoff) { + return null; + } + @Override + public long getInhabitedTicks() { + try { + return inhabitedTicks[chunkindex]; + } catch (Exception x) { + return 0; + } + } + } + + private class OurEndMapIterator extends OurMapIterator { + + OurEndMapIterator(int x0, int y0, int z0) { + super(x0, y0, z0); + } + @Override + public final int getBlockSkyLight() { + return 15; + } + } + + public interface Snapshot { + 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 int getHighestBlockYAt(int x, int z); + public Biome getBiome(int x, int z); + public double getRawBiomeTemperature(int x, int z); + public double getRawBiomeRainfall(int x, int z); + public boolean isSectionEmpty(int sy); + public Object[] getBiomeBaseFromSnapshot(); + } + + public static class WrappedSnapshot implements Snapshot { + private final ChunkSnapshot ss; + private final DataPaletteBlock[] blockids; + + public WrappedSnapshot(ChunkSnapshot ss) { + this.ss = ss; + blockids = (DataPaletteBlock[]) BukkitVersionHelper.helper.getBlockIDFieldFromSnapshot(ss); + } + public final DynmapBlockState getBlockType(int x, int y, int z) { + return BukkitVersionHelperSpigot113.dataToState.getOrDefault(blockids[y >> 4].a(x & 0xF, y & 0xF, z & 0xF), DynmapBlockState.AIR); + } + public final int getBlockSkyLight(int x, int y, int z) { + return ss.getBlockSkyLight(x, y, z); + } + public final int getBlockEmittedLight(int x, int y, int z) { + return ss.getBlockEmittedLight(x, y, z); + } + public final int getHighestBlockYAt(int x, int z) { + return ss.getHighestBlockYAt(x, z); + } + public final Biome getBiome(int x, int z) { + return ss.getBiome(x, z); + } + public final double getRawBiomeTemperature(int x, int z) { + return ss.getRawBiomeTemperature(x, z); + } + public final double getRawBiomeRainfall(int x, int z) { + return 0.0; + } + public final boolean isSectionEmpty(int sy) { + return ss.isSectionEmpty(sy); + } + public final Object[] getBiomeBaseFromSnapshot() { + return BukkitVersionHelper.helper.getBiomeBaseFromSnapshot(ss); + } + } + + /** + * Chunk cache for representing unloaded chunk (or air) + */ + private static class EmptyChunk implements Snapshot { + public final DynmapBlockState getBlockType(int x, int y, int z) { + return DynmapBlockState.AIR; + } + public final int getBlockSkyLight(int x, int y, int z) { + return 15; + } + public final int getBlockEmittedLight(int x, int y, int z) { + return 0; + } + public final int getHighestBlockYAt(int x, int z) { + return 0; + } + public Biome getBiome(int x, int z) { + return null; + } + public double getRawBiomeTemperature(int x, int z) { + return 0.0; + } + public double getRawBiomeRainfall(int x, int z) { + return 0.0; + } + public boolean isSectionEmpty(int sy) { + return true; + } + public Object[] getBiomeBaseFromSnapshot() { + return new Object[256]; + } + } + + /** + * Chunk cache for representing generic stone chunk + */ + private static class PlainChunk implements Snapshot { + private DynmapBlockState fill; + PlainChunk(String blockname) { this.fill = DynmapBlockState.getBaseStateByName(blockname); } + + public final DynmapBlockState getBlockType(int x, int y, int z) { + return (y < 64) ? fill : DynmapBlockState.AIR; + } + public Biome getBiome(int x, int z) { return null; } + public double getRawBiomeTemperature(int x, int z) { return 0.0; } + public double getRawBiomeRainfall(int x, int z) { return 0.0; } + public final int getBlockSkyLight(int x, int y, int z) { + if(y < 64) + return 0; + return 15; + } + public final int getBlockEmittedLight(int x, int y, int z) { + return 0; + } + public final int getHighestBlockYAt(int x, int z) { + return 64; + } + public boolean isSectionEmpty(int sy) { + return (sy < 4); + } + public Object[] getBiomeBaseFromSnapshot() { + return new Object[256]; + } + } + + private static final EmptyChunk EMPTY = new EmptyChunk(); + private static final PlainChunk STONE = new PlainChunk(DynmapBlockState.STONE_BLOCK); + private static final PlainChunk OCEAN = new PlainChunk(DynmapBlockState.WATER_BLOCK); + + /** + * Construct empty cache + */ + public MapChunkCache113() { + if(!init) { + init = true; + } + } + public void setChunks(BukkitWorld dw, List chunks) { + this.dw = dw; + this.w = dw.getWorld(); + if(this.w == null) { + this.chunks = new ArrayList(); + } + nsect = dw.worldheight >> 4; + this.chunks = chunks; + /* Compute range */ + if(chunks.size() == 0) { + this.x_min = 0; + this.x_max = 0; + this.z_min = 0; + this.z_max = 0; + x_dim = 1; + } + else { + x_min = x_max = chunks.get(0).x; + z_min = z_max = chunks.get(0).z; + for(DynmapChunk c : chunks) { + if(c.x > x_max) + x_max = c.x; + if(c.x < x_min) + x_min = c.x; + if(c.z > z_max) + z_max = c.z; + if(c.z < z_min) + z_min = c.z; + } + x_dim = x_max - x_min + 1; + } + + snapcnt = x_dim * (z_max-z_min+1); + snaparray = new Snapshot[snapcnt]; + inhabitedTicks = new long[snapcnt]; + snaptile = new DynIntHashMap[snapcnt]; + isSectionNotEmpty = new boolean[snapcnt][]; + } + + public int loadChunks(int max_to_load) { + if(dw.isLoaded() == false) + return 0; + Object queue = BukkitVersionHelper.helper.getUnloadQueue(w); + + int cnt = 0; + if(iterator == null) + iterator = chunks.listIterator(); + + DynmapCore.setIgnoreChunkLoads(true); + //boolean isnormral = w.getEnvironment() == Environment.NORMAL; + // 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; + 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 = new WrappedSnapshot(ssr.ss); + } + int idx = (chunk.x-x_min) + (chunk.z - z_min)*x_dim; + snaparray[idx] = ss; + snaptile[idx] = ssr.tileData; + inhabitedTicks[idx] = inhabited_ticks; + + endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT); + continue; + } + boolean wasLoaded = w.isChunkLoaded(chunk.x, chunk.z); + boolean didload = false; + boolean isunloadpending = false; + if (queue != null) { + isunloadpending = BukkitVersionHelper.helper.isInUnloadQueue(queue, chunk.x, chunk.z); + } + if (isunloadpending) { /* Workaround: can't be pending if not loaded */ + wasLoaded = true; + } + try { + didload = w.loadChunk(chunk.x, chunk.z, false); + } catch (Throwable t) { /* Catch chunk error from Bukkit */ + Log.warning("Bukkit error loading chunk " + chunk.x + "," + chunk.z + " on " + w.getName()); + if(!wasLoaded) { /* If wasn't loaded, we loaded it if it now is */ + didload = w.isChunkLoaded(chunk.x, chunk.z); + } + } + /* If it did load, make cache of it */ + if(didload) { + tileData = new DynIntHashMap(); + + Chunk c = w.getChunkAt(chunk.x, chunk.z); /* Get the chunk */ + /* Get inhabited ticks count */ + inhabited_ticks = BukkitVersionHelper.helper.getInhabitedTicks(c); + if(!vis) { + if(hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) + ss = STONE; + else if(hidestyle == HiddenChunkStyle.FILL_OCEAN) + ss = OCEAN; + else + ss = EMPTY; + } + else { + ChunkSnapshot css; + if(blockdata || highesty) { + css = c.getChunkSnapshot(highesty, biome, biomeraw); + ss = new WrappedSnapshot(css); + /* Get tile entity data */ + List vals = new ArrayList(); + Map tileents = BukkitVersionHelper.helper.getTileEntitiesForChunk(c); + for(Object t : tileents.values()) { + int te_x = BukkitVersionHelper.helper.getTileEntityX(t); + int te_y = BukkitVersionHelper.helper.getTileEntityY(t); + int te_z = BukkitVersionHelper.helper.getTileEntityZ(t); + int cx = te_x & 0xF; + int cz = te_z & 0xF; + String[] te_fields = HDBlockModels.getTileEntityFieldsNeeded(ss.getBlockType(cx, te_y, cz)); + if(te_fields != null) { + Object nbtcompound = BukkitVersionHelper.helper.readTileEntityNBT(t); + + vals.clear(); + for(String id: te_fields) { + Object val = BukkitVersionHelper.helper.getFieldValue(nbtcompound, id); + if(val != null) { + vals.add(id); + vals.add(val); + } + } + if(vals.size() > 0) { + Object[] vlist = vals.toArray(new Object[vals.size()]); + tileData.put(getIndexInChunk(cx,te_y,cz), vlist); + } + } + } + } + else { + css = w.getEmptyChunkSnapshot(chunk.x, chunk.z, biome, biomeraw); + ss = new WrappedSnapshot(css); + } + if(ss != null) { + ssr = new SnapshotRec(); + ssr.ss = css; + ssr.inhabitedTicks = inhabited_ticks; + ssr.tileData = tileData; + SnapshotCache.sscache.putSnapshot(dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty); + } + } + int chunkIndex = (chunk.x-x_min) + (chunk.z - z_min)*x_dim; + snaparray[chunkIndex] = ss; + snaptile[chunkIndex] = tileData; + inhabitedTicks[chunkIndex] = inhabited_ticks; + + /* If wasn't loaded before, we need to do unload */ + if (!wasLoaded) { + /* Since we only remember ones we loaded, and we're synchronous, no player has + * moved, so it must be safe (also prevent chunk leak, which appears to happen + * because isChunkInUse defined "in use" as being within 256 blocks of a player, + * while the actual in-use chunk area for a player where the chunks are managed + * by the MC base server is 21x21 (or about a 160 block radius). + * Also, if we did generate it, need to save it */ + if (w.isChunkInUse(chunk.x, chunk.z) == false) { + if (BukkitVersionHelper.helper.isUnloadChunkBroken()) { + // Give up on broken unloadChunk API - lets see if this works + w.unloadChunkRequest(chunk.x, chunk.z); + } + else { + BukkitVersionHelper.helper.unloadChunkNoSave(w, c, chunk.x, chunk.z); + } + } + endChunkLoad(startTime, ChunkStats.UNLOADED_CHUNKS); + } + else if (isunloadpending) { /* Else, if loaded and unload is pending */ + if (w.isChunkInUse(chunk.x, chunk.z) == false) { + w.unloadChunkRequest(chunk.x, chunk.z); /* Request new unload */ + } + endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS); + } + else { + endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS); + } + } + else { + endChunkLoad(startTime, ChunkStats.UNGENERATED_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; + } + /** + * Test if done loading + */ + public boolean isDoneLoading() { + if(dw.isLoaded() == false) { + isempty = true; + unloadChunks(); + return true; + } + if(iterator != null) + return !iterator.hasNext(); + return false; + } + /** + * Test if all empty blocks + */ + public boolean isEmpty() { + return isempty; + } + /** + * Unload chunks + */ + public void unloadChunks() { + if(snaparray != null) { + for(int i = 0; i < snaparray.length; i++) { + snaparray[i] = null; + } + snaparray = null; + inhabitedTicks = null; + } + } + private void initSectionData(int idx) { + isSectionNotEmpty[idx] = new boolean[nsect + 1]; + if(snaparray[idx] != EMPTY) { + for(int i = 0; i < nsect; i++) { + if(snaparray[idx].isSectionEmpty(i) == false) { + isSectionNotEmpty[idx][i] = true; + } + } + } + } + public boolean isEmptySection(int sx, int sy, int sz) { + int idx = (sx - x_min) + (sz - z_min) * x_dim; + if(isSectionNotEmpty[idx] == null) { + initSectionData(idx); + } + return !isSectionNotEmpty[idx][sy]; + } + + /** + * Get cache iterator + */ + public MapIterator getIterator(int x, int y, int z) { + if(w.getEnvironment().toString().equals("THE_END")) + return new OurEndMapIterator(x, y, z); + return new OurMapIterator(x, y, z); + } + /** + * Set hidden chunk style (default is FILL_AIR) + */ + public void setHiddenFillStyle(HiddenChunkStyle style) { + this.hidestyle = style; + } + /** + * Add visible area limit - can be called more than once + * Needs to be set before chunks are loaded + * Coordinates are block coordinates + */ + public void setVisibleRange(VisibilityLimit lim) { + if(visible_limits == null) + visible_limits = new ArrayList(); + visible_limits.add(lim); + } + /** + * Add hidden area limit - can be called more than once + * Needs to be set before chunks are loaded + * Coordinates are block coordinates + */ + public void setHiddenRange(VisibilityLimit lim) { + if(hidden_limits == null) + hidden_limits = new ArrayList(); + hidden_limits.add(lim); + } + @Override + public boolean setChunkDataTypes(boolean blockdata, boolean biome, boolean highestblocky, boolean rawbiome) { + this.biome = biome; + this.biomeraw = rawbiome; + this.highesty = highestblocky; + this.blockdata = blockdata; + return true; + } + @Override + public DynmapWorld getWorld() { + return dw; + } + + static { + Biome[] b = Biome.values(); + BiomeMap[] bm = BiomeMap.values(); + biome_to_bmap = new BiomeMap[1024]; + for(int i = 0; i < biome_to_bmap.length; i++) { + biome_to_bmap[i] = BiomeMap.NULL; + } + for(int i = 0; i < b.length; i++) { + String bs = b[i].toString(); + for(int j = 0; j < bm.length; j++) { + if(bm[j].toString().equals(bs)) { + biome_to_bmap[b[i].ordinal()] = bm[j]; + break; + } + } + } + } +} diff --git a/pom.xml b/pom.xml index ec5bf33a..f50c38d4 100644 --- a/pom.xml +++ b/pom.xml @@ -2,8 +2,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 us.dynmap - dynmap - dynmap + dynmap-bukkit + dynmap-bukkit ${maven.build.timestamp} yyyyMMddHHmm @@ -15,152 +15,11 @@ GitHub https://github.com/webbukkit/dynmap/issues - - - - src/main/resources - true - - *.yml - *.txt - - - - src/main/resources - false - - *.yml - *.txt - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 2.0.2 - - 1.8 - 1.8 - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.0.0 - - - - org.bstats:* - us.dynmap:dynmap-api:jar:* - us.dynmap:DynmapCore:jar:* - - - - - org.bstats - org.dynmap - - - - - - package - - shade - - - - - - org.apache.maven.plugins - maven-source-plugin - 2.2.1 - - - attach-sources - - jar - - - - - - - - - - - - - - dynmap-repo - http://repo.mikeprimm.com/ - - - bstats-repo - http://repo.bstats.org/content/repositories/releases/ - - - - - com.nijikokun.bukkit - Permissions - 3.1.6 - - - org.bukkit - bukkit - 1.7.10-R0.1-SNAPSHOT - - - us.dynmap - dynmap-api - ${project.version} - - - - us.dynmap - DynmapCore - ${project.version} - - - ru.tehkode - PermissionsEx - 1.19.1 - - - de.bananaco - bPermissions - 2.9.1 - - - com.platymuus.bukkit.permissions - PermissionsBukkit - 1.6 - - - org.anjocaido - EssentialsGroupManager - 2.10.1 - - - org.bstats - bstats-bukkit - 1.1 - - - com.googlecode.json-simple - json-simple - 1.1.1 - - - - com.google.code.gson - gson - 2.8.2 - - + pom + + core + helper113 + helper + 3.0-SNAPSHOT From 6a4554f44cd671c5d3986863443ea889cdade83e Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Thu, 9 Aug 2018 02:54:48 -0500 Subject: [PATCH 04/50] More 1.13 fixes, optimizations --- .../bukkit/helper/v113/MapChunkCache113.java | 49 ++++++++++++------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/helper113/src/main/java/org/dynmap/bukkit/helper/v113/MapChunkCache113.java b/helper113/src/main/java/org/dynmap/bukkit/helper/v113/MapChunkCache113.java index f6a9a250..7930cda5 100644 --- a/helper113/src/main/java/org/dynmap/bukkit/helper/v113/MapChunkCache113.java +++ b/helper113/src/main/java/org/dynmap/bukkit/helper/v113/MapChunkCache113.java @@ -362,6 +362,7 @@ public class MapChunkCache113 extends MapChunkCache { mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); } } catch (Exception x) { + Log.warning("Water colormult exception", x); mult = 0xFFFFFF; } return mult; @@ -597,8 +598,6 @@ public class MapChunkCache113 extends MapChunkCache { public int getBlockEmittedLight(int x, int y, int z); public int getHighestBlockYAt(int x, int z); public Biome getBiome(int x, int z); - public double getRawBiomeTemperature(int x, int z); - public double getRawBiomeRainfall(int x, int z); public boolean isSectionEmpty(int sy); public Object[] getBiomeBaseFromSnapshot(); } @@ -606,35 +605,44 @@ public class MapChunkCache113 extends MapChunkCache { public static class WrappedSnapshot implements Snapshot { private final ChunkSnapshot ss; private final DataPaletteBlock[] blockids; - + private final int sectionmask; public WrappedSnapshot(ChunkSnapshot ss) { this.ss = ss; blockids = (DataPaletteBlock[]) BukkitVersionHelper.helper.getBlockIDFieldFromSnapshot(ss); + int mask = 0; + for (int i = 0; i < blockids.length; i++) { + if (ss.isSectionEmpty(i)) + mask |= (1 << i); + } + sectionmask = mask; } + @Override public final DynmapBlockState getBlockType(int x, int y, int z) { + if ((sectionmask & (1 << (y >> 4))) != 0) + return DynmapBlockState.AIR; return BukkitVersionHelperSpigot113.dataToState.getOrDefault(blockids[y >> 4].a(x & 0xF, y & 0xF, z & 0xF), DynmapBlockState.AIR); } + @Override public final int getBlockSkyLight(int x, int y, int z) { return ss.getBlockSkyLight(x, y, z); } + @Override public final int getBlockEmittedLight(int x, int y, int z) { return ss.getBlockEmittedLight(x, y, z); } + @Override public final int getHighestBlockYAt(int x, int z) { return ss.getHighestBlockYAt(x, z); } + @Override public final Biome getBiome(int x, int z) { return ss.getBiome(x, z); } - public final double getRawBiomeTemperature(int x, int z) { - return ss.getRawBiomeTemperature(x, z); - } - public final double getRawBiomeRainfall(int x, int z) { - return 0.0; - } + @Override public final boolean isSectionEmpty(int sy) { - return ss.isSectionEmpty(sy); + return (sectionmask & (1 << sy)) != 0; } + @Override public final Object[] getBiomeBaseFromSnapshot() { return BukkitVersionHelper.helper.getBiomeBaseFromSnapshot(ss); } @@ -647,27 +655,27 @@ public class MapChunkCache113 extends MapChunkCache { public final DynmapBlockState getBlockType(int x, int y, int z) { return DynmapBlockState.AIR; } + @Override public final int getBlockSkyLight(int x, int y, int z) { return 15; } + @Override public final int getBlockEmittedLight(int x, int y, int z) { return 0; } + @Override public final int getHighestBlockYAt(int x, int z) { return 0; } + @Override public Biome getBiome(int x, int z) { return null; } - public double getRawBiomeTemperature(int x, int z) { - return 0.0; - } - public double getRawBiomeRainfall(int x, int z) { - return 0.0; - } + @Override public boolean isSectionEmpty(int sy) { return true; } + @Override public Object[] getBiomeBaseFromSnapshot() { return new Object[256]; } @@ -680,26 +688,31 @@ public class MapChunkCache113 extends MapChunkCache { private DynmapBlockState fill; PlainChunk(String blockname) { this.fill = DynmapBlockState.getBaseStateByName(blockname); } + @Override public final DynmapBlockState getBlockType(int x, int y, int z) { return (y < 64) ? fill : DynmapBlockState.AIR; } + @Override public Biome getBiome(int x, int z) { return null; } - public double getRawBiomeTemperature(int x, int z) { return 0.0; } - public double getRawBiomeRainfall(int x, int z) { return 0.0; } + @Override public final int getBlockSkyLight(int x, int y, int z) { if(y < 64) return 0; return 15; } + @Override public final int getBlockEmittedLight(int x, int y, int z) { return 0; } + @Override public final int getHighestBlockYAt(int x, int z) { return 64; } + @Override public boolean isSectionEmpty(int sy) { return (sy < 4); } + @Override public Object[] getBiomeBaseFromSnapshot() { return new Object[256]; } From d5160dcaf6e44353e76140505c5e918ca09f1818 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Fri, 10 Aug 2018 01:03:38 -0500 Subject: [PATCH 05/50] Consolidate 1.13 vs classic ChunkCache code --- .../bukkit/helper/AbstractMapChunkCache.java | 1033 +++++++++++++++++ .../bukkit/helper/BukkitVersionHelper.java | 2 +- .../bukkit/helper/MapChunkCacheClassic.java | 89 ++ .../bukkit/helper/v113/MapChunkCache113.java | 1021 +--------------- 4 files changed, 1129 insertions(+), 1016 deletions(-) create mode 100644 helper/src/main/java/org/dynmap/bukkit/helper/AbstractMapChunkCache.java create mode 100644 helper/src/main/java/org/dynmap/bukkit/helper/MapChunkCacheClassic.java diff --git a/helper/src/main/java/org/dynmap/bukkit/helper/AbstractMapChunkCache.java b/helper/src/main/java/org/dynmap/bukkit/helper/AbstractMapChunkCache.java new file mode 100644 index 00000000..a00e97d1 --- /dev/null +++ b/helper/src/main/java/org/dynmap/bukkit/helper/AbstractMapChunkCache.java @@ -0,0 +1,1033 @@ +package org.dynmap.bukkit.helper; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +import org.bukkit.World; +import org.bukkit.Chunk; +import org.bukkit.block.Biome; +import org.bukkit.ChunkSnapshot; +import org.dynmap.DynmapChunk; +import org.dynmap.DynmapCore; +import org.dynmap.DynmapWorld; +import org.dynmap.Log; +import org.dynmap.bukkit.helper.BukkitVersionHelper; +import org.dynmap.bukkit.helper.BukkitWorld; +import org.dynmap.bukkit.helper.SnapshotCache; +import org.dynmap.bukkit.helper.SnapshotCache.SnapshotRec; +import org.dynmap.common.BiomeMap; +import org.dynmap.hdmap.HDBlockModels; +import org.dynmap.renderer.DynmapBlockState; +import org.dynmap.renderer.RenderPatchFactory; +import org.dynmap.utils.DynIntHashMap; +import org.dynmap.utils.MapChunkCache; +import org.dynmap.utils.MapIterator; +import org.dynmap.utils.BlockStep; +import org.dynmap.utils.VisibilityLimit; + +/** + * Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread + */ +public abstract class AbstractMapChunkCache extends MapChunkCache { + // Reduced interface for snapshots + public interface Snapshot { + 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 int getHighestBlockYAt(int x, int z); + public Biome getBiome(int x, int z); + public boolean isSectionEmpty(int sy); + public Object[] getBiomeBaseFromSnapshot(); + } + + private static boolean init = false; + + private World w; + private DynmapWorld dw; + private int nsect; + private List chunks; + private ListIterator iterator; + private int x_min, x_max, z_min, z_max; + private int x_dim; + private boolean biome, biomeraw, highesty, blockdata; + private HiddenChunkStyle hidestyle = HiddenChunkStyle.FILL_AIR; + private List visible_limits = null; + private List hidden_limits = null; + private boolean isempty = true; + private int snapcnt; + private Snapshot[] snaparray; /* Index = (x-x_min) + ((z-z_min)*x_dim) */ + private DynIntHashMap[] snaptile; + private byte[][] sameneighborbiomecnt; + private BiomeMap[][] biomemap; + private boolean[][] isSectionNotEmpty; /* Indexed by snapshot index, then by section index */ + private long[] inhabitedTicks; /* Index = (x-x_min) + ((z-z_min)*x_dim) */ + private static final BiomeMap[] nullBiomeMap = { BiomeMap.NULL }; + + private static final BlockStep unstep[] = { BlockStep.X_MINUS, BlockStep.Y_MINUS, BlockStep.Z_MINUS, + BlockStep.X_PLUS, BlockStep.Y_PLUS, BlockStep.Z_PLUS }; + + private static BiomeMap[] biome_to_bmap; + + private static final int getIndexInChunk(int cx, int cy, int cz) { + return (cy << 8) | (cz << 4) | cx; + } + + /** + * Iterator for traversing map chunk cache (base is for non-snapshot) + */ + public class BasetMapIterator implements MapIterator { + @SuppressWarnings("unused") + private int x, y, z, chunkindex, bx, bz, off; + private Snapshot snap; + private BlockStep laststep; + private DynmapBlockState type = null; + private final int worldheight; + private final int x_base; + private final int z_base; + + BasetMapIterator(int x0, int y0, int z0) { + x_base = x_min << 4; + z_base = z_min << 4; + if(biome) + biomePrep(); + initialize(x0, y0, z0); + worldheight = w.getMaxHeight(); + } + + @Override + public final void initialize(int x0, int y0, int z0) { + this.x = x0; + this.y = y0; + this.z = z0; + this.chunkindex = ((x >> 4) - x_min) + (((z >> 4) - z_min) * x_dim); + this.bx = x & 0xF; + this.bz = z & 0xF; + this.off = bx + (bz << 4); + if ((chunkindex >= snapcnt) || (chunkindex < 0)) { + snap = EMPTY; + } + else { + snap = snaparray[chunkindex]; + } + laststep = BlockStep.Y_MINUS; + if((y >= 0) && (y < worldheight)) + type = null; + else + type = DynmapBlockState.AIR; + } + + @Override + public final DynmapBlockState getBlockType() { + if (type == null) { + type = snap.getBlockType(bx, y, bz); + } + return type; + } + @Override + public int getBlockSkyLight() { + try { + return snap.getBlockSkyLight(bx, y, bz); + } catch (ArrayIndexOutOfBoundsException aioobx) { + return 15; + } + } + @Override + public final int getBlockEmittedLight() { + try { + return snap.getBlockEmittedLight(bx, y, bz); + } catch (ArrayIndexOutOfBoundsException aioobx) { + return 0; + } + } + 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]; + } + Snapshot last_css = null; + Object[] biomebase = null; + for(int i = 0; i < x_size; i++) { + for(int j = 0; j < z_size; j++) { + BiomeMap bm; + if (j == 0) { + initialize(i + x_base, 64, z_base); + } + else { + stepPosition(BlockStep.Z_PLUS); + } + if (last_css != snap) { + if ((snap instanceof EmptyChunk) || (snap instanceof PlainChunk)) { + biomebase = nullBiomeMap; + } + else { + biomebase = snap.getBiomeBaseFromSnapshot(); + } + last_css = snap; + } + if (biomebase == nullBiomeMap) { + bm = BiomeMap.NULL; + } + else if(biomebase != null) { + bm = BiomeMap.byBiomeID(BukkitVersionHelper.helper.getBiomeBaseID(biomebase[bz << 4 | bx])); + } + else { + Biome bb = snap.getBiome(bx, bz); + if(bb == null) + bm = BiomeMap.NULL; + else + bm = biome_to_bmap[bb.ordinal()]; + } + 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]; + } catch (Exception ex) { + return BiomeMap.NULL; + } + } + @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 rmult = bm.getModifiedGrassMultiplier(colormap[bm.biomeLookup()]); + raccum += (rmult >> 16) & 0xFF; + gaccum += (rmult >> 8) & 0xFF; + baccum += rmult & 0xFF; + } + } + mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); + } + } catch (Exception x) { + mult = 0xFFFFFF; + } + return mult; + } + @Override + public final int getSmoothFoliageColorMultiplier(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.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 rmult = bm.getModifiedFoliageMultiplier(colormap[bm.biomeLookup()]); + raccum += (rmult >> 16) & 0xFF; + gaccum += (rmult >> 8) & 0xFF; + baccum += rmult & 0xFF; + } + } + mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); + } + } catch (Exception x) { + mult = 0xFFFFFF; + } + return mult; + } + @Override + public final int getSmoothColorMultiplier(int[] colormap, int[] swampmap) { + 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 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; + } + } + mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); + } + } catch (Exception x) { + mult = 0xFFFFFF; + } + return mult; + } + @Override + public final int getSmoothWaterColorMultiplier() { + 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? */ + return bm.getWaterColorMult(); + } + 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; + } + } + return ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); + } catch (Exception x) { + return 0xFFFFFF; + } + } + @Override + public final int getSmoothWaterColorMultiplier(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 = 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 rmult = colormap[bm.biomeLookup()]; + raccum += (rmult >> 16) & 0xFF; + gaccum += (rmult >> 8) & 0xFF; + baccum += rmult & 0xFF; + } + } + mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); + } + } catch (Exception x) { + Log.warning("Water colormult exception", x); + mult = 0xFFFFFF; + } + return mult; + } + /** + * Step current position in given direction + */ + @Override + public final void stepPosition(BlockStep step) { + type = null; + switch(step.ordinal()) { + case 0: + x++; + bx++; + off++; + if(bx == 16) { /* Next chunk? */ + bx = 0; + off -= 16; + chunkindex++; + if ((chunkindex >= snapcnt) || (chunkindex < 0)) { + snap = EMPTY; + } + else { + snap = snaparray[chunkindex]; + } + } + break; + case 1: + y++; + if(y >= worldheight) { + type = DynmapBlockState.AIR; + } + break; + case 2: + z++; + bz++; + off+=16; + if(bz == 16) { /* Next chunk? */ + bz = 0; + off -= 256; + chunkindex += x_dim; + if ((chunkindex >= snapcnt) || (chunkindex < 0)) { + snap = EMPTY; + } + else { + snap = snaparray[chunkindex]; + } + } + break; + case 3: + x--; + bx--; + off--; + if(bx == -1) { /* Next chunk? */ + bx = 15; + off += 16; + chunkindex--; + if ((chunkindex >= snapcnt) || (chunkindex < 0)) { + snap = EMPTY; + } + else { + snap = snaparray[chunkindex]; + } + } + break; + case 4: + y--; + if(y < 0) { + type = DynmapBlockState.AIR; + } + break; + case 5: + z--; + bz--; + off-=16; + if(bz == -1) { /* Next chunk? */ + bz = 15; + off += 256; + chunkindex -= x_dim; + if ((chunkindex >= snapcnt) || (chunkindex < 0)) { + snap = EMPTY; + } + else { + snap = snaparray[chunkindex]; + } + } + break; + } + laststep = step; + } + /** + * Unstep current position to previous position + */ + @Override + public BlockStep unstepPosition() { + BlockStep ls = laststep; + stepPosition(unstep[ls.ordinal()]); + return ls; + } + /** + * Unstep current position in oppisite director of given step + */ + @Override + public void unstepPosition(BlockStep s) { + stepPosition(unstep[s.ordinal()]); + } + @Override + public final void setY(int y) { + if(y > this.y) + laststep = BlockStep.Y_PLUS; + else + laststep = BlockStep.Y_MINUS; + this.y = y; + if((y < 0) || (y >= worldheight)) { + type = DynmapBlockState.AIR; + } + else { + type = null; + } + } + @Override + public final int getX() { + return x; + } + @Override + public final int getY() { + return y; + } + @Override + public final int getZ() { + return z; + } + @Override + public final DynmapBlockState getBlockTypeAt(BlockStep s) { + if(s == BlockStep.Y_MINUS) { + if(y > 0) + return snap.getBlockType(bx, y-1, bz); + } + else if(s == BlockStep.Y_PLUS) { + if(y < (worldheight-1)) + return snap.getBlockType(bx, y+1, bz); + } + else { + BlockStep ls = laststep; + stepPosition(s); + DynmapBlockState tid = snap.getBlockType(bx, y, bz); + unstepPosition(); + laststep = ls; + return tid; + } + return DynmapBlockState.AIR; + } + @Override + public BlockStep getLastStep() { + return laststep; + } + @Override + public int getWorldHeight() { + return worldheight; + } + @Override + public long getBlockKey() { + return (((chunkindex * worldheight) + y) << 8) | (bx << 4) | bz; + } + @Override + public final boolean isEmptySection() { + try { + return !isSectionNotEmpty[chunkindex][y >> 4]; + } catch (Exception x) { + initSectionData(chunkindex); + return !isSectionNotEmpty[chunkindex][y >> 4]; + } + } + @Override + public RenderPatchFactory getPatchFactory() { + return HDBlockModels.getPatchDefinitionFactory(); + } + @Override + public Object getBlockTileEntityField(String fieldId) { + try { + int idx = getIndexInChunk(bx,y,bz); + Object[] vals = (Object[])snaptile[chunkindex].get(idx); + for (int i = 0; i < vals.length; i += 2) { + if (vals[i].equals(fieldId)) { + return vals[i+1]; + } + } + } catch (Exception x) { + } + return null; + } + @Override + public DynmapBlockState getBlockTypeAt(int xoff, int yoff, int zoff) { + int xx = this.x + xoff; + int yy = this.y + yoff; + int zz = this.z + zoff; + int idx = ((xx >> 4) - x_min) + (((zz >> 4) - z_min) * x_dim); + try { + return snaparray[idx].getBlockType(xx & 0xF, yy, zz & 0xF); + } catch (Exception x) { + return DynmapBlockState.AIR; + } + } + @Override + public Object getBlockTileEntityFieldAt(String fieldId, int xoff, + int yoff, int zoff) { + return null; + } + @Override + public long getInhabitedTicks() { + try { + return inhabitedTicks[chunkindex]; + } catch (Exception x) { + return 0; + } + } + } + + // Special iterator for END : forces skylight to 15 + private class OurEndMapIterator extends BasetMapIterator { + + OurEndMapIterator(int x0, int y0, int z0) { + super(x0, y0, z0); + } + @Override + public final int getBlockSkyLight() { + return 15; + } + } + + /** + * Chunk cache for representing unloaded chunk (or air) + */ + private static class EmptyChunk implements Snapshot { + public final DynmapBlockState getBlockType(int x, int y, int z) { + return DynmapBlockState.AIR; + } + @Override + public final int getBlockSkyLight(int x, int y, int z) { + return 15; + } + @Override + public final int getBlockEmittedLight(int x, int y, int z) { + return 0; + } + @Override + public final int getHighestBlockYAt(int x, int z) { + return 0; + } + @Override + public Biome getBiome(int x, int z) { + return null; + } + @Override + public boolean isSectionEmpty(int sy) { + return true; + } + @Override + public Object[] getBiomeBaseFromSnapshot() { + return new Object[256]; + } + } + + /** + * Chunk cache for representing generic stone chunk + */ + private static class PlainChunk implements Snapshot { + private DynmapBlockState fill; + PlainChunk(String blockname) { this.fill = DynmapBlockState.getBaseStateByName(blockname); } + + @Override + public final DynmapBlockState getBlockType(int x, int y, int z) { + return (y < 64) ? fill : DynmapBlockState.AIR; + } + @Override + public Biome getBiome(int x, int z) { return null; } + @Override + public final int getBlockSkyLight(int x, int y, int z) { + if(y < 64) + return 0; + return 15; + } + @Override + public final int getBlockEmittedLight(int x, int y, int z) { + return 0; + } + @Override + public final int getHighestBlockYAt(int x, int z) { + return 64; + } + @Override + public boolean isSectionEmpty(int sy) { + return (sy < 4); + } + @Override + public Object[] getBiomeBaseFromSnapshot() { + return new Object[256]; + } + } + + // Well known choices for hidden/empty chunks + private static final EmptyChunk EMPTY = new EmptyChunk(); + private static final PlainChunk STONE = new PlainChunk(DynmapBlockState.STONE_BLOCK); + private static final PlainChunk OCEAN = new PlainChunk(DynmapBlockState.WATER_BLOCK); + + /** + * Construct empty cache + */ + public AbstractMapChunkCache() { + if(!init) { + init = true; + } + } + + public void setChunks(BukkitWorld dw, List chunks) { + this.dw = dw; + this.w = dw.getWorld(); + if(this.w == null) { + this.chunks = new ArrayList(); + } + nsect = dw.worldheight >> 4; + this.chunks = chunks; + /* Compute range */ + if(chunks.size() == 0) { + this.x_min = 0; + this.x_max = 0; + this.z_min = 0; + this.z_max = 0; + x_dim = 1; + } + else { + x_min = x_max = chunks.get(0).x; + z_min = z_max = chunks.get(0).z; + for(DynmapChunk c : chunks) { + if(c.x > x_max) + x_max = c.x; + if(c.x < x_min) + x_min = c.x; + if(c.z > z_max) + z_max = c.z; + if(c.z < z_min) + z_min = c.z; + } + x_dim = x_max - x_min + 1; + } + + snapcnt = x_dim * (z_max-z_min+1); + snaparray = new Snapshot[snapcnt]; + inhabitedTicks = new long[snapcnt]; + snaptile = new DynIntHashMap[snapcnt]; + isSectionNotEmpty = new boolean[snapcnt][]; + } + + public abstract Snapshot wrapChunkSnapshot(ChunkSnapshot css); + + // Load chunk snapshots + public int loadChunks(int max_to_load) { + if(dw.isLoaded() == false) + return 0; + Object queue = BukkitVersionHelper.helper.getUnloadQueue(w); + + int cnt = 0; + if(iterator == null) + iterator = chunks.listIterator(); + + DynmapCore.setIgnoreChunkLoads(true); + //boolean isnormral = w.getEnvironment() == Environment.NORMAL; + // 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; + 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 = wrapChunkSnapshot(ssr.ss); + } + int idx = (chunk.x-x_min) + (chunk.z - z_min)*x_dim; + snaparray[idx] = ss; + snaptile[idx] = ssr.tileData; + inhabitedTicks[idx] = inhabited_ticks; + + endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT); + continue; + } + boolean wasLoaded = w.isChunkLoaded(chunk.x, chunk.z); + boolean didload = false; + boolean isunloadpending = false; + if (queue != null) { + isunloadpending = BukkitVersionHelper.helper.isInUnloadQueue(queue, chunk.x, chunk.z); + } + if (isunloadpending) { /* Workaround: can't be pending if not loaded */ + wasLoaded = true; + } + try { + didload = w.loadChunk(chunk.x, chunk.z, false); + } catch (Throwable t) { /* Catch chunk error from Bukkit */ + Log.warning("Bukkit error loading chunk " + chunk.x + "," + chunk.z + " on " + w.getName()); + if(!wasLoaded) { /* If wasn't loaded, we loaded it if it now is */ + didload = w.isChunkLoaded(chunk.x, chunk.z); + } + } + /* If it did load, make cache of it */ + if(didload) { + tileData = new DynIntHashMap(); + + Chunk c = w.getChunkAt(chunk.x, chunk.z); /* Get the chunk */ + /* Get inhabited ticks count */ + inhabited_ticks = BukkitVersionHelper.helper.getInhabitedTicks(c); + if(!vis) { + if(hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) + ss = STONE; + else if(hidestyle == HiddenChunkStyle.FILL_OCEAN) + ss = OCEAN; + else + ss = EMPTY; + } + else { + ChunkSnapshot css; + if(blockdata || highesty) { + css = c.getChunkSnapshot(highesty, biome, biomeraw); + ss = wrapChunkSnapshot(css); + /* Get tile entity data */ + List vals = new ArrayList(); + Map tileents = BukkitVersionHelper.helper.getTileEntitiesForChunk(c); + for(Object t : tileents.values()) { + int te_x = BukkitVersionHelper.helper.getTileEntityX(t); + int te_y = BukkitVersionHelper.helper.getTileEntityY(t); + int te_z = BukkitVersionHelper.helper.getTileEntityZ(t); + int cx = te_x & 0xF; + int cz = te_z & 0xF; + String[] te_fields = HDBlockModels.getTileEntityFieldsNeeded(ss.getBlockType(cx, te_y, cz)); + if(te_fields != null) { + Object nbtcompound = BukkitVersionHelper.helper.readTileEntityNBT(t); + + vals.clear(); + for(String id: te_fields) { + Object val = BukkitVersionHelper.helper.getFieldValue(nbtcompound, id); + if(val != null) { + vals.add(id); + vals.add(val); + } + } + if(vals.size() > 0) { + Object[] vlist = vals.toArray(new Object[vals.size()]); + tileData.put(getIndexInChunk(cx,te_y,cz), vlist); + } + } + } + } + else { + css = w.getEmptyChunkSnapshot(chunk.x, chunk.z, biome, biomeraw); + ss = wrapChunkSnapshot(css); + } + if(ss != null) { + ssr = new SnapshotRec(); + ssr.ss = css; + ssr.inhabitedTicks = inhabited_ticks; + ssr.tileData = tileData; + SnapshotCache.sscache.putSnapshot(dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty); + } + } + int chunkIndex = (chunk.x-x_min) + (chunk.z - z_min)*x_dim; + snaparray[chunkIndex] = ss; + snaptile[chunkIndex] = tileData; + inhabitedTicks[chunkIndex] = inhabited_ticks; + + /* If wasn't loaded before, we need to do unload */ + if (!wasLoaded) { + /* Since we only remember ones we loaded, and we're synchronous, no player has + * moved, so it must be safe (also prevent chunk leak, which appears to happen + * because isChunkInUse defined "in use" as being within 256 blocks of a player, + * while the actual in-use chunk area for a player where the chunks are managed + * by the MC base server is 21x21 (or about a 160 block radius). + * Also, if we did generate it, need to save it */ + if (w.isChunkInUse(chunk.x, chunk.z) == false) { + if (BukkitVersionHelper.helper.isUnloadChunkBroken()) { + // Give up on broken unloadChunk API - lets see if this works + w.unloadChunkRequest(chunk.x, chunk.z); + } + else { + BukkitVersionHelper.helper.unloadChunkNoSave(w, c, chunk.x, chunk.z); + } + } + endChunkLoad(startTime, ChunkStats.UNLOADED_CHUNKS); + } + else if (isunloadpending) { /* Else, if loaded and unload is pending */ + if (w.isChunkInUse(chunk.x, chunk.z) == false) { + w.unloadChunkRequest(chunk.x, chunk.z); /* Request new unload */ + } + endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS); + } + else { + endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS); + } + } + else { + endChunkLoad(startTime, ChunkStats.UNGENERATED_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; + } + /** + * Test if done loading + */ + public boolean isDoneLoading() { + if(dw.isLoaded() == false) { + isempty = true; + unloadChunks(); + return true; + } + if(iterator != null) + return !iterator.hasNext(); + return false; + } + /** + * Test if all empty blocks + */ + public boolean isEmpty() { + return isempty; + } + /** + * Unload chunks + */ + public void unloadChunks() { + if(snaparray != null) { + for(int i = 0; i < snaparray.length; i++) { + snaparray[i] = null; + } + snaparray = null; + inhabitedTicks = null; + } + } + private void initSectionData(int idx) { + isSectionNotEmpty[idx] = new boolean[nsect + 1]; + if(snaparray[idx] != EMPTY) { + for(int i = 0; i < nsect; i++) { + if(snaparray[idx].isSectionEmpty(i) == false) { + isSectionNotEmpty[idx][i] = true; + } + } + } + } + public boolean isEmptySection(int sx, int sy, int sz) { + int idx = (sx - x_min) + (sz - z_min) * x_dim; + if(isSectionNotEmpty[idx] == null) { + initSectionData(idx); + } + return !isSectionNotEmpty[idx][sy]; + } + + /** + * Get cache iterator + */ + public MapIterator getIterator(int x, int y, int z) { + if(w.getEnvironment().toString().equals("THE_END")) + return new OurEndMapIterator(x, y, z); + return new BasetMapIterator(x, y, z); + } + /** + * Set hidden chunk style (default is FILL_AIR) + */ + public void setHiddenFillStyle(HiddenChunkStyle style) { + this.hidestyle = style; + } + /** + * Add visible area limit - can be called more than once + * Needs to be set before chunks are loaded + * Coordinates are block coordinates + */ + public void setVisibleRange(VisibilityLimit lim) { + if(visible_limits == null) + visible_limits = new ArrayList(); + visible_limits.add(lim); + } + /** + * Add hidden area limit - can be called more than once + * Needs to be set before chunks are loaded + * Coordinates are block coordinates + */ + public void setHiddenRange(VisibilityLimit lim) { + if(hidden_limits == null) + hidden_limits = new ArrayList(); + hidden_limits.add(lim); + } + @Override + public boolean setChunkDataTypes(boolean blockdata, boolean biome, boolean highestblocky, boolean rawbiome) { + this.biome = biome; + this.biomeraw = rawbiome; + this.highesty = highestblocky; + this.blockdata = blockdata; + return true; + } + @Override + public DynmapWorld getWorld() { + return dw; + } + + static { + Biome[] b = Biome.values(); + BiomeMap[] bm = BiomeMap.values(); + biome_to_bmap = new BiomeMap[1024]; + for(int i = 0; i < biome_to_bmap.length; i++) { + biome_to_bmap[i] = BiomeMap.NULL; + } + for(int i = 0; i < b.length; i++) { + String bs = b[i].toString(); + for(int j = 0; j < bm.length; j++) { + if(bm[j].toString().equals(bs)) { + biome_to_bmap[b[i].ordinal()] = bm[j]; + break; + } + } + } + } +} diff --git a/helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelper.java b/helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelper.java index ce3b828f..803d30bc 100644 --- a/helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelper.java +++ b/helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelper.java @@ -162,7 +162,7 @@ public abstract class BukkitVersionHelper { * @return cache */ public MapChunkCache getChunkCache(BukkitWorld dw, List chunks) { - NewMapChunkCache c = new NewMapChunkCache(); + AbstractMapChunkCache c = new MapChunkCacheClassic(); c.setChunks(dw, chunks); return c; } diff --git a/helper/src/main/java/org/dynmap/bukkit/helper/MapChunkCacheClassic.java b/helper/src/main/java/org/dynmap/bukkit/helper/MapChunkCacheClassic.java new file mode 100644 index 00000000..3fb0e4fc --- /dev/null +++ b/helper/src/main/java/org/dynmap/bukkit/helper/MapChunkCacheClassic.java @@ -0,0 +1,89 @@ +package org.dynmap.bukkit.helper; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +import org.bukkit.World; +import org.bukkit.Chunk; +import org.bukkit.block.Biome; +import org.bukkit.ChunkSnapshot; +import org.dynmap.DynmapChunk; +import org.dynmap.DynmapCore; +import org.dynmap.DynmapWorld; +import org.dynmap.Log; +import org.dynmap.bukkit.helper.AbstractMapChunkCache.Snapshot; +import org.dynmap.bukkit.helper.SnapshotCache.SnapshotRec; +import org.dynmap.common.BiomeMap; +import org.dynmap.hdmap.HDBlockModels; +import org.dynmap.renderer.DynmapBlockState; +import org.dynmap.renderer.RenderPatchFactory; +import org.dynmap.utils.DynIntHashMap; +import org.dynmap.utils.MapChunkCache; +import org.dynmap.utils.MapIterator; +import org.dynmap.utils.BlockStep; +import org.dynmap.utils.VisibilityLimit; + +/** + * Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread + */ +public class MapChunkCacheClassic extends AbstractMapChunkCache { + + public static class WrappedSnapshot implements Snapshot { + private final ChunkSnapshot ss; + private final int sectionmask; + public WrappedSnapshot(ChunkSnapshot ss) { + this.ss = ss; + int mask = 0; + for (int i = 0; i < 16; i++) { + if (ss.isSectionEmpty(i)) + mask |= (1 << i); + } + sectionmask = mask; + } + @Override + public final DynmapBlockState getBlockType(int x, int y, int z) { + if ((sectionmask & (1 << (y >> 4))) != 0) + return DynmapBlockState.AIR; + return BukkitVersionHelper.stateByID[(ss.getBlockTypeId(x, y, z) << 4) | ss.getBlockData(x, y, z)]; + } + @Override + public final int getBlockSkyLight(int x, int y, int z) { + return ss.getBlockSkyLight(x, y, z); + } + @Override + public final int getBlockEmittedLight(int x, int y, int z) { + return ss.getBlockEmittedLight(x, y, z); + } + @Override + public final int getHighestBlockYAt(int x, int z) { + return ss.getHighestBlockYAt(x, z); + } + @Override + public final Biome getBiome(int x, int z) { + return ss.getBiome(x, z); + } + @Override + public final boolean isSectionEmpty(int sy) { + return (sectionmask & (1 << sy)) != 0; + } + @Override + public final Object[] getBiomeBaseFromSnapshot() { + return BukkitVersionHelper.helper.getBiomeBaseFromSnapshot(ss); + } + } + + /** + * Construct empty cache + */ + public MapChunkCacheClassic() { + + } + + @Override + public Snapshot wrapChunkSnapshot(ChunkSnapshot css) { + return new WrappedSnapshot(css); + } + +} diff --git a/helper113/src/main/java/org/dynmap/bukkit/helper/v113/MapChunkCache113.java b/helper113/src/main/java/org/dynmap/bukkit/helper/v113/MapChunkCache113.java index 7930cda5..3570b2ff 100644 --- a/helper113/src/main/java/org/dynmap/bukkit/helper/v113/MapChunkCache113.java +++ b/helper113/src/main/java/org/dynmap/bukkit/helper/v113/MapChunkCache113.java @@ -1,606 +1,17 @@ package org.dynmap.bukkit.helper.v113; -import java.util.ArrayList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import org.bukkit.World; -import org.bukkit.Chunk; import org.bukkit.block.Biome; import org.bukkit.ChunkSnapshot; -import org.dynmap.DynmapChunk; -import org.dynmap.DynmapCore; -import org.dynmap.DynmapWorld; -import org.dynmap.Log; +import org.dynmap.bukkit.helper.AbstractMapChunkCache; import org.dynmap.bukkit.helper.BukkitVersionHelper; -import org.dynmap.bukkit.helper.BukkitWorld; -import org.dynmap.bukkit.helper.SnapshotCache; -import org.dynmap.bukkit.helper.SnapshotCache.SnapshotRec; -import org.dynmap.common.BiomeMap; -import org.dynmap.hdmap.HDBlockModels; import org.dynmap.renderer.DynmapBlockState; -import org.dynmap.renderer.RenderPatchFactory; -import org.dynmap.utils.DynIntHashMap; -import org.dynmap.utils.MapChunkCache; -import org.dynmap.utils.MapIterator; -import org.dynmap.utils.BlockStep; -import org.dynmap.utils.VisibilityLimit; import net.minecraft.server.v1_13_R1.DataPaletteBlock; -import net.minecraft.server.v1_13_R1.IBlockData; /** * Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread */ -public class MapChunkCache113 extends MapChunkCache { - private static boolean init = false; - - private World w; - private DynmapWorld dw; - private int nsect; - private List chunks; - private ListIterator iterator; - private int x_min, x_max, z_min, z_max; - private int x_dim; - private boolean biome, biomeraw, highesty, blockdata; - private HiddenChunkStyle hidestyle = HiddenChunkStyle.FILL_AIR; - private List visible_limits = null; - private List hidden_limits = null; - private boolean isempty = true; - private int snapcnt; - private Snapshot[] snaparray; /* Index = (x-x_min) + ((z-z_min)*x_dim) */ - private DynIntHashMap[] snaptile; - private byte[][] sameneighborbiomecnt; - private BiomeMap[][] biomemap; - private boolean[][] isSectionNotEmpty; /* Indexed by snapshot index, then by section index */ - private long[] inhabitedTicks; /* Index = (x-x_min) + ((z-z_min)*x_dim) */ - private static final BiomeMap[] nullBiomeMap = { BiomeMap.NULL }; - - private static final BlockStep unstep[] = { BlockStep.X_MINUS, BlockStep.Y_MINUS, BlockStep.Z_MINUS, - BlockStep.X_PLUS, BlockStep.Y_PLUS, BlockStep.Z_PLUS }; - - private static BiomeMap[] biome_to_bmap; - - private static final int getIndexInChunk(int cx, int cy, int cz) { - return (cy << 8) | (cz << 4) | cx; - } - - /** - * Iterator for traversing map chunk cache (base is for non-snapshot) - */ - public class OurMapIterator implements MapIterator { - @SuppressWarnings("unused") - private int x, y, z, chunkindex, bx, bz, off; - private Snapshot snap; - private BlockStep laststep; - private DynmapBlockState type = null; - private final int worldheight; - private final int x_base; - private final int z_base; - - OurMapIterator(int x0, int y0, int z0) { - x_base = x_min << 4; - z_base = z_min << 4; - if(biome) - biomePrep(); - initialize(x0, y0, z0); - worldheight = w.getMaxHeight(); - } - - @Override - public final void initialize(int x0, int y0, int z0) { - this.x = x0; - this.y = y0; - this.z = z0; - this.chunkindex = ((x >> 4) - x_min) + (((z >> 4) - z_min) * x_dim); - this.bx = x & 0xF; - this.bz = z & 0xF; - this.off = bx + (bz << 4); - if ((chunkindex >= snapcnt) || (chunkindex < 0)) { - snap = EMPTY; - } - else { - snap = snaparray[chunkindex]; - } - laststep = BlockStep.Y_MINUS; - if((y >= 0) && (y < worldheight)) - type = null; - else - type = DynmapBlockState.AIR; - } - - @Override - public final DynmapBlockState getBlockType() { - if (type == null) { - type = snap.getBlockType(bx, y, bz); - } - return type; - } - @Override - public int getBlockSkyLight() { - try { - return snap.getBlockSkyLight(bx, y, bz); - } catch (ArrayIndexOutOfBoundsException aioobx) { - return 15; - } - } - @Override - public final int getBlockEmittedLight() { - try { - return snap.getBlockEmittedLight(bx, y, bz); - } catch (ArrayIndexOutOfBoundsException aioobx) { - return 0; - } - } - 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]; - } - Snapshot last_css = null; - Object[] biomebase = null; - for(int i = 0; i < x_size; i++) { - for(int j = 0; j < z_size; j++) { - BiomeMap bm; - if (j == 0) { - initialize(i + x_base, 64, z_base); - } - else { - stepPosition(BlockStep.Z_PLUS); - } - if (last_css != snap) { - if ((snap instanceof EmptyChunk) || (snap instanceof PlainChunk)) { - biomebase = nullBiomeMap; - } - else { - biomebase = snap.getBiomeBaseFromSnapshot(); - } - last_css = snap; - } - if (biomebase == nullBiomeMap) { - bm = BiomeMap.NULL; - } - else if(biomebase != null) { - bm = BiomeMap.byBiomeID(BukkitVersionHelper.helper.getBiomeBaseID(biomebase[bz << 4 | bx])); - } - else { - Biome bb = snap.getBiome(bx, bz); - if(bb == null) - bm = BiomeMap.NULL; - else - bm = biome_to_bmap[bb.ordinal()]; - } - 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]; - } catch (Exception ex) { - return BiomeMap.NULL; - } - } - @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 rmult = bm.getModifiedGrassMultiplier(colormap[bm.biomeLookup()]); - raccum += (rmult >> 16) & 0xFF; - gaccum += (rmult >> 8) & 0xFF; - baccum += rmult & 0xFF; - } - } - mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); - } - } catch (Exception x) { - mult = 0xFFFFFF; - } - return mult; - } - @Override - public final int getSmoothFoliageColorMultiplier(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.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 rmult = bm.getModifiedFoliageMultiplier(colormap[bm.biomeLookup()]); - raccum += (rmult >> 16) & 0xFF; - gaccum += (rmult >> 8) & 0xFF; - baccum += rmult & 0xFF; - } - } - mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); - } - } catch (Exception x) { - mult = 0xFFFFFF; - } - return mult; - } - @Override - public final int getSmoothColorMultiplier(int[] colormap, int[] swampmap) { - 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 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; - } - } - mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); - } - } catch (Exception x) { - mult = 0xFFFFFF; - } - return mult; - } - @Override - public final int getSmoothWaterColorMultiplier() { - 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? */ - return bm.getWaterColorMult(); - } - 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; - } - } - return ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); - } catch (Exception x) { - return 0xFFFFFF; - } - } - @Override - public final int getSmoothWaterColorMultiplier(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 = 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 rmult = colormap[bm.biomeLookup()]; - raccum += (rmult >> 16) & 0xFF; - gaccum += (rmult >> 8) & 0xFF; - baccum += rmult & 0xFF; - } - } - mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); - } - } catch (Exception x) { - Log.warning("Water colormult exception", x); - mult = 0xFFFFFF; - } - return mult; - } - /** - * Step current position in given direction - */ - @Override - public final void stepPosition(BlockStep step) { - type = null; - switch(step.ordinal()) { - case 0: - x++; - bx++; - off++; - if(bx == 16) { /* Next chunk? */ - bx = 0; - off -= 16; - chunkindex++; - if ((chunkindex >= snapcnt) || (chunkindex < 0)) { - snap = EMPTY; - } - else { - snap = snaparray[chunkindex]; - } - } - break; - case 1: - y++; - if(y >= worldheight) { - type = DynmapBlockState.AIR; - } - break; - case 2: - z++; - bz++; - off+=16; - if(bz == 16) { /* Next chunk? */ - bz = 0; - off -= 256; - chunkindex += x_dim; - if ((chunkindex >= snapcnt) || (chunkindex < 0)) { - snap = EMPTY; - } - else { - snap = snaparray[chunkindex]; - } - } - break; - case 3: - x--; - bx--; - off--; - if(bx == -1) { /* Next chunk? */ - bx = 15; - off += 16; - chunkindex--; - if ((chunkindex >= snapcnt) || (chunkindex < 0)) { - snap = EMPTY; - } - else { - snap = snaparray[chunkindex]; - } - } - break; - case 4: - y--; - if(y < 0) { - type = DynmapBlockState.AIR; - } - break; - case 5: - z--; - bz--; - off-=16; - if(bz == -1) { /* Next chunk? */ - bz = 15; - off += 256; - chunkindex -= x_dim; - if ((chunkindex >= snapcnt) || (chunkindex < 0)) { - snap = EMPTY; - } - else { - snap = snaparray[chunkindex]; - } - } - break; - } - laststep = step; - } - /** - * Unstep current position to previous position - */ - @Override - public BlockStep unstepPosition() { - BlockStep ls = laststep; - stepPosition(unstep[ls.ordinal()]); - return ls; - } - /** - * Unstep current position in oppisite director of given step - */ - @Override - public void unstepPosition(BlockStep s) { - stepPosition(unstep[s.ordinal()]); - } - @Override - public final void setY(int y) { - if(y > this.y) - laststep = BlockStep.Y_PLUS; - else - laststep = BlockStep.Y_MINUS; - this.y = y; - if((y < 0) || (y >= worldheight)) { - type = DynmapBlockState.AIR; - } - else { - type = null; - } - } - @Override - public final int getX() { - return x; - } - @Override - public final int getY() { - return y; - } - @Override - public final int getZ() { - return z; - } - @Override - public final DynmapBlockState getBlockTypeAt(BlockStep s) { - if(s == BlockStep.Y_MINUS) { - if(y > 0) - return snap.getBlockType(bx, y-1, bz); - } - else if(s == BlockStep.Y_PLUS) { - if(y < (worldheight-1)) - return snap.getBlockType(bx, y+1, bz); - } - else { - BlockStep ls = laststep; - stepPosition(s); - DynmapBlockState tid = snap.getBlockType(bx, y, bz); - unstepPosition(); - laststep = ls; - return tid; - } - return DynmapBlockState.AIR; - } - @Override - public BlockStep getLastStep() { - return laststep; - } - @Override - public int getWorldHeight() { - return worldheight; - } - @Override - public long getBlockKey() { - return (((chunkindex * worldheight) + y) << 8) | (bx << 4) | bz; - } - @Override - public final boolean isEmptySection() { - try { - return !isSectionNotEmpty[chunkindex][y >> 4]; - } catch (Exception x) { - initSectionData(chunkindex); - return !isSectionNotEmpty[chunkindex][y >> 4]; - } - } - @Override - public RenderPatchFactory getPatchFactory() { - return HDBlockModels.getPatchDefinitionFactory(); - } - @Override - public Object getBlockTileEntityField(String fieldId) { - try { - int idx = getIndexInChunk(bx,y,bz); - Object[] vals = (Object[])snaptile[chunkindex].get(idx); - for (int i = 0; i < vals.length; i += 2) { - if (vals[i].equals(fieldId)) { - return vals[i+1]; - } - } - } catch (Exception x) { - } - return null; - } - @Override - public DynmapBlockState getBlockTypeAt(int xoff, int yoff, int zoff) { - int xx = this.x + xoff; - int yy = this.y + yoff; - int zz = this.z + zoff; - int idx = ((xx >> 4) - x_min) + (((zz >> 4) - z_min) * x_dim); - try { - return snaparray[idx].getBlockType(xx & 0xF, yy, zz & 0xF); - } catch (Exception x) { - return DynmapBlockState.AIR; - } - } - @Override - public Object getBlockTileEntityFieldAt(String fieldId, int xoff, - int yoff, int zoff) { - return null; - } - @Override - public long getInhabitedTicks() { - try { - return inhabitedTicks[chunkindex]; - } catch (Exception x) { - return 0; - } - } - } - - private class OurEndMapIterator extends OurMapIterator { - - OurEndMapIterator(int x0, int y0, int z0) { - super(x0, y0, z0); - } - @Override - public final int getBlockSkyLight() { - return 15; - } - } - - public interface Snapshot { - 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 int getHighestBlockYAt(int x, int z); - public Biome getBiome(int x, int z); - public boolean isSectionEmpty(int sy); - public Object[] getBiomeBaseFromSnapshot(); - } +public class MapChunkCache113 extends AbstractMapChunkCache { public static class WrappedSnapshot implements Snapshot { private final ChunkSnapshot ss; @@ -648,428 +59,8 @@ public class MapChunkCache113 extends MapChunkCache { } } - /** - * Chunk cache for representing unloaded chunk (or air) - */ - private static class EmptyChunk implements Snapshot { - public final DynmapBlockState getBlockType(int x, int y, int z) { - return DynmapBlockState.AIR; - } - @Override - public final int getBlockSkyLight(int x, int y, int z) { - return 15; - } - @Override - public final int getBlockEmittedLight(int x, int y, int z) { - return 0; - } - @Override - public final int getHighestBlockYAt(int x, int z) { - return 0; - } - @Override - public Biome getBiome(int x, int z) { - return null; - } - @Override - public boolean isSectionEmpty(int sy) { - return true; - } - @Override - public Object[] getBiomeBaseFromSnapshot() { - return new Object[256]; - } - } - - /** - * Chunk cache for representing generic stone chunk - */ - private static class PlainChunk implements Snapshot { - private DynmapBlockState fill; - PlainChunk(String blockname) { this.fill = DynmapBlockState.getBaseStateByName(blockname); } - - @Override - public final DynmapBlockState getBlockType(int x, int y, int z) { - return (y < 64) ? fill : DynmapBlockState.AIR; - } - @Override - public Biome getBiome(int x, int z) { return null; } - @Override - public final int getBlockSkyLight(int x, int y, int z) { - if(y < 64) - return 0; - return 15; - } - @Override - public final int getBlockEmittedLight(int x, int y, int z) { - return 0; - } - @Override - public final int getHighestBlockYAt(int x, int z) { - return 64; - } - @Override - public boolean isSectionEmpty(int sy) { - return (sy < 4); - } - @Override - public Object[] getBiomeBaseFromSnapshot() { - return new Object[256]; - } - } - - private static final EmptyChunk EMPTY = new EmptyChunk(); - private static final PlainChunk STONE = new PlainChunk(DynmapBlockState.STONE_BLOCK); - private static final PlainChunk OCEAN = new PlainChunk(DynmapBlockState.WATER_BLOCK); - - /** - * Construct empty cache - */ - public MapChunkCache113() { - if(!init) { - init = true; - } - } - public void setChunks(BukkitWorld dw, List chunks) { - this.dw = dw; - this.w = dw.getWorld(); - if(this.w == null) { - this.chunks = new ArrayList(); - } - nsect = dw.worldheight >> 4; - this.chunks = chunks; - /* Compute range */ - if(chunks.size() == 0) { - this.x_min = 0; - this.x_max = 0; - this.z_min = 0; - this.z_max = 0; - x_dim = 1; - } - else { - x_min = x_max = chunks.get(0).x; - z_min = z_max = chunks.get(0).z; - for(DynmapChunk c : chunks) { - if(c.x > x_max) - x_max = c.x; - if(c.x < x_min) - x_min = c.x; - if(c.z > z_max) - z_max = c.z; - if(c.z < z_min) - z_min = c.z; - } - x_dim = x_max - x_min + 1; - } - - snapcnt = x_dim * (z_max-z_min+1); - snaparray = new Snapshot[snapcnt]; - inhabitedTicks = new long[snapcnt]; - snaptile = new DynIntHashMap[snapcnt]; - isSectionNotEmpty = new boolean[snapcnt][]; - } - - public int loadChunks(int max_to_load) { - if(dw.isLoaded() == false) - return 0; - Object queue = BukkitVersionHelper.helper.getUnloadQueue(w); - - int cnt = 0; - if(iterator == null) - iterator = chunks.listIterator(); - - DynmapCore.setIgnoreChunkLoads(true); - //boolean isnormral = w.getEnvironment() == Environment.NORMAL; - // 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; - 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 = new WrappedSnapshot(ssr.ss); - } - int idx = (chunk.x-x_min) + (chunk.z - z_min)*x_dim; - snaparray[idx] = ss; - snaptile[idx] = ssr.tileData; - inhabitedTicks[idx] = inhabited_ticks; - - endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT); - continue; - } - boolean wasLoaded = w.isChunkLoaded(chunk.x, chunk.z); - boolean didload = false; - boolean isunloadpending = false; - if (queue != null) { - isunloadpending = BukkitVersionHelper.helper.isInUnloadQueue(queue, chunk.x, chunk.z); - } - if (isunloadpending) { /* Workaround: can't be pending if not loaded */ - wasLoaded = true; - } - try { - didload = w.loadChunk(chunk.x, chunk.z, false); - } catch (Throwable t) { /* Catch chunk error from Bukkit */ - Log.warning("Bukkit error loading chunk " + chunk.x + "," + chunk.z + " on " + w.getName()); - if(!wasLoaded) { /* If wasn't loaded, we loaded it if it now is */ - didload = w.isChunkLoaded(chunk.x, chunk.z); - } - } - /* If it did load, make cache of it */ - if(didload) { - tileData = new DynIntHashMap(); - - Chunk c = w.getChunkAt(chunk.x, chunk.z); /* Get the chunk */ - /* Get inhabited ticks count */ - inhabited_ticks = BukkitVersionHelper.helper.getInhabitedTicks(c); - if(!vis) { - if(hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) - ss = STONE; - else if(hidestyle == HiddenChunkStyle.FILL_OCEAN) - ss = OCEAN; - else - ss = EMPTY; - } - else { - ChunkSnapshot css; - if(blockdata || highesty) { - css = c.getChunkSnapshot(highesty, biome, biomeraw); - ss = new WrappedSnapshot(css); - /* Get tile entity data */ - List vals = new ArrayList(); - Map tileents = BukkitVersionHelper.helper.getTileEntitiesForChunk(c); - for(Object t : tileents.values()) { - int te_x = BukkitVersionHelper.helper.getTileEntityX(t); - int te_y = BukkitVersionHelper.helper.getTileEntityY(t); - int te_z = BukkitVersionHelper.helper.getTileEntityZ(t); - int cx = te_x & 0xF; - int cz = te_z & 0xF; - String[] te_fields = HDBlockModels.getTileEntityFieldsNeeded(ss.getBlockType(cx, te_y, cz)); - if(te_fields != null) { - Object nbtcompound = BukkitVersionHelper.helper.readTileEntityNBT(t); - - vals.clear(); - for(String id: te_fields) { - Object val = BukkitVersionHelper.helper.getFieldValue(nbtcompound, id); - if(val != null) { - vals.add(id); - vals.add(val); - } - } - if(vals.size() > 0) { - Object[] vlist = vals.toArray(new Object[vals.size()]); - tileData.put(getIndexInChunk(cx,te_y,cz), vlist); - } - } - } - } - else { - css = w.getEmptyChunkSnapshot(chunk.x, chunk.z, biome, biomeraw); - ss = new WrappedSnapshot(css); - } - if(ss != null) { - ssr = new SnapshotRec(); - ssr.ss = css; - ssr.inhabitedTicks = inhabited_ticks; - ssr.tileData = tileData; - SnapshotCache.sscache.putSnapshot(dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty); - } - } - int chunkIndex = (chunk.x-x_min) + (chunk.z - z_min)*x_dim; - snaparray[chunkIndex] = ss; - snaptile[chunkIndex] = tileData; - inhabitedTicks[chunkIndex] = inhabited_ticks; - - /* If wasn't loaded before, we need to do unload */ - if (!wasLoaded) { - /* Since we only remember ones we loaded, and we're synchronous, no player has - * moved, so it must be safe (also prevent chunk leak, which appears to happen - * because isChunkInUse defined "in use" as being within 256 blocks of a player, - * while the actual in-use chunk area for a player where the chunks are managed - * by the MC base server is 21x21 (or about a 160 block radius). - * Also, if we did generate it, need to save it */ - if (w.isChunkInUse(chunk.x, chunk.z) == false) { - if (BukkitVersionHelper.helper.isUnloadChunkBroken()) { - // Give up on broken unloadChunk API - lets see if this works - w.unloadChunkRequest(chunk.x, chunk.z); - } - else { - BukkitVersionHelper.helper.unloadChunkNoSave(w, c, chunk.x, chunk.z); - } - } - endChunkLoad(startTime, ChunkStats.UNLOADED_CHUNKS); - } - else if (isunloadpending) { /* Else, if loaded and unload is pending */ - if (w.isChunkInUse(chunk.x, chunk.z) == false) { - w.unloadChunkRequest(chunk.x, chunk.z); /* Request new unload */ - } - endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS); - } - else { - endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS); - } - } - else { - endChunkLoad(startTime, ChunkStats.UNGENERATED_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; - } - /** - * Test if done loading - */ - public boolean isDoneLoading() { - if(dw.isLoaded() == false) { - isempty = true; - unloadChunks(); - return true; - } - if(iterator != null) - return !iterator.hasNext(); - return false; - } - /** - * Test if all empty blocks - */ - public boolean isEmpty() { - return isempty; - } - /** - * Unload chunks - */ - public void unloadChunks() { - if(snaparray != null) { - for(int i = 0; i < snaparray.length; i++) { - snaparray[i] = null; - } - snaparray = null; - inhabitedTicks = null; - } - } - private void initSectionData(int idx) { - isSectionNotEmpty[idx] = new boolean[nsect + 1]; - if(snaparray[idx] != EMPTY) { - for(int i = 0; i < nsect; i++) { - if(snaparray[idx].isSectionEmpty(i) == false) { - isSectionNotEmpty[idx][i] = true; - } - } - } - } - public boolean isEmptySection(int sx, int sy, int sz) { - int idx = (sx - x_min) + (sz - z_min) * x_dim; - if(isSectionNotEmpty[idx] == null) { - initSectionData(idx); - } - return !isSectionNotEmpty[idx][sy]; - } - - /** - * Get cache iterator - */ - public MapIterator getIterator(int x, int y, int z) { - if(w.getEnvironment().toString().equals("THE_END")) - return new OurEndMapIterator(x, y, z); - return new OurMapIterator(x, y, z); - } - /** - * Set hidden chunk style (default is FILL_AIR) - */ - public void setHiddenFillStyle(HiddenChunkStyle style) { - this.hidestyle = style; - } - /** - * Add visible area limit - can be called more than once - * Needs to be set before chunks are loaded - * Coordinates are block coordinates - */ - public void setVisibleRange(VisibilityLimit lim) { - if(visible_limits == null) - visible_limits = new ArrayList(); - visible_limits.add(lim); - } - /** - * Add hidden area limit - can be called more than once - * Needs to be set before chunks are loaded - * Coordinates are block coordinates - */ - public void setHiddenRange(VisibilityLimit lim) { - if(hidden_limits == null) - hidden_limits = new ArrayList(); - hidden_limits.add(lim); - } - @Override - public boolean setChunkDataTypes(boolean blockdata, boolean biome, boolean highestblocky, boolean rawbiome) { - this.biome = biome; - this.biomeraw = rawbiome; - this.highesty = highestblocky; - this.blockdata = blockdata; - return true; - } - @Override - public DynmapWorld getWorld() { - return dw; - } - - static { - Biome[] b = Biome.values(); - BiomeMap[] bm = BiomeMap.values(); - biome_to_bmap = new BiomeMap[1024]; - for(int i = 0; i < biome_to_bmap.length; i++) { - biome_to_bmap[i] = BiomeMap.NULL; - } - for(int i = 0; i < b.length; i++) { - String bs = b[i].toString(); - for(int j = 0; j < bm.length; j++) { - if(bm[j].toString().equals(bs)) { - biome_to_bmap[b[i].ordinal()] = bm[j]; - break; - } - } - } - } + @Override + public Snapshot wrapChunkSnapshot(ChunkSnapshot css) { + return new WrappedSnapshot(css); + } } From 57bf7fb99d30fb39656f03f35628f861d2e78e59 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Sat, 11 Aug 2018 21:54:48 -0500 Subject: [PATCH 06/50] Prep for combining under gradle build --- .gitignore | 2 + {core => bukkit}/.gitignore | 0 {core => bukkit}/pom.xml | 2 +- .../src/main/assembly/package.xml | 0 .../main/java/org/dynmap/bukkit/Armor.java | 0 .../java/org/dynmap/bukkit/DynmapPlugin.java | 0 .../main/java/org/dynmap/bukkit/Helper.java | 0 .../bukkit/permissions/BukkitPermissions.java | 0 .../permissions/GroupManagerPermissions.java | 0 .../permissions/NijikokunPermissions.java | 0 .../bukkit/permissions/OpPermissions.java | 0 .../bukkit/permissions/PEXPermissions.java | 0 .../permissions/PermBukkitPermissions.java | 0 .../permissions/PermissionProvider.java | 0 .../bukkit/permissions/bPermPermissions.java | 0 .../src/main/resources/configuration.txt | 0 .../src/main/resources/plugin.yml | 0 {core => bukkit}/tools/Biomes.ods | Bin .../tools/bukkit_formatting_profile.xml | 0 helper/pom.xml | 2 +- .../bukkit/helper/NewMapChunkCache.java | 1040 ----------------- helper113/pom.xml | 2 +- pom.xml | 4 +- 23 files changed, 7 insertions(+), 1045 deletions(-) rename {core => bukkit}/.gitignore (100%) rename {core => bukkit}/pom.xml (99%) rename {core => bukkit}/src/main/assembly/package.xml (100%) rename {core => bukkit}/src/main/java/org/dynmap/bukkit/Armor.java (100%) rename {core => bukkit}/src/main/java/org/dynmap/bukkit/DynmapPlugin.java (100%) rename {core => bukkit}/src/main/java/org/dynmap/bukkit/Helper.java (100%) rename {core => bukkit}/src/main/java/org/dynmap/bukkit/permissions/BukkitPermissions.java (100%) rename {core => bukkit}/src/main/java/org/dynmap/bukkit/permissions/GroupManagerPermissions.java (100%) rename {core => bukkit}/src/main/java/org/dynmap/bukkit/permissions/NijikokunPermissions.java (100%) rename {core => bukkit}/src/main/java/org/dynmap/bukkit/permissions/OpPermissions.java (100%) rename {core => bukkit}/src/main/java/org/dynmap/bukkit/permissions/PEXPermissions.java (100%) rename {core => bukkit}/src/main/java/org/dynmap/bukkit/permissions/PermBukkitPermissions.java (100%) rename {core => bukkit}/src/main/java/org/dynmap/bukkit/permissions/PermissionProvider.java (100%) rename {core => bukkit}/src/main/java/org/dynmap/bukkit/permissions/bPermPermissions.java (100%) rename {core => bukkit}/src/main/resources/configuration.txt (100%) rename {core => bukkit}/src/main/resources/plugin.yml (100%) rename {core => bukkit}/tools/Biomes.ods (100%) rename {core => bukkit}/tools/bukkit_formatting_profile.xml (100%) delete mode 100644 helper/src/main/java/org/dynmap/bukkit/helper/NewMapChunkCache.java diff --git a/.gitignore b/.gitignore index a140d2bf..ae6d9363 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ # Mac filesystem dust /.DS_Store /dependency-reduced-pom.xml + +/.gradle diff --git a/core/.gitignore b/bukkit/.gitignore similarity index 100% rename from core/.gitignore rename to bukkit/.gitignore diff --git a/core/pom.xml b/bukkit/pom.xml similarity index 99% rename from core/pom.xml rename to bukkit/pom.xml index b2b4c5ec..1c05c6b6 100644 --- a/core/pom.xml +++ b/bukkit/pom.xml @@ -170,7 +170,7 @@ 3.0-SNAPSHOT us.dynmap - dynmap-bukkit + dynmap-common 3.0-SNAPSHOT .. diff --git a/core/src/main/assembly/package.xml b/bukkit/src/main/assembly/package.xml similarity index 100% rename from core/src/main/assembly/package.xml rename to bukkit/src/main/assembly/package.xml diff --git a/core/src/main/java/org/dynmap/bukkit/Armor.java b/bukkit/src/main/java/org/dynmap/bukkit/Armor.java similarity index 100% rename from core/src/main/java/org/dynmap/bukkit/Armor.java rename to bukkit/src/main/java/org/dynmap/bukkit/Armor.java diff --git a/core/src/main/java/org/dynmap/bukkit/DynmapPlugin.java b/bukkit/src/main/java/org/dynmap/bukkit/DynmapPlugin.java similarity index 100% rename from core/src/main/java/org/dynmap/bukkit/DynmapPlugin.java rename to bukkit/src/main/java/org/dynmap/bukkit/DynmapPlugin.java diff --git a/core/src/main/java/org/dynmap/bukkit/Helper.java b/bukkit/src/main/java/org/dynmap/bukkit/Helper.java similarity index 100% rename from core/src/main/java/org/dynmap/bukkit/Helper.java rename to bukkit/src/main/java/org/dynmap/bukkit/Helper.java diff --git a/core/src/main/java/org/dynmap/bukkit/permissions/BukkitPermissions.java b/bukkit/src/main/java/org/dynmap/bukkit/permissions/BukkitPermissions.java similarity index 100% rename from core/src/main/java/org/dynmap/bukkit/permissions/BukkitPermissions.java rename to bukkit/src/main/java/org/dynmap/bukkit/permissions/BukkitPermissions.java diff --git a/core/src/main/java/org/dynmap/bukkit/permissions/GroupManagerPermissions.java b/bukkit/src/main/java/org/dynmap/bukkit/permissions/GroupManagerPermissions.java similarity index 100% rename from core/src/main/java/org/dynmap/bukkit/permissions/GroupManagerPermissions.java rename to bukkit/src/main/java/org/dynmap/bukkit/permissions/GroupManagerPermissions.java diff --git a/core/src/main/java/org/dynmap/bukkit/permissions/NijikokunPermissions.java b/bukkit/src/main/java/org/dynmap/bukkit/permissions/NijikokunPermissions.java similarity index 100% rename from core/src/main/java/org/dynmap/bukkit/permissions/NijikokunPermissions.java rename to bukkit/src/main/java/org/dynmap/bukkit/permissions/NijikokunPermissions.java diff --git a/core/src/main/java/org/dynmap/bukkit/permissions/OpPermissions.java b/bukkit/src/main/java/org/dynmap/bukkit/permissions/OpPermissions.java similarity index 100% rename from core/src/main/java/org/dynmap/bukkit/permissions/OpPermissions.java rename to bukkit/src/main/java/org/dynmap/bukkit/permissions/OpPermissions.java diff --git a/core/src/main/java/org/dynmap/bukkit/permissions/PEXPermissions.java b/bukkit/src/main/java/org/dynmap/bukkit/permissions/PEXPermissions.java similarity index 100% rename from core/src/main/java/org/dynmap/bukkit/permissions/PEXPermissions.java rename to bukkit/src/main/java/org/dynmap/bukkit/permissions/PEXPermissions.java diff --git a/core/src/main/java/org/dynmap/bukkit/permissions/PermBukkitPermissions.java b/bukkit/src/main/java/org/dynmap/bukkit/permissions/PermBukkitPermissions.java similarity index 100% rename from core/src/main/java/org/dynmap/bukkit/permissions/PermBukkitPermissions.java rename to bukkit/src/main/java/org/dynmap/bukkit/permissions/PermBukkitPermissions.java diff --git a/core/src/main/java/org/dynmap/bukkit/permissions/PermissionProvider.java b/bukkit/src/main/java/org/dynmap/bukkit/permissions/PermissionProvider.java similarity index 100% rename from core/src/main/java/org/dynmap/bukkit/permissions/PermissionProvider.java rename to bukkit/src/main/java/org/dynmap/bukkit/permissions/PermissionProvider.java diff --git a/core/src/main/java/org/dynmap/bukkit/permissions/bPermPermissions.java b/bukkit/src/main/java/org/dynmap/bukkit/permissions/bPermPermissions.java similarity index 100% rename from core/src/main/java/org/dynmap/bukkit/permissions/bPermPermissions.java rename to bukkit/src/main/java/org/dynmap/bukkit/permissions/bPermPermissions.java diff --git a/core/src/main/resources/configuration.txt b/bukkit/src/main/resources/configuration.txt similarity index 100% rename from core/src/main/resources/configuration.txt rename to bukkit/src/main/resources/configuration.txt diff --git a/core/src/main/resources/plugin.yml b/bukkit/src/main/resources/plugin.yml similarity index 100% rename from core/src/main/resources/plugin.yml rename to bukkit/src/main/resources/plugin.yml diff --git a/core/tools/Biomes.ods b/bukkit/tools/Biomes.ods similarity index 100% rename from core/tools/Biomes.ods rename to bukkit/tools/Biomes.ods diff --git a/core/tools/bukkit_formatting_profile.xml b/bukkit/tools/bukkit_formatting_profile.xml similarity index 100% rename from core/tools/bukkit_formatting_profile.xml rename to bukkit/tools/bukkit_formatting_profile.xml diff --git a/helper/pom.xml b/helper/pom.xml index 7501d231..90ee5500 100644 --- a/helper/pom.xml +++ b/helper/pom.xml @@ -2,7 +2,7 @@ 4.0.0 us.dynmap - dynmap-bukkit + dynmap-common 3.0-SNAPSHOT .. diff --git a/helper/src/main/java/org/dynmap/bukkit/helper/NewMapChunkCache.java b/helper/src/main/java/org/dynmap/bukkit/helper/NewMapChunkCache.java deleted file mode 100644 index 56a1a103..00000000 --- a/helper/src/main/java/org/dynmap/bukkit/helper/NewMapChunkCache.java +++ /dev/null @@ -1,1040 +0,0 @@ -package org.dynmap.bukkit.helper; - -import java.util.ArrayList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import org.bukkit.World; -import org.bukkit.Chunk; -import org.bukkit.block.Biome; -import org.bukkit.ChunkSnapshot; -import org.dynmap.DynmapChunk; -import org.dynmap.DynmapCore; -import org.dynmap.DynmapWorld; -import org.dynmap.Log; -import org.dynmap.bukkit.helper.SnapshotCache.SnapshotRec; -import org.dynmap.common.BiomeMap; -import org.dynmap.hdmap.HDBlockModels; -import org.dynmap.renderer.DynmapBlockState; -import org.dynmap.renderer.RenderPatchFactory; -import org.dynmap.utils.DynIntHashMap; -import org.dynmap.utils.MapChunkCache; -import org.dynmap.utils.MapIterator; -import org.dynmap.utils.BlockStep; -import org.dynmap.utils.VisibilityLimit; - -/** - * Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread - */ -public class NewMapChunkCache extends MapChunkCache { - private static boolean init = false; - - private World w; - private DynmapWorld dw; - private int nsect; - private List chunks; - private ListIterator iterator; - private int x_min, x_max, z_min, z_max; - private int x_dim; - private boolean biome, biomeraw, highesty, blockdata; - private HiddenChunkStyle hidestyle = HiddenChunkStyle.FILL_AIR; - private List visible_limits = null; - private List hidden_limits = null; - private boolean isempty = true; - private int snapcnt; - private ChunkSnapshot[] snaparray; /* Index = (x-x_min) + ((z-z_min)*x_dim) */ - private DynIntHashMap[] snaptile; - private byte[][] sameneighborbiomecnt; - private BiomeMap[][] biomemap; - private boolean[][] isSectionNotEmpty; /* Indexed by snapshot index, then by section index */ - private long[] inhabitedTicks; /* Index = (x-x_min) + ((z-z_min)*x_dim) */ - private static final BiomeMap[] nullBiomeMap = { BiomeMap.NULL }; - - private static final BlockStep unstep[] = { BlockStep.X_MINUS, BlockStep.Y_MINUS, BlockStep.Z_MINUS, - BlockStep.X_PLUS, BlockStep.Y_PLUS, BlockStep.Z_PLUS }; - - private static BiomeMap[] biome_to_bmap; - - private static final int getIndexInChunk(int cx, int cy, int cz) { - return (cy << 8) | (cz << 4) | cx; - } - - private static DynmapBlockState getTypeAt(ChunkSnapshot ss, int x, int y, int z) { - return BukkitVersionHelper.stateByID[(ss.getBlockTypeId(x, y, z) << 4) | ss.getBlockData(x, y, z)]; - } - - /** - * Iterator for traversing map chunk cache (base is for non-snapshot) - */ - public class OurMapIterator implements MapIterator { - @SuppressWarnings("unused") - private int x, y, z, chunkindex, bx, bz, off; - private ChunkSnapshot snap; - private BlockStep laststep; - private DynmapBlockState type = null; - private final int worldheight; - private final int x_base; - private final int z_base; - - OurMapIterator(int x0, int y0, int z0) { - x_base = x_min << 4; - z_base = z_min << 4; - if(biome) - biomePrep(); - initialize(x0, y0, z0); - worldheight = w.getMaxHeight(); - } - - @Override - public final void initialize(int x0, int y0, int z0) { - this.x = x0; - this.y = y0; - this.z = z0; - this.chunkindex = ((x >> 4) - x_min) + (((z >> 4) - z_min) * x_dim); - this.bx = x & 0xF; - this.bz = z & 0xF; - this.off = bx + (bz << 4); - if ((chunkindex >= snapcnt) || (chunkindex < 0)) { - snap = EMPTY; - } - else { - snap = snaparray[chunkindex]; - } - laststep = BlockStep.Y_MINUS; - if((y >= 0) && (y < worldheight)) - type = null; - else - type = DynmapBlockState.AIR; - } - - @Override - public final DynmapBlockState getBlockType() { - if (type == null) { - type = getTypeAt(snap, bx, y, bz); - } - return type; - } - @Override - public int getBlockSkyLight() { - try { - return snap.getBlockSkyLight(bx, y, bz); - } catch (ArrayIndexOutOfBoundsException aioobx) { - return 15; - } - } - @Override - public final int getBlockEmittedLight() { - try { - return snap.getBlockEmittedLight(bx, y, bz); - } catch (ArrayIndexOutOfBoundsException aioobx) { - return 0; - } - } - 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]; - } - ChunkSnapshot last_css = null; - Object[] biomebase = null; - for(int i = 0; i < x_size; i++) { - for(int j = 0; j < z_size; j++) { - BiomeMap bm; - if (j == 0) { - initialize(i + x_base, 64, z_base); - } - else { - stepPosition(BlockStep.Z_PLUS); - } - if (last_css != snap) { - if ((snap instanceof EmptyChunk) || (snap instanceof PlainChunk)) { - biomebase = nullBiomeMap; - } - else { - biomebase = BukkitVersionHelper.helper.getBiomeBaseFromSnapshot(snap); - } - last_css = snap; - } - if (biomebase == nullBiomeMap) { - bm = BiomeMap.NULL; - } - else if(biomebase != null) { - bm = BiomeMap.byBiomeID(BukkitVersionHelper.helper.getBiomeBaseID(biomebase[bz << 4 | bx])); - } - else { - Biome bb = snap.getBiome(bx, bz); - if(bb == null) - bm = BiomeMap.NULL; - else - bm = biome_to_bmap[bb.ordinal()]; - } - 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]; - } catch (Exception ex) { - return BiomeMap.NULL; - } - } - @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 rmult = bm.getModifiedGrassMultiplier(colormap[bm.biomeLookup()]); - raccum += (rmult >> 16) & 0xFF; - gaccum += (rmult >> 8) & 0xFF; - baccum += rmult & 0xFF; - } - } - mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); - } - } catch (Exception x) { - mult = 0xFFFFFF; - } - return mult; - } - @Override - public final int getSmoothFoliageColorMultiplier(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.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 rmult = bm.getModifiedFoliageMultiplier(colormap[bm.biomeLookup()]); - raccum += (rmult >> 16) & 0xFF; - gaccum += (rmult >> 8) & 0xFF; - baccum += rmult & 0xFF; - } - } - mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); - } - } catch (Exception x) { - mult = 0xFFFFFF; - } - return mult; - } - @Override - public final int getSmoothColorMultiplier(int[] colormap, int[] swampmap) { - 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 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; - } - } - mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); - } - } catch (Exception x) { - mult = 0xFFFFFF; - } - return mult; - } - @Override - public final int getSmoothWaterColorMultiplier() { - 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? */ - return bm.getWaterColorMult(); - } - 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; - } - } - return ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); - } catch (Exception x) { - return 0xFFFFFF; - } - } - @Override - public final int getSmoothWaterColorMultiplier(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 = 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 rmult = colormap[bm.biomeLookup()]; - raccum += (rmult >> 16) & 0xFF; - gaccum += (rmult >> 8) & 0xFF; - baccum += rmult & 0xFF; - } - } - mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); - } - } catch (Exception x) { - mult = 0xFFFFFF; - } - return mult; - } - /** - * Step current position in given direction - */ - @Override - public final void stepPosition(BlockStep step) { - type = null; - switch(step.ordinal()) { - case 0: - x++; - bx++; - off++; - if(bx == 16) { /* Next chunk? */ - bx = 0; - off -= 16; - chunkindex++; - if ((chunkindex >= snapcnt) || (chunkindex < 0)) { - snap = EMPTY; - } - else { - snap = snaparray[chunkindex]; - } - } - break; - case 1: - y++; - if(y >= worldheight) { - type = DynmapBlockState.AIR; - } - break; - case 2: - z++; - bz++; - off+=16; - if(bz == 16) { /* Next chunk? */ - bz = 0; - off -= 256; - chunkindex += x_dim; - if ((chunkindex >= snapcnt) || (chunkindex < 0)) { - snap = EMPTY; - } - else { - snap = snaparray[chunkindex]; - } - } - break; - case 3: - x--; - bx--; - off--; - if(bx == -1) { /* Next chunk? */ - bx = 15; - off += 16; - chunkindex--; - if ((chunkindex >= snapcnt) || (chunkindex < 0)) { - snap = EMPTY; - } - else { - snap = snaparray[chunkindex]; - } - } - break; - case 4: - y--; - if(y < 0) { - type = DynmapBlockState.AIR; - } - break; - case 5: - z--; - bz--; - off-=16; - if(bz == -1) { /* Next chunk? */ - bz = 15; - off += 256; - chunkindex -= x_dim; - if ((chunkindex >= snapcnt) || (chunkindex < 0)) { - snap = EMPTY; - } - else { - snap = snaparray[chunkindex]; - } - } - break; - } - laststep = step; - } - /** - * Unstep current position to previous position - */ - @Override - public BlockStep unstepPosition() { - BlockStep ls = laststep; - stepPosition(unstep[ls.ordinal()]); - return ls; - } - /** - * Unstep current position in oppisite director of given step - */ - @Override - public void unstepPosition(BlockStep s) { - stepPosition(unstep[s.ordinal()]); - } - @Override - public final void setY(int y) { - if(y > this.y) - laststep = BlockStep.Y_PLUS; - else - laststep = BlockStep.Y_MINUS; - this.y = y; - if((y < 0) || (y >= worldheight)) { - type = DynmapBlockState.AIR; - } - else { - type = null; - } - } - @Override - public final int getX() { - return x; - } - @Override - public final int getY() { - return y; - } - @Override - public final int getZ() { - return z; - } - @Override - public final DynmapBlockState getBlockTypeAt(BlockStep s) { - if(s == BlockStep.Y_MINUS) { - if(y > 0) - return getTypeAt(snap, bx, y-1, bz); - } - else if(s == BlockStep.Y_PLUS) { - if(y < (worldheight-1)) - return getTypeAt(snap, bx, y+1, bz); - } - else { - BlockStep ls = laststep; - stepPosition(s); - DynmapBlockState tid = getTypeAt(snap, bx, y, bz); - unstepPosition(); - laststep = ls; - return tid; - } - return DynmapBlockState.AIR; - } - @Override - public BlockStep getLastStep() { - return laststep; - } - @Override - public int getWorldHeight() { - return worldheight; - } - @Override - public long getBlockKey() { - return (((chunkindex * worldheight) + y) << 8) | (bx << 4) | bz; - } - @Override - public final boolean isEmptySection() { - try { - return !isSectionNotEmpty[chunkindex][y >> 4]; - } catch (Exception x) { - initSectionData(chunkindex); - return !isSectionNotEmpty[chunkindex][y >> 4]; - } - } - @Override - public RenderPatchFactory getPatchFactory() { - return HDBlockModels.getPatchDefinitionFactory(); - } - @Override - public Object getBlockTileEntityField(String fieldId) { - try { - int idx = getIndexInChunk(bx,y,bz); - Object[] vals = (Object[])snaptile[chunkindex].get(idx); - for (int i = 0; i < vals.length; i += 2) { - if (vals[i].equals(fieldId)) { - return vals[i+1]; - } - } - } catch (Exception x) { - } - return null; - } - @Override - public DynmapBlockState getBlockTypeAt(int xoff, int yoff, int zoff) { - int xx = this.x + xoff; - int yy = this.y + yoff; - int zz = this.z + zoff; - int idx = ((xx >> 4) - x_min) + (((zz >> 4) - z_min) * x_dim); - try { - return getTypeAt(snaparray[idx], xx & 0xF, yy, zz & 0xF); - } catch (Exception x) { - return DynmapBlockState.AIR; - } - } - @Override - public Object getBlockTileEntityFieldAt(String fieldId, int xoff, - int yoff, int zoff) { - return null; - } - @Override - public long getInhabitedTicks() { - try { - return inhabitedTicks[chunkindex]; - } catch (Exception x) { - return 0; - } - } - } - - private class OurEndMapIterator extends OurMapIterator { - - OurEndMapIterator(int x0, int y0, int z0) { - super(x0, y0, z0); - } - @Override - public final int getBlockSkyLight() { - return 15; - } - } - /** - * Chunk cache for representing unloaded chunk (or air) - */ - private static class EmptyChunk implements ChunkSnapshot { - /* Need these for interface, but not used */ - @Override - public int getX() { return 0; } - @Override - public int getZ() { return 0; } - @Override - public String getWorldName() { return ""; } - @Override - public long getCaptureFullTime() { return 0; } - @Override - public final int getBlockTypeId(int x, int y, int z) { - return 0; - } - @Override - public final int getBlockData(int x, int y, int z) { - return 0; - } - @Override - public final int getBlockSkyLight(int x, int y, int z) { - return 15; - } - @Override - public final int getBlockEmittedLight(int x, int y, int z) { - return 0; - } - @Override - public final int getHighestBlockYAt(int x, int z) { - return 0; - } - @Override - public Biome getBiome(int x, int z) { - return null; - } - @Override - public double getRawBiomeTemperature(int x, int z) { - return 0.0; - } - @Override - public double getRawBiomeRainfall(int x, int z) { - return 0.0; - } - @Override - public boolean isSectionEmpty(int sy) { - return true; - } - } - - /** - * Chunk cache for representing generic stone chunk - */ - private static class PlainChunk implements ChunkSnapshot { - private int fillid; - PlainChunk(int fillid) { this.fillid = fillid; } - /* Need these for interface, but not used */ - @Override - public int getX() { return 0; } - @Override - public int getZ() { return 0; } - @Override - public String getWorldName() { return ""; } - @Override - public Biome getBiome(int x, int z) { return null; } - @Override - public double getRawBiomeTemperature(int x, int z) { return 0.0; } - @Override - public double getRawBiomeRainfall(int x, int z) { return 0.0; } - @Override - public long getCaptureFullTime() { return 0; } - @Override - public final int getBlockTypeId(int x, int y, int z) { - if(y < 64) return fillid; - return 0; - } - @Override - public final int getBlockData(int x, int y, int z) { - return 0; - } - @Override - public final int getBlockSkyLight(int x, int y, int z) { - if(y < 64) - return 0; - return 15; - } - @Override - public final int getBlockEmittedLight(int x, int y, int z) { - return 0; - } - @Override - public final int getHighestBlockYAt(int x, int z) { - return 64; - } - @Override - public boolean isSectionEmpty(int sy) { - return (sy < 4); - } - } - - private static final EmptyChunk EMPTY = new EmptyChunk(); - private static final PlainChunk STONE = new PlainChunk(1); - private static final PlainChunk OCEAN = new PlainChunk(9); - - /** - * Construct empty cache - */ - public NewMapChunkCache() { - if(!init) { - init = true; - } - } - public void setChunks(BukkitWorld dw, List chunks) { - this.dw = dw; - this.w = dw.getWorld(); - if(this.w == null) { - this.chunks = new ArrayList(); - } - nsect = dw.worldheight >> 4; - this.chunks = chunks; - /* Compute range */ - if(chunks.size() == 0) { - this.x_min = 0; - this.x_max = 0; - this.z_min = 0; - this.z_max = 0; - x_dim = 1; - } - else { - x_min = x_max = chunks.get(0).x; - z_min = z_max = chunks.get(0).z; - for(DynmapChunk c : chunks) { - if(c.x > x_max) - x_max = c.x; - if(c.x < x_min) - x_min = c.x; - if(c.z > z_max) - z_max = c.z; - if(c.z < z_min) - z_min = c.z; - } - x_dim = x_max - x_min + 1; - } - - snapcnt = x_dim * (z_max-z_min+1); - snaparray = new ChunkSnapshot[snapcnt]; - inhabitedTicks = new long[snapcnt]; - snaptile = new DynIntHashMap[snapcnt]; - isSectionNotEmpty = new boolean[snapcnt][]; - } - - public int loadChunks(int max_to_load) { - if(dw.isLoaded() == false) - return 0; - Object queue = BukkitVersionHelper.helper.getUnloadQueue(w); - - int cnt = 0; - if(iterator == null) - iterator = chunks.listIterator(); - - DynmapCore.setIgnoreChunkLoads(true); - //boolean isnormral = w.getEnvironment() == Environment.NORMAL; - // 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 */ - ChunkSnapshot ss = null; - long inhabited_ticks = 0; - DynIntHashMap tileData = null; - SnapshotRec ssr = SnapshotCache.sscache.getSnapshot(dw.getName(), chunk.x, chunk.z, blockdata, biome, biomeraw, highesty); - if(ssr != null) { - ss = ssr.ss; - 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; - } - int idx = (chunk.x-x_min) + (chunk.z - z_min)*x_dim; - snaparray[idx] = ss; - snaptile[idx] = ssr.tileData; - inhabitedTicks[idx] = inhabited_ticks; - - endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT); - continue; - } - boolean wasLoaded = w.isChunkLoaded(chunk.x, chunk.z); - boolean didload = false; - boolean isunloadpending = false; - if (queue != null) { - isunloadpending = BukkitVersionHelper.helper.isInUnloadQueue(queue, chunk.x, chunk.z); - } - if (isunloadpending) { /* Workaround: can't be pending if not loaded */ - wasLoaded = true; - } - try { - didload = w.loadChunk(chunk.x, chunk.z, false); - } catch (Throwable t) { /* Catch chunk error from Bukkit */ - Log.warning("Bukkit error loading chunk " + chunk.x + "," + chunk.z + " on " + w.getName()); - if(!wasLoaded) { /* If wasn't loaded, we loaded it if it now is */ - didload = w.isChunkLoaded(chunk.x, chunk.z); - } - } - /* If it did load, make cache of it */ - if(didload) { - tileData = new DynIntHashMap(); - - Chunk c = w.getChunkAt(chunk.x, chunk.z); /* Get the chunk */ - /* Get inhabited ticks count */ - inhabited_ticks = BukkitVersionHelper.helper.getInhabitedTicks(c); - if(!vis) { - if(hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) - ss = STONE; - else if(hidestyle == HiddenChunkStyle.FILL_OCEAN) - ss = OCEAN; - else - ss = EMPTY; - } - else { - if(blockdata || highesty) { - ss = c.getChunkSnapshot(highesty, biome, biomeraw); - /* Get tile entity data */ - List vals = new ArrayList(); - Map tileents = BukkitVersionHelper.helper.getTileEntitiesForChunk(c); - for(Object t : tileents.values()) { - int te_x = BukkitVersionHelper.helper.getTileEntityX(t); - int te_y = BukkitVersionHelper.helper.getTileEntityY(t); - int te_z = BukkitVersionHelper.helper.getTileEntityZ(t); - int cx = te_x & 0xF; - int cz = te_z & 0xF; - String[] te_fields = HDBlockModels.getTileEntityFieldsNeeded(getTypeAt(ss, cx, te_y, cz)); - if(te_fields != null) { - Object nbtcompound = BukkitVersionHelper.helper.readTileEntityNBT(t); - - vals.clear(); - for(String id: te_fields) { - Object val = BukkitVersionHelper.helper.getFieldValue(nbtcompound, id); - if(val != null) { - vals.add(id); - vals.add(val); - } - } - if(vals.size() > 0) { - Object[] vlist = vals.toArray(new Object[vals.size()]); - tileData.put(getIndexInChunk(cx,te_y,cz), vlist); - } - } - } - } - else - ss = w.getEmptyChunkSnapshot(chunk.x, chunk.z, biome, biomeraw); - if(ss != null) { - 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); - } - } - int chunkIndex = (chunk.x-x_min) + (chunk.z - z_min)*x_dim; - snaparray[chunkIndex] = ss; - snaptile[chunkIndex] = tileData; - inhabitedTicks[chunkIndex] = inhabited_ticks; - - /* If wasn't loaded before, we need to do unload */ - if (!wasLoaded) { - /* Since we only remember ones we loaded, and we're synchronous, no player has - * moved, so it must be safe (also prevent chunk leak, which appears to happen - * because isChunkInUse defined "in use" as being within 256 blocks of a player, - * while the actual in-use chunk area for a player where the chunks are managed - * by the MC base server is 21x21 (or about a 160 block radius). - * Also, if we did generate it, need to save it */ - if (w.isChunkInUse(chunk.x, chunk.z) == false) { - if (BukkitVersionHelper.helper.isUnloadChunkBroken()) { - // Give up on broken unloadChunk API - lets see if this works - w.unloadChunkRequest(chunk.x, chunk.z); - } - else { - BukkitVersionHelper.helper.unloadChunkNoSave(w, c, chunk.x, chunk.z); - } - } - endChunkLoad(startTime, ChunkStats.UNLOADED_CHUNKS); - } - else if (isunloadpending) { /* Else, if loaded and unload is pending */ - if (w.isChunkInUse(chunk.x, chunk.z) == false) { - w.unloadChunkRequest(chunk.x, chunk.z); /* Request new unload */ - } - endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS); - } - else { - endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS); - } - } - else { - endChunkLoad(startTime, ChunkStats.UNGENERATED_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; - } - /** - * Test if done loading - */ - public boolean isDoneLoading() { - if(dw.isLoaded() == false) { - isempty = true; - unloadChunks(); - return true; - } - if(iterator != null) - return !iterator.hasNext(); - return false; - } - /** - * Test if all empty blocks - */ - public boolean isEmpty() { - return isempty; - } - /** - * Unload chunks - */ - public void unloadChunks() { - if(snaparray != null) { - for(int i = 0; i < snaparray.length; i++) { - snaparray[i] = null; - } - snaparray = null; - inhabitedTicks = null; - } - } - private void initSectionData(int idx) { - isSectionNotEmpty[idx] = new boolean[nsect + 1]; - if(snaparray[idx] != EMPTY) { - for(int i = 0; i < nsect; i++) { - if(snaparray[idx].isSectionEmpty(i) == false) { - isSectionNotEmpty[idx][i] = true; - } - } - } - } - public boolean isEmptySection(int sx, int sy, int sz) { - int idx = (sx - x_min) + (sz - z_min) * x_dim; - if(isSectionNotEmpty[idx] == null) { - initSectionData(idx); - } - return !isSectionNotEmpty[idx][sy]; - } - - /** - * Get cache iterator - */ - public MapIterator getIterator(int x, int y, int z) { - if(w.getEnvironment().toString().equals("THE_END")) - return new OurEndMapIterator(x, y, z); - return new OurMapIterator(x, y, z); - } - /** - * Set hidden chunk style (default is FILL_AIR) - */ - public void setHiddenFillStyle(HiddenChunkStyle style) { - this.hidestyle = style; - } - /** - * Add visible area limit - can be called more than once - * Needs to be set before chunks are loaded - * Coordinates are block coordinates - */ - public void setVisibleRange(VisibilityLimit lim) { - if(visible_limits == null) - visible_limits = new ArrayList(); - visible_limits.add(lim); - } - /** - * Add hidden area limit - can be called more than once - * Needs to be set before chunks are loaded - * Coordinates are block coordinates - */ - public void setHiddenRange(VisibilityLimit lim) { - if(hidden_limits == null) - hidden_limits = new ArrayList(); - hidden_limits.add(lim); - } - @Override - public boolean setChunkDataTypes(boolean blockdata, boolean biome, boolean highestblocky, boolean rawbiome) { - this.biome = biome; - this.biomeraw = rawbiome; - this.highesty = highestblocky; - this.blockdata = blockdata; - return true; - } - @Override - public DynmapWorld getWorld() { - return dw; - } - - static { - Biome[] b = Biome.values(); - BiomeMap[] bm = BiomeMap.values(); - biome_to_bmap = new BiomeMap[1024]; - for(int i = 0; i < biome_to_bmap.length; i++) { - biome_to_bmap[i] = BiomeMap.NULL; - } - for(int i = 0; i < b.length; i++) { - String bs = b[i].toString(); - for(int j = 0; j < bm.length; j++) { - if(bm[j].toString().equals(bs)) { - biome_to_bmap[b[i].ordinal()] = bm[j]; - break; - } - } - } - } -} diff --git a/helper113/pom.xml b/helper113/pom.xml index 70d29637..948a1924 100644 --- a/helper113/pom.xml +++ b/helper113/pom.xml @@ -2,7 +2,7 @@ 4.0.0 us.dynmap - dynmap-bukkit + dynmap-common 3.0-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index f50c38d4..8f52c457 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 us.dynmap - dynmap-bukkit + dynmap-common dynmap-bukkit ${maven.build.timestamp} @@ -17,7 +17,7 @@ pom - core + bukkit helper113 helper From 47fd51a2473cc972ae6b4ac739c94193e9637635 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Sat, 11 Aug 2018 23:11:20 -0500 Subject: [PATCH 07/50] Switch to gradle build --- build.gradle | 44 ++ bukkit/.gitignore | 1 + bukkit/build.gradle | 53 ++ bukkit/pom.xml | 177 ------ bukkit/src/main/resources/plugin.yml | 764 +++++++++++------------ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54413 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 172 +++++ gradlew.bat | 84 +++ helper/.gitignore | 1 + helper/build.gradle | 9 + helper/pom.xml | 47 -- helper113/.gitignore | 1 + helper113/build.gradle | 10 + helper113/pom.xml | 50 -- pom.xml | 25 - settings.gradle | 8 + 17 files changed, 770 insertions(+), 681 deletions(-) create mode 100644 build.gradle create mode 100644 bukkit/build.gradle delete mode 100644 bukkit/pom.xml create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 helper/build.gradle delete mode 100644 helper/pom.xml create mode 100644 helper113/build.gradle delete mode 100644 helper113/pom.xml delete mode 100644 pom.xml create mode 100644 settings.gradle diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..bd4bcc56 --- /dev/null +++ b/build.gradle @@ -0,0 +1,44 @@ +plugins { + id "com.github.johnrengelman.shadow" version "2.0.4" + id 'java' + id 'maven' + id 'maven-publish' +} + +allprojects { + repositories { + mavenCentral() + mavenLocal() + maven { url "https://oss.sonatype.org/content/repositories/releases" } + maven { url "http://repo.mikeprimm.com" } + maven { url "http://repo.maven.apache.org/maven2" } + maven { url "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" } + maven { url "http://repo.bstats.org/content/repositories/releases/" } + } + + apply plugin: 'java' + + group = 'us.dynmap' + version = '3.0-SNAPSHOT' + +} + +class Globals { + String buildNumber = System.getenv().BUILD_NUMBER ?: "Dev" +} +ext { + globals = new Globals() +} + +subprojects { + apply plugin: "com.github.johnrengelman.shadow" + apply plugin: 'java' + apply plugin: 'maven' + apply plugin: 'maven-publish' + + sourceCompatibility = 1.8 + targetCompatibility = 1.8 + tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' + } +} diff --git a/bukkit/.gitignore b/bukkit/.gitignore index c8ee1df6..72c9368f 100644 --- a/bukkit/.gitignore +++ b/bukkit/.gitignore @@ -1,2 +1,3 @@ /target/ /dependency-reduced-pom.xml +/build/ diff --git a/bukkit/build.gradle b/bukkit/build.gradle new file mode 100644 index 00000000..fcd61d2c --- /dev/null +++ b/bukkit/build.gradle @@ -0,0 +1,53 @@ + +description = 'dynmap' + +dependencies { + compile group: 'org.bukkit', name: 'bukkit', version:'1.7.10-R0.1-SNAPSHOT' + compile 'com.nijikokun.bukkit:Permissions:3.1.6' + compile "us.dynmap:dynmap-api:${project.version}" + compile "us.dynmap:DynmapCore:${project.version}" + compile group: 'ru.tehkode', name: 'PermissionsEx', version:'1.19.1' + compile group: 'de.bananaco', name: 'bPermissions', version:'2.9.1' + compile group: 'com.platymuus.bukkit.permissions', name: 'PermissionsBukkit', version:'1.6' + compile group: 'org.anjocaido', name: 'EssentialsGroupManager', version:'2.10.1' + compile group: 'org.bstats', name: 'bstats-bukkit', version:'1.1' + compile group: 'com.googlecode.json-simple', name: 'json-simple', version:'1.1.1' + compile group: 'com.google.code.gson', name: 'gson', version:'2.8.2' + compile project(':dynmap-helper') + implementation(project(':dynmap-helper-113')) { + transitive = false + } +} + +processResources { + // replace stuff in mcmod.info, nothing else + from('src/main/resources') { + include "plugin.yml" + // replace version and mcversion + expand( + buildnumber: project.parent.ext.globals.buildNumber, + version: project.version + ) + } +} + +jar { + classifier = 'unshaded' +} + +shadowJar { + dependencies { + include(dependency('org.bstats::')) + include(dependency('us.dynmap:dynmap-api:')) + include(dependency('us.dynmap:DynmapCore:')) + include(dependency(':dynmap-helper')) + include(dependency(':dynmap-helper-113')) + } + relocate('org.bstats', 'org.dynmap.bstats') + destinationDir = file '../target' + classifier = '' +} + +artifacts { + archives shadowJar +} diff --git a/bukkit/pom.xml b/bukkit/pom.xml deleted file mode 100644 index 1c05c6b6..00000000 --- a/bukkit/pom.xml +++ /dev/null @@ -1,177 +0,0 @@ - - 4.0.0 - us.dynmap - dynmap - dynmap - http://github.com/webbukkit/dynmap/ - - GitHub - https://github.com/webbukkit/dynmap/issues - - - - - src/main/resources - true - - *.yml - *.txt - - - - src/main/resources - false - - *.yml - *.txt - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 2.0.2 - - 1.8 - 1.8 - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.0.0 - - - - org.bstats:* - us.dynmap:dynmap-api:jar:* - us.dynmap:DynmapCore:jar:* - us.dynmap:dynmap-helper:jar:* - us.dynmap:dynmap-helper-113:jar:* - - - - - org.bstats - org.dynmap - - - - - - package - - shade - - - - - - org.apache.maven.plugins - maven-source-plugin - 2.2.1 - - - attach-sources - - jar - - - - - - - - - - dynmap-repo - http://repo.mikeprimm.com/ - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - bstats-repo - http://repo.bstats.org/content/repositories/releases/ - - - - - com.nijikokun.bukkit - Permissions - 3.1.6 - - - org.bukkit - bukkit - 1.7.10-R0.1-SNAPSHOT - - - us.dynmap - dynmap-api - 3.0-SNAPSHOT - - - us.dynmap - DynmapCore - 3.0-SNAPSHOT - - - ru.tehkode - PermissionsEx - 1.19.1 - - - de.bananaco - bPermissions - 2.9.1 - - - com.platymuus.bukkit.permissions - PermissionsBukkit - 1.6 - - - org.anjocaido - EssentialsGroupManager - 2.10.1 - - - org.bstats - bstats-bukkit - 1.1 - - - com.googlecode.json-simple - json-simple - 1.1.1 - - - - com.google.code.gson - gson - 2.8.2 - - - us.dynmap - dynmap-helper - 3.0-SNAPSHOT - - - us.dynmap - dynmap-helper-113 - 3.0-SNAPSHOT - - - 3.0-SNAPSHOT - - us.dynmap - dynmap-common - 3.0-SNAPSHOT - .. - - diff --git a/bukkit/src/main/resources/plugin.yml b/bukkit/src/main/resources/plugin.yml index 3cfc9d0c..926e8dbf 100644 --- a/bukkit/src/main/resources/plugin.yml +++ b/bukkit/src/main/resources/plugin.yml @@ -1,382 +1,382 @@ -name: dynmap -main: org.dynmap.bukkit.DynmapPlugin -version: "${project.version}-${BUILD_NUMBER}" -authors: [mikeprimm] -website: "http://www.minecraftforum.net/topic/1543523-dynmap-dynamic-web-based-maps-for-minecraft/" -softdepend: [ Permissions, PermissionEx, bPermissions, PermissionsBukkit, GroupManager ] -commands: - dynmap: - description: Controls Dynmap. - usage: | - / hide - hides the player from the map. - / hide TheDude - hides the player 'TheDude' on the map. - / show - shows the player on the map. - / show TheDude - shows the player 'TheDude' on the map. - / render - Renders the tile at your location. - / fullrender - Render all maps for entire world from your location. - / fullrender world - Render all maps for entire world 'world'. - / fullrender world:mapname - Render map 'mapname' of world 'world'. - / radiusrender ## - Render at least ## block radius from your location on all maps. - / radiusrender ## mapname - Render at least ## block radius from your location on map 'mapname' - / radiusrender worldname x z ## - Render at least ## block radius from location x,z on world 'worldname' - / radiusrender worldname x z ## mapname - Render at least ## block radius from location x,z on world 'worldname' on map 'mapname' - / updaterender - Render updates starting at your location on all maps. - / updaterender mapname - Render updates starting at your location on give map - / updaterender worldname x z mapname - Render updates starting at location x,z on world 'worldname' for given map - / cancelrender - Cancels any active renders on current world - / cancelrender world - Cancels any active renders of world 'world' - / stats - Show render statistics. - / triggerstats - Show render trigger statistics - / resetstats - Reset render statistics. - / sendtoweb msg - Send message to web users - / purgequeue - Set tile update queue to empty - / purgequeue worldname - Set tile update queue to empty for world 'worldname' - / purgemap worldname mapname - Delete all the tiles for map 'mapname' of world 'worldname' - / purgeworld worldname - Delete all the files for world 'worldname' - / pause - Show render pause state - / pause - Set render pause state - / quiet - Stop progress messages from active jobs - / ids-for-ip - Show player IDs that have logged in from given IP address - / ips-for-id - Show IP addresses that have been used for the given player ID - / add-id-for-ip - Add player ID to given IP address - / del-id-for-ip - Delete player ID from given IP address - / webregister - Start registration process for creating web login account - - dmarker: - description: Manipulate map markers - usage: | - / add