Compare commits

...

57 Commits

Author SHA1 Message Date
Mike Primm b13c26c0d6 Switch to submodules 2014-10-12 17:32:38 -05:00
Mike Primm 3fd4ac7373 Update to fix Glowstone support 2014-09-13 21:17:37 -05:00
Mike Primm ac0f756fae More Glowstone fixes 2014-09-06 22:25:56 -05:00
Mike Primm 551f35f3f9 Add initial support for Glowstone server 2014-09-06 19:19:20 -05:00
Mike Primm ec9ebf2dbb Add well known 1.7 biomes only when appropriate version 2014-08-22 23:48:12 -05:00
Mike Primm 3702918a6f Add well known 1.7.x biomes only when version is appropriate 2014-08-22 23:15:57 -05:00
Mike Primm 8085221087 Add prefix setting for MySQL table names 2014-08-22 01:50:47 -05:00
mikeprimm 7de967f1c2 Merge pull request #1603 from KovuTheHusky/roundcoords
Add option to round coordinates to nearest integer
2014-08-20 18:10:10 -05:00
mikeprimm f6e127b7f0 Merge pull request #1601 from KovuTheHusky/master
Fix javadoc errors for building with Java SE 8
2014-08-20 18:08:20 -05:00
Mike Primm 22d1923ad5 Add support for 1.7.10 2014-07-09 22:20:33 -05:00
Mike Primm d8d3061696 Add config defaults for MySQL map storage 2014-06-08 21:59:32 -05:00
Kevin Breslin 14da080d52 Add option to round coordinates to nearest integer 2014-05-27 01:34:11 -04:00
Kevin Breslin 10ce166b54 Fix javadoc errors for building with Java SE 8 2014-05-26 22:37:53 -04:00
Mike Primm cb9f964348 Update default suffix 2014-05-10 14:36:50 -05:00
Mike Primm 9850a03945 More comments on storage config 2014-05-10 13:47:14 -05:00
Mike Primm 8abfae3d79 Add storage/type settings to control file tree vs sqlite storage 2014-05-10 00:42:02 -05:00
Mike Primm f486ad75f1 Bump to 2.0.0-SNAPSHOT 2014-05-05 00:30:03 -05:00
Mike Primm 54b3fb429c Switch to SNAPSHOT 2014-04-20 11:47:57 -05:00
Mike Primm 86547f8d78 Bump to 1.9.5 2014-04-20 11:09:49 -05:00
Mike Primm 8ec80937e3 Add plugin versions for sources and javadoc plugins 2014-04-17 08:59:38 -05:00
Mike Primm 0e5e602a90 Add plugin versions for javadocs and sources 2014-04-16 23:02:35 -05:00
Mike Primm 3239d539c0 Add sources and javadoc generation to POM 2014-04-16 22:28:29 -05:00
Mike Primm 05bd2544fd Switch to groupID us.dynmap (owned domain) - sonatype central repo prep 2014-04-16 19:46:47 -05:00
Mike Primm 252da2a5c6 Add exportpath, default-sign-set settings 2014-03-12 00:10:17 -05:00
Mike Primm 5d83ebf8aa Add sign change API to help with marker sign support on MCPC+ 2014-03-11 23:58:01 -05:00
Mike Primm 026cc72233 Bump to 1.9.4 2014-03-08 02:31:06 -06:00
Mike Primm 0d2cceea4b Add /dynmapexp command (for OBJ exporter support) 2014-02-24 00:27:05 -06:00
Mike Primm a1dfae7f79 Bump to 1.9.2 2014-02-06 08:37:24 -06:00
Mike Primm d6eb822b26 Rework chunk loading timing stats - simpler, more useful 2014-02-04 07:05:24 -06:00
Mike Primm d4f161ca99 Remove unneeded synchronized() 2014-02-03 22:29:00 -06:00
Mike Primm 376ec447ed Revert "Add more metrics to chunk loading (for testing)"
This reverts commit 926d2a3dbc.
2014-02-03 22:27:04 -06:00
Mike Primm 926d2a3dbc Add more metrics to chunk loading (for testing) 2014-02-03 21:36:43 -06:00
Mike Primm eeffa4f98d Add stubs for block unique ID support 2014-02-01 01:16:15 -06:00
Mike Primm 8350727a73 Fix inhabitedTime field lookup 2014-01-17 23:05:54 -06:00
Mike Primm 3b79890166 Add getInhabitedTime() 2014-01-17 17:40:39 -06:00
Mike Primm 17174c177c Handle textures loading from other mods 2014-01-11 23:41:23 -06:00
Mike Primm 07e7d53a93 Add debug option for dumping IDs of blocks with no render data 2014-01-06 21:41:12 -06:00
Mike Primm 76863aeb71 Add use-brightness-table setting, and support for world-specific brightness tables 2014-01-04 21:16:29 -06:00
Mike Primm f7d2dac826 Add permissions and help for /dynmap quiet command 2013-12-30 01:46:29 -06:00
Mike Primm 3cb7ba342c Add setting for periodic save of pending jobs 2013-12-30 01:45:17 -06:00
Mike Primm d2ab466dc0 Update server interface for mod-supplied texture/model files 2013-12-28 23:56:22 -06:00
Mike Primm d03ed7a461 Bump to 1.9.2 2013-12-24 10:52:17 -06:00
Mike Primm c8469d7aba Strip version check 2013-12-05 00:11:40 -06:00
Mike Primm e7c92096b2 Turn off version check (dev.bukkit.org doesn't like it...) 2013-12-02 16:12:11 -06:00
Mike Primm 0c9d397144 Update to support CB 1.7.2-R0.1 2013-12-01 08:32:16 -06:00
Mike Primm b4a3b61c11 Start mod support API 2013-11-30 22:51:48 -06:00
Mike Primm 564c38b44a Back to 1.9.1 2013-11-16 23:27:35 -06:00
Mike Primm 664e7da659 Bump to 2.0 2013-10-21 19:33:37 -05:00
Mike Primm 9046212a47 Update for mod image loading support 2013-09-18 17:17:23 -05:00
Mike Primm b6ee68c9b0 Fix comment typo 2013-09-14 16:38:38 -05:00
Mike Primm 7854568d88 Fix typo in security flag for dynmap.webregister.other 2013-09-14 15:56:24 -05:00
Mike Primm f1c9417237 Add support for web server bindaddress to be set to match MC server-ip setting 2013-09-08 00:00:25 -05:00
Mike Primm 336f8302c4 Have spout code handle renderdata not being defined yet 2013-09-07 23:11:35 -05:00
Mike Primm d8ccc26109 Add mod version check code 2013-08-16 02:17:10 -05:00
Mike Primm d396046249 Add block-id-alias setting 2013-08-04 18:07:36 -05:00
Mike Primm 1793d910d4 Straighten out GroupManager offline permissions 2013-07-18 08:44:33 -05:00
Mike Primm f0f881d126 Bump to 1.9 2013-07-07 22:01:02 -05:00
29 changed files with 1838 additions and 865 deletions
+56
View File
@@ -0,0 +1,56 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>us.dynmap</groupId>
<artifactId>DynmapBukkitBase</artifactId>
<name>DynmapBukkitBase</name>
<url>http://github.com/webbukkit/dynmap/</url>
<issueManagement>
<system>GitHub</system>
<url>https://github.com/webbukkit/dynmap/issues</url>
</issueManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<releases>
</releases>
<snapshots>
</snapshots>
<id>bukkit-repo</id>
<url>http://repo.bukkit.org/content/repositories/releases/</url>
</repository>
<repository>
<releases>
</releases>
<snapshots>
</snapshots>
<id>dynmap-repo</id>
<url>http://repo.mikeprimm.com/</url>
</repository>
</repositories>
<version>2.0.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>Bukkit</artifactId>
<version>1.7.10-R0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>us.dynmap</groupId>
<artifactId>DynmapCore</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
@@ -22,48 +22,53 @@ import org.dynmap.utils.MapChunkCache;
import org.dynmap.utils.MapIterator; import org.dynmap.utils.MapIterator;
import org.dynmap.utils.BlockStep; import org.dynmap.utils.BlockStep;
import org.dynmap.utils.VisibilityLimit; import org.dynmap.utils.VisibilityLimit;
import org.getspout.spoutapi.block.SpoutChunk;
/** /**
* Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread * Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread
*/ */
public class NewMapChunkCache implements MapChunkCache { public abstract class BaseMapChunkCache extends MapChunkCache {
private static boolean init = false; private static boolean init = false;
private static boolean use_spout = false;
private World w; protected World w;
private DynmapWorld dw; protected DynmapWorld dw;
private int nsect; private int nsect;
private List<DynmapChunk> chunks; protected List<DynmapChunk> chunks;
private ListIterator<DynmapChunk> iterator; protected ListIterator<DynmapChunk> iterator;
private int x_min, x_max, z_min, z_max; protected int x_min;
private int x_dim;
private boolean biome, biomeraw, highesty, blockdata; private int x_max;
private HiddenChunkStyle hidestyle = HiddenChunkStyle.FILL_AIR;
private List<VisibilityLimit> visible_limits = null; protected int z_min;
private List<VisibilityLimit> hidden_limits = null;
private boolean isempty = true; private int z_max;
protected int x_dim;
protected boolean biome;
protected boolean biomeraw;
protected boolean highesty;
protected boolean blockdata;
protected HiddenChunkStyle hidestyle = HiddenChunkStyle.FILL_AIR;
protected List<VisibilityLimit> visible_limits = null;
protected List<VisibilityLimit> hidden_limits = null;
protected boolean isempty = true;
private int snapcnt; private int snapcnt;
private ChunkSnapshot[] snaparray; /* Index = (x-x_min) + ((z-z_min)*x_dim) */ protected ChunkSnapshot[] snaparray; /* Index = (x-x_min) + ((z-z_min)*x_dim) */
private DynIntHashMap[] snaptile; protected DynIntHashMap[] snaptile;
private byte[][] sameneighborbiomecnt; private byte[][] sameneighborbiomecnt;
private BiomeMap[][] biomemap; private BiomeMap[][] biomemap;
private boolean[][] isSectionNotEmpty; /* Indexed by snapshot index, then by section index */ private boolean[][] isSectionNotEmpty; /* Indexed by snapshot index, then by section index */
protected long[] inhabitedTicks; /* Index = (x-x_min) + ((z-z_min)*x_dim) */
private int chunks_read; /* Number of chunks actually loaded */ protected static BukkitVersionHelper helper = BukkitVersionHelper.getHelper();
private int chunks_attempted; /* Number of chunks attempted to load */
private long total_loadtime; /* Total time loading chunks, in nanoseconds */
private long exceptions;
private static BukkitVersionHelper helper = BukkitVersionHelper.getHelper();
private static final BlockStep unstep[] = { BlockStep.X_MINUS, BlockStep.Y_MINUS, BlockStep.Z_MINUS, private static final BlockStep unstep[] = { BlockStep.X_MINUS, BlockStep.Y_MINUS, BlockStep.Z_MINUS,
BlockStep.X_PLUS, BlockStep.Y_PLUS, BlockStep.Z_PLUS }; BlockStep.X_PLUS, BlockStep.Y_PLUS, BlockStep.Z_PLUS };
private static BiomeMap[] biome_to_bmap; private static BiomeMap[] biome_to_bmap;
private static final int getIndexInChunk(int cx, int cy, int cz) { protected static final int getIndexInChunk(int cx, int cy, int cz) {
return (cy << 8) | (cz << 4) | cx; return (cy << 8) | (cz << 4) | cx;
} }
@@ -166,9 +171,6 @@ public class NewMapChunkCache implements MapChunkCache {
if(snap != biome_css) { if(snap != biome_css) {
biomebase = null; biomebase = null;
biome_css = snap; biome_css = snap;
if (biome_css instanceof SpoutChunkSnapshot) {
biome_css = ((SpoutChunkSnapshot)biome_css).chunk;
}
biomebase = helper.getBiomeBaseFromSnapshot(biome_css); biomebase = helper.getBiomeBaseFromSnapshot(biome_css);
} }
if(biomebase != null) { if(biomebase != null) {
@@ -210,7 +212,6 @@ public class NewMapChunkCache implements MapChunkCache {
try { try {
return biomemap[x - x_base][z - z_base]; return biomemap[x - x_base][z - z_base];
} catch (Exception ex) { } catch (Exception ex) {
exceptions++;
return BiomeMap.NULL; return BiomeMap.NULL;
} }
} }
@@ -240,7 +241,6 @@ public class NewMapChunkCache implements MapChunkCache {
mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9);
} }
} catch (Exception x) { } catch (Exception x) {
exceptions++;
mult = 0xFFFFFF; mult = 0xFFFFFF;
} }
return mult; return mult;
@@ -271,7 +271,6 @@ public class NewMapChunkCache implements MapChunkCache {
mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9);
} }
} catch (Exception x) { } catch (Exception x) {
exceptions++;
mult = 0xFFFFFF; mult = 0xFFFFFF;
} }
return mult; return mult;
@@ -313,7 +312,6 @@ public class NewMapChunkCache implements MapChunkCache {
mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9);
} }
} catch (Exception x) { } catch (Exception x) {
exceptions++;
mult = 0xFFFFFF; mult = 0xFFFFFF;
} }
return mult; return mult;
@@ -341,7 +339,6 @@ public class NewMapChunkCache implements MapChunkCache {
} }
return ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); return ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9);
} catch (Exception x) { } catch (Exception x) {
exceptions++;
return 0xFFFFFF; return 0xFFFFFF;
} }
} }
@@ -371,7 +368,6 @@ public class NewMapChunkCache implements MapChunkCache {
mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9); mult = ((raccum / 9) << 16) | ((gaccum / 9) << 8) | (baccum / 9);
} }
} catch (Exception x) { } catch (Exception x) {
exceptions++;
mult = 0xFFFFFF; mult = 0xFFFFFF;
} }
return mult; return mult;
@@ -593,6 +589,14 @@ public class NewMapChunkCache implements MapChunkCache {
int yoff, int zoff) { int yoff, int zoff) {
return null; return null;
} }
@Override
public long getInhabitedTicks() {
try {
return inhabitedTicks[chunkindex];
} catch (Exception x) {
return 0;
}
}
} }
private class OurEndMapIterator extends OurMapIterator { private class OurEndMapIterator extends OurMapIterator {
@@ -680,68 +684,16 @@ public class NewMapChunkCache implements MapChunkCache {
return (sy < 4); return (sy < 4);
} }
} }
private static class SpoutChunkSnapshot implements ChunkSnapshot {
private ChunkSnapshot chunk;
private short[] customids;
private final int shiftx;
private final int shiftz;
SpoutChunkSnapshot(ChunkSnapshot chunk, short[] customids, int height) {
this.chunk = chunk;
this.customids = customids.clone();
int sx = 11;
int sz = 7; /* 128 high values */
while(height > 128) {
sx++;
sz++;
height = (height >> 1);
}
shiftx = sx;
shiftz = sz;
}
/* Need these for interface, but not used */
public final int getX() { return chunk.getX(); }
public final int getZ() { return chunk.getZ(); }
public final String getWorldName() { return chunk.getWorldName(); }
public final Biome getBiome(int x, int z) { return chunk.getBiome(x, z); }
public final double getRawBiomeTemperature(int x, int z) { return chunk.getRawBiomeTemperature(x, z); }
public final double getRawBiomeRainfall(int x, int z) { return chunk.getRawBiomeRainfall(x, z); }
public final long getCaptureFullTime() { return chunk.getCaptureFullTime(); }
public final int getBlockTypeId(int x, int y, int z) {
int id = customids[(x << shiftx) | (z << shiftz) | y];
if(id != 0) return id;
return chunk.getBlockTypeId(x, y, z);
}
public final int getBlockData(int x, int y, int z) {
return chunk.getBlockData(x, y, z);
}
public final int getBlockSkyLight(int x, int y, int z) {
return chunk.getBlockSkyLight(x, y, z);
}
public final int getBlockEmittedLight(int x, int y, int z) {
return chunk.getBlockEmittedLight(x, y, z);
}
public final int getHighestBlockYAt(int x, int z) {
return chunk.getHighestBlockYAt(x, z);
}
public boolean isSectionEmpty(int sy) {
return chunk.isSectionEmpty(sy);
}
}
private static final EmptyChunk EMPTY = new EmptyChunk(); protected static final EmptyChunk EMPTY = new EmptyChunk();
private static final PlainChunk STONE = new PlainChunk(1); protected static final PlainChunk STONE = new PlainChunk(1);
private static final PlainChunk OCEAN = new PlainChunk(9); protected static final PlainChunk OCEAN = new PlainChunk(9);
/** /**
* Construct empty cache * Construct empty cache
*/ */
public NewMapChunkCache() { public BaseMapChunkCache() {
if(!init) { if(!init) {
use_spout = DynmapPlugin.plugin.hasSpout();
init = true; init = true;
} }
} }
@@ -779,199 +731,25 @@ public class NewMapChunkCache implements MapChunkCache {
snapcnt = x_dim * (z_max-z_min+1); snapcnt = x_dim * (z_max-z_min+1);
snaparray = new ChunkSnapshot[snapcnt]; snaparray = new ChunkSnapshot[snapcnt];
inhabitedTicks = new long[snapcnt];
snaptile = new DynIntHashMap[snapcnt]; snaptile = new DynIntHashMap[snapcnt];
isSectionNotEmpty = new boolean[snapcnt][]; isSectionNotEmpty = new boolean[snapcnt][];
} }
private ChunkSnapshot checkSpoutData(Chunk c, ChunkSnapshot ss) {
if(c instanceof SpoutChunk) {
SpoutChunk sc = (SpoutChunk)c;
short[] custids = sc.getCustomBlockIds();
if(custids != null) {
return new SpoutChunkSnapshot(ss, custids, c.getWorld().getMaxHeight());
}
}
return ss;
}
public int loadChunks(int max_to_load) {
if(dw.isLoaded() == false)
return 0;
long t0 = System.nanoTime();
Object queue = helper.getUnloadQueue(helper.getNMSWorld(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()) {
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;
DynIntHashMap tileData = null;
SnapshotRec ssr = DynmapPlugin.plugin.sscache.getSnapshot(dw.getName(), chunk.x, chunk.z, blockdata, biome, biomeraw, highesty);
if(ssr != null) {
ss = ssr.ss;
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;
continue;
}
chunks_attempted++;
boolean wasLoaded = w.isChunkLoaded(chunk.x, chunk.z);
boolean didload = false;
boolean isunloadpending = false;
if (queue != null) {
isunloadpending = 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 */
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);
if(use_spout) {
ss = checkSpoutData(c, ss);
}
/* Get tile entity data */
List<Object> vals = new ArrayList<Object>();
Map<?,?> tileents = 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 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);
if(te_fields != null) {
Object nbtcompound = helper.readTileEntityNBT(t);
vals.clear();
for(String id: te_fields) {
Object val = 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.tileData = tileData;
DynmapPlugin.plugin.sscache.putSnapshot(dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty);
}
}
snaparray[(chunk.x-x_min) + (chunk.z - z_min)*x_dim] = ss;
snaptile[(chunk.x-x_min) + (chunk.z - z_min)*x_dim] = tileData;
/* If wasn't loaded before, we need to do unload */
if (!wasLoaded) {
chunks_read++;
/* 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 */
helper.unloadChunkNoSave(w, c, chunk.x, chunk.z);
}
else if (isunloadpending) { /* Else, if loaded and unload is pending */
w.unloadChunkRequest(chunk.x, chunk.z); /* Request new unload */
}
}
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;
}
}
total_loadtime += System.nanoTime() - t0;
return cnt;
}
/** /**
* Test if done loading * Loading call executed from main server thread - must
* @param max_to_load - maximum number to load at once
* @return number loaded
*/ */
public boolean isDoneLoading() { public abstract int loadChunks(int max_to_load);
if(dw.isLoaded() == false) { /**
isempty = true; * Test if done loading (no more loadChunks calls needed)
unloadChunks(); */
return true; public abstract boolean isDoneLoading();
} /**
if(iterator != null) * Read call executed from off of main thread (if off thread loading is supported)
return !iterator.hasNext(); */
return false; public abstract int readChunks();
}
/** /**
* Test if all empty blocks * Test if all empty blocks
*/ */
@@ -979,7 +757,7 @@ public class NewMapChunkCache implements MapChunkCache {
return isempty; return isempty;
} }
/** /**
* Unload chunks * Unload chunks (cleanup - if needed)
*/ */
public void unloadChunks() { public void unloadChunks() {
if(snaparray != null) { if(snaparray != null) {
@@ -987,8 +765,10 @@ public class NewMapChunkCache implements MapChunkCache {
snaparray[i] = null; snaparray[i] = null;
} }
snaparray = null; snaparray = null;
inhabitedTicks = null;
} }
} }
private void initSectionData(int idx) { private void initSectionData(int idx) {
isSectionNotEmpty[idx] = new boolean[nsect + 1]; isSectionNotEmpty[idx] = new boolean[nsect + 1];
if(snaparray[idx] != EMPTY) { if(snaparray[idx] != EMPTY) {
@@ -1053,22 +833,6 @@ public class NewMapChunkCache implements MapChunkCache {
public DynmapWorld getWorld() { public DynmapWorld getWorld() {
return dw; return dw;
} }
@Override
public int getChunksLoaded() {
return chunks_read;
}
@Override
public int getChunkLoadsAttempted() {
return chunks_attempted;
}
@Override
public long getTotalRuntimeNanos() {
return total_loadtime;
}
@Override
public long getExceptionCount() {
return exceptions;
}
static { static {
Biome[] b = Biome.values(); Biome[] b = Biome.values();
@@ -5,11 +5,13 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.ChunkSnapshot; import org.bukkit.ChunkSnapshot;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Player;
import org.dynmap.Log; import org.dynmap.Log;
/** /**
@@ -21,6 +23,7 @@ public abstract class BukkitVersionHelper {
public static final BukkitVersionHelper getHelper() { public static final BukkitVersionHelper getHelper() {
if(helper == null) { if(helper == null) {
Log.info("version=" + Bukkit.getServer().getVersion());
if(Bukkit.getServer().getVersion().contains("MCPC")) { if(Bukkit.getServer().getVersion().contains("MCPC")) {
Log.severe("*********************************************************************************"); Log.severe("*********************************************************************************");
Log.severe("* MCPC-Plus is no longer supported via the Bukkit version of Dynmap. *"); Log.severe("* MCPC-Plus is no longer supported via the Bukkit version of Dynmap. *");
@@ -35,6 +38,10 @@ public abstract class BukkitVersionHelper {
Log.severe("* Add the DynmapCBBridge plugin to enable support for Dynmap-compatible plugins *"); Log.severe("* Add the DynmapCBBridge plugin to enable support for Dynmap-compatible plugins *");
Log.severe("*********************************************************************************"); Log.severe("*********************************************************************************");
} }
else if(Bukkit.getServer().getClass().getName().contains("GlowServer")) {
Log.info("Loading Glowstone support");
helper = new BukkitVersionHelperGlowstone();
}
else { else {
helper = new BukkitVersionHelperCB(); helper = new BukkitVersionHelperCB();
} }
@@ -64,14 +71,10 @@ public abstract class BukkitVersionHelper {
* Get ID from biomebase * Get ID from biomebase
*/ */
public abstract int getBiomeBaseID(Object bb); public abstract int getBiomeBaseID(Object bb);
/**
* Get net.minecraft.server.world for given world
*/
public abstract Object getNMSWorld(World w);
/** /**
* Get unload queue for given NMS world * Get unload queue for given NMS world
*/ */
public abstract Object getUnloadQueue(Object nmsworld); public abstract Object getUnloadQueue(World world);
/** /**
* For testing unload queue for presence of givne chunk * For testing unload queue for presence of givne chunk
*/ */
@@ -80,14 +83,14 @@ public abstract class BukkitVersionHelper {
* Read raw biome ID from snapshot * Read raw biome ID from snapshot
*/ */
public abstract Object[] getBiomeBaseFromSnapshot(ChunkSnapshot css); public abstract Object[] getBiomeBaseFromSnapshot(ChunkSnapshot css);
/**
* Test if normal chunk snapshot
*/
public abstract boolean isCraftChunkSnapshot(ChunkSnapshot css);
/** /**
* Remove entities from given chunk * Remove entities from given chunk
*/ */
public abstract void removeEntitiesFromChunk(Chunk c); public abstract void removeEntitiesFromChunk(Chunk c);
/**
* Get inhabited ticks count from chunk
*/
public abstract long getInhabitedTicks(Chunk c);
/** /**
* Get tile entities map from chunk * Get tile entities map from chunk
*/ */
@@ -128,4 +131,12 @@ public abstract class BukkitVersionHelper {
* Get block material index list * Get block material index list
*/ */
public abstract int[] getBlockMaterialMap(); public abstract int[] getBlockMaterialMap();
/**
* Get list of online players
*/
public abstract Player[] getOnlinePlayers();
/**
* Get player health
*/
public abstract int getHealth(Player p);
} }
@@ -1,6 +1,7 @@
package org.dynmap.bukkit; package org.dynmap.bukkit;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Map; import java.util.Map;
@@ -21,6 +22,7 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric {
private Field blockbyid; private Field blockbyid;
private Field blockname; private Field blockname;
private Field material; private Field material;
private Method blockbyidfunc; // 1.7+ method for getting block by id
BukkitVersionHelperCB() { BukkitVersionHelperCB() {
} }
@@ -43,17 +45,20 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric {
nmsblock = getNMSClass("net.minecraft.server.Block"); nmsblock = getNMSClass("net.minecraft.server.Block");
nmsblockarray = getNMSClass("[Lnet.minecraft.server.Block;"); nmsblockarray = getNMSClass("[Lnet.minecraft.server.Block;");
nmsmaterial = getNMSClass("net.minecraft.server.Material"); nmsmaterial = getNMSClass("net.minecraft.server.Material");
blockbyid = getField(nmsblock, new String[] { "byId" }, nmsblockarray); blockbyid = getFieldNoFail(nmsblock, new String[] { "byId" }, nmsblockarray);
if (blockbyid == null) {
blockbyidfunc = getMethod(nmsblock, new String[] { "getById", "e" }, new Class[] { int.class });
}
blockname = getPrivateField(nmsblock, new String[] { "name", "b" }, String.class); blockname = getPrivateField(nmsblock, new String[] { "name", "b" }, String.class);
material = getField(nmsblock, new String[] { "material" }, nmsmaterial); material = getPrivateField(nmsblock, new String[] { "material" }, nmsmaterial);
/* Set up biomebase fields */ /* Set up biomebase fields */
biomebase = getNMSClass("net.minecraft.server.BiomeBase"); biomebase = getNMSClass("net.minecraft.server.BiomeBase");
biomebasearray = getNMSClass("[Lnet.minecraft.server.BiomeBase;"); biomebasearray = getNMSClass("[Lnet.minecraft.server.BiomeBase;");
biomebaselist = getField(biomebase, new String[] { "biomes" }, biomebasearray); biomebaselist = getPrivateField(biomebase, new String[] { "biomes" }, biomebasearray);
biomebasetemp = getField(biomebase, new String[] { "temperature", "F" }, float.class); biomebasetemp = getField(biomebase, new String[] { "temperature", "F" }, float.class);
biomebasehumi = getField(biomebase, new String[] { "humidity", "G" }, float.class); biomebasehumi = getField(biomebase, new String[] { "humidity", "G" }, float.class);
biomebaseidstring = getField(biomebase, new String[] { "y" }, String.class); biomebaseidstring = getField(biomebase, new String[] { "y", "af" }, String.class);
biomebaseid = getField(biomebase, new String[] { "id" }, int.class); biomebaseid = getField(biomebase, new String[] { "id" }, int.class);
/* n.m.s.World */ /* n.m.s.World */
nmsworld = getNMSClass("net.minecraft.server.WorldServer"); nmsworld = getNMSClass("net.minecraft.server.WorldServer");
@@ -76,7 +81,11 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric {
/** n.m.s.Chunk */ /** n.m.s.Chunk */
nmschunk = getNMSClass("net.minecraft.server.Chunk"); nmschunk = getNMSClass("net.minecraft.server.Chunk");
nmsc_removeentities = getMethod(nmschunk, new String[] { "removeEntities" }, new Class[0]); nmsc_removeentities = getMethod(nmschunk, new String[] { "removeEntities" }, new Class[0]);
nmsc_tileentities = getField(nmschunk, new String[] { "tileEntities" }, Map.class); nmsc_tileentities = getField(nmschunk, new String[] { "tileEntities" }, Map.class);
nmsc_inhabitedticks = getFieldNoFail(nmschunk, new String[] { "s", "q" }, long.class);
if (nmsc_inhabitedticks == null) {
Log.info("inhabitedTicks field not found - inhabited shader not functional");
}
/** nbt classes */ /** nbt classes */
nbttagcompound = getNMSClass("net.minecraft.server.NBTTagCompound"); nbttagcompound = getNMSClass("net.minecraft.server.NBTTagCompound");
nbttagbyte = getNMSClass("net.minecraft.server.NBTTagByte"); nbttagbyte = getNMSClass("net.minecraft.server.NBTTagByte");
@@ -89,15 +98,15 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric {
nbttagstring = getNMSClass("net.minecraft.server.NBTTagString"); nbttagstring = getNMSClass("net.minecraft.server.NBTTagString");
nbttagintarray = getNMSClass("net.minecraft.server.NBTTagIntArray"); nbttagintarray = getNMSClass("net.minecraft.server.NBTTagIntArray");
compound_get = getMethod(nbttagcompound, new String[] { "get" }, new Class[] { String.class }); compound_get = getMethod(nbttagcompound, new String[] { "get" }, new Class[] { String.class });
nbttagbyte_val = getField(nbttagbyte, new String[] { "data" }, byte.class); nbttagbyte_val = getPrivateField(nbttagbyte, new String[] { "data" }, byte.class);
nbttagshort_val = getField(nbttagshort, new String[] { "data" }, short.class); nbttagshort_val = getPrivateField(nbttagshort, new String[] { "data" }, short.class);
nbttagint_val = getField(nbttagint, new String[] { "data" }, int.class); nbttagint_val = getPrivateField(nbttagint, new String[] { "data" }, int.class);
nbttaglong_val = getField(nbttaglong, new String[] { "data" }, long.class); nbttaglong_val = getPrivateField(nbttaglong, new String[] { "data" }, long.class);
nbttagfloat_val = getField(nbttagfloat, new String[] { "data" }, float.class); nbttagfloat_val = getPrivateField(nbttagfloat, new String[] { "data" }, float.class);
nbttagdouble_val = getField(nbttagdouble, new String[] { "data" }, double.class); nbttagdouble_val = getPrivateField(nbttagdouble, new String[] { "data" }, double.class);
nbttagbytearray_val = getField(nbttagbytearray, new String[] { "data" }, byte[].class); nbttagbytearray_val = getPrivateField(nbttagbytearray, new String[] { "data" }, byte[].class);
nbttagstring_val = getField(nbttagstring, new String[] { "data" }, String.class); nbttagstring_val = getPrivateField(nbttagstring, new String[] { "data" }, String.class);
nbttagintarray_val = getField(nbttagintarray, new String[] { "data" }, int[].class); nbttagintarray_val = getPrivateField(nbttagintarray, new String[] { "data" }, int[].class);
/** Tile entity */ /** Tile entity */
nms_tileentity = getNMSClass("net.minecraft.server.TileEntity"); nms_tileentity = getNMSClass("net.minecraft.server.TileEntity");
@@ -117,16 +126,27 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric {
@Override @Override
public String[] getBlockShortNames() { public String[] getBlockShortNames() {
try { try {
Object[] byid = (Object[])blockbyid.get(nmsblock); String[] names = new String[4096];
String[] names = new String[byid.length]; if (blockbyid != null) {
for (int i = 0; i < names.length; i++) { Object[] byid = (Object[])blockbyid.get(nmsblock);
if (byid[i] != null) { for (int i = 0; i < names.length; i++) {
names[i] = (String)blockname.get(byid[i]); if (byid[i] != null) {
names[i] = (String)blockname.get(byid[i]);
}
}
}
else {
for (int i = 0; i < names.length; i++) {
Object blk = blockbyidfunc.invoke(nmsblock, i);
if (blk != null) {
names[i] = (String)blockname.get(blk);
}
} }
} }
return names; return names;
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
} }
return new String[0]; return new String[0];
} }
@@ -153,27 +173,49 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric {
*/ */
public int[] getBlockMaterialMap() { public int[] getBlockMaterialMap() {
try { try {
Object[] byid = (Object[])blockbyid.get(nmsblock); int[] map = new int[4096];
int[] map = new int[byid.length]; if (blockbyid != null) {
ArrayList<Object> mats = new ArrayList<Object>(); Object[] byid = (Object[])blockbyid.get(nmsblock);
for (int i = 0; i < map.length; i++) { ArrayList<Object> mats = new ArrayList<Object>();
if (byid[i] != null) { for (int i = 0; i < map.length; i++) {
Object mat = (Object)material.get(byid[i]); if (byid[i] != null) {
if (mat != null) { Object mat = (Object)material.get(byid[i]);
map[i] = mats.indexOf(mat); if (mat != null) {
if (map[i] < 0) { map[i] = mats.indexOf(mat);
map[i] = mats.size(); if (map[i] < 0) {
mats.add(mat); map[i] = mats.size();
mats.add(mat);
}
}
else {
map[i] = -1;
} }
} }
else { }
map[i] = -1; }
else {
ArrayList<Object> mats = new ArrayList<Object>();
for (int i = 0; i < map.length; i++) {
Object blk = blockbyidfunc.invoke(nmsblock, i);
if (blk != null) {
Object mat = (Object)material.get(blk);
if (mat != null) {
map[i] = mats.indexOf(mat);
if (map[i] < 0) {
map[i] = mats.size();
mats.add(mat);
}
}
else {
map[i] = -1;
}
} }
} }
} }
return map; return map;
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
} }
return new int[0]; return new int[0];
} }
@@ -3,13 +3,17 @@ package org.dynmap.bukkit;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.ChunkSnapshot; import org.bukkit.ChunkSnapshot;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Player;
import org.dynmap.Log; import org.dynmap.Log;
/** /**
@@ -51,6 +55,7 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
protected Class<?> nmschunk; protected Class<?> nmschunk;
protected Method nmsc_removeentities; protected Method nmsc_removeentities;
protected Field nmsc_tileentities; protected Field nmsc_tileentities;
protected Field nmsc_inhabitedticks;
/** nbt classes */ /** nbt classes */
protected Class<?> nbttagcompound; protected Class<?> nbttagcompound;
protected Class<?> nbttagbyte; protected Class<?> nbttagbyte;
@@ -78,6 +83,10 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
protected Field nmst_x; protected Field nmst_x;
protected Field nmst_y; protected Field nmst_y;
protected Field nmst_z; protected Field nmst_z;
/** Server */
protected Method server_getonlineplayers;
/** Player */
protected Method player_gethealth;
BukkitVersionHelperGeneric() { BukkitVersionHelperGeneric() {
failed = false; failed = false;
@@ -98,6 +107,12 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
/* CraftChunk */ /* CraftChunk */
craftchunk = getOBCClass("org.bukkit.craftbukkit.CraftChunk"); craftchunk = getOBCClass("org.bukkit.craftbukkit.CraftChunk");
cc_gethandle = getMethod(craftchunk, new String[] { "getHandle" }, new Class[0]); cc_gethandle = getMethod(craftchunk, new String[] { "getHandle" }, new Class[0]);
/** Server */
server_getonlineplayers = getMethod(Server.class, new String[] { "getOnlinePlayers" }, new Class[0]);
/** Player */
player_gethealth = getMethod(Player.class, new String[] { "getHealth" }, new Class[0]);
/* Get NMS classes and fields */ /* Get NMS classes and fields */
if(!failed) if(!failed)
loadNMS(); loadNMS();
@@ -254,13 +269,13 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
} }
/* Get net.minecraft.server.world for given world */ /* Get net.minecraft.server.world for given world */
public Object getNMSWorld(World w) { protected Object getNMSWorld(World w) {
return callMethod(w, cw_gethandle, nullargs, null); return callMethod(w, cw_gethandle, nullargs, null);
} }
/* Get unload queue for given NMS world */ /* Get unload queue for given NMS world */
public Object getUnloadQueue(Object nmsworld) { public Object getUnloadQueue(World world) {
Object cps = getFieldValue(nmsworld, nmsw_chunkproviderserver, null); // Get chunkproviderserver Object cps = getFieldValue(getNMSWorld(world), nmsw_chunkproviderserver, null); // Get chunkproviderserver
if(cps != null) { if(cps != null) {
return getFieldValue(cps, cps_unloadqueue, null); return getFieldValue(cps, cps_unloadqueue, null);
} }
@@ -278,12 +293,12 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
public Object[] getBiomeBaseFromSnapshot(ChunkSnapshot css) { public Object[] getBiomeBaseFromSnapshot(ChunkSnapshot css) {
return (Object[])getFieldValue(css, ccss_biome, null); return (Object[])getFieldValue(css, ccss_biome, null);
} }
public boolean isCraftChunkSnapshot(ChunkSnapshot css) { // public boolean isCraftChunkSnapshot(ChunkSnapshot css) {
if(craftchunksnapshot != null) { // if(craftchunksnapshot != null) {
return craftchunksnapshot.isAssignableFrom(css.getClass()); // return craftchunksnapshot.isAssignableFrom(css.getClass());
} // }
return false; // return false;
} // }
/** Remove entities from given chunk */ /** Remove entities from given chunk */
public void removeEntitiesFromChunk(Chunk c) { public void removeEntitiesFromChunk(Chunk c) {
Object omsc = callMethod(c, cc_gethandle, nullargs, null); Object omsc = callMethod(c, cc_gethandle, nullargs, null);
@@ -291,6 +306,21 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
callMethod(omsc, nmsc_removeentities, nullargs, null); callMethod(omsc, nmsc_removeentities, nullargs, null);
} }
} }
/**
* Get inhabited ticks count from chunk
*/
private static final Long zero = new Long(0);
public long getInhabitedTicks(Chunk c) {
if (nmsc_inhabitedticks == null) {
return 0;
}
Object omsc = callMethod(c, cc_gethandle, nullargs, null);
if(omsc != null) {
return (Long)getFieldValue(omsc, nmsc_inhabitedticks, zero);
}
return 0;
}
/** Get tile entities map from chunk */ /** Get tile entities map from chunk */
public Map getTileEntitiesForChunk(Chunk c) { public Map getTileEntitiesForChunk(Chunk c) {
Object omsc = callMethod(c, cc_gethandle, nullargs, null); Object omsc = callMethod(c, cc_gethandle, nullargs, null);
@@ -369,4 +399,31 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
} }
return null; return null;
} }
/**
* Get list of online players
*/
public Player[] getOnlinePlayers() {
Object players = callMethod(Bukkit.getServer(), server_getonlineplayers, nullargs, null);
if (players instanceof Player[]) { /* Pre 1.7.10 */
return (Player[]) players;
}
else {
@SuppressWarnings("unchecked")
Collection<? extends Player> p = (Collection<? extends Player>) players;
return p.toArray(new Player[0]);
}
}
/**
* Get player health
*/
public int getHealth(Player p) {
Object health = callMethod(p, player_gethealth, nullargs, null);
if (health instanceof Integer) {
return (Integer) health;
}
else {
return ((Double) health).intValue();
}
}
} }
@@ -0,0 +1,451 @@
package org.dynmap.bukkit;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.ChunkSnapshot;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Player;
public class BukkitVersionHelperGlowstone extends BukkitVersionHelper {
private Method rawbiome;
private Method server_getonlineplayers;
public BukkitVersionHelperGlowstone() {
try {
Class<?> c = Class.forName("net.glowstone.GlowChunkSnapshot");
rawbiome = c.getMethod("getRawBiomes", new Class[0]);
/** Server */
server_getonlineplayers = Server.class.getMethod("getOnlinePlayers", new Class[0]);
} catch (SecurityException e) {
} catch (NoSuchMethodException e) {
} catch (ClassNotFoundException e) {
}
if ((rawbiome == null) && (server_getonlineplayers == null)) {
throw new IllegalArgumentException("Error initializing dynmap - Glowstone version incompatible!");
}
}
@Override
public Object[] getBiomeBaseList() {
return new Object[0];
}
@Override
public float getBiomeBaseTemperature(Object bb) {
return 0;
}
@Override
public float getBiomeBaseHumidity(Object bb) {
return 0;
}
@Override
public String getBiomeBaseIDString(Object bb) {
return "";
}
@Override
public int getBiomeBaseID(Object bb) {
if (bb != null)
return (Integer) bb;
else
return 0;
}
@Override
public Object getUnloadQueue(World world) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isInUnloadQueue(Object unloadqueue, int x, int z) {
// TODO Auto-generated method stub
return false;
}
@Override
public Object[] getBiomeBaseFromSnapshot(ChunkSnapshot css) {
Integer b[] = new Integer[256];
byte[] rb = null;
try {
rb = (byte[]) rawbiome.invoke(css, new Object[0]);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
if (rb != null) {
for (int i = 0; i < 256; i++) {
b[i] = Integer.valueOf(255 & (int)rb[i]);
}
}
return b;
}
@Override
public void removeEntitiesFromChunk(Chunk c) {
// TODO Auto-generated method stub
}
@Override
public long getInhabitedTicks(Chunk c) {
// TODO Auto-generated method stub
return 0;
}
@Override
public Map getTileEntitiesForChunk(Chunk c) {
// TODO Auto-generated method stub
return Collections.emptyMap();
}
@Override
public int getTileEntityX(Object te) {
// TODO Auto-generated method stub
return 0;
}
@Override
public int getTileEntityY(Object te) {
// TODO Auto-generated method stub
return 0;
}
@Override
public int getTileEntityZ(Object te) {
// TODO Auto-generated method stub
return 0;
}
@Override
public Object readTileEntityNBT(Object te) {
// TODO Auto-generated method stub
return null;
}
@Override
public Object getFieldValue(Object nbt, String field) {
// TODO Auto-generated method stub
return null;
}
@Override
public void unloadChunkNoSave(World w, Chunk c, int cx, int cz) {
// TODO Auto-generated method stub
}
@Override
public String[] getBlockShortNames() {
// TODO Auto-generated method stub
return null;
}
private static final String[] bnames = {
"Ocean",
"Plains",
"Desert",
"Extreme Hills",
"Forest",
"Taiga",
"Swampland",
"River",
"Hell",
"Sky",
"FrozenOcean",
"FrozenRiver",
"Ice Plains",
"Ice Mountains",
"MushroomIsland",
"MushroomIslandShore",
"Beach",
"DesertHills",
"ForestHills",
"TaigaHills",
"Extreme Hills Edge",
"Jungle",
"JungleHills",
"JungleEdge",
"Deep Ocean",
"Stone Beach",
"Cold Beach",
"Birch Forest",
"Birch Forest Hills",
"Roofed Forest",
"Cold Taiga",
"Cold Taiga Hills",
"Mega Taiga",
"Mega Taiga Hills",
"Extreme Hills+",
"Savanna",
"Savanna Plateau",
"Mesa",
"Mesa Plateau F",
"Mesa Plateau",
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
"Sunflower Plains",
"Desert M",
"Extreme Hills M",
"Flower Forest",
"Taiga M",
"Swampland M",
null,
null,
null,
null,
null,
"Ice Plains Spikes",
null,
null,
null,
null,
null,
null,
null,
null,
"Jungle M",
null,
"JungleEdge M",
null,
null,
null,
"Birch Forest M",
"Birch Forest Hills M",
"Roofed Forest M",
"Cold Taiga M",
null,
"Mega Spruce Taiga",
"Mega Spruce Taiga",
"Extreme Hills+ M",
"Savanna M",
"Savanna Plateau M",
"Mesa (Bryce)",
"Mesa Plateau F M",
"Mesa Plateau M",
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null
};
@Override
public String[] getBiomeNames() {
return bnames;
}
@Override
public int[] getBlockMaterialMap() {
// TODO Auto-generated method stub
return null;
}
/**
* Get list of online players
*/
public Player[] getOnlinePlayers() {
Object players;
try {
players = server_getonlineplayers.invoke(Bukkit.getServer(), new Object[0]);
if (players instanceof Player[]) { /* Pre 1.7.10 */
return (Player[]) players;
}
else {
@SuppressWarnings("unchecked")
Collection<? extends Player> p = (Collection<? extends Player>) players;
return p.toArray(new Player[0]);
}
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
return new Player[0];
}
@Override
public int getHealth(Player p) {
return (int) p.getHealth();
}
}
@@ -36,6 +36,20 @@ public class BukkitWorld extends DynmapWorld {
this.env = env; this.env = env;
skylight = (env == World.Environment.NORMAL); skylight = (env == World.Environment.NORMAL);
new Permission("dynmap.world." + getName(), "Dynmap access for world " + getName(), PermissionDefault.OP); new Permission("dynmap.world." + getName(), "Dynmap access for world " + getName(), PermissionDefault.OP);
// Generate non-default environment lighting table
switch (env) {
case NETHER:
{
float f = 0.1F;
for (int i = 0; i <= 15; ++i) {
float f1 = 1.0F - (float)i / 15.0F;
this.setBrightnessTableEntry(i, (1.0F - f1) / (f1 * 3.0F + 1.0F) * (1.0F - f) + f);
}
}
break;
default:
break;
}
} }
/** /**
* Set world online * Set world online
@@ -154,7 +168,7 @@ public class BukkitWorld extends DynmapWorld {
@Override @Override
public MapChunkCache getChunkCache(List<DynmapChunk> chunks) { public MapChunkCache getChunkCache(List<DynmapChunk> chunks) {
if(isLoaded()) { if(isLoaded()) {
NewMapChunkCache c = new NewMapChunkCache(); LegacyMapChunkCache c = new LegacyMapChunkCache();
c.setChunks(this, chunks); c.setChunks(this, chunks);
return c; return c;
} }
@@ -0,0 +1,225 @@
package org.dynmap.bukkit;
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.SnapshotCache.SnapshotRec;
import org.dynmap.common.BiomeMap;
import org.dynmap.hdmap.HDBlockModels;
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 LegacyMapChunkCache extends BaseMapChunkCache {
@Override
public int loadChunks(int max_to_load) {
if(dw.isLoaded() == false)
return 0;
Object queue = 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.cache.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 = 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 = 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<Object> vals = new ArrayList<Object>();
Map<?,?> tileents = 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 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);
if(te_fields != null) {
Object nbtcompound = helper.readTileEntityNBT(t);
vals.clear();
for(String id: te_fields) {
Object val = 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.cache.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 */
helper.unloadChunkNoSave(w, c, chunk.x, chunk.z);
endChunkLoad(startTime, ChunkStats.UNLOADED_CHUNKS);
}
else if (isunloadpending) { /* Else, if loaded and unload is pending */
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
*/
@Override
public boolean isDoneLoading() {
if(dw.isLoaded() == false) {
isempty = true;
unloadChunks();
return true;
}
if(iterator != null)
return !iterator.hasNext();
return false;
}
@Override
public int readChunks() {
return 0;
}
}
@@ -14,9 +14,11 @@ import org.dynmap.utils.DynIntHashMap;
public class SnapshotCache { public class SnapshotCache {
public static class SnapshotRec { public static class SnapshotRec {
public ChunkSnapshot ss; public ChunkSnapshot ss;
public long inhabitedTicks;
public DynIntHashMap tileData; public DynIntHashMap tileData;
}; };
public static SnapshotCache cache;
private CacheHashMap snapcache; private CacheHashMap snapcache;
private ReferenceQueue<SnapshotRec> refqueue; private ReferenceQueue<SnapshotRec> refqueue;
private long cache_attempts; private long cache_attempts;
@@ -0,0 +1,5 @@
#Generated by Maven
#Fri Sep 19 23:52:48 CDT 2014
version=2.0.0-SNAPSHOT
groupId=us.dynmap
artifactId=DynmapBukkitBase
+53
View File
@@ -0,0 +1,53 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>us.dynmap</groupId>
<artifactId>DynmapBukkit_1_7_10</artifactId>
<name>DynmapBukkit_1_7_10</name>
<url>http://github.com/webbukkit/dynmap/</url>
<issueManagement>
<system>GitHub</system>
<url>https://github.com/webbukkit/dynmap/issues</url>
</issueManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<releases>
</releases>
<snapshots>
</snapshots>
<id>dynmap-repo</id>
<url>http://repo.mikeprimm.com/</url>
</repository>
</repositories>
<version>2.0.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>Bukkit</artifactId>
<version>1.7.10-R0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>us.dynmap</groupId>
<artifactId>DynmapCore</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>CraftBukkit</artifactId>
<version>1.7.10-R0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,414 @@
package org.dynmap.bukkit;
import java.io.DataInputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import net.minecraft.server.v1_7_R4.ChunkProviderServer;
import net.minecraft.server.v1_7_R4.ChunkRegionLoader;
import net.minecraft.server.v1_7_R4.IChunkLoader;
import net.minecraft.server.v1_7_R4.NBTTagCompound;
import org.bukkit.World;
import org.bukkit.Chunk;
import org.bukkit.block.Biome;
import org.bukkit.craftbukkit.v1_7_R4.CraftWorld;
import org.bukkit.ChunkSnapshot;
import org.dynmap.DynmapChunk;
import org.dynmap.DynmapCore;
import org.dynmap.DynmapWorld;
import org.dynmap.Log;
import org.dynmap.bukkit.BaseMapChunkCache;
import org.dynmap.bukkit.SnapshotCache;
import org.dynmap.bukkit.SnapshotCache.SnapshotRec;
import org.dynmap.common.BiomeMap;
import org.dynmap.hdmap.HDBlockModels;
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 V1_7_10_MapChunkCache extends BaseMapChunkCache {
private boolean doneLoad = false;
private ChunkProviderServer cps;
private ChunkRegionLoader loader;
private static boolean didInit = false;
private static Field loaderField = null;
public V1_7_10_MapChunkCache() {
if (!didInit) {
try {
loaderField = ChunkProviderServer.class.getField("f");
} catch (NoSuchFieldException nsfx) {
Log.info("Error finding chunk loader");
loaderField = null;
}
didInit = true;
}
}
private boolean isVisibleChunk(DynmapChunk chunk) {
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;
}
}
}
return vis;
}
private boolean isInCache(DynmapChunk chunk, int idx, boolean vis) {
SnapshotRec ssr = SnapshotCache.cache.getSnapshot(dw.getName(), chunk.x, chunk.z, blockdata, biome, biomeraw, highesty);
if(ssr != null) {
ChunkSnapshot ss = ssr.ss;
if(!vis) {
if(hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN)
ss = STONE;
else if(hidestyle == HiddenChunkStyle.FILL_OCEAN)
ss = OCEAN;
else
ss = EMPTY;
}
snaparray[idx] = ss;
snaptile[idx] = ssr.tileData;
inhabitedTicks[idx] = ssr.inhabitedTicks;
}
return (ssr != null);
}
@Override
public int loadChunks(int max_to_load) {
if(dw.isLoaded() == false)
return 0;
Object queue = helper.getUnloadQueue(w);
int cnt = 0;
Iterator<DynmapChunk> iterator = chunks.listIterator();
//boolean isnormral = w.getEnvironment() == Environment.NORMAL;
// Load the required chunks.
while (iterator.hasNext()) {
long startTime = System.nanoTime();
DynmapChunk chunk = iterator.next();
int idx = (chunk.x - x_min) + ((chunk.z - z_min) * x_dim);
if (snaparray[idx] != null) {
continue;
}
boolean vis = isVisibleChunk(chunk);
/* Check if cached chunk snapshot found */
if (isInCache(chunk, idx, vis)) {
endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT);
continue;
}
ChunkSnapshot ss = null;
long inhabited_ticks = 0;
DynIntHashMap tileData = null;
// See if chunk already loaded
boolean wasLoaded = w.isChunkLoaded(chunk.x, chunk.z);
boolean isunloadpending = false;
if (queue != null) {
isunloadpending = helper.isInUnloadQueue(queue, chunk.x, chunk.z);
}
// If loaded, and not being unloaded, read live chunk
if (wasLoaded && (!isunloadpending)) {
tileData = new DynIntHashMap();
Chunk c = w.getChunkAt(chunk.x, chunk.z); /* Get the chunk */
/* Get inhabited ticks count */
inhabited_ticks = 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<Object> vals = new ArrayList<Object>();
Map<?,?> tileents = 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 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);
if(te_fields != null) {
Object nbtcompound = helper.readTileEntityNBT(t);
vals.clear();
for(String id: te_fields) {
Object val = 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) {
SnapshotRec ssr = new SnapshotRec();
ssr.ss = ss;
ssr.inhabitedTicks = inhabited_ticks;
ssr.tileData = tileData;
SnapshotCache.cache.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;
endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS);
}
else {
endChunkLoad(startTime, ChunkStats.UNGENERATED_CHUNKS);
}
cnt++;
}
doneLoad = true;
return cnt;
}
/**
* Test if done loading
*/
@Override
public boolean isDoneLoading() {
return doneLoad;
}
@Override
public int readChunks() {
if(dw.isLoaded() == false)
return 0;
Object queue = helper.getUnloadQueue(w);
cps = ((CraftWorld) w).getHandle().chunkProviderServer;
try {
IChunkLoader cloader = (IChunkLoader) loaderField.get(cps);
if (cloader instanceof ChunkRegionLoader) {
loader = (ChunkRegionLoader) cloader;
}
} catch (IllegalArgumentException iax) {
} catch (IllegalAccessException ixx) {
}
if (loader == null) {
Log.warning("Unable to find usable chunk loader");
return 0;
}
int cnt = 0;
Iterator<DynmapChunk> iterator = chunks.listIterator();
//boolean isnormral = w.getEnvironment() == Environment.NORMAL;
// Load the required chunks.
while (iterator.hasNext()) {
long startTime = System.nanoTime();
DynmapChunk chunk = iterator.next();
int idx = (chunk.x - x_min) + ((chunk.z - z_min) * x_dim);
if (snaparray[idx] != null) {
continue;
}
boolean vis = isVisibleChunk(chunk);
}
// Finish up any chunks that didn't get loaded or read
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 0;
}
public NBTTagCompound readChunk(int x, int z) {
try {
List<?> chunkstoremove = null;
Set<?> pendingcoords = null;
LinkedHashMap<?,?> pendingsavesmcpc = null;
if (pendingAnvilChunksMCPC != null) {
pendingsavesmcpc = (LinkedHashMap<?,?>)pendingAnvilChunksMCPC.get(acl);
}
else {
chunkstoremove = (List<?>)chunksToRemove.get(acl);
pendingcoords = (Set<?>)pendingAnvilChunksCoordinates.get(acl);
}
Object synclock = syncLockObject.get(acl);
NBTTagCompound rslt = null;
ChunkCoordIntPair coord = new ChunkCoordIntPair(x, z);
synchronized (synclock) {
if (pendingAnvilChunksMCPC != null) {
Object rec = pendingsavesmcpc.get(coord);
if(rec != null) {
if (chunkCoord == null) {
Field[] f = rec.getClass().getDeclaredFields();
for(Field ff : f) {
if((chunkCoord == null) && (ff.getType().equals(ChunkCoordIntPair.class))) {
chunkCoord = ff;
}
else if((nbtTag == null) && (ff.getType().equals(NBTTagCompound.class))) {
nbtTag = ff;
}
}
}
rslt = (NBTTagCompound)nbtTag.get(rec);
}
}
else {
if (pendingcoords.contains(coord)) {
for (int i = 0; i < chunkstoremove.size(); i++) {
Object o = chunkstoremove.get(i);
if (chunkCoord == null) {
Field[] f = o.getClass().getDeclaredFields();
for(Field ff : f) {
if((chunkCoord == null) && (ff.getType().equals(ChunkCoordIntPair.class))) {
chunkCoord = ff;
}
else if((nbtTag == null) && (ff.getType().equals(NBTTagCompound.class))) {
nbtTag = ff;
}
}
}
ChunkCoordIntPair occ = (ChunkCoordIntPair)chunkCoord.get(o);
if (occ.equals(coord)) {
rslt = (NBTTagCompound)nbtTag.get(o);
break;
}
}
}
}
}
if (rslt == null) {
DataInputStream str = RegionFileCache.getChunkInputStream(acl.chunkSaveLocation, x, z);
if (str == null) {
return null;
}
rslt = CompressedStreamTools.read(str);
}
if(rslt != null)
rslt = rslt.getCompoundTag("Level");
return rslt;
} catch (Exception exc) {
return null;
}
}
private Object getNBTValue(NBTBase v) {
Object val = null;
switch(v.getId()) {
case 1: // Byte
val = Byte.valueOf(((NBTTagByte)v).func_150290_f());
break;
case 2: // Short
val = Short.valueOf(((NBTTagShort)v).func_150289_e());
break;
case 3: // Int
val = Integer.valueOf(((NBTTagInt)v).func_150287_d());
break;
case 4: // Long
val = Long.valueOf(((NBTTagLong)v).func_150291_c());
break;
case 5: // Float
val = Float.valueOf(((NBTTagFloat)v).func_150288_h());
break;
case 6: // Double
val = Double.valueOf(((NBTTagDouble)v).func_150286_g());
break;
case 7: // Byte[]
val = ((NBTTagByteArray)v).func_150292_c();
break;
case 8: // String
val = ((NBTTagString)v).func_150285_a_();
break;
case 9: // List
NBTTagList tl = (NBTTagList) v;
ArrayList<Object> vlist = new ArrayList<Object>();
int type = tl.func_150303_d();
for (int i = 0; i < tl.tagCount(); i++) {
switch (type) {
case 5:
float fv = tl.func_150308_e(i);
vlist.add(fv);
break;
case 6:
double dv = tl.func_150309_d(i);
vlist.add(dv);
break;
case 8:
String sv = tl.getStringTagAt(i);
vlist.add(sv);
break;
case 10:
NBTTagCompound tc = tl.getCompoundTagAt(i);
vlist.add(getNBTValue(tc));
break;
case 11:
int[] ia = tl.func_150306_c(i);
vlist.add(ia);
break;
}
}
val = vlist;
break;
case 10: // Map
NBTTagCompound tc = (NBTTagCompound) v;
HashMap<String, Object> vmap = new HashMap<String, Object>();
for (Object t : tc.func_150296_c()) {
String st = (String) t;
NBTBase tg = tc.getTag(st);
vmap.put(st, getNBTValue(tg));
}
val = vmap;
break;
case 11: // Int[]
val = ((NBTTagIntArray)v).func_150302_c();
break;
}
return val;
}
}
+177
View File
@@ -0,0 +1,177 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>us.dynmap</groupId>
<artifactId>dynmap</artifactId>
<name>dynmap</name>
<properties>
<timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<BUILD_NUMBER>Dev${timestamp}</BUILD_NUMBER>
</properties>
<url>http://github.com/webbukkit/dynmap/</url>
<issueManagement>
<system>GitHub</system>
<url>https://github.com/webbukkit/dynmap/issues</url>
</issueManagement>
<build>
<directory>../target</directory>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>*.yml</include>
<include>*.txt</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>*.yml</exclude>
<exclude>*.txt</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>us.dynmap:dynmap-api:jar:*</include>
<include>us.dynmap:DynmapCore:jar:*</include>
<include>us.dynmap:DynmapBukkitBase:jar:*</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<releases>
</releases>
<snapshots>
</snapshots>
<id>bukkit-repo</id>
<url>http://repo.bukkit.org/content/repositories/releases/</url>
</repository>
<repository>
<releases>
</releases>
<snapshots>
</snapshots>
<id>dynmap-repo</id>
<url>http://repo.mikeprimm.com/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.nijikokun.bukkit</groupId>
<artifactId>Permissions</artifactId>
<version>3.1.6</version>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>Bukkit</artifactId>
<version>1.7.10-R0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>us.dynmap</groupId>
<artifactId>dynmap-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>us.dynmap</groupId>
<artifactId>DynmapCore</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>ru.tehkode</groupId>
<artifactId>PermissionsEx</artifactId>
<version>1.19.1</version>
</dependency>
<dependency>
<groupId>de.bananaco</groupId>
<artifactId>bPermissions</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>com.platymuus.bukkit.permissions</groupId>
<artifactId>PermissionsBukkit</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>org.anjocaido</groupId>
<artifactId>EssentialsGroupManager</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>us.dynmap</groupId>
<artifactId>DynmapSpigot</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>us.dynmap</groupId>
<artifactId>DynmapBukkitBase</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>us.dynmap</groupId>
<artifactId>DynmapBukkit_1_7_10</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<version>2.0.0-SNAPSHOT</version>
</project>
@@ -56,9 +56,9 @@ import java.util.logging.Level;
* <p> The metrics class obtains data about a plugin and submits statistics about it to the metrics backend. </p> <p> * <p> The metrics class obtains data about a plugin and submits statistics about it to the metrics backend. </p> <p>
* Public methods provided by this class: </p> * Public methods provided by this class: </p>
* <code> * <code>
* Graph createGraph(String name); <br/> * Graph createGraph(String name); <br>
* void addCustomData(BukkitMetrics.Plotter plotter); <br/> * void addCustomData(BukkitMetrics.Plotter plotter); <br>
* void start(); <br/> * void start(); <br>
* </code> * </code>
*/ */
public class Metrics { public class Metrics {
@@ -121,6 +121,8 @@ public class Metrics {
*/ */
private volatile BukkitTask task = null; private volatile BukkitTask task = null;
private BukkitVersionHelper helper;
public Metrics(final Plugin plugin) throws IOException { public Metrics(final Plugin plugin) throws IOException {
if (plugin == null) { if (plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null"); throw new IllegalArgumentException("Plugin cannot be null");
@@ -146,6 +148,8 @@ public class Metrics {
// Load the guid then // Load the guid then
guid = configuration.getString("guid"); guid = configuration.getString("guid");
debug = configuration.getBoolean("debug", false); debug = configuration.getBoolean("debug", false);
helper = BukkitVersionHelper.getHelper();
} }
/** /**
@@ -359,7 +363,7 @@ public class Metrics {
boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled
String pluginVersion = description.getVersion(); String pluginVersion = description.getVersion();
String serverVersion = Bukkit.getVersion(); String serverVersion = Bukkit.getVersion();
int playersOnline = Bukkit.getServer().getOnlinePlayers().length; int playersOnline = helper.getOnlinePlayers().length;
// END server software specific section -- all code below does not use any code outside of this class / Java // END server software specific section -- all code below does not use any code outside of this class / Java
@@ -35,15 +35,16 @@ public class GroupManagerPermissions implements PermissionProvider {
} }
@Override @Override
public boolean has(CommandSender sender, String permission) { public boolean has(CommandSender sender, String permission) {
Player player = sender instanceof Player ? (Player) sender : null; Player player = sender instanceof Player ? (Player) sender : null;
return (player != null) ? wh.getWorldPermissions(player).has(player, name + "." + permission) : true; boolean rslt = (player != null) ? gm.getWorldsHolder().getDefaultWorld().getPermissionsHandler().permission(player, name + "." + permission) : true;
return rslt;
} }
@Override @Override
public Set<String> hasOfflinePermissions(String player, Set<String> perms) { public Set<String> hasOfflinePermissions(String player, Set<String> perms) {
HashSet<String> hasperms = new HashSet<String>(); HashSet<String> hasperms = new HashSet<String>();
AnjoPermissionsHandler apm = wh.getWorldPermissionsByPlayerName(player); AnjoPermissionsHandler apm = gm.getWorldsHolder().getDefaultWorld().getPermissionsHandler();
if (apm != null) { if (apm != null) {
for (String pp : perms) { for (String pp : perms) {
if (apm.permission(player, name + "." + pp)) { if (apm.permission(player, name + "." + pp)) {
@@ -55,10 +56,11 @@ public class GroupManagerPermissions implements PermissionProvider {
} }
@Override @Override
public boolean hasOfflinePermission(String player, String perm) { public boolean hasOfflinePermission(String player, String perm) {
AnjoPermissionsHandler apm = wh.getWorldPermissionsByPlayerName(player); AnjoPermissionsHandler apm = gm.getWorldsHolder().getDefaultWorld().getPermissionsHandler();
boolean rslt = false;
if(apm != null) { if(apm != null) {
return apm.permission(player, name + "." + perm); rslt = apm.permission(player, name + "." + perm);
} }
return false; return rslt;
} }
} }

Some files were not shown because too many files have changed in this diff Show More