I forget if I've tested all this
This commit is contained in:
parent
590b052e08
commit
845a0e56e5
5 changed files with 127 additions and 193 deletions
src/iieLoadSaveEntireWorld
|
@ -5,18 +5,18 @@ import org.bukkit.configuration.file.FileConfiguration;
|
|||
|
||||
public class ConfigProcess implements Runnable {
|
||||
|
||||
//STATIC
|
||||
static Main plugin;
|
||||
static FileConfiguration config;
|
||||
static Main plugin; //initialized in Main onEnable()
|
||||
static FileConfiguration config;//
|
||||
|
||||
final String name;
|
||||
//================================STATIC================================
|
||||
static final boolean isNew(String name)
|
||||
{
|
||||
return !config.contains(name);
|
||||
}
|
||||
static final void addNew(String name, WorldObject newWorld)
|
||||
static final void addNew(String name, WorldObj newWorld)
|
||||
{
|
||||
config.set(name + ".width", newWorld.width);
|
||||
config.set(name + ".lowerleft.x", newWorld.lowerleft[0]);
|
||||
config.set(name + ".lowerleft.z", newWorld.lowerleft[1]);
|
||||
config.set(name + ".total", newWorld.total);
|
||||
config.set(name + ".currentRegion.x", newWorld.current[0]);
|
||||
config.set(name + ".currentRegion.z", newWorld.current[1]);
|
||||
config.set(name + ".n", 1);
|
||||
|
@ -26,16 +26,11 @@ public class ConfigProcess implements Runnable {
|
|||
config.set(name + ".B", 0);
|
||||
plugin.saveConfig();
|
||||
}
|
||||
static final WorldObject getUnfinished(String name)
|
||||
static final WorldObj getUnfinished(String name)
|
||||
{
|
||||
return new WorldObject
|
||||
return new WorldObj
|
||||
(
|
||||
config.getInt(name + ".width"),
|
||||
new int[]
|
||||
{
|
||||
config.getInt(name + ".lowerleft.x"),
|
||||
config.getInt(name + ".lowerleft.z")
|
||||
},
|
||||
config.getInt(name + ".total"),
|
||||
new int[]
|
||||
{
|
||||
config.getInt(name + ".currentRegion.x"),
|
||||
|
@ -57,36 +52,34 @@ public class ConfigProcess implements Runnable {
|
|||
return config.getString("@ CRASH RESUME");
|
||||
}
|
||||
|
||||
|
||||
//INSTANCE
|
||||
private final String name = TaskManager.loadProcess.worldname;
|
||||
ConfigProcess()
|
||||
//===============================INSTANCE===============================
|
||||
ConfigProcess(String name)
|
||||
{
|
||||
this.name = name;
|
||||
config.set("@ CRASH RESUME", name);
|
||||
}
|
||||
}
|
||||
ConfigProcess(boolean b)
|
||||
{
|
||||
//don't create crash resume
|
||||
name = config.getString("@ CRASH RESUME");
|
||||
}
|
||||
public final void run()
|
||||
{
|
||||
final int[] currentRegion = TaskManager.loadProcess.currentRegion;
|
||||
Bukkit.getLogger().info
|
||||
(
|
||||
"Saving world-load progress: " + name
|
||||
+ "["
|
||||
+ currentRegion[0] + ","
|
||||
+ currentRegion[1]
|
||||
+ "]"
|
||||
);
|
||||
config.set(name + ".currentRegion.x", currentRegion[0]);
|
||||
config.set(name + ".currentRegion.z", currentRegion[1]);
|
||||
{
|
||||
config.set(name + ".currentRegion.x", TaskManager.loadProcess.currentRegion[0]);
|
||||
config.set(name + ".currentRegion.z", TaskManager.loadProcess.currentRegion[1]);
|
||||
config.set(name + ".n", TaskManager.loadProcess.n);
|
||||
config.set(name + ".c", TaskManager.loadProcess.c);
|
||||
config.set(name + ".D", TaskManager.loadProcess.D);
|
||||
config.set(name + ".d", TaskManager.loadProcess.d);
|
||||
config.set(name + ".B", TaskManager.loadProcess.B ? 1 : 0);
|
||||
plugin.saveConfig();
|
||||
Bukkit.getLogger().info
|
||||
(
|
||||
"Saving world-load progress: " + name
|
||||
+ "["
|
||||
+ TaskManager.loadProcess.currentRegion[0] + ","
|
||||
+ TaskManager.loadProcess.currentRegion[1]
|
||||
+ "]"
|
||||
);
|
||||
}
|
||||
final void finish()
|
||||
{
|
||||
|
@ -100,7 +93,7 @@ public class ConfigProcess implements Runnable {
|
|||
run();
|
||||
config.set("@ CRASH RESUME", null);
|
||||
plugin.saveConfig();
|
||||
Bukkit.getLogger().info("...stopping world-load");
|
||||
|
||||
Bukkit.getLogger()
|
||||
.info("...stopping world-load");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,38 +7,25 @@ public class LoadProcess implements Runnable
|
|||
{
|
||||
//=================================INIT=================================
|
||||
|
||||
final World world;
|
||||
final String worldname;
|
||||
final int totalRegions;
|
||||
int[] currentRegion;
|
||||
|
||||
|
||||
LoadProcess(String name, WorldObject newWorld)
|
||||
private final World world;
|
||||
final int totalRegions;
|
||||
int[] currentRegion;
|
||||
LoadProcess(String name, WorldObj newWorld)
|
||||
{
|
||||
ConfigProcess.addNew(name, newWorld);
|
||||
|
||||
world = Bukkit.getWorld(name);
|
||||
worldname = name;
|
||||
|
||||
totalRegions = newWorld.width * newWorld.width;
|
||||
totalRegions = newWorld.total;
|
||||
currentRegion = newWorld.current;
|
||||
|
||||
lowerleft = newWorld.lowerleft;
|
||||
allChunkCoords = generateAllChunkCoords(newWorld.width);
|
||||
}
|
||||
LoadProcess(String name)
|
||||
{
|
||||
final WorldObject unfinished = ConfigProcess.getUnfinished(name);
|
||||
final WorldObj unfinished = ConfigProcess.getUnfinished(name);
|
||||
|
||||
world = Bukkit.getWorld(name);
|
||||
worldname = name;
|
||||
|
||||
totalRegions = unfinished.width * unfinished.width;
|
||||
totalRegions = unfinished.total;
|
||||
currentRegion = unfinished.current;
|
||||
|
||||
lowerleft = unfinished.lowerleft;
|
||||
allChunkCoords = generateAllChunkCoords(unfinished.width);
|
||||
|
||||
n = unfinished.n;
|
||||
c = unfinished.c;
|
||||
D = unfinished.D;
|
||||
|
@ -75,15 +62,16 @@ public class LoadProcess implements Runnable
|
|||
|
||||
private final boolean setNextRegion()
|
||||
{
|
||||
n++;
|
||||
|
||||
if (n == totalRegions) return false;
|
||||
if (d != D) d++;
|
||||
else
|
||||
if (d == D)
|
||||
{
|
||||
d = 0; if (B) D++;
|
||||
d = 1;
|
||||
if (B) D++;
|
||||
B = !B;
|
||||
c = c == 4 ? 1 : c + 1;
|
||||
}
|
||||
else d++;
|
||||
switch (c)
|
||||
{
|
||||
case 1 : currentRegion[0]++; break;
|
||||
|
@ -91,60 +79,27 @@ public class LoadProcess implements Runnable
|
|||
case 3 : currentRegion[0]--; break;
|
||||
case 4 : currentRegion[1]--; break;
|
||||
}
|
||||
n++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//===============================CHUNK MAP==============================
|
||||
|
||||
private final int[] lowerleft;
|
||||
private final int[][][][][] allChunkCoords;
|
||||
private final int[][][][][] generateAllChunkCoords(int w)
|
||||
//==============================GET CHUNKS==============================
|
||||
private final int[][][] getChunksCurrentRegion()
|
||||
{
|
||||
int[][][][][] allChunkCoords = new int[w][w][32][32][2];
|
||||
|
||||
int regionX = lowerleft[0];
|
||||
int regionZ = lowerleft[1];
|
||||
boolean negX = true;
|
||||
boolean negZ = true;
|
||||
int chunkX = 0;
|
||||
int chunkZ = 0;
|
||||
for (int[][][][] xRowRegions : allChunkCoords)
|
||||
final int[][][] chunks = new int[32][32][2];
|
||||
int z;
|
||||
for (int x = 0; x < 32; x++)
|
||||
{
|
||||
regionZ = lowerleft[1];
|
||||
negZ = true;
|
||||
for (int[][][] region : xRowRegions)
|
||||
z = 0;
|
||||
for (; z < 32; z++)
|
||||
{
|
||||
chunkX = 0;
|
||||
for (int[][] xRowChunks : region)
|
||||
{
|
||||
chunkZ = 0;
|
||||
for (int[] chunk : xRowChunks)
|
||||
{
|
||||
chunk[0] = (regionX * 32) + (negX ? 0 - chunkX : chunkX);
|
||||
chunk[1] = (regionZ * 32) + (negZ ? 0 - chunkZ : chunkZ);
|
||||
chunkZ++;
|
||||
}
|
||||
chunkX++;
|
||||
}
|
||||
regionZ++;
|
||||
if (negZ)
|
||||
negZ = regionZ < 0;
|
||||
chunks[x][z][0] = (currentRegion[0] * 32) + x;
|
||||
chunks[x][z][1] = (currentRegion[1] * 32) + z;
|
||||
}
|
||||
regionX++;
|
||||
if (negX)
|
||||
negX = regionX < 0;
|
||||
}
|
||||
return allChunkCoords;
|
||||
return chunks;
|
||||
}
|
||||
private final int[][][] getChunksCurrentRegion(){
|
||||
return
|
||||
allChunkCoords
|
||||
[ currentRegion[0] - lowerleft[0] ]
|
||||
[ currentRegion[1] - lowerleft[1] ];
|
||||
}
|
||||
|
||||
|
||||
//==================================RUN=================================
|
||||
private static volatile boolean ready = true;
|
||||
public final void run()
|
||||
|
@ -158,7 +113,7 @@ public class LoadProcess implements Runnable
|
|||
for (int[] chunk : xRow)
|
||||
{
|
||||
world.loadChunk(chunk[0], chunk[1], true);
|
||||
world.unloadChunk(chunk[0], chunk[1]);
|
||||
world.unloadChunkRequest(chunk[0], chunk[1]);
|
||||
}
|
||||
}
|
||||
if (!setNextRegion())
|
||||
|
|
|
@ -4,21 +4,17 @@ import org.bukkit.Bukkit;
|
|||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class Main extends JavaPlugin {
|
||||
|
||||
|
||||
public void onEnable()
|
||||
{
|
||||
saveDefaultConfig();
|
||||
|
||||
getCommand("beginfullmapload").setExecutor(new TaskManager.StartCommand());
|
||||
getCommand("stopfullmapload").setExecutor(new TaskManager.StopCommand());
|
||||
|
||||
TaskManager.plugin = this;
|
||||
ConfigProcess.plugin = this;
|
||||
ConfigProcess.config = getConfig();
|
||||
|
||||
if (TaskManager.crashResume())
|
||||
{
|
||||
if (TaskManager.crashResume())
|
||||
Bukkit.getLogger().info("...resuming from crash");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,35 +8,36 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
public class TaskManager {
|
||||
|
||||
static Main plugin;
|
||||
|
||||
|
||||
static boolean inProgress = false;
|
||||
static boolean canRun = true;
|
||||
|
||||
static LoadProcess loadProcess;
|
||||
static ConfigProcess configProcess;
|
||||
static BukkitTask loadTask;
|
||||
static BukkitTask configTask;
|
||||
static LoadProcess loadProcess;
|
||||
static ConfigProcess configProcess;
|
||||
private static BukkitTask loadTask;
|
||||
private static BukkitTask configTask;
|
||||
|
||||
//===================================CONTROLS===================================
|
||||
private static final boolean start(String name, String[] args)
|
||||
|
||||
//===================================CONTROLS==================================
|
||||
|
||||
private static final void schedule(long delay)
|
||||
{
|
||||
loadTask = Bukkit.getScheduler().runTaskTimer(ConfigProcess.plugin, loadProcess, delay, 100);
|
||||
configTask = Bukkit.getScheduler().runTaskTimer(ConfigProcess.plugin, loadProcess, delay, 100);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
private static final boolean start(String[] args, String name)
|
||||
{
|
||||
final boolean isNew;
|
||||
if (ConfigProcess.isNew(name))
|
||||
{
|
||||
loadProcess = new LoadProcess(name, WorldObject.generate(args));
|
||||
isNew = true;
|
||||
loadProcess = new LoadProcess(name, WorldObj.generate(args));
|
||||
configProcess = new ConfigProcess(name);
|
||||
schedule(0);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
loadProcess = new LoadProcess(name);
|
||||
isNew = false;
|
||||
}
|
||||
configProcess = new ConfigProcess();
|
||||
loadTask = Bukkit.getScheduler().runTaskTimer( plugin, loadProcess, 0, 100 );
|
||||
configTask = Bukkit.getScheduler().runTaskTimer( plugin, configProcess, 0, 200 );
|
||||
return isNew;
|
||||
loadProcess = new LoadProcess(name);
|
||||
configProcess = new ConfigProcess(name);
|
||||
schedule(0);
|
||||
return false;
|
||||
}
|
||||
static final boolean crashResume()
|
||||
{
|
||||
|
@ -44,18 +45,15 @@ public class TaskManager {
|
|||
{
|
||||
loadProcess = new LoadProcess(ConfigProcess.getCrashResume());
|
||||
configProcess = new ConfigProcess(false);
|
||||
|
||||
loadTask = Bukkit.getScheduler().runTaskTimer( plugin, loadProcess, 1200, 100 );
|
||||
configTask = Bukkit.getScheduler().runTaskTimer( plugin, configProcess, 1200, 200 );
|
||||
schedule(1200);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static final void finish()
|
||||
static final void stop_or_finish()
|
||||
{
|
||||
loadTask.cancel();
|
||||
configTask.cancel();
|
||||
configProcess.finish();
|
||||
|
||||
loadProcess = null;
|
||||
configProcess = null;
|
||||
|
@ -64,6 +62,11 @@ public class TaskManager {
|
|||
|
||||
inProgress = false;
|
||||
}
|
||||
static final void finish()
|
||||
{
|
||||
configProcess.finish();
|
||||
|
||||
}
|
||||
static final boolean stop()
|
||||
{
|
||||
if (inProgress)
|
||||
|
@ -87,34 +90,10 @@ public class TaskManager {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
//===================================COMMANDS===================================
|
||||
|
||||
static final class StartCommand implements CommandExecutor
|
||||
{
|
||||
@Override
|
||||
public final boolean onCommand(CommandSender sender, Command label, String command, String[] args)
|
||||
{
|
||||
if (inProgress)
|
||||
{
|
||||
sender.sendMessage("a process is already running (" + loadProcess.worldname + "). /StopLoadSave to stop.");
|
||||
return false;
|
||||
}
|
||||
else inProgress = true;
|
||||
if (start(((Player)sender).getWorld().getName(),args))
|
||||
{
|
||||
sender.sendMessage("starting...");
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.sendMessage("resuming...");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static final class StopCommand implements CommandExecutor
|
||||
{
|
||||
@Override
|
||||
public final boolean onCommand(CommandSender sender, Command label, String command, String[] args)
|
||||
{
|
||||
if (stop())
|
||||
|
@ -126,4 +105,23 @@ public class TaskManager {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
static final class StartCommand implements CommandExecutor
|
||||
{
|
||||
public final boolean onCommand(CommandSender sender, Command label, String command, String[] args)
|
||||
{
|
||||
if (inProgress)
|
||||
{
|
||||
sender.sendMessage("a process is already running (" + configProcess.name + "). /StopLoadSave to stop.");
|
||||
return false;
|
||||
}
|
||||
inProgress = true;
|
||||
sender.sendMessage
|
||||
(
|
||||
start(args,((Player)sender).getWorld().getName()) ?
|
||||
"starting..." :
|
||||
"resuming..."
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package iieLoadSaveEntireWorld;
|
||||
|
||||
public class WorldObject {
|
||||
public class WorldObj {
|
||||
|
||||
final int width;
|
||||
final int[] lowerleft;
|
||||
final int total;
|
||||
int[] current;
|
||||
int n;
|
||||
int c;
|
||||
|
@ -11,25 +10,20 @@ public class WorldObject {
|
|||
int d;
|
||||
boolean B;
|
||||
|
||||
WorldObject()
|
||||
WorldObj()
|
||||
{
|
||||
width = 44;
|
||||
lowerleft = new int[] { -22, -22 };
|
||||
total = 1936; //44 * 44
|
||||
current = new int[] { -1, -1 };
|
||||
}
|
||||
WorldObject(int width, int[] lowerleft, int[] center)
|
||||
WorldObj(int total, int[] center)
|
||||
{
|
||||
this.width = width;
|
||||
this.lowerleft = lowerleft;
|
||||
this.total = total;
|
||||
this.current = center;
|
||||
}
|
||||
WorldObject(
|
||||
int width, int[] lowerleft, int[] current,
|
||||
int n, int c, int D, int d, boolean B
|
||||
)
|
||||
WorldObj(int total, int[] current,
|
||||
int n, int c, int D, int d, boolean B)
|
||||
{
|
||||
this.width = width;
|
||||
this.lowerleft = lowerleft;
|
||||
this.total = total;
|
||||
this.current = current;
|
||||
this.n = n;
|
||||
this.c = c;
|
||||
|
@ -38,22 +32,22 @@ public class WorldObject {
|
|||
this.B = B;
|
||||
}
|
||||
|
||||
static final WorldObject generate(String[] args)
|
||||
static final WorldObj generate(String[] args)
|
||||
{
|
||||
if (args.length == 0)
|
||||
{
|
||||
return new WorldObject();
|
||||
}
|
||||
if (args.length == 0) return new WorldObj();
|
||||
|
||||
int[] bounds = regionBounds(new ParsedArgs(args));
|
||||
return new WorldObject
|
||||
|
||||
return new WorldObj
|
||||
(
|
||||
bounds[2] - bounds[0],//----------------------------width
|
||||
new int[] { bounds[0], bounds[2] },//---------------lowerleft
|
||||
new int[] { //--------------------------------------center
|
||||
bounds[0] - 1 + (bounds[1]-bounds[0] + 1)/2,
|
||||
bounds[2] - 1 + (bounds[3]-bounds[2] + 1)/2
|
||||
}
|
||||
(bounds[2] - bounds[0]) * (bounds[2] - bounds[0]),//width ^ 2
|
||||
new int[]
|
||||
{
|
||||
bounds[0] - 1 + (bounds[1]-bounds[0] + 1)/2,
|
||||
bounds[2] - 1 + (bounds[3]-bounds[2] + 1)/2
|
||||
}
|
||||
);
|
||||
|
||||
/* for even widths, the math above returns the
|
||||
* minimum center not the maximum center. So:
|
||||
*
|
||||
|
@ -118,14 +112,12 @@ public class WorldObject {
|
|||
{
|
||||
int[] bounds = new int[]
|
||||
{
|
||||
// [ get region ] [ get block ]
|
||||
Math.floorDiv( a.center[0] - a.radius, 512 ),
|
||||
Math.floorDiv( a.center[0] + a.radius, 512 ),
|
||||
Math.floorDiv( a.center[1] - a.radius, 512 ),
|
||||
Math.floorDiv( a.center[1] + a.radius, 512 )
|
||||
};
|
||||
|
||||
//add margins------------
|
||||
//add margins---------------------------------------------------------------
|
||||
|
||||
final int[] edges = new int[4];
|
||||
final int[] radii = new int[4];
|
||||
|
@ -143,7 +135,7 @@ public class WorldObject {
|
|||
radii[2] = Math.abs(a.center[1] - edges[2]);
|
||||
radii[3] = Math.abs(a.center[1] - edges[3]);
|
||||
|
||||
//compare to original block radius, if difference is < 4 chunks add a region width
|
||||
//compare to original block radius: if difference < 64 blocks add a region width
|
||||
if (radii[0] - a.radius < 64) { bounds[0] -= 1; margin[0] = true; }
|
||||
if (radii[1] - a.radius < 64) { bounds[1] += 1; margin[1] = true; }
|
||||
if (radii[2] - a.radius < 64) { bounds[2] -= 1; margin[2] = true; }
|
Loading…
Add table
Reference in a new issue