mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-11-24 19:25:15 +01:00
Change autogenerate-to-visibilitylimits to have options for map-only (temporary generated chunks) versus permanent (world growing)
Fix exception catching code in thread pool
This commit is contained in:
parent
6dac7f0689
commit
39281188bc
@ -315,9 +315,9 @@ worlds:
|
||||
# # Use hidestyle to control how hidden-but-existing chunks are to be rendered (air=empty air (same as ungenerated), stone=a flat stone plain, ocean=a flat ocean)
|
||||
# hidestyle: stone
|
||||
# # Use 'autogenerate-to-visibilitylimits: true' to choose to force the generation of ungenerated chunks while rendering maps on this world, for any chunks within the defined
|
||||
# # visibilitylimits (limits must be set). This will result in initializing all game world areas within the visible ranges that have not yet been initialized.
|
||||
# # Note: BE SURE YOU WANT TO DO THIS - there isn't a good way to "ungenerate" terrain chunks once generated (although tools like WorldEdit can regenerate them)
|
||||
# autogenerate-to-visibilitylimits: false
|
||||
# # visibilitylimits (limits must be set). The three options here are: none (default - no autogenerate), map-only (temporarily generate chunks for map, but don't save them (no world change),
|
||||
# # permanent (generate and save chunks - this permanently adds the chunks to the world, as if a player had visited them - BE SURE THIS IS WHAT YOU WANT)
|
||||
# autogenerate-to-visibilitylimits: map-only
|
||||
# Use 'template: mycustomtemplate' to use the properties specified in the template 'mycustomtemplate' to this world. Default it is set to the environment-name (normal or nether).
|
||||
# template: mycustomtemplate
|
||||
# Rest of comes from template - uncomment to tailor for world specifically
|
||||
|
@ -53,6 +53,7 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
/* Flag to let code know that we're doing reload - make sure we don't double-register event handlers */
|
||||
public boolean is_reload = false;
|
||||
private boolean generate_only = false;
|
||||
private static boolean ignore_chunk_loads = false; /* Flat to keep us from processing our own chunk loads */
|
||||
|
||||
public static File dataDirectory;
|
||||
public static File tilesDirectory;
|
||||
@ -248,6 +249,8 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
WorldListener renderTrigger = new WorldListener() {
|
||||
@Override
|
||||
public void onChunkLoad(ChunkLoadEvent event) {
|
||||
if(ignore_chunk_loads)
|
||||
return;
|
||||
if(generate_only) {
|
||||
if(!isNewChunk(event))
|
||||
return;
|
||||
@ -494,4 +497,8 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
public String getWebPath() {
|
||||
return configuration.getString("webpath", "web");
|
||||
}
|
||||
|
||||
public static void setIgnoreChunkLoads(boolean ignore) {
|
||||
ignore_chunk_loads = ignore;
|
||||
}
|
||||
}
|
||||
|
@ -21,13 +21,18 @@ import java.util.HashSet;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
public class DynmapWorld {
|
||||
public enum AutoGenerateOption {
|
||||
NONE,
|
||||
FORMAPONLY,
|
||||
PERMANENT
|
||||
}
|
||||
public World world;
|
||||
public List<MapType> maps = new ArrayList<MapType>();
|
||||
public UpdateQueue updates = new UpdateQueue();
|
||||
public ConfigurationNode configuration;
|
||||
public List<Location> seedloc;
|
||||
public List<MapChunkCache.VisibilityLimit> visibility_limits;
|
||||
public boolean do_autogenerate;
|
||||
public AutoGenerateOption do_autogenerate;
|
||||
public MapChunkCache.HiddenChunkStyle hiddenchunkstyle;
|
||||
public int servertime;
|
||||
public boolean sendposition;
|
||||
|
@ -10,6 +10,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -17,6 +18,7 @@ import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.dynmap.DynmapWorld.AutoGenerateOption;
|
||||
import org.dynmap.debug.Debug;
|
||||
import org.dynmap.utils.LegacyMapChunkCache;
|
||||
import org.dynmap.utils.MapChunkCache;
|
||||
@ -94,6 +96,33 @@ public class MapManager {
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void execute(final Runnable r) {
|
||||
final Runnable rr = r;
|
||||
super.execute(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
r.run();
|
||||
} catch (Exception x) {
|
||||
Log.severe("Exception during render job: " + r);
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public ScheduledFuture<?> schedule(final Runnable command, long delay, TimeUnit unit) {
|
||||
return super.schedule(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
command.run();
|
||||
} catch (Exception x) {
|
||||
Log.severe("Exception during render job: " + command);
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, delay, unit);
|
||||
}
|
||||
}
|
||||
/* This always runs on render pool threads - no bukkit calls from here */
|
||||
private class FullWorldRenderState implements Runnable {
|
||||
@ -391,10 +420,19 @@ public class MapManager {
|
||||
dynmapWorld.seedloc.add(new Location(w, (lim.x0+lim.x1)/2, 64, (lim.z0+lim.z1)/2));
|
||||
}
|
||||
}
|
||||
dynmapWorld.do_autogenerate = worldConfiguration.getBoolean("autogenerate-to-visibilitylimits", false);
|
||||
if(dynmapWorld.do_autogenerate && (dynmapWorld.visibility_limits == null)) {
|
||||
Log.info("Warning: Automatic world generation to visible limits option requires that visiblelimits be set - option disabled");
|
||||
dynmapWorld.do_autogenerate = false;
|
||||
String autogen = worldConfiguration.getString("autogenerate-to-visibilitylimits", "none");
|
||||
if(autogen.equals("permanent")) {
|
||||
dynmapWorld.do_autogenerate = AutoGenerateOption.PERMANENT;
|
||||
}
|
||||
else if(autogen.equals("map-only")) {
|
||||
dynmapWorld.do_autogenerate = AutoGenerateOption.FORMAPONLY;
|
||||
}
|
||||
else {
|
||||
dynmapWorld.do_autogenerate = AutoGenerateOption.NONE;
|
||||
}
|
||||
if((dynmapWorld.do_autogenerate != AutoGenerateOption.NONE) && (dynmapWorld.visibility_limits == null)) {
|
||||
Log.info("Warning: Automatic world generation to visible limits option requires that visibitylimits be set - option disabled");
|
||||
dynmapWorld.do_autogenerate = AutoGenerateOption.NONE;
|
||||
}
|
||||
String hiddenchunkstyle = worldConfiguration.getString("hidestyle", "stone");
|
||||
if(hiddenchunkstyle.equals("air"))
|
||||
|
@ -11,6 +11,8 @@ import org.bukkit.Chunk;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.dynmap.DynmapChunk;
|
||||
import org.dynmap.DynmapPlugin;
|
||||
import org.dynmap.DynmapWorld;
|
||||
import org.dynmap.Log;
|
||||
|
||||
import java.util.List;
|
||||
@ -28,7 +30,9 @@ public class LegacyMapChunkCache implements MapChunkCache {
|
||||
private World w;
|
||||
private List<DynmapChunk> chunks;
|
||||
private ListIterator<DynmapChunk> iterator;
|
||||
private boolean do_generate;
|
||||
private DynmapWorld.AutoGenerateOption generateopt;
|
||||
private boolean do_generate = false;
|
||||
private boolean do_save = false;
|
||||
private boolean isempty = true;
|
||||
|
||||
private int x_min, x_max, z_min, z_max;
|
||||
@ -263,6 +267,7 @@ public class LegacyMapChunkCache implements MapChunkCache {
|
||||
if(iterator == null)
|
||||
iterator = chunks.listIterator();
|
||||
|
||||
DynmapPlugin.setIgnoreChunkLoads(true);
|
||||
// Load the required chunks.
|
||||
while((cnt < max_to_load) && iterator.hasNext()) {
|
||||
DynmapChunk chunk = iterator.next();
|
||||
@ -278,7 +283,7 @@ public class LegacyMapChunkCache implements MapChunkCache {
|
||||
}
|
||||
}
|
||||
boolean wasLoaded = w.isChunkLoaded(chunk.x, chunk.z);
|
||||
boolean didload = w.loadChunk(chunk.x, chunk.z, do_generate && vis);
|
||||
boolean didload = w.loadChunk(chunk.x, chunk.z, false);
|
||||
boolean didgenerate = false;
|
||||
/* If we didn't load, and we're supposed to generate, do it */
|
||||
if((!didload) && do_generate && vis)
|
||||
@ -325,7 +330,7 @@ public class LegacyMapChunkCache implements MapChunkCache {
|
||||
* 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 */
|
||||
w.unloadChunk(chunk.x, chunk.z, didgenerate, false);
|
||||
w.unloadChunk(chunk.x, chunk.z, didgenerate && do_save, false);
|
||||
/* And pop preserved chunk - this is a bad leak in Bukkit for map traversals like us */
|
||||
try {
|
||||
if(poppreservedchunk != null)
|
||||
@ -337,6 +342,8 @@ public class LegacyMapChunkCache implements MapChunkCache {
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
DynmapPlugin.setIgnoreChunkLoads(false);
|
||||
|
||||
/* If done, finish table */
|
||||
if(iterator.hasNext() == false) {
|
||||
isempty = true;
|
||||
@ -456,12 +463,14 @@ public class LegacyMapChunkCache implements MapChunkCache {
|
||||
/**
|
||||
* Set autogenerate - must be done after at least one visible range has been set
|
||||
*/
|
||||
public void setAutoGenerateVisbileRanges(boolean do_generate) {
|
||||
if(do_generate && ((visible_limits == null) || (visible_limits.size() == 0))) {
|
||||
public void setAutoGenerateVisbileRanges(DynmapWorld.AutoGenerateOption generateopt) {
|
||||
if((generateopt != DynmapWorld.AutoGenerateOption.NONE) && ((visible_limits == null) || (visible_limits.size() == 0))) {
|
||||
Log.severe("Cannot setAutoGenerateVisibleRanges() without visible ranges defined");
|
||||
return;
|
||||
}
|
||||
this.do_generate = do_generate;
|
||||
this.generateopt = generateopt;
|
||||
this.do_generate = (generateopt != DynmapWorld.AutoGenerateOption.NONE);
|
||||
this.do_save = (generateopt == DynmapWorld.AutoGenerateOption.PERMANENT);
|
||||
}
|
||||
@Override
|
||||
public boolean setChunkDataTypes(boolean blockdata, boolean biome, boolean highestblocky, boolean rawbiome) {
|
||||
|
@ -4,6 +4,7 @@ import org.bukkit.block.Biome;
|
||||
|
||||
import java.util.List;
|
||||
import org.dynmap.DynmapChunk;
|
||||
import org.dynmap.DynmapWorld;
|
||||
|
||||
public interface MapChunkCache {
|
||||
public enum HiddenChunkStyle {
|
||||
@ -94,5 +95,5 @@ public interface MapChunkCache {
|
||||
/**
|
||||
* Set autogenerate - must be done after at least one visible range has been set
|
||||
*/
|
||||
public void setAutoGenerateVisbileRanges(boolean do_generate);
|
||||
public void setAutoGenerateVisbileRanges(DynmapWorld.AutoGenerateOption do_generate);
|
||||
}
|
||||
|
@ -12,7 +12,10 @@ import org.bukkit.block.Biome;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.ChunkSnapshot;
|
||||
import org.dynmap.DynmapChunk;
|
||||
import org.dynmap.DynmapPlugin;
|
||||
import org.dynmap.DynmapWorld;
|
||||
import org.dynmap.Log;
|
||||
import org.dynmap.MapManager;
|
||||
|
||||
/**
|
||||
* Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread
|
||||
@ -31,7 +34,9 @@ public class NewMapChunkCache implements MapChunkCache {
|
||||
private boolean biome, biomeraw, highesty, blockdata;
|
||||
private HiddenChunkStyle hidestyle = HiddenChunkStyle.FILL_AIR;
|
||||
private List<VisibilityLimit> visible_limits = null;
|
||||
private DynmapWorld.AutoGenerateOption generateopt;
|
||||
private boolean do_generate = false;
|
||||
private boolean do_save = false;
|
||||
private boolean isempty = true;
|
||||
|
||||
private ChunkSnapshot[] snaparray; /* Index = (x-x_min) + ((z-z_min)*x_dim) */
|
||||
@ -284,6 +289,7 @@ public class NewMapChunkCache implements MapChunkCache {
|
||||
if(iterator == null)
|
||||
iterator = chunks.listIterator();
|
||||
|
||||
DynmapPlugin.setIgnoreChunkLoads(true);
|
||||
// Load the required chunks.
|
||||
while((cnt < max_to_load) && iterator.hasNext()) {
|
||||
DynmapChunk chunk = iterator.next();
|
||||
@ -298,7 +304,7 @@ public class NewMapChunkCache implements MapChunkCache {
|
||||
}
|
||||
}
|
||||
boolean wasLoaded = w.isChunkLoaded(chunk.x, chunk.z);
|
||||
boolean didload = w.loadChunk(chunk.x, chunk.z, do_generate && vis);
|
||||
boolean didload = w.loadChunk(chunk.x, chunk.z, false);
|
||||
boolean didgenerate = false;
|
||||
/* If we didn't load, and we're supposed to generate, do it */
|
||||
if((!didload) && do_generate && vis)
|
||||
@ -348,7 +354,7 @@ public class NewMapChunkCache implements MapChunkCache {
|
||||
* 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 */
|
||||
w.unloadChunk(chunk.x, chunk.z, didgenerate, false);
|
||||
w.unloadChunk(chunk.x, chunk.z, didgenerate && do_save, false);
|
||||
/* And pop preserved chunk - this is a bad leak in Bukkit for map traversals like us */
|
||||
try {
|
||||
if(poppreservedchunk != null)
|
||||
@ -359,6 +365,8 @@ public class NewMapChunkCache implements MapChunkCache {
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
DynmapPlugin.setIgnoreChunkLoads(false);
|
||||
|
||||
if(iterator.hasNext() == false) { /* If we're done */
|
||||
isempty = true;
|
||||
/* Fill missing chunks with empty dummy chunk */
|
||||
@ -457,12 +465,14 @@ public class NewMapChunkCache implements MapChunkCache {
|
||||
/**
|
||||
* Set autogenerate - must be done after at least one visible range has been set
|
||||
*/
|
||||
public void setAutoGenerateVisbileRanges(boolean do_generate) {
|
||||
if(do_generate && ((visible_limits == null) || (visible_limits.size() == 0))) {
|
||||
public void setAutoGenerateVisbileRanges(DynmapWorld.AutoGenerateOption generateopt) {
|
||||
if((generateopt != DynmapWorld.AutoGenerateOption.NONE) && ((visible_limits == null) || (visible_limits.size() == 0))) {
|
||||
Log.severe("Cannot setAutoGenerateVisibleRanges() without visible ranges defined");
|
||||
return;
|
||||
}
|
||||
this.do_generate = do_generate;
|
||||
this.generateopt = generateopt;
|
||||
this.do_generate = (generateopt != DynmapWorld.AutoGenerateOption.NONE);
|
||||
this.do_save = (generateopt == DynmapWorld.AutoGenerateOption.PERMANENT);
|
||||
}
|
||||
/**
|
||||
* Add visible area limit - can be called more than once
|
||||
|
Loading…
Reference in New Issue
Block a user