mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-09-27 13:22:34 +02:00
Merge pull request #2633 from Marvosg/v3.0
Resume full renders (skip already rendered tiles)
This commit is contained in:
commit
49ea99b703
@ -1046,7 +1046,9 @@ public class DynmapCore implements DynmapCommonAPI {
|
|||||||
new CommandInfo("dynmap", "render", "Renders the tile at your location."),
|
new CommandInfo("dynmap", "render", "Renders the tile at your location."),
|
||||||
new CommandInfo("dynmap", "fullrender", "Render all maps for entire world from your location."),
|
new CommandInfo("dynmap", "fullrender", "Render all maps for entire world from your location."),
|
||||||
new CommandInfo("dynmap", "fullrender", "<world>", "Render all maps for world <world>."),
|
new CommandInfo("dynmap", "fullrender", "<world>", "Render all maps for world <world>."),
|
||||||
new CommandInfo("dynmap", "fullrender", "<world>:<map>", "Render map <map> of world'<world>."),
|
new CommandInfo("dynmap", "fullrender", "<world>:<map>", "Render map <map> of world <world>."),
|
||||||
|
new CommandInfo("dynmap", "fullrender", "resume <world>", "Resume render of all maps for world <world>. Skip already rendered tiles."),
|
||||||
|
new CommandInfo("dynmap", "fullrender", "resume <world>:<map>", "Resume render of map <map> of world <world>. Skip already rendered tiles."),
|
||||||
new CommandInfo("dynmap", "radiusrender", "<radius>", "Render at least <radius> block radius from your location on all maps."),
|
new CommandInfo("dynmap", "radiusrender", "<radius>", "Render at least <radius> block radius from your location on all maps."),
|
||||||
new CommandInfo("dynmap", "radiusrender", "<radius> <mapname>", "Render at least <radius> block radius from your location on map <mapname>."),
|
new CommandInfo("dynmap", "radiusrender", "<radius> <mapname>", "Render at least <radius> block radius from your location on map <mapname>."),
|
||||||
new CommandInfo("dynmap", "radiusrender", "<world> <x> <z> <radius>", "Render at least <radius> block radius from location <x>,<z> on world <world>."),
|
new CommandInfo("dynmap", "radiusrender", "<world> <x> <z> <radius>", "Render at least <radius> block radius from location <x>,<z> on world <world>."),
|
||||||
@ -1319,7 +1321,7 @@ public class DynmapCore implements DynmapCommonAPI {
|
|||||||
loc = new DynmapLocation(w.getName(), x, 64, z);
|
loc = new DynmapLocation(w.getName(), x, 64, z);
|
||||||
}
|
}
|
||||||
if(loc != null)
|
if(loc != null)
|
||||||
mapManager.renderFullWorld(loc, sender, mapname, true);
|
mapManager.renderFullWorld(loc, sender, mapname, true, false);
|
||||||
} else if (c.equals("hide")) {
|
} else if (c.equals("hide")) {
|
||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
if(player != null && checkPlayerPermission(sender,"hide.self")) {
|
if(player != null && checkPlayerPermission(sender,"hide.self")) {
|
||||||
@ -1347,7 +1349,12 @@ public class DynmapCore implements DynmapCommonAPI {
|
|||||||
} else if (c.equals("fullrender") && checkPlayerPermission(sender,"fullrender")) {
|
} else if (c.equals("fullrender") && checkPlayerPermission(sender,"fullrender")) {
|
||||||
String map = null;
|
String map = null;
|
||||||
if (args.length > 1) {
|
if (args.length > 1) {
|
||||||
|
boolean resume = false;
|
||||||
for (int i = 1; i < args.length; i++) {
|
for (int i = 1; i < args.length; i++) {
|
||||||
|
if (args[i].equalsIgnoreCase("resume")) {
|
||||||
|
resume = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
int dot = args[i].indexOf(":");
|
int dot = args[i].indexOf(":");
|
||||||
DynmapWorld w;
|
DynmapWorld w;
|
||||||
String wname = args[i];
|
String wname = args[i];
|
||||||
@ -1362,7 +1369,7 @@ public class DynmapCore implements DynmapCommonAPI {
|
|||||||
loc = w.center;
|
loc = w.center;
|
||||||
else
|
else
|
||||||
loc = w.getSpawnLocation();
|
loc = w.getSpawnLocation();
|
||||||
mapManager.renderFullWorld(loc,sender, map, false);
|
mapManager.renderFullWorld(loc,sender, map, false, resume);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sender.sendMessage("World '" + wname + "' not defined/loaded");
|
sender.sendMessage("World '" + wname + "' not defined/loaded");
|
||||||
@ -1372,7 +1379,7 @@ public class DynmapCore implements DynmapCommonAPI {
|
|||||||
if(args.length > 1)
|
if(args.length > 1)
|
||||||
map = args[1];
|
map = args[1];
|
||||||
if(loc != null)
|
if(loc != null)
|
||||||
mapManager.renderFullWorld(loc, sender, map, false);
|
mapManager.renderFullWorld(loc, sender, map, false, false);
|
||||||
} else {
|
} else {
|
||||||
sender.sendMessage("World name is required");
|
sender.sendMessage("World name is required");
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import java.util.concurrent.ScheduledFuture;
|
|||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
@ -32,6 +33,10 @@ import org.dynmap.debug.Debug;
|
|||||||
import org.dynmap.exporter.OBJExport;
|
import org.dynmap.exporter.OBJExport;
|
||||||
import org.dynmap.hdmap.HDMapManager;
|
import org.dynmap.hdmap.HDMapManager;
|
||||||
import org.dynmap.renderer.DynmapBlockState;
|
import org.dynmap.renderer.DynmapBlockState;
|
||||||
|
import org.dynmap.storage.MapStorage;
|
||||||
|
import org.dynmap.storage.MapStorageBaseTileEnumCB;
|
||||||
|
import org.dynmap.storage.MapStorageTileSearchEndCB;
|
||||||
|
import org.dynmap.storage.MapStorageTile;
|
||||||
import org.dynmap.utils.MapChunkCache;
|
import org.dynmap.utils.MapChunkCache;
|
||||||
import org.dynmap.utils.Polygon;
|
import org.dynmap.utils.Polygon;
|
||||||
import org.dynmap.utils.TileFlags;
|
import org.dynmap.utils.TileFlags;
|
||||||
@ -233,6 +238,7 @@ public class MapManager {
|
|||||||
LinkedList<MapTile> renderQueue = null;
|
LinkedList<MapTile> renderQueue = null;
|
||||||
MapTile tile0 = null;
|
MapTile tile0 = null;
|
||||||
int rendercnt = 0;
|
int rendercnt = 0;
|
||||||
|
int skipcnt = 0;
|
||||||
DynmapCommandSender sender;
|
DynmapCommandSender sender;
|
||||||
String player;
|
String player;
|
||||||
long timeaccum;
|
long timeaccum;
|
||||||
@ -246,22 +252,52 @@ public class MapManager {
|
|||||||
boolean shutdown = false;
|
boolean shutdown = false;
|
||||||
boolean pausedforworld = false;
|
boolean pausedforworld = false;
|
||||||
boolean updaterender = false;
|
boolean updaterender = false;
|
||||||
|
boolean resume = false;
|
||||||
boolean quiet = false;
|
boolean quiet = false;
|
||||||
String mapname;
|
String mapname;
|
||||||
AtomicLong total_render_ns = new AtomicLong(0L);
|
AtomicLong total_render_ns = new AtomicLong(0L);
|
||||||
AtomicInteger rendercalls = new AtomicInteger(0);
|
AtomicInteger rendercalls = new AtomicInteger(0);
|
||||||
long lastPendingSaveTS = 0; // Timestamp of last pending state save (msec)
|
long lastPendingSaveTS = 0; // Timestamp of last pending state save (msec)
|
||||||
|
HashSet<String> storedTileIds = new HashSet<>();
|
||||||
|
|
||||||
/* Full world, all maps render */
|
/* Full world, all maps render */
|
||||||
FullWorldRenderState(DynmapWorld dworld, DynmapLocation l, DynmapCommandSender sender, String mapname, boolean updaterender) {
|
FullWorldRenderState(DynmapWorld dworld, DynmapLocation l, DynmapCommandSender sender, String mapname, boolean updaterender, boolean resume) {
|
||||||
this(dworld, l, sender, mapname, -1);
|
this(dworld, l, sender, mapname, -1);
|
||||||
if(updaterender) {
|
if(updaterender) {
|
||||||
rendertype = RENDERTYPE_UPDATERENDER;
|
rendertype = RENDERTYPE_UPDATERENDER;
|
||||||
this.updaterender = true;
|
this.updaterender = true;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
rendertype = RENDERTYPE_FULLRENDER;
|
rendertype = RENDERTYPE_FULLRENDER;
|
||||||
}
|
}
|
||||||
|
this.resume = resume;
|
||||||
|
|
||||||
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
if (resume) { // if resume render
|
||||||
|
final MapStorage ms = world.getMapStorage();
|
||||||
|
ms.enumMapBaseTiles(world, map, new MapStorageBaseTileEnumCB() {
|
||||||
|
@Override
|
||||||
|
public void tileFound(MapStorageTile tile, MapType.ImageEncoding enc) {
|
||||||
|
String tileId = String.format("%s_%s_%d_%d", tile.world.getName(), tile.map.getName(), tile.x, tile.y);
|
||||||
|
//sender.sendMessage("Tile found: " + tileId);
|
||||||
|
storedTileIds.add(tileId);
|
||||||
|
}
|
||||||
|
}, new MapStorageTileSearchEndCB() {
|
||||||
|
@Override
|
||||||
|
public void searchEnded() {
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
latch.await(10, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
sender.sendMessage(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Full world, all maps render, with optional render radius */
|
/* Full world, all maps render, with optional render radius */
|
||||||
FullWorldRenderState(DynmapWorld dworld, DynmapLocation l, DynmapCommandSender sender, String mapname, int radius) {
|
FullWorldRenderState(DynmapWorld dworld, DynmapLocation l, DynmapCommandSender sender, String mapname, int radius) {
|
||||||
@ -481,13 +517,22 @@ public class MapManager {
|
|||||||
if(rndcalls == 0) rndcalls = 1;
|
if(rndcalls == 0) rndcalls = 1;
|
||||||
double rendtime = total_render_ns.doubleValue() * 0.000001 / rndcalls;
|
double rendtime = total_render_ns.doubleValue() * 0.000001 / rndcalls;
|
||||||
if(activemapcnt > 1) {
|
if(activemapcnt > 1) {
|
||||||
|
if (skipcnt > 1)
|
||||||
|
sendMessage(String.format("%s of maps [%s] of '%s' completed - %d tiles rendered each (%.2f msec/map-tile, %.2f msec per render) (%d tiles skipped)",
|
||||||
|
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime, skipcnt));
|
||||||
|
else
|
||||||
sendMessage(String.format("%s of maps [%s] of '%s' completed - %d tiles rendered each (%.2f msec/map-tile, %.2f msec per render)",
|
sendMessage(String.format("%s of maps [%s] of '%s' completed - %d tiles rendered each (%.2f msec/map-tile, %.2f msec per render)",
|
||||||
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime));
|
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (skipcnt > 1)
|
||||||
|
sendMessage(String.format("%s of map '%s' of '%s' completed - %d tiles rendered (%.2f msec/map-tile, %.2f msec per render) (%d tiles skipped)",
|
||||||
|
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime, skipcnt));
|
||||||
|
else
|
||||||
sendMessage(String.format("%s of map '%s' of '%s' completed - %d tiles rendered (%.2f msec/map-tile, %.2f msec per render)",
|
sendMessage(String.format("%s of map '%s' of '%s' completed - %d tiles rendered (%.2f msec/map-tile, %.2f msec per render)",
|
||||||
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime));
|
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime));
|
||||||
}
|
}
|
||||||
|
skipcnt = 0;
|
||||||
/* Now, if fullrender, use the render bitmap to purge obsolete tiles */
|
/* Now, if fullrender, use the render bitmap to purge obsolete tiles */
|
||||||
if(rendertype.equals(RENDERTYPE_FULLRENDER)) {
|
if(rendertype.equals(RENDERTYPE_FULLRENDER)) {
|
||||||
if(activemapcnt == 1) {
|
if(activemapcnt == 1) {
|
||||||
@ -698,19 +743,37 @@ public class MapManager {
|
|||||||
chunks_read[cs.ordinal()].addAndGet(cache.getChunksLoaded(cs));
|
chunks_read[cs.ordinal()].addAndGet(cache.getChunksLoaded(cs));
|
||||||
chunks_read_times[cs.ordinal()].addAndGet(cache.getTotalRuntimeNanos(cs));
|
chunks_read_times[cs.ordinal()].addAndGet(cache.getTotalRuntimeNanos(cs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean skipTile = false;
|
||||||
|
if (resume) {
|
||||||
|
String tileId = String.format("%s_%s_%d_%d", tile.world.getName(), map.getName(), tile.tileOrdinalX(), tile.tileOrdinalY());
|
||||||
|
skipTile = storedTileIds.contains(tileId);
|
||||||
|
}
|
||||||
|
|
||||||
if(tile0 != null) { /* Single tile? */
|
if(tile0 != null) { /* Single tile? */
|
||||||
if(cache.isEmpty() == false)
|
if(cache.isEmpty() == false) {
|
||||||
|
if (skipTile) {
|
||||||
|
skipcnt++;
|
||||||
|
} else {
|
||||||
tile.render(cache, null);
|
tile.render(cache, null);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
/* Remove tile from tile queue, since we're processing it already */
|
/* Remove tile from tile queue, since we're processing it already */
|
||||||
tileQueue.remove(tile);
|
tileQueue.remove(tile);
|
||||||
/* Switch to not checking if rendered tile is blank - breaks us on skylands, where tiles can be nominally blank - just work off chunk cache empty */
|
/* Switch to not checking if rendered tile is blank - breaks us on skylands, where tiles can be nominally blank - just work off chunk cache empty */
|
||||||
if (cache.isEmpty() == false) {
|
if (cache.isEmpty() == false) {
|
||||||
|
boolean upd;
|
||||||
|
if (skipTile) {
|
||||||
|
upd = false;
|
||||||
|
skipcnt++;
|
||||||
|
} else {
|
||||||
long rt0 = System.nanoTime();
|
long rt0 = System.nanoTime();
|
||||||
boolean upd = tile.render(cache, mapname);
|
upd = tile.render(cache, mapname);
|
||||||
total_render_ns.addAndGet(System.nanoTime()-rt0);
|
total_render_ns.addAndGet(System.nanoTime()-rt0);
|
||||||
rendercalls.incrementAndGet();
|
rendercalls.incrementAndGet();
|
||||||
|
}
|
||||||
synchronized(lock) {
|
synchronized(lock) {
|
||||||
rendered.setFlag(tile.tileOrdinalX(), tile.tileOrdinalY(), true);
|
rendered.setFlag(tile.tileOrdinalX(), tile.tileOrdinalY(), true);
|
||||||
if(upd || (!updaterender)) { /* If updated or not an update render */
|
if(upd || (!updaterender)) { /* If updated or not an update render */
|
||||||
@ -733,13 +796,23 @@ public class MapManager {
|
|||||||
if (rndcalls == 0) rndcalls = 1;
|
if (rndcalls == 0) rndcalls = 1;
|
||||||
double rendtime = total_render_ns.doubleValue() * 0.000001 / rndcalls;
|
double rendtime = total_render_ns.doubleValue() * 0.000001 / rndcalls;
|
||||||
double msecpertile = (double)timeaccum / (double)rendercnt / (double)activemapcnt;
|
double msecpertile = (double)timeaccum / (double)rendercnt / (double)activemapcnt;
|
||||||
if(activemapcnt > 1)
|
if(activemapcnt > 1) {
|
||||||
|
if (skipcnt > 1)
|
||||||
|
sendMessage(String.format("%s of maps [%s] of '%s' in progress - %d tiles rendered each (%.2f msec/map-tile, %.2f msec per render) (%d tiles skipped)",
|
||||||
|
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime, skipcnt));
|
||||||
|
else
|
||||||
sendMessage(String.format("%s of maps [%s] of '%s' in progress - %d tiles rendered each (%.2f msec/map-tile, %.2f msec per render)",
|
sendMessage(String.format("%s of maps [%s] of '%s' in progress - %d tiles rendered each (%.2f msec/map-tile, %.2f msec per render)",
|
||||||
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime));
|
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime));
|
||||||
|
} else {
|
||||||
|
if (skipcnt > 1)
|
||||||
|
sendMessage(String.format("%s of map '%s' of '%s' in progress - %d tiles rendered (%.2f msec/tile, %.2f msec per render) (%d tiles skipped)",
|
||||||
|
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime, skipcnt));
|
||||||
else
|
else
|
||||||
sendMessage(String.format("%s of map '%s' of '%s' in progress - %d tiles rendered (%.2f msec/tile, %.2f msec per render)",
|
sendMessage(String.format("%s of map '%s' of '%s' in progress - %d tiles rendered (%.2f msec/tile, %.2f msec per render)",
|
||||||
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime));
|
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime));
|
||||||
}
|
}
|
||||||
|
skipcnt = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -751,6 +824,7 @@ public class MapManager {
|
|||||||
|
|
||||||
public void cancelRender() {
|
public void cancelRender() {
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
|
storedTileIds.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shutdownRender() {
|
public void shutdownRender() {
|
||||||
@ -968,7 +1042,7 @@ public class MapManager {
|
|||||||
tileQueue.start();
|
tileQueue.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderFullWorld(DynmapLocation l, DynmapCommandSender sender, String mapname, boolean update) {
|
void renderFullWorld(DynmapLocation l, DynmapCommandSender sender, String mapname, boolean update, boolean resume) {
|
||||||
DynmapWorld world = getWorld(l.world);
|
DynmapWorld world = getWorld(l.world);
|
||||||
if (world == null) {
|
if (world == null) {
|
||||||
sender.sendMessage("Could not render: world '" + l.world + "' not defined in configuration.");
|
sender.sendMessage("Could not render: world '" + l.world + "' not defined in configuration.");
|
||||||
@ -982,7 +1056,7 @@ public class MapManager {
|
|||||||
sender.sendMessage(rndr.rendertype + " of world '" + wname + "' already active.");
|
sender.sendMessage(rndr.rendertype + " of world '" + wname + "' already active.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rndr = new FullWorldRenderState(world,l,sender, mapname, update); /* Make new activation record */
|
rndr = new FullWorldRenderState(world,l,sender, mapname, update, resume); /* Make new activation record */
|
||||||
active_renders.put(wname, rndr); /* Add to active table */
|
active_renders.put(wname, rndr); /* Add to active table */
|
||||||
}
|
}
|
||||||
/* Schedule first tile to be worked */
|
/* Schedule first tile to be worked */
|
||||||
@ -990,6 +1064,8 @@ public class MapManager {
|
|||||||
|
|
||||||
if(update)
|
if(update)
|
||||||
sender.sendMessage("Update render starting on world '" + wname + "'...");
|
sender.sendMessage("Update render starting on world '" + wname + "'...");
|
||||||
|
else if (resume)
|
||||||
|
sender.sendMessage("Full render resuming on world '" + wname + "'...");
|
||||||
else
|
else
|
||||||
sender.sendMessage("Full render starting on world '" + wname + "'...");
|
sender.sendMessage("Full render starting on world '" + wname + "'...");
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,15 @@ public abstract class MapStorage {
|
|||||||
*/
|
*/
|
||||||
public abstract void enumMapTiles(DynmapWorld world, MapType map, MapStorageTileEnumCB cb);
|
public abstract void enumMapTiles(DynmapWorld world, MapType map, MapStorageTileEnumCB cb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumerate existing map tiles, matching given constraints, with zoom at 0
|
||||||
|
* @param world - specific world
|
||||||
|
* @param map - specific map (if non-null)
|
||||||
|
* @param cbBase - callback to receive matching tiles
|
||||||
|
* @param cbEnd - callback to receive end-of-search event
|
||||||
|
*/
|
||||||
|
public abstract void enumMapBaseTiles(DynmapWorld world, MapType map, MapStorageBaseTileEnumCB cbBase, MapStorageTileSearchEndCB cbEnd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Purge existing map tiles, matching given constraints
|
* Purge existing map tiles, matching given constraints
|
||||||
* @param world - specific world
|
* @param world - specific world
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package org.dynmap.storage;
|
||||||
|
|
||||||
|
import org.dynmap.MapType.ImageEncoding;
|
||||||
|
|
||||||
|
public interface MapStorageBaseTileEnumCB {
|
||||||
|
/**
|
||||||
|
* Callback for base (non-zoomed) tile enumeration calls
|
||||||
|
* @param tile - tile found
|
||||||
|
* @param enc - image encoding
|
||||||
|
*/
|
||||||
|
public void tileFound(MapStorageTile tile, ImageEncoding enc);
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package org.dynmap.storage;
|
||||||
|
|
||||||
|
import org.dynmap.MapType.ImageEncoding;
|
||||||
|
|
||||||
|
public interface MapStorageTileSearchEndCB {
|
||||||
|
/**
|
||||||
|
* Callback for end of tile enumeration calls
|
||||||
|
*/
|
||||||
|
public void searchEnded();
|
||||||
|
}
|
@ -22,6 +22,8 @@ import org.dynmap.debug.Debug;
|
|||||||
import org.dynmap.storage.MapStorage;
|
import org.dynmap.storage.MapStorage;
|
||||||
import org.dynmap.storage.MapStorageTile;
|
import org.dynmap.storage.MapStorageTile;
|
||||||
import org.dynmap.storage.MapStorageTileEnumCB;
|
import org.dynmap.storage.MapStorageTileEnumCB;
|
||||||
|
import org.dynmap.storage.MapStorageBaseTileEnumCB;
|
||||||
|
import org.dynmap.storage.MapStorageTileSearchEndCB;
|
||||||
import org.dynmap.utils.BufferInputStream;
|
import org.dynmap.utils.BufferInputStream;
|
||||||
import org.dynmap.utils.BufferOutputStream;
|
import org.dynmap.utils.BufferOutputStream;
|
||||||
|
|
||||||
@ -295,9 +297,13 @@ public class FileTreeMapStorage extends MapStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void processEnumMapTiles(DynmapWorld world, MapType map, File base, ImageVariant var, MapStorageTileEnumCB cb) {
|
private void processEnumMapTiles(DynmapWorld world, MapType map, File base, ImageVariant var, MapStorageTileEnumCB cb, MapStorageBaseTileEnumCB cbBase, MapStorageTileSearchEndCB cbEnd) {
|
||||||
File bdir = new File(base, map.getPrefix() + var.variantSuffix);
|
File bdir = new File(base, map.getPrefix() + var.variantSuffix);
|
||||||
if (bdir.isDirectory() == false) return;
|
if (bdir.isDirectory() == false) {
|
||||||
|
if(cbEnd != null)
|
||||||
|
cbEnd.searchEnded();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LinkedList<File> dirs = new LinkedList<File>(); // List to traverse
|
LinkedList<File> dirs = new LinkedList<File>(); // List to traverse
|
||||||
dirs.add(bdir); // Directory for map
|
dirs.add(bdir); // Directory for map
|
||||||
@ -343,7 +349,10 @@ public class FileTreeMapStorage extends MapStorage {
|
|||||||
int y = Integer.parseInt(coord[1]);
|
int y = Integer.parseInt(coord[1]);
|
||||||
// Invoke callback
|
// Invoke callback
|
||||||
MapStorageTile t = new StorageTile(world, map, x, y, zoom, var);
|
MapStorageTile t = new StorageTile(world, map, x, y, zoom, var);
|
||||||
|
if(cb != null)
|
||||||
cb.tileFound(t, fmt);
|
cb.tileFound(t, fmt);
|
||||||
|
if(cbBase != null && t.zoom == 0)
|
||||||
|
cbBase.tileFound(t, fmt);
|
||||||
t.cleanup();
|
t.cleanup();
|
||||||
} catch (NumberFormatException nfx) {
|
} catch (NumberFormatException nfx) {
|
||||||
}
|
}
|
||||||
@ -351,6 +360,9 @@ public class FileTreeMapStorage extends MapStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(cbEnd != null) {
|
||||||
|
cbEnd.searchEnded();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -367,7 +379,26 @@ public class FileTreeMapStorage extends MapStorage {
|
|||||||
for (MapType mt : mtlist) {
|
for (MapType mt : mtlist) {
|
||||||
ImageVariant[] vars = mt.getVariants();
|
ImageVariant[] vars = mt.getVariants();
|
||||||
for (ImageVariant var : vars) {
|
for (ImageVariant var : vars) {
|
||||||
processEnumMapTiles(world, mt, base, var, cb);
|
processEnumMapTiles(world, mt, base, var, cb, null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enumMapBaseTiles(DynmapWorld world, MapType map, MapStorageBaseTileEnumCB cbBase, MapStorageTileSearchEndCB cbEnd) {
|
||||||
|
File base = new File(baseTileDir, world.getName()); // Get base directory for world
|
||||||
|
List<MapType> mtlist;
|
||||||
|
|
||||||
|
if (map != null) {
|
||||||
|
mtlist = Collections.singletonList(map);
|
||||||
|
}
|
||||||
|
else { // Else, add all directories under world directory (for maps)
|
||||||
|
mtlist = new ArrayList<MapType>(world.maps);
|
||||||
|
}
|
||||||
|
for (MapType mt : mtlist) {
|
||||||
|
ImageVariant[] vars = mt.getVariants();
|
||||||
|
for (ImageVariant var : vars) {
|
||||||
|
processEnumMapTiles(world, mt, base, var, null, cbBase, cbEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@ import org.dynmap.PlayerFaces.FaceType;
|
|||||||
import org.dynmap.storage.MapStorage;
|
import org.dynmap.storage.MapStorage;
|
||||||
import org.dynmap.storage.MapStorageTile;
|
import org.dynmap.storage.MapStorageTile;
|
||||||
import org.dynmap.storage.MapStorageTileEnumCB;
|
import org.dynmap.storage.MapStorageTileEnumCB;
|
||||||
|
import org.dynmap.storage.MapStorageBaseTileEnumCB;
|
||||||
|
import org.dynmap.storage.MapStorageTileSearchEndCB;
|
||||||
import org.dynmap.utils.BufferInputStream;
|
import org.dynmap.utils.BufferInputStream;
|
||||||
import org.dynmap.utils.BufferOutputStream;
|
import org.dynmap.utils.BufferOutputStream;
|
||||||
|
|
||||||
@ -620,15 +622,36 @@ public class MariaDBMapStorage extends MapStorage {
|
|||||||
for (MapType mt : mtlist) {
|
for (MapType mt : mtlist) {
|
||||||
ImageVariant[] vars = mt.getVariants();
|
ImageVariant[] vars = mt.getVariants();
|
||||||
for (ImageVariant var : vars) {
|
for (ImageVariant var : vars) {
|
||||||
processEnumMapTiles(world, mt, var, cb);
|
processEnumMapTiles(world, mt, var, cb, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void processEnumMapTiles(DynmapWorld world, MapType map, ImageVariant var, MapStorageTileEnumCB cb) {
|
@Override
|
||||||
|
public void enumMapBaseTiles(DynmapWorld world, MapType map, MapStorageBaseTileEnumCB cbBase, MapStorageTileSearchEndCB cbEnd) {
|
||||||
|
List<MapType> mtlist;
|
||||||
|
|
||||||
|
if (map != null) {
|
||||||
|
mtlist = Collections.singletonList(map);
|
||||||
|
}
|
||||||
|
else { // Else, add all directories under world directory (for maps)
|
||||||
|
mtlist = new ArrayList<MapType>(world.maps);
|
||||||
|
}
|
||||||
|
for (MapType mt : mtlist) {
|
||||||
|
ImageVariant[] vars = mt.getVariants();
|
||||||
|
for (ImageVariant var : vars) {
|
||||||
|
processEnumMapTiles(world, mt, var, null, cbBase, cbEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void processEnumMapTiles(DynmapWorld world, MapType map, ImageVariant var, MapStorageTileEnumCB cb, MapStorageBaseTileEnumCB cbBase, MapStorageTileSearchEndCB cbEnd) {
|
||||||
Connection c = null;
|
Connection c = null;
|
||||||
boolean err = false;
|
boolean err = false;
|
||||||
Integer mapkey = getMapKey(world, map, var);
|
Integer mapkey = getMapKey(world, map, var);
|
||||||
if (mapkey == null) return;
|
if (mapkey == null) {
|
||||||
|
if(cbEnd != null)
|
||||||
|
cbEnd.searchEnded();
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
c = getConnection();
|
c = getConnection();
|
||||||
// Query tiles for given mapkey
|
// Query tiles for given mapkey
|
||||||
@ -636,9 +659,15 @@ public class MariaDBMapStorage extends MapStorage {
|
|||||||
ResultSet rs = stmt.executeQuery("SELECT x,y,zoom,Format FROM " + tableTiles + " WHERE MapID=" + mapkey + ";");
|
ResultSet rs = stmt.executeQuery("SELECT x,y,zoom,Format FROM " + tableTiles + " WHERE MapID=" + mapkey + ";");
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
StorageTile st = new StorageTile(world, map, rs.getInt("x"), rs.getInt("y"), rs.getInt("zoom"), var);
|
StorageTile st = new StorageTile(world, map, rs.getInt("x"), rs.getInt("y"), rs.getInt("zoom"), var);
|
||||||
cb.tileFound(st, MapType.ImageEncoding.fromOrd(rs.getInt("Format")));
|
final MapType.ImageEncoding encoding = MapType.ImageEncoding.fromOrd(rs.getInt("Format"));
|
||||||
|
if(cb != null)
|
||||||
|
cb.tileFound(st, encoding);
|
||||||
|
if(cbBase != null && st.zoom == 0)
|
||||||
|
cbBase.tileFound(st, encoding);
|
||||||
st.cleanup();
|
st.cleanup();
|
||||||
}
|
}
|
||||||
|
if(cbEnd != null)
|
||||||
|
cbEnd.searchEnded();
|
||||||
rs.close();
|
rs.close();
|
||||||
stmt.close();
|
stmt.close();
|
||||||
} catch (SQLException x) {
|
} catch (SQLException x) {
|
||||||
|
@ -25,6 +25,8 @@ import org.dynmap.PlayerFaces.FaceType;
|
|||||||
import org.dynmap.storage.MapStorage;
|
import org.dynmap.storage.MapStorage;
|
||||||
import org.dynmap.storage.MapStorageTile;
|
import org.dynmap.storage.MapStorageTile;
|
||||||
import org.dynmap.storage.MapStorageTileEnumCB;
|
import org.dynmap.storage.MapStorageTileEnumCB;
|
||||||
|
import org.dynmap.storage.MapStorageBaseTileEnumCB;
|
||||||
|
import org.dynmap.storage.MapStorageTileSearchEndCB;
|
||||||
import org.dynmap.utils.BufferInputStream;
|
import org.dynmap.utils.BufferInputStream;
|
||||||
import org.dynmap.utils.BufferOutputStream;
|
import org.dynmap.utils.BufferOutputStream;
|
||||||
|
|
||||||
@ -622,15 +624,36 @@ public class MySQLMapStorage extends MapStorage {
|
|||||||
for (MapType mt : mtlist) {
|
for (MapType mt : mtlist) {
|
||||||
ImageVariant[] vars = mt.getVariants();
|
ImageVariant[] vars = mt.getVariants();
|
||||||
for (ImageVariant var : vars) {
|
for (ImageVariant var : vars) {
|
||||||
processEnumMapTiles(world, mt, var, cb);
|
processEnumMapTiles(world, mt, var, cb, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void processEnumMapTiles(DynmapWorld world, MapType map, ImageVariant var, MapStorageTileEnumCB cb) {
|
@Override
|
||||||
|
public void enumMapBaseTiles(DynmapWorld world, MapType map, MapStorageBaseTileEnumCB cbBase, MapStorageTileSearchEndCB cbEnd) {
|
||||||
|
List<MapType> mtlist;
|
||||||
|
|
||||||
|
if (map != null) {
|
||||||
|
mtlist = Collections.singletonList(map);
|
||||||
|
}
|
||||||
|
else { // Else, add all directories under world directory (for maps)
|
||||||
|
mtlist = new ArrayList<MapType>(world.maps);
|
||||||
|
}
|
||||||
|
for (MapType mt : mtlist) {
|
||||||
|
ImageVariant[] vars = mt.getVariants();
|
||||||
|
for (ImageVariant var : vars) {
|
||||||
|
processEnumMapTiles(world, mt, var, null, cbBase, cbEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void processEnumMapTiles(DynmapWorld world, MapType map, ImageVariant var, MapStorageTileEnumCB cb, MapStorageBaseTileEnumCB cbBase, MapStorageTileSearchEndCB cbEnd) {
|
||||||
Connection c = null;
|
Connection c = null;
|
||||||
boolean err = false;
|
boolean err = false;
|
||||||
Integer mapkey = getMapKey(world, map, var);
|
Integer mapkey = getMapKey(world, map, var);
|
||||||
if (mapkey == null) return;
|
if (mapkey == null) {
|
||||||
|
if(cbEnd != null)
|
||||||
|
cbEnd.searchEnded();
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
c = getConnection();
|
c = getConnection();
|
||||||
// Query tiles for given mapkey
|
// Query tiles for given mapkey
|
||||||
@ -638,9 +661,15 @@ public class MySQLMapStorage extends MapStorage {
|
|||||||
ResultSet rs = stmt.executeQuery("SELECT x,y,zoom,Format FROM " + tableTiles + " WHERE MapID=" + mapkey + ";");
|
ResultSet rs = stmt.executeQuery("SELECT x,y,zoom,Format FROM " + tableTiles + " WHERE MapID=" + mapkey + ";");
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
StorageTile st = new StorageTile(world, map, rs.getInt("x"), rs.getInt("y"), rs.getInt("zoom"), var);
|
StorageTile st = new StorageTile(world, map, rs.getInt("x"), rs.getInt("y"), rs.getInt("zoom"), var);
|
||||||
cb.tileFound(st, MapType.ImageEncoding.fromOrd(rs.getInt("Format")));
|
final MapType.ImageEncoding encoding = MapType.ImageEncoding.fromOrd(rs.getInt("Format"));
|
||||||
|
if(cb != null)
|
||||||
|
cb.tileFound(st, encoding);
|
||||||
|
if(cbBase != null && st.zoom == 0)
|
||||||
|
cbBase.tileFound(st, encoding);
|
||||||
st.cleanup();
|
st.cleanup();
|
||||||
}
|
}
|
||||||
|
if(cbEnd != null)
|
||||||
|
cbEnd.searchEnded();
|
||||||
rs.close();
|
rs.close();
|
||||||
stmt.close();
|
stmt.close();
|
||||||
} catch (SQLException x) {
|
} catch (SQLException x) {
|
||||||
|
@ -23,6 +23,8 @@ import org.dynmap.PlayerFaces.FaceType;
|
|||||||
import org.dynmap.storage.MapStorage;
|
import org.dynmap.storage.MapStorage;
|
||||||
import org.dynmap.storage.MapStorageTile;
|
import org.dynmap.storage.MapStorageTile;
|
||||||
import org.dynmap.storage.MapStorageTileEnumCB;
|
import org.dynmap.storage.MapStorageTileEnumCB;
|
||||||
|
import org.dynmap.storage.MapStorageBaseTileEnumCB;
|
||||||
|
import org.dynmap.storage.MapStorageTileSearchEndCB;
|
||||||
import org.dynmap.utils.BufferInputStream;
|
import org.dynmap.utils.BufferInputStream;
|
||||||
import org.dynmap.utils.BufferOutputStream;
|
import org.dynmap.utils.BufferOutputStream;
|
||||||
|
|
||||||
@ -553,15 +555,38 @@ public class SQLiteMapStorage extends MapStorage {
|
|||||||
for (MapType mt : mtlist) {
|
for (MapType mt : mtlist) {
|
||||||
ImageVariant[] vars = mt.getVariants();
|
ImageVariant[] vars = mt.getVariants();
|
||||||
for (ImageVariant var : vars) {
|
for (ImageVariant var : vars) {
|
||||||
processEnumMapTiles(world, mt, var, cb);
|
processEnumMapTiles(world, mt, var, cb, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void processEnumMapTiles(DynmapWorld world, MapType map, ImageVariant var, MapStorageTileEnumCB cb) {
|
|
||||||
|
@Override
|
||||||
|
public void enumMapBaseTiles(DynmapWorld world, MapType map, MapStorageBaseTileEnumCB cbBase, MapStorageTileSearchEndCB cbEnd) {
|
||||||
|
List<MapType> mtlist;
|
||||||
|
|
||||||
|
if (map != null) {
|
||||||
|
mtlist = Collections.singletonList(map);
|
||||||
|
}
|
||||||
|
else { // Else, add all directories under world directory (for maps)
|
||||||
|
mtlist = new ArrayList<MapType>(world.maps);
|
||||||
|
}
|
||||||
|
for (MapType mt : mtlist) {
|
||||||
|
ImageVariant[] vars = mt.getVariants();
|
||||||
|
for (ImageVariant var : vars) {
|
||||||
|
processEnumMapTiles(world, mt, var, null, cbBase, cbEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processEnumMapTiles(DynmapWorld world, MapType map, ImageVariant var, MapStorageTileEnumCB cb, MapStorageBaseTileEnumCB cbBase, MapStorageTileSearchEndCB cbEnd) {
|
||||||
Connection c = null;
|
Connection c = null;
|
||||||
boolean err = false;
|
boolean err = false;
|
||||||
Integer mapkey = getMapKey(world, map, var);
|
Integer mapkey = getMapKey(world, map, var);
|
||||||
if (mapkey == null) return;
|
if (mapkey == null) {
|
||||||
|
if(cbEnd != null)
|
||||||
|
cbEnd.searchEnded();
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
c = getConnection();
|
c = getConnection();
|
||||||
// Query tiles for given mapkey
|
// Query tiles for given mapkey
|
||||||
@ -570,9 +595,15 @@ public class SQLiteMapStorage extends MapStorage {
|
|||||||
ResultSet rs = doExecuteQuery(stmt, "SELECT x,y,zoom,Format FROM Tiles WHERE MapID=" + mapkey + ";");
|
ResultSet rs = doExecuteQuery(stmt, "SELECT x,y,zoom,Format FROM Tiles WHERE MapID=" + mapkey + ";");
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
StorageTile st = new StorageTile(world, map, rs.getInt("x"), rs.getInt("y"), rs.getInt("zoom"), var);
|
StorageTile st = new StorageTile(world, map, rs.getInt("x"), rs.getInt("y"), rs.getInt("zoom"), var);
|
||||||
cb.tileFound(st, MapType.ImageEncoding.fromOrd(rs.getInt("Format")));
|
final MapType.ImageEncoding encoding = MapType.ImageEncoding.fromOrd(rs.getInt("Format"));
|
||||||
|
if(cb != null)
|
||||||
|
cb.tileFound(st, encoding);
|
||||||
|
if(cbBase != null && st.zoom == 0)
|
||||||
|
cbBase.tileFound(st, encoding);
|
||||||
st.cleanup();
|
st.cleanup();
|
||||||
}
|
}
|
||||||
|
if(cbEnd != null)
|
||||||
|
cbEnd.searchEnded();
|
||||||
rs.close();
|
rs.close();
|
||||||
stmt.close();
|
stmt.close();
|
||||||
} catch (SQLException x) {
|
} catch (SQLException x) {
|
||||||
|
Loading…
Reference in New Issue
Block a user