Compare commits

...

1 Commits

Author SHA1 Message Date
Mike Primm b13c26c0d6 Switch to submodules 2014-10-12 17:32:38 -05:00
29 changed files with 1028 additions and 769 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,43 +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 extends 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 */
private long[] inhabitedTicks; /* Index = (x-x_min) + ((z-z_min)*x_dim) */ protected long[] inhabitedTicks; /* Index = (x-x_min) + ((z-z_min)*x_dim) */
private static BukkitVersionHelper helper = BukkitVersionHelper.getHelper(); protected 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;
} }
@@ -161,9 +171,6 @@ public class NewMapChunkCache extends 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) {
@@ -677,68 +684,16 @@ public class NewMapChunkCache extends 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;
} }
} }
@@ -780,210 +735,21 @@ public class NewMapChunkCache extends MapChunkCache {
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;
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 = DynmapPlugin.plugin.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 = 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);
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.inhabitedTicks = inhabited_ticks;
ssr.tileData = tileData;
DynmapPlugin.plugin.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 */
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 * 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
*/ */
@@ -991,7 +757,7 @@ public class NewMapChunkCache extends MapChunkCache {
return isempty; return isempty;
} }
/** /**
* Unload chunks * Unload chunks (cleanup - if needed)
*/ */
public void unloadChunks() { public void unloadChunks() {
if(snaparray != null) { if(snaparray != null) {
@@ -1002,6 +768,7 @@ public class NewMapChunkCache extends MapChunkCache {
inhabitedTicks = 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) {
@@ -83,10 +83,6 @@ 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
*/ */
@@ -445,7 +445,7 @@ public class BukkitVersionHelperGlowstone extends BukkitVersionHelper {
@Override @Override
public int getHealth(Player p) { public int getHealth(Player p) {
return p.getHealth(); return (int) p.getHealth();
} }
} }
@@ -168,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;
}
}
@@ -17,7 +17,8 @@ public class SnapshotCache {
public long inhabitedTicks; 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>
@@ -2,11 +2,9 @@ package org.dynmap.bukkit;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
@@ -102,12 +100,9 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
private DynmapCore core; private DynmapCore core;
private PermissionProvider permissions; private PermissionProvider permissions;
private String version; private String version;
public SnapshotCache sscache;
private boolean has_spout = false;
public PlayerList playerList; public PlayerList playerList;
private MapManager mapManager; private MapManager mapManager;
public static DynmapPlugin plugin; public static DynmapPlugin plugin;
public SpoutPluginBlocks spb;
public PluginManager pm; public PluginManager pm;
private Metrics metrics; private Metrics metrics;
private BukkitEnableCoreCallback enabCoreCB = new BukkitEnableCoreCallback(); private BukkitEnableCoreCallback enabCoreCB = new BukkitEnableCoreCallback();
@@ -169,26 +164,9 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
private class BukkitEnableCoreCallback extends DynmapCore.EnableCoreCallbacks { private class BukkitEnableCoreCallback extends DynmapCore.EnableCoreCallbacks {
@Override @Override
public void configurationLoaded() { public void configurationLoaded() {
/* Check for Spout */ File st = new File(core.getDataFolder(), "renderdata/spout-texture.txt");
if(detectSpout()) { if(st.exists())
if(core.configuration.getBoolean("spout/enabled", true)) { st.delete();
has_spout = true;
Log.info("Detected Spout");
if(spb == null) {
spb = new SpoutPluginBlocks(DynmapPlugin.this);
}
modsused.add("SpoutPlugin");
}
else {
Log.info("Detected Spout - Support Disabled");
}
}
if(!has_spout) { /* If not, clean up old spout texture, if needed */
File st = new File(core.getDataFolder(), "renderdata/spout-texture.txt");
if(st.exists())
st.delete();
}
} }
} }
@@ -383,11 +361,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
} }
@Override @Override
public double getCacheHitRate() { public double getCacheHitRate() {
return sscache.getHitRate(); return SnapshotCache.cache.getHitRate();
} }
@Override @Override
public void resetCacheStats() { public void resetCacheStats() {
sscache.resetStats(); SnapshotCache.cache.resetStats();
} }
@Override @Override
public DynmapWorld getWorldByName(String wname) { public DynmapWorld getWorldByName(String wname) {
@@ -429,7 +407,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
@Override @Override
public MapChunkCache createMapChunkCache(DynmapWorld w, List<DynmapChunk> chunks, public MapChunkCache createMapChunkCache(DynmapWorld w, List<DynmapChunk> chunks,
boolean blockdata, boolean highesty, boolean biome, boolean rawbiome) { boolean blockdata, boolean highesty, boolean biome, boolean rawbiome) {
MapChunkCache c = w.getChunkCache(chunks); BaseMapChunkCache c = (BaseMapChunkCache) w.getChunkCache(chunks);
if(c == null) { /* Can fail if not currently loaded */ if(c == null) { /* Can fail if not currently loaded */
return null; return null;
} }
@@ -496,6 +474,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
try { Thread.sleep(25); } catch (InterruptedException ix) {} try { Thread.sleep(25); } catch (InterruptedException ix) {}
} }
} }
/* Finish reading chunks in requesting thread z*/
c.readChunks();
/* If cancelled due to world unload return nothing */ /* If cancelled due to world unload return nothing */
if(w.isLoaded() == false) if(w.isLoaded() == false)
return null; return null;
@@ -842,7 +822,6 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true) @EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
public void onPluginEnabled(PluginEnableEvent evt) { public void onPluginEnabled(PluginEnableEvent evt) {
if (!readyToEnable()) { if (!readyToEnable()) {
spb.markPluginEnabled(evt.getPlugin());
if (readyToEnable()) { /* If we;re ready now, finish enable */ if (readyToEnable()) { /* If we;re ready now, finish enable */
doEnable(); /* Finish enable */ doEnable(); /* Finish enable */
} }
@@ -867,25 +846,17 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
} }
private boolean readyToEnable() { private boolean readyToEnable() {
if (spb != null) {
return spb.isReady();
}
return true; return true;
} }
private void doEnable() { private void doEnable() {
/* Prep spout support, if needed */
if(spb != null) {
spb.processSpoutBlocks(this, core);
}
/* Enable core */ /* Enable core */
if(!core.enableCore(enabCoreCB)) { if(!core.enableCore(enabCoreCB)) {
this.setEnabled(false); this.setEnabled(false);
return; return;
} }
playerList = core.playerList; playerList = core.playerList;
sscache = new SnapshotCache(core.getSnapShotCacheSize(), core.useSoftRefInSnapShotCache()); SnapshotCache.cache = new SnapshotCache(core.getSnapShotCacheSize(), core.useSoftRefInSnapShotCache());
/* Get map manager from core */ /* Get map manager from core */
mapManager = core.getMapManager(); mapManager = core.getMapManager();
@@ -919,9 +890,9 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
/* Disable core */ /* Disable core */
core.disableCore(); core.disableCore();
if(sscache != null) { if(SnapshotCache.cache != null) {
sscache.cleanup(); SnapshotCache.cache.cleanup();
sscache = null; SnapshotCache.cache = null;
} }
Log.info("Disabled"); Log.info("Disabled");
} }
@@ -1104,7 +1075,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
if(btt.typeid == 9) btt.typeid = 8; if(btt.typeid == 9) btt.typeid = 8;
if((bt != btt.typeid) || (btt.data != w.getBlockAt(loc).getData())) { if((bt != btt.typeid) || (btt.data != w.getBlockAt(loc).getData())) {
String wn = getWorld(w).getName(); String wn = getWorld(w).getName();
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); SnapshotCache.cache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), btt.trigger); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), btt.trigger);
} }
} }
@@ -1172,7 +1143,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onBlockPlace(BlockPlaceEvent event) { public void onBlockPlace(BlockPlaceEvent event) {
Location loc = event.getBlock().getLocation(); Location loc = event.getBlock().getLocation();
String wn = getWorld(loc.getWorld()).getName(); String wn = getWorld(loc.getWorld()).getName();
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); SnapshotCache.cache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockplace"); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockplace");
} }
}; };
@@ -1187,7 +1158,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
if(b == null) return; /* Stupid mod workaround */ if(b == null) return; /* Stupid mod workaround */
Location loc = b.getLocation(); Location loc = b.getLocation();
String wn = getWorld(loc.getWorld()).getName(); String wn = getWorld(loc.getWorld()).getName();
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); SnapshotCache.cache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockbreak"); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockbreak");
} }
}; };
@@ -1200,7 +1171,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onLeavesDecay(LeavesDecayEvent event) { public void onLeavesDecay(LeavesDecayEvent event) {
Location loc = event.getBlock().getLocation(); Location loc = event.getBlock().getLocation();
String wn = getWorld(loc.getWorld()).getName(); String wn = getWorld(loc.getWorld()).getName();
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); SnapshotCache.cache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onleaves) { if(onleaves) {
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "leavesdecay"); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "leavesdecay");
} }
@@ -1215,7 +1186,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onBlockBurn(BlockBurnEvent event) { public void onBlockBurn(BlockBurnEvent event) {
Location loc = event.getBlock().getLocation(); Location loc = event.getBlock().getLocation();
String wn = getWorld(loc.getWorld()).getName(); String wn = getWorld(loc.getWorld()).getName();
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); SnapshotCache.cache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onburn) { if(onburn) {
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockburn"); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockburn");
} }
@@ -1279,14 +1250,14 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
} }
String wn = getWorld(loc.getWorld()).getName(); String wn = getWorld(loc.getWorld()).getName();
int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ(); int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
sscache.invalidateSnapshot(wn, x, y, z); SnapshotCache.cache.invalidateSnapshot(wn, x, y, z);
if(onpiston) if(onpiston)
mapManager.touch(wn, x, y, z, "pistonretract"); mapManager.touch(wn, x, y, z, "pistonretract");
for(int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
x += dir.getModX(); x += dir.getModX();
y += dir.getModY(); y += dir.getModY();
z += dir.getModZ(); z += dir.getModZ();
sscache.invalidateSnapshot(wn, x, y, z); SnapshotCache.cache.invalidateSnapshot(wn, x, y, z);
mapManager.touch(wn, x, y, z, "pistonretract"); mapManager.touch(wn, x, y, z, "pistonretract");
} }
} }
@@ -1303,14 +1274,14 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
} }
String wn = getWorld(loc.getWorld()).getName(); String wn = getWorld(loc.getWorld()).getName();
int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ(); int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
sscache.invalidateSnapshot(wn, x, y, z); SnapshotCache.cache.invalidateSnapshot(wn, x, y, z);
if(onpiston) if(onpiston)
mapManager.touch(wn, x, y, z, "pistonretract"); mapManager.touch(wn, x, y, z, "pistonretract");
for(int i = 0; i < 1+event.getLength(); i++) { for(int i = 0; i < 1+event.getLength(); i++) {
x += dir.getModX(); x += dir.getModX();
y += dir.getModY(); y += dir.getModY();
z += dir.getModZ(); z += dir.getModZ();
sscache.invalidateSnapshot(wn, x, y, z); SnapshotCache.cache.invalidateSnapshot(wn, x, y, z);
mapManager.touch(wn, x, y, z, "pistonretract"); mapManager.touch(wn, x, y, z, "pistonretract");
} }
} }
@@ -1324,7 +1295,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onBlockSpread(BlockSpreadEvent event) { public void onBlockSpread(BlockSpreadEvent event) {
Location loc = event.getBlock().getLocation(); Location loc = event.getBlock().getLocation();
String wn = getWorld(loc.getWorld()).getName(); String wn = getWorld(loc.getWorld()).getName();
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); SnapshotCache.cache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockspread"); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockspread");
} }
}; };
@@ -1337,7 +1308,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onBlockForm(BlockFormEvent event) { public void onBlockForm(BlockFormEvent event) {
Location loc = event.getBlock().getLocation(); Location loc = event.getBlock().getLocation();
String wn = getWorld(loc.getWorld()).getName(); String wn = getWorld(loc.getWorld()).getName();
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); SnapshotCache.cache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockform"); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockform");
} }
}; };
@@ -1350,7 +1321,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onBlockFade(BlockFadeEvent event) { public void onBlockFade(BlockFadeEvent event) {
Location loc = event.getBlock().getLocation(); Location loc = event.getBlock().getLocation();
String wn = getWorld(loc.getWorld()).getName(); String wn = getWorld(loc.getWorld()).getName();
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); SnapshotCache.cache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfade"); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfade");
} }
}; };
@@ -1365,7 +1336,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onBlockGrow(BlockGrowEvent event) { public void onBlockGrow(BlockGrowEvent event) {
Location loc = event.getBlock().getLocation(); Location loc = event.getBlock().getLocation();
String wn = getWorld(loc.getWorld()).getName(); String wn = getWorld(loc.getWorld()).getName();
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); SnapshotCache.cache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockgrow"); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockgrow");
} }
}; };
@@ -1378,7 +1349,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onBlockRedstone(BlockRedstoneEvent event) { public void onBlockRedstone(BlockRedstoneEvent event) {
Location loc = event.getBlock().getLocation(); Location loc = event.getBlock().getLocation();
String wn = getWorld(loc.getWorld()).getName(); String wn = getWorld(loc.getWorld()).getName();
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); SnapshotCache.cache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockredstone"); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockredstone");
} }
}; };
@@ -1435,7 +1406,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
if(z < minz) minz = z; if(z < minz) minz = z;
if(z > maxz) maxz = z; if(z > maxz) maxz = z;
} }
sscache.invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz); SnapshotCache.cache.invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz);
if(onexplosion) { if(onexplosion) {
mapManager.touchVolume(wname, minx, miny, minz, maxx, maxy, maxz, "entityexplode"); mapManager.touchVolume(wname, minx, miny, minz, maxx, maxy, maxz, "entityexplode");
} }
@@ -1482,7 +1453,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
if(z < minz) minz = z; if(z < minz) minz = z;
if(z > maxz) maxz = z; if(z > maxz) maxz = z;
} }
sscache.invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz); SnapshotCache.cache.invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz);
if(onstructuregrow) { if(onstructuregrow) {
mapManager.touchVolume(wname, minx, miny, minz, maxx, maxy, maxz, "structuregrow"); mapManager.touchVolume(wname, minx, miny, minz, maxx, maxy, maxz, "structuregrow");
} }
@@ -1515,18 +1486,6 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
} }
} }
private boolean detectSpout() {
Plugin p = this.getServer().getPluginManager().getPlugin("Spout");
if(p != null) {
return p.isEnabled();
}
return false;
}
public boolean hasSpout() {
return has_spout;
}
@Override @Override
public void assertPlayerInvisibility(String player, boolean is_invisible, public void assertPlayerInvisibility(String player, boolean is_invisible,
String plugin_id) { String plugin_id) {
@@ -1577,14 +1536,6 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
return 0; return 0;
} }
}); });
features.addPlotter(new Metrics.Plotter("Spout") {
@Override
public int getValue() {
if(plugin.has_spout)
return 1;
return 0;
}
});
features.addPlotter(new Metrics.Plotter("Login Security") { features.addPlotter(new Metrics.Plotter("Login Security") {
@Override @Override
public int getValue() { public int getValue() {

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