use of org.dynmap.utils.DynIntHashMap in project dynmap by webbukkit.
the class AbstractMapChunkCache method loadChunks.
// Load chunk snapshots
public int loadChunks(int max_to_load) {
if (dw.isLoaded() == false)
return 0;
Object queue = BukkitVersionHelper.helper.getUnloadQueue(w);
int cnt = 0;
if (iterator == null)
iterator = chunks.listIterator();
DynmapCore.setIgnoreChunkLoads(true);
// Load the required chunks.
while ((cnt < max_to_load) && iterator.hasNext()) {
long startTime = System.nanoTime();
DynmapChunk chunk = iterator.next();
boolean vis = true;
if (visible_limits != null) {
vis = false;
for (VisibilityLimit limit : visible_limits) {
if (limit.doIntersectChunk(chunk.x, chunk.z)) {
vis = true;
break;
}
}
}
if (vis && (hidden_limits != null)) {
for (VisibilityLimit limit : hidden_limits) {
if (limit.doIntersectChunk(chunk.x, chunk.z)) {
vis = false;
break;
}
}
}
/* Check if cached chunk snapshot found */
Snapshot ss = null;
long inhabited_ticks = 0;
DynIntHashMap tileData = null;
SnapshotRec ssr = SnapshotCache.sscache.getSnapshot(dw.getName(), chunk.x, chunk.z, blockdata, biome, biomeraw, highesty);
if (ssr != null) {
inhabited_ticks = ssr.inhabitedTicks;
if (!vis) {
if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN)
ss = STONE;
else if (hidestyle == HiddenChunkStyle.FILL_OCEAN)
ss = OCEAN;
else
ss = EMPTY;
} else {
ss = ssr.ss;
}
int idx = (chunk.x - x_min) + (chunk.z - z_min) * x_dim;
snaparray[idx] = ss;
snaptile[idx] = ssr.tileData;
inhabitedTicks[idx] = inhabited_ticks;
endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT);
continue;
}
boolean wasLoaded = w.isChunkLoaded(chunk.x, chunk.z);
boolean didload = false;
boolean isunloadpending = false;
if (queue != null) {
isunloadpending = BukkitVersionHelper.helper.isInUnloadQueue(queue, chunk.x, chunk.z);
}
if (isunloadpending) {
/* Workaround: can't be pending if not loaded */
wasLoaded = true;
}
try {
didload = loadChunkNoGenerate(w, chunk.x, chunk.z);
} catch (Throwable t) {
/* Catch chunk error from Bukkit */
Log.warning("Bukkit error loading chunk " + chunk.x + "," + chunk.z + " on " + w.getName());
if (!wasLoaded) {
/* If wasn't loaded, we loaded it if it now is */
didload = w.isChunkLoaded(chunk.x, chunk.z);
}
}
/* If it did load, make cache of it */
if (didload) {
tileData = new DynIntHashMap();
Chunk c = w.getChunkAt(chunk.x, chunk.z);
/* Get the chunk */
/* Get inhabited ticks count */
inhabited_ticks = BukkitVersionHelper.helper.getInhabitedTicks(c);
if (!vis) {
if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN)
ss = STONE;
else if (hidestyle == HiddenChunkStyle.FILL_OCEAN)
ss = OCEAN;
else
ss = EMPTY;
} else {
ChunkSnapshot css;
if (blockdata || highesty) {
css = c.getChunkSnapshot(highesty, biome, biomeraw);
ss = wrapChunkSnapshot(css);
/* Get tile entity data */
List<Object> vals = new ArrayList<Object>();
Map<?, ?> tileents = BukkitVersionHelper.helper.getTileEntitiesForChunk(c);
for (Object t : tileents.values()) {
int te_x = BukkitVersionHelper.helper.getTileEntityX(t);
int te_y = BukkitVersionHelper.helper.getTileEntityY(t);
int te_z = BukkitVersionHelper.helper.getTileEntityZ(t);
int cx = te_x & 0xF;
int cz = te_z & 0xF;
String[] te_fields = HDBlockModels.getTileEntityFieldsNeeded(ss.getBlockType(cx, te_y, cz));
if (te_fields != null) {
Object nbtcompound = BukkitVersionHelper.helper.readTileEntityNBT(t);
vals.clear();
for (String id : te_fields) {
Object val = BukkitVersionHelper.helper.getFieldValue(nbtcompound, id);
if (val != null) {
vals.add(id);
vals.add(val);
}
}
if (vals.size() > 0) {
Object[] vlist = vals.toArray(new Object[vals.size()]);
tileData.put(getIndexInChunk(cx, te_y, cz), vlist);
}
}
}
} else {
css = w.getEmptyChunkSnapshot(chunk.x, chunk.z, biome, biomeraw);
ss = wrapChunkSnapshot(css);
}
if (ss != null) {
ssr = new SnapshotRec();
ssr.ss = ss;
ssr.inhabitedTicks = inhabited_ticks;
ssr.tileData = tileData;
SnapshotCache.sscache.putSnapshot(dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty);
}
}
int chunkIndex = (chunk.x - x_min) + (chunk.z - z_min) * x_dim;
snaparray[chunkIndex] = ss;
snaptile[chunkIndex] = tileData;
inhabitedTicks[chunkIndex] = inhabited_ticks;
/* If wasn't loaded before, we need to do unload */
if (!wasLoaded) {
/* Since we only remember ones we loaded, and we're synchronous, no player has
* moved, so it must be safe (also prevent chunk leak, which appears to happen
* because isChunkInUse defined "in use" as being within 256 blocks of a player,
* while the actual in-use chunk area for a player where the chunks are managed
* by the MC base server is 21x21 (or about a 160 block radius).
* Also, if we did generate it, need to save it */
if (w.isChunkInUse(chunk.x, chunk.z) == false) {
if (BukkitVersionHelper.helper.isUnloadChunkBroken()) {
// Give up on broken unloadChunk API - lets see if this works
w.unloadChunkRequest(chunk.x, chunk.z);
} else {
BukkitVersionHelper.helper.unloadChunkNoSave(w, c, chunk.x, chunk.z);
}
}
endChunkLoad(startTime, ChunkStats.UNLOADED_CHUNKS);
} else if (isunloadpending) {
/* Else, if loaded and unload is pending */
if (w.isChunkInUse(chunk.x, chunk.z) == false) {
w.unloadChunkRequest(chunk.x, chunk.z);
/* Request new unload */
}
endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS);
} else {
endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS);
}
} else {
endChunkLoad(startTime, ChunkStats.UNGENERATED_CHUNKS);
}
cnt++;
}
DynmapCore.setIgnoreChunkLoads(false);
if (iterator.hasNext() == false) {
/* If we're done */
isempty = true;
/* Fill missing chunks with empty dummy chunk */
for (int i = 0; i < snaparray.length; i++) {
if (snaparray[i] == null)
snaparray[i] = EMPTY;
else if (snaparray[i] != EMPTY)
isempty = false;
}
}
return cnt;
}
use of org.dynmap.utils.DynIntHashMap in project dynmap by webbukkit.
the class ForgeMapChunkCache method prepChunkSnapshot.
// Prep snapshot and add to cache
private SnapshotRec prepChunkSnapshot(DynmapChunk chunk, CompoundNBT nbt) {
ChunkSnapshot ss = new ChunkSnapshot(nbt, dw.worldheight);
DynIntHashMap tileData = new DynIntHashMap();
ListNBT tiles = nbt.getList("TileEntities", 10);
if (tiles == null)
tiles = new ListNBT();
/* Get tile entity data */
List<Object> vals = new ArrayList<Object>();
for (int tid = 0; tid < tiles.size(); tid++) {
CompoundNBT tc = tiles.getCompound(tid);
int tx = tc.getInt("x");
int ty = tc.getInt("y");
int tz = tc.getInt("z");
int cx = tx & 0xF;
int cz = tz & 0xF;
DynmapBlockState blk = ss.getBlockType(cx, ty, cz);
String[] te_fields = HDBlockModels.getTileEntityFieldsNeeded(blk);
if (te_fields != null) {
vals.clear();
for (String id : te_fields) {
INBT v = tc.get(id);
/* Get field */
if (v != null) {
Object val = getNBTValue(v);
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, ty, cz), vlist);
}
}
}
SnapshotRec ssr = new SnapshotRec();
ssr.ss = ss;
ssr.tileData = tileData;
DynmapPlugin.plugin.sscache.putSnapshot(dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty);
return ssr;
}
use of org.dynmap.utils.DynIntHashMap in project dynmap by webbukkit.
the class ForgeMapChunkCache method getLoadedChunks.
/**
* Read NBT data from loaded chunks - needs to be called from server/world thread to be safe
* @returns number loaded
*/
public int getLoadedChunks() {
int cnt = 0;
if (!dw.isLoaded()) {
isempty = true;
unloadChunks();
return 0;
}
ListIterator<DynmapChunk> iter = chunks.listIterator();
while (iter.hasNext()) {
long startTime = System.nanoTime();
DynmapChunk chunk = iter.next();
int chunkindex = (chunk.x - x_min) + (chunk.z - z_min) * x_dim;
// Skip if already processed
if (snaparray[chunkindex] != null)
continue;
boolean vis = isChunkVisible(chunk);
/* Check if cached chunk snapshot found */
if (tryChunkCache(chunk, vis)) {
endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT);
cnt++;
} else // If chunk is loaded and not being unloaded, we're grabbing its NBT data
if (cps.chunkExists(chunk.x, chunk.z)) {
ChunkSnapshot ss;
DynIntHashMap tileData;
if (vis) {
// If visible
CompoundNBT nbt = ChunkSerializer.write((ServerWorld) w, cps.getChunk(chunk.x, chunk.z, false));
if (nbt != null)
nbt = nbt.getCompound("Level");
SnapshotRec ssr = prepChunkSnapshot(chunk, nbt);
ss = ssr.ss;
tileData = ssr.tileData;
} else {
if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) {
ss = STONE;
} else if (hidestyle == HiddenChunkStyle.FILL_OCEAN) {
ss = OCEAN;
} else {
ss = EMPTY;
}
tileData = new DynIntHashMap();
}
snaparray[chunkindex] = ss;
snaptile[chunkindex] = tileData;
endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS);
cnt++;
}
}
return cnt;
}
use of org.dynmap.utils.DynIntHashMap in project dynmap by webbukkit.
the class ForgeMapChunkCache method getLoadedChunks.
/**
* Read NBT data from loaded chunks - needs to be called from server/world thread to be safe
* @returns number loaded
*/
public int getLoadedChunks() {
int cnt = 0;
if (!dw.isLoaded()) {
isempty = true;
unloadChunks();
return 0;
}
ListIterator<DynmapChunk> iter = chunks.listIterator();
while (iter.hasNext()) {
long startTime = System.nanoTime();
DynmapChunk chunk = iter.next();
int chunkindex = (chunk.x - x_min) + (chunk.z - z_min) * x_dim;
// Skip if already processed
if (snaparray[chunkindex] != null)
continue;
boolean vis = isChunkVisible(chunk);
/* Check if cached chunk snapshot found */
if (tryChunkCache(chunk, vis)) {
endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT);
cnt++;
} else // If chunk is loaded and not being unloaded, we're grabbing its NBT data
if (cps.chunkExists(chunk.x, chunk.z)) {
ChunkSnapshot ss;
DynIntHashMap tileData;
if (vis) {
// If visible
CompoundNBT nbt = ChunkSerializer.write((ServerWorld) w, cps.getChunk(chunk.x, chunk.z, false));
if (nbt != null)
nbt = nbt.getCompound("Level");
SnapshotRec ssr = prepChunkSnapshot(chunk, nbt);
ss = ssr.ss;
tileData = ssr.tileData;
} else {
if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) {
ss = STONE;
} else if (hidestyle == HiddenChunkStyle.FILL_OCEAN) {
ss = OCEAN;
} else {
ss = EMPTY;
}
tileData = new DynIntHashMap();
}
snaparray[chunkindex] = ss;
snaptile[chunkindex] = tileData;
endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS);
cnt++;
}
}
return cnt;
}
use of org.dynmap.utils.DynIntHashMap in project dynmap by webbukkit.
the class ForgeMapChunkCache method getLoadedChunks.
/**
* Read NBT data from loaded chunks - needs to be called from server/world thread to be safe
* @returns number loaded
*/
public int getLoadedChunks() {
int cnt = 0;
if (!dw.isLoaded()) {
isempty = true;
unloadChunks();
return 0;
}
ListIterator<DynmapChunk> iter = chunks.listIterator();
while (iter.hasNext()) {
long startTime = System.nanoTime();
DynmapChunk chunk = iter.next();
int chunkindex = (chunk.x - x_min) + (chunk.z - z_min) * x_dim;
// Skip if already processed
if (snaparray[chunkindex] != null)
continue;
boolean vis = isChunkVisible(chunk);
/* Check if cached chunk snapshot found */
if (tryChunkCache(chunk, vis)) {
endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT);
cnt++;
} else // If chunk is loaded and not being unloaded, we're grabbing its NBT data
if (cps.chunkExists(chunk.x, chunk.z) && (!isChunkUnloadPending(chunk))) {
ChunkSnapshot ss;
DynIntHashMap tileData;
if (vis) {
// If visible
NBTTagCompound nbt = new NBTTagCompound();
try {
writechunktonbt.invoke(cps.chunkLoader, cps.loadChunk(chunk.x, chunk.z), w, nbt);
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
} catch (InvocationTargetException e) {
}
SnapshotRec ssr = prepChunkSnapshot(chunk, nbt);
ss = ssr.ss;
tileData = ssr.tileData;
} else {
if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) {
ss = STONE;
} else if (hidestyle == HiddenChunkStyle.FILL_OCEAN) {
ss = OCEAN;
} else {
ss = EMPTY;
}
tileData = new DynIntHashMap();
}
snaparray[chunkindex] = ss;
snaptile[chunkindex] = tileData;
endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS);
cnt++;
}
}
return cnt;
}
Aggregations