From 8a75d0e63092a14a51f73841ae4a18411eb1bf68 Mon Sep 17 00:00:00 2001 From: Brettflan Date: Wed, 18 Dec 2013 01:12:44 -0600 Subject: [PATCH] New command /wb fillautosave , which lets you set the interval for automatic saving of the world during the Fill process (default 30 seconds). Set to 0 to disable, though this is not generally recommended as any errors or crashes during world generation can then result in a lot of lost progress. Requires new permission "worldborder.fillautosave". --- .../java/com/wimbli/WorldBorder/Config.java | 20 ++++++++++- .../com/wimbli/WorldBorder/WBCommand.java | 36 +++++++++++++++++++ .../com/wimbli/WorldBorder/WorldFillTask.java | 9 +++-- src/main/resources/plugin.yml | 5 +++ 4 files changed, 64 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/wimbli/WorldBorder/Config.java b/src/main/java/com/wimbli/WorldBorder/Config.java index ee78bc3..1458f76 100644 --- a/src/main/java/com/wimbli/WorldBorder/Config.java +++ b/src/main/java/com/wimbli/WorldBorder/Config.java @@ -31,12 +31,12 @@ public class Config private static int borderTask = -1; public static WorldFillTask fillTask; public static WorldTrimTask trimTask; - private static Set bypassPlayers = Collections.synchronizedSet(new LinkedHashSet()); private static Runtime rt = Runtime.getRuntime(); // actual configuration values which can be changed private static boolean shapeRound = true; private static Map borders = Collections.synchronizedMap(new LinkedHashMap()); + private static Set bypassPlayers = Collections.synchronizedSet(new LinkedHashSet()); private static String message; // raw message without color code formatting private static String messageFmt; // message with color code formatting ("&" changed to funky sort-of-double-dollar-sign for legitimate color/formatting codes) private static String messageClean; // message cleaned of formatting codes @@ -50,6 +50,7 @@ public class Config private static int remountDelayTicks = 0; private static boolean killPlayer = false; private static boolean denyEnderpearl = false; + private static int fillAutosaveFrequency = 30; // for monitoring plugin efficiency // public static long timeUsed = 0; @@ -311,6 +312,21 @@ public class Config return remountDelayTicks; } + public static void setFillAutosaveFrequency(int seconds) + { + fillAutosaveFrequency = seconds; + if (fillAutosaveFrequency == 0) + Log("World autosave frequency during Fill process set to 0, disabling it. Note that much progress can be lost this way if there is a bug or crash in the world generation process from Bukkit or any world generation plugin you use."); + else + Log("World autosave frequency during Fill process set to " + fillAutosaveFrequency + " seconds (rounded to a multiple of 5). New chunks generated by the Fill process will be forcibly saved to disk this often to prevent loss of progress due to bugs or crashes in the world generation process."); + save(true); + } + + public static int FillAutosaveFrequency() + { + return fillAutosaveFrequency; + } + public static void setDynmapBorderEnabled(boolean enable) { @@ -511,6 +527,7 @@ public class Config LogConfig("Using " + (ShapeName()) + " border, knockback of " + knockBack + " blocks, and timer delay of " + timerTicks + "."); killPlayer = cfg.getBoolean("player-killed-bad-spawn", false); denyEnderpearl = cfg.getBoolean("deny-enderpearl", false); + fillAutosaveFrequency = cfg.getInt("fill-autosave-frequency", 30); bypassPlayers = Collections.synchronizedSet(new LinkedHashSet(cfg.getStringList("bypass-list"))); StartBorderTimer(); @@ -607,6 +624,7 @@ public class Config cfg.set("dynmap-border-message", dynmapMessage); cfg.set("player-killed-bad-spawn", killPlayer); cfg.set("deny-enderpearl", denyEnderpearl); + cfg.set("fill-autosave-frequency", fillAutosaveFrequency); cfg.set("bypass-list", new ArrayList(bypassPlayers)); cfg.set("worlds", null); diff --git a/src/main/java/com/wimbli/WorldBorder/WBCommand.java b/src/main/java/com/wimbli/WorldBorder/WBCommand.java index f8dc7be..64bc715 100644 --- a/src/main/java/com/wimbli/WorldBorder/WBCommand.java +++ b/src/main/java/com/wimbli/WorldBorder/WBCommand.java @@ -716,6 +716,41 @@ public class WBCommand implements CommandExecutor } } + // "fillautosave" command from player or console + else if (split.length == 2 && split[0].equalsIgnoreCase("fillautosave")) + { + if (!Config.HasPermission(player, "fillautosave")) return true; + + int seconds = 0; + try + { + seconds = Integer.parseInt(split[1]); + if (seconds < 0) + throw new NumberFormatException(); + } + catch(NumberFormatException ex) + { + sender.sendMessage(clrErr + "The world autosave frequency must be an integer of 0 or higher. Setting to 0 will disable autosaving of the world during the Fill process."); + return true; + } + + Config.setFillAutosaveFrequency(seconds); + + if (player != null) + { + if (seconds == 0) + { + sender.sendMessage("World autosave frequency during Fill process set to 0, disabling it."); + sender.sendMessage("Note that much progress can be lost this way if there is a bug or crash in the world generation process from Bukkit or any world generation plugin you use."); + } + else + { + sender.sendMessage("World autosave frequency during Fill process set to " + seconds + " seconds (rounded to a multiple of 5)."); + sender.sendMessage("New chunks generated by the Fill process will be forcibly saved to disk this often to prevent loss of progress due to bugs or crashes in the world generation process."); + } + } + } + // "dynmap" command from player or console else if (split.length == 2 && split[0].equalsIgnoreCase("dynmap")) { @@ -859,6 +894,7 @@ public class WBCommand implements CommandExecutor if (page == 0 || page == 4) { sender.sendMessage(cmd+" bypasslist " + clrDesc + " - list players with border bypass enabled."); + sender.sendMessage(cmd+" fillautosave " + clrReq + "" + clrDesc + " - world save interval for Fill."); sender.sendMessage(cmd+" portal " + clrReq + "" + clrDesc + " - turn portal redirection on or off."); sender.sendMessage(cmd+" reload" + clrDesc + " - re-load data from config.yml."); sender.sendMessage(cmd+" debug " + clrReq + "" + clrDesc + " - turn console debug output on or off."); diff --git a/src/main/java/com/wimbli/WorldBorder/WorldFillTask.java b/src/main/java/com/wimbli/WorldBorder/WorldFillTask.java index 68c5f32..4176b12 100644 --- a/src/main/java/com/wimbli/WorldBorder/WorldFillTask.java +++ b/src/main/java/com/wimbli/WorldBorder/WorldFillTask.java @@ -49,6 +49,7 @@ public class WorldFillTask implements Runnable // for reporting progress back to user occasionally private transient long lastReport = Config.Now(); + private transient long lastAutosave = Config.Now(); private transient int reportTarget = 0; private transient int reportTotal = 0; private transient int reportNum = 0; @@ -375,7 +376,6 @@ public class WorldFillTask implements Runnable } // let the user know how things are coming along - private int reportCounter = 0; private void reportProgress() { lastReport = Config.Now(); @@ -385,11 +385,10 @@ public class WorldFillTask implements Runnable reportTotal += reportNum; reportNum = 0; - reportCounter++; - // go ahead and save world to disk every 30 seconds or so, just in case; can take a couple of seconds or more, so we don't want to run it too often - if (reportCounter >= 6) + // go ahead and save world to disk every 30 seconds or so by default, just in case; can take a couple of seconds or more, so we don't want to run it too often + if (Config.FillAutosaveFrequency() > 0 && lastAutosave + (Config.FillAutosaveFrequency() * 1000) < lastReport) { - reportCounter = 0; + lastAutosave = lastReport; sendMessage("Saving the world to disk, just to be on the safe side."); world.save(); } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 9727ff9..be50ecc 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -34,6 +34,7 @@ commands: / bypass [player] [on/off] - let player go beyond border. / bypasslist - list players with border bypass enabled. / remount - delay before remounting after knockback. + / fillautosave - world save interval for Fill process. / dynmap - turn DynMap border display on or off. / dynmapmsg - DynMap border labels will show this. / debug - turn debug mode on or off. @@ -64,6 +65,7 @@ permissions: worldborder.wrap: true worldborder.portal: true worldborder.remount: true + worldborder.fillautosave: true worldborder.set: description: Can set borders for any world default: op @@ -121,6 +123,9 @@ permissions: worldborder.remount: description: Can set the delay before remounting a player to their vehicle after knockback default: op + worldborder.fillautosave: + description: Can set the world save interval for the Fill process + default: op worldborder.dynmap: description: Can enable/disable DynMap border display integration default: op