still not quite finished, and still not tested
This commit is contained in:
parent
4dd1048994
commit
7f67c7f6f9
8 changed files with 429 additions and 312 deletions
67
src/iieLoadSaveEntireWorld/Cache.java
Normal file
67
src/iieLoadSaveEntireWorld/Cache.java
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
package iieLoadSaveEntireWorld;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class Cache {
|
||||||
|
|
||||||
|
static int maxNameLength;
|
||||||
|
static char[][] worldsFinished;
|
||||||
|
static char[][] worldsUnfinished;
|
||||||
|
static void set()
|
||||||
|
{
|
||||||
|
Set<String> fin = Main.config.getConfigurationSection("finished worlds").getKeys(false);
|
||||||
|
Set<String> unfin = Main.config.getConfigurationSection("unfinished worlds").getKeys(false);
|
||||||
|
|
||||||
|
maxNameLength = Main.config.getInt("max name length");
|
||||||
|
worldsFinished = populate(fin);
|
||||||
|
worldsUnfinished = populate(unfin);
|
||||||
|
}
|
||||||
|
static char[][] populate(Set<String> set)
|
||||||
|
{
|
||||||
|
char[][] worlds = new char[set.size()][maxNameLength];
|
||||||
|
int i = 0;
|
||||||
|
int ii = 0;
|
||||||
|
for (String name : set)
|
||||||
|
{
|
||||||
|
for (char c : name.toCharArray())
|
||||||
|
{
|
||||||
|
worlds[i][ii] = c;
|
||||||
|
ii++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
ii = 0;
|
||||||
|
}
|
||||||
|
return worlds;
|
||||||
|
}
|
||||||
|
static boolean isFinished(String name){
|
||||||
|
int i = 0;
|
||||||
|
boolean match = true;
|
||||||
|
for (char[] world : worldsFinished)
|
||||||
|
{
|
||||||
|
for (char c : name.toCharArray())
|
||||||
|
{
|
||||||
|
if (c != world[i]){ match = false; break; }
|
||||||
|
}
|
||||||
|
if (match) break;
|
||||||
|
i = 0;
|
||||||
|
match = true;
|
||||||
|
}
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
static boolean isUnfinished(String name){
|
||||||
|
int i = 0;
|
||||||
|
boolean match = true;
|
||||||
|
for (char[] world : worldsUnfinished)
|
||||||
|
{
|
||||||
|
for (char c : name.toCharArray())
|
||||||
|
{
|
||||||
|
if (c != world[i]){ match = false; break; }
|
||||||
|
}
|
||||||
|
if (match) break;
|
||||||
|
i = 0;
|
||||||
|
match = true;
|
||||||
|
}
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
5
src/iieLoadSaveEntireWorld/ConfirmCommand.java
Normal file
5
src/iieLoadSaveEntireWorld/ConfirmCommand.java
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
package iieLoadSaveEntireWorld;
|
||||||
|
|
||||||
|
public class ConfirmCommand {
|
||||||
|
|
||||||
|
}
|
184
src/iieLoadSaveEntireWorld/Dimensions.java
Normal file
184
src/iieLoadSaveEntireWorld/Dimensions.java
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
package iieLoadSaveEntireWorld;
|
||||||
|
|
||||||
|
public class Dimensions {
|
||||||
|
|
||||||
|
private static final int[][] defaultDimensions = new int[][] { {22528,0,0} , {44,-1,-1,-22,-22} };
|
||||||
|
int width;
|
||||||
|
int[] center;
|
||||||
|
int[] lowerleft;
|
||||||
|
|
||||||
|
Dimensions(String[] args){
|
||||||
|
int length = args.length;
|
||||||
|
if (length == 0)
|
||||||
|
{
|
||||||
|
width = defaultDimensions[1][0];
|
||||||
|
center = new int[] { defaultDimensions[1][1], defaultDimensions[1][2] };
|
||||||
|
lowerleft = new int[] { defaultDimensions[1][3], defaultDimensions[1][4] };
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int blockRadius = blockRadius(args[0]);
|
||||||
|
int[] blockCenter = length > 2 ?
|
||||||
|
blockCenter(args[1], args[2]) :
|
||||||
|
new int[]
|
||||||
|
{
|
||||||
|
defaultDimensions[0][1],
|
||||||
|
defaultDimensions[0][2]
|
||||||
|
};
|
||||||
|
int[] blockBounds = blockBounds(blockCenter,blockRadius);
|
||||||
|
int[] regionBounds =
|
||||||
|
addMargins(
|
||||||
|
regionBounds(blockBounds),
|
||||||
|
blockCenter,
|
||||||
|
blockRadius
|
||||||
|
);
|
||||||
|
width = regionBounds[2] - regionBounds[0];
|
||||||
|
center = regionCenter(regionBounds);
|
||||||
|
lowerleft[0] = regionBounds[0];
|
||||||
|
lowerleft[1] = regionBounds[2];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isInt(String arg)
|
||||||
|
{
|
||||||
|
int length = arg.length();
|
||||||
|
int i = 0;
|
||||||
|
if (arg.charAt(0) == '-')
|
||||||
|
if (length == 1) return false;
|
||||||
|
else i = 1;
|
||||||
|
for (; i < length; i++) {
|
||||||
|
char c = arg.charAt(i);
|
||||||
|
if (c < '0' || c > '9')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
private static int blockRadius(String arg0)
|
||||||
|
{
|
||||||
|
int blockWidth;
|
||||||
|
if (isInt(arg0))
|
||||||
|
{
|
||||||
|
blockWidth = Integer.parseInt(arg0);
|
||||||
|
if (blockWidth == 0) blockWidth = defaultDimensions[0][0];
|
||||||
|
}
|
||||||
|
else blockWidth = defaultDimensions[0][0];
|
||||||
|
return blockWidth/2;
|
||||||
|
}
|
||||||
|
private static int[] blockCenter(String arg1, String arg2)
|
||||||
|
{
|
||||||
|
int xBlock = isInt(arg1) ? Integer.parseInt(arg1) : 0;
|
||||||
|
int zBlock = isInt(arg2) ? Integer.parseInt(arg2) : 0;
|
||||||
|
return new int[] {xBlock,zBlock};
|
||||||
|
}
|
||||||
|
private static int[] blockBounds(int[] center, int blockRadius)
|
||||||
|
{
|
||||||
|
int xMinBlock = center[0] - blockRadius;
|
||||||
|
int xMaxBlock = center[0] + blockRadius;
|
||||||
|
int zMinBlock = center[1] - blockRadius;
|
||||||
|
int zMaxBlock = center[1] + blockRadius;
|
||||||
|
return new int[] {xMinBlock,xMaxBlock,zMinBlock,zMaxBlock};
|
||||||
|
}
|
||||||
|
private static int[] regionBounds(int[] blockBounds)
|
||||||
|
{
|
||||||
|
int xMinRegion = Math.floorDiv(blockBounds[0],512);
|
||||||
|
int xMaxRegion = Math.floorDiv(blockBounds[1],512);
|
||||||
|
int zMinRegion = Math.floorDiv(blockBounds[2],512);
|
||||||
|
int zMaxRegion = Math.floorDiv(blockBounds[3],512);
|
||||||
|
return new int[] {xMinRegion,xMaxRegion,zMinRegion,zMaxRegion};
|
||||||
|
}
|
||||||
|
private static int[] regionCenter(int[] regionBounds){
|
||||||
|
int regionCenterX = regionBounds[0] - 1 + (regionBounds[1]-regionBounds[0] + 1)/2;
|
||||||
|
int regionCenterZ = regionBounds[2] - 1 + (regionBounds[3]-regionBounds[2] + 1)/2;
|
||||||
|
return new int[] {regionCenterX, regionCenterZ};
|
||||||
|
}
|
||||||
|
private static int[] addMargins(int[] regionBounds, int[] blockCenter, int blockRadius)
|
||||||
|
{
|
||||||
|
int[] radii = new int[4]; //region block edge radii
|
||||||
|
boolean[] marAdd = new boolean[4]; //margins added
|
||||||
|
|
||||||
|
//get block edge farthest from center
|
||||||
|
int xMinRegionBlockEdge = regionBounds[0] *512;
|
||||||
|
int xMaxRegionBlockEdge = (regionBounds[1]+1) *512 - 1;
|
||||||
|
int zMinRegionBlockEdge = regionBounds[2] *512;
|
||||||
|
int zMaxRegionBlockEdge = (regionBounds[3]+1) *512 - 1;
|
||||||
|
|
||||||
|
//get edge's block distance from center
|
||||||
|
radii[0] = Math.abs(blockCenter[0] - xMinRegionBlockEdge);
|
||||||
|
radii[1] = Math.abs(blockCenter[0] - xMaxRegionBlockEdge);
|
||||||
|
radii[2] = Math.abs(blockCenter[1] - zMinRegionBlockEdge);
|
||||||
|
radii[3] = Math.abs(blockCenter[1] - zMaxRegionBlockEdge);
|
||||||
|
|
||||||
|
//compare to original block radius, if difference is < 4 chunks add a region width
|
||||||
|
if (radii[0] - blockRadius < 64) { regionBounds[0] -= 1; marAdd[0] = true; }
|
||||||
|
if (radii[1] - blockRadius < 64) { regionBounds[1] += 1; marAdd[1] = true; }
|
||||||
|
if (radii[2] - blockRadius < 64) { regionBounds[2] -= 1; marAdd[2] = true; }
|
||||||
|
if (radii[3] - blockRadius < 64) { regionBounds[3] += 1; marAdd[3] = true; }
|
||||||
|
|
||||||
|
//resquare the selection
|
||||||
|
if (!marAdd[0])
|
||||||
|
if (!marAdd[1])
|
||||||
|
if (!marAdd[2])
|
||||||
|
if (!marAdd[3])//-----------0000
|
||||||
|
return regionBounds;
|
||||||
|
else//----------------------0001
|
||||||
|
if (radii[0] < radii[1])
|
||||||
|
regionBounds[0]++;
|
||||||
|
else
|
||||||
|
regionBounds[1]++;
|
||||||
|
else
|
||||||
|
if (!marAdd[3])//-----------0010
|
||||||
|
if (radii[0] < radii[1])
|
||||||
|
regionBounds[0]++;
|
||||||
|
else
|
||||||
|
regionBounds[1]++;
|
||||||
|
else//----------------------0011
|
||||||
|
{
|
||||||
|
regionBounds[0]++;
|
||||||
|
regionBounds[1]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!marAdd[2])
|
||||||
|
if (!marAdd[3])//-----------0100
|
||||||
|
if (radii[2] < radii[3])
|
||||||
|
regionBounds[2]++;
|
||||||
|
else
|
||||||
|
regionBounds[3]++;
|
||||||
|
else//----------------------0101
|
||||||
|
return regionBounds;
|
||||||
|
else
|
||||||
|
if (!marAdd[3])//-----------0110
|
||||||
|
return regionBounds;
|
||||||
|
else//----------------------0111
|
||||||
|
regionBounds[0]++;
|
||||||
|
else
|
||||||
|
if (marAdd[1])
|
||||||
|
if (marAdd[2])
|
||||||
|
if (marAdd[3])//------------1111
|
||||||
|
return regionBounds;
|
||||||
|
else//----------------------1110
|
||||||
|
regionBounds[3]++;
|
||||||
|
else
|
||||||
|
if (marAdd[3])//------------1101
|
||||||
|
regionBounds[2]++;
|
||||||
|
else//----------------------1100
|
||||||
|
{
|
||||||
|
regionBounds[2]++;
|
||||||
|
regionBounds[3]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (marAdd[2])
|
||||||
|
if (marAdd[3])//------------1011
|
||||||
|
regionBounds[1]++;
|
||||||
|
else//----------------------1010
|
||||||
|
return regionBounds;
|
||||||
|
else
|
||||||
|
if (marAdd[3])//------------1001
|
||||||
|
return regionBounds;
|
||||||
|
else//----------------------1000
|
||||||
|
if (radii[2] == radii[3])
|
||||||
|
regionBounds[0]++;
|
||||||
|
else
|
||||||
|
regionBounds[1]++;
|
||||||
|
|
||||||
|
return regionBounds;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package iieLoadSaveEntireWorld;
|
package iieLoadSaveEntireWorld;
|
||||||
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
public class LoadSaveProcess implements Runnable {
|
public class LoadSaveProcess implements Runnable {
|
||||||
|
|
||||||
|
@ -8,19 +9,31 @@ public class LoadSaveProcess implements Runnable {
|
||||||
//=============================STATIC FIELDS============================
|
//=============================STATIC FIELDS============================
|
||||||
|
|
||||||
static boolean inProgress = false;
|
static boolean inProgress = false;
|
||||||
|
static boolean taskRunning = false;
|
||||||
|
|
||||||
private static int[] startRegion;
|
private static World world;
|
||||||
|
private static String worldName;
|
||||||
|
|
||||||
private static int[] currentRegion;
|
private static int[] currentRegion;
|
||||||
|
private static int totalRegions;
|
||||||
|
|
||||||
private static TranslatedCoordinates map;
|
private static int untilNextProgSave;
|
||||||
|
|
||||||
private static int[][][][][] allChunkCoords;
|
|
||||||
|
|
||||||
public LoadSaveProcess(int width, int[] center, int[] lowCorner){
|
LoadSaveProcess(int width, int[] center, int[] lowerleft, String worldName)
|
||||||
currentRegion = startRegion = new int[] {center[0],center[1]};
|
{
|
||||||
map = new TranslatedCoordinates(width,lowCorner[0],lowCorner[1]);
|
world = Bukkit.getWorld(worldName);
|
||||||
generateAllChunkCoords(width,lowCorner[0],lowCorner[1]);
|
LoadSaveProcess.worldName = worldName;
|
||||||
|
currentRegion = center;
|
||||||
|
totalRegions = width*width;
|
||||||
|
untilNextProgSave = 10;
|
||||||
|
Map.init(width, lowerleft);
|
||||||
|
|
||||||
|
int length = worldName.length();
|
||||||
|
if (length > Cache.maxNameLength)
|
||||||
|
Main.config.set("max namelength",length);
|
||||||
|
Main.config.set("unfinished worlds." + worldName + ".width", width);
|
||||||
|
Cache.set();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,11 +59,11 @@ public class LoadSaveProcess implements Runnable {
|
||||||
* etc.
|
* etc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private static int n = 1; //number
|
static int n = 1; //number
|
||||||
private static int c = 1; //direction of travel: E,N,W,S - 1,2,3,4
|
static int c = 1; //direction of travel: E,N,W,S - 1,2,3,4
|
||||||
private static int D = 1; //distance to travel
|
static int D = 1; //distance to travel
|
||||||
private static int d = 0; //distance already traveled
|
static int d = 0; //distance already traveled
|
||||||
private static boolean B = false; //OK to change direction?
|
static boolean B = false; //OK to change direction?
|
||||||
static void reset()
|
static void reset()
|
||||||
{
|
{
|
||||||
c = 1;
|
c = 1;
|
||||||
|
@ -58,15 +71,6 @@ public class LoadSaveProcess implements Runnable {
|
||||||
d = 0;
|
d = 0;
|
||||||
B = false;
|
B = false;
|
||||||
}
|
}
|
||||||
static class Loc{//used when pausing the process
|
|
||||||
int c; int D; int d; boolean B;
|
|
||||||
Loc(){
|
|
||||||
this.c = SavePattern.c;
|
|
||||||
this.D = SavePattern.D;
|
|
||||||
this.d = SavePattern.d;
|
|
||||||
this.B = SavePattern.B;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void setNextRegion()
|
static void setNextRegion()
|
||||||
{
|
{
|
||||||
n++;
|
n++;
|
||||||
|
@ -86,73 +90,104 @@ public class LoadSaveProcess implements Runnable {
|
||||||
B = !B;
|
B = !B;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static boolean complete(){
|
||||||
|
return n == totalRegions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===============================CHUNK MAP==============================
|
||||||
|
|
||||||
//=================================UTIL=================================
|
private static class Map
|
||||||
|
{
|
||||||
//TRACKER, COORDINATE TRANSLATOR
|
private static int[] lowerleft;
|
||||||
private static class TranslatedCoordinates {
|
private static int[][][][][] allChunkCoords;
|
||||||
|
static void init(int w,int[] lowerleft)
|
||||||
int xAdjust;
|
|
||||||
int zAdjust;
|
|
||||||
//boolean[][] savemap;
|
|
||||||
public TranslatedCoordinates(int w, int lowX, int lowZ)
|
|
||||||
{
|
{
|
||||||
xAdjust = 0 - lowX;
|
Map.lowerleft = lowerleft;
|
||||||
zAdjust = 0 - lowZ;
|
allChunkCoords = new int[w][w][32][32][2];
|
||||||
//savemap = new boolean[w][w];
|
|
||||||
}
|
|
||||||
int x(int x){ return x + xAdjust; }
|
|
||||||
int z(int z){ return z + zAdjust; }
|
|
||||||
/*
|
|
||||||
void save(int x, int z) { savemap[x(x)][z(z)] = true; }
|
|
||||||
boolean isSaved(int x, int z) { return savemap[x(x)][z(z)]; }
|
|
||||||
|
|
||||||
boolean allSaved(){
|
int regionX = lowerleft[0];
|
||||||
for (boolean[] xRow : savemap){
|
int regionZ = lowerleft[1];
|
||||||
for (boolean region : xRow){
|
boolean negX = true;
|
||||||
if (!region) return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
//GENERATE ALL CHUNK COORDINATES
|
|
||||||
private static void generateAllChunkCoords(int width, int lowX, int lowZ) {
|
|
||||||
allChunkCoords = new int[width][width][32][32][2];
|
|
||||||
int regionX = lowX;
|
|
||||||
boolean negX = true;
|
|
||||||
for (int[][][][] xRowRegions : allChunkCoords){
|
|
||||||
int regionZ = lowZ;
|
|
||||||
boolean negZ = true;
|
boolean negZ = true;
|
||||||
for (int[][][] region : xRowRegions){
|
int chunkX = 0;
|
||||||
int chunkX = 0;
|
int chunkZ = 0;
|
||||||
for (int[][] xRowChunks : region){
|
for (int[][][][] xRowRegions : allChunkCoords)
|
||||||
int chunkZ = 0;
|
{
|
||||||
for (int[] chunk : xRowChunks){
|
regionZ = lowerleft[1];
|
||||||
chunk[0] = (regionX * 32) + (negX ? 0 - chunkX : chunkX);
|
negZ = true;
|
||||||
chunk[1] = (regionZ * 32) + (negZ ? 0 - chunkZ : chunkZ);
|
for (int[][][] region : xRowRegions)
|
||||||
chunkZ++;
|
{
|
||||||
|
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++;
|
||||||
}
|
}
|
||||||
chunkX++;
|
regionZ++;
|
||||||
|
if (negZ)
|
||||||
|
negZ = regionZ < 0;
|
||||||
}
|
}
|
||||||
regionZ++;
|
regionX++;
|
||||||
if (negZ)
|
if (negX)
|
||||||
negZ = regionZ < 0;
|
negX = regionX < 0;
|
||||||
}
|
}
|
||||||
regionX++;
|
}
|
||||||
if (negX)
|
static int[][][] getChunksCurrentRegion(){
|
||||||
negX = regionX < 0;
|
return
|
||||||
|
allChunkCoords
|
||||||
|
[ currentRegion[0] - lowerleft[0] ]
|
||||||
|
[ currentRegion[1] - lowerleft[1] ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//==================================RUN=================================
|
//==================================RUN=================================
|
||||||
public void run() {
|
public void run()
|
||||||
|
{
|
||||||
|
if (taskRunning) return;
|
||||||
|
else taskRunning = true;
|
||||||
|
int[][][] r = Map.getChunksCurrentRegion();
|
||||||
|
for (int[][] xRow : r)
|
||||||
|
for (int[] chunk : xRow){
|
||||||
|
world.loadChunk(chunk[0], chunk[1], true);
|
||||||
|
world.unloadChunk(chunk[0], chunk[1]);
|
||||||
|
}
|
||||||
|
SavePattern.setNextRegion();
|
||||||
|
}
|
||||||
|
//===============================CONTROLS===============================
|
||||||
|
public static void saveProgress()
|
||||||
|
{
|
||||||
|
String path = "unfinishedWorlds." + worldName + ".";
|
||||||
|
Main.config.set(path + "current region.x", currentRegion[0]);
|
||||||
|
Main.config.set(path + "current region.z", currentRegion[1]);
|
||||||
|
Main.config.set(path + "n", SavePattern.n);
|
||||||
|
Main.config.set(path + "D", SavePattern.D);
|
||||||
|
Main.config.set(path + "d", SavePattern.d);
|
||||||
|
Main.config.set(path + "B", SavePattern.B);
|
||||||
|
Main.plugin.saveConfig();
|
||||||
|
}
|
||||||
|
public void stop()
|
||||||
|
{
|
||||||
|
saveProgress();
|
||||||
|
SavePattern.reset();
|
||||||
|
try {
|
||||||
|
wait(30000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resume(String worldName)
|
||||||
|
{
|
||||||
|
String path = "unfinishedWorlds." + worldName + ".";
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,26 @@
|
||||||
package iieLoadSaveEntireWorld;
|
package iieLoadSaveEntireWorld;
|
||||||
|
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
|
||||||
public class Main extends JavaPlugin {
|
public class Main extends JavaPlugin {
|
||||||
|
|
||||||
static Main plugin;
|
static Main plugin;
|
||||||
|
static FileConfiguration config;
|
||||||
|
static StartCommand start;
|
||||||
|
static LoadSaveProcess process;
|
||||||
static BukkitTask task;
|
static BukkitTask task;
|
||||||
|
|
||||||
public void onEnable() {
|
public void onEnable()
|
||||||
|
{
|
||||||
plugin = this;
|
plugin = this;
|
||||||
|
config = plugin.getConfig();
|
||||||
|
start = new StartCommand(plugin);
|
||||||
|
|
||||||
saveDefaultConfig();
|
saveDefaultConfig();
|
||||||
getCommand("loadsaveentireworld").setExecutor(new StartCommand(plugin));
|
getCommand("beginloadsave").setExecutor(start);
|
||||||
|
getCommand("stoploadsave").setExecutor(new StopCommand(plugin));
|
||||||
|
Cache.set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,227 +4,35 @@ import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public class StartCommand implements CommandExecutor {
|
public class StartCommand implements CommandExecutor {
|
||||||
private Main plugin;
|
|
||||||
|
private static Main plugin;
|
||||||
StartCommand(Main Plugin){
|
StartCommand(Main Plugin){
|
||||||
plugin = Plugin;
|
plugin = Plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command label, String command, String[] args) {
|
public synchronized boolean onCommand(CommandSender sender, Command label, String command, String[] args)
|
||||||
|
{
|
||||||
|
String worldName = ((Player)sender).getWorld().getName();
|
||||||
if (LoadSaveProcess.inProgress)
|
if (LoadSaveProcess.inProgress)
|
||||||
{
|
{
|
||||||
sender.sendMessage("a process is already running. /StopLoadSave to stop.");
|
sender.sendMessage("a process is already running (" + worldName + "). /StopLoadSave to stop.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else LoadSaveProcess.inProgress = true;
|
||||||
LoadSaveProcess.inProgress = true;
|
if ((Cache.isUnfinished(worldName)))
|
||||||
Dimensions dimensions = new Dimensions(args);
|
{
|
||||||
Main.task = Bukkit.getScheduler().runTaskTimer
|
sender.sendMessage("resuming...");
|
||||||
(
|
LoadSaveProcess.resume(worldName);
|
||||||
plugin,
|
|
||||||
new LoadSaveProcess(
|
|
||||||
dimensions.width,dimensions.center,dimensions.lowCorner
|
|
||||||
),
|
|
||||||
0, 100
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int[][] defaultDimensions =
|
|
||||||
new int[][] { {22528,0,0} , {44,-1,-1,-22,-22} };
|
|
||||||
|
|
||||||
private static class Dimensions{
|
|
||||||
int width;
|
|
||||||
int[] center;
|
|
||||||
int[] lowCorner;
|
|
||||||
|
|
||||||
Dimensions(String[] args){
|
|
||||||
int length = args.length;
|
|
||||||
if (length == 0)
|
|
||||||
{
|
|
||||||
width = defaultDimensions[1][0];
|
|
||||||
center = new int[] { defaultDimensions[1][1], defaultDimensions[1][2] };
|
|
||||||
lowCorner = new int[] { defaultDimensions[1][3], defaultDimensions[1][4] };
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int blockRadius = blockRadius(args[0]);
|
|
||||||
int[] blockCenter = length > 2 ?
|
|
||||||
blockCenter(args[1], args[2]) :
|
|
||||||
new int[]
|
|
||||||
{
|
|
||||||
defaultDimensions[0][1],
|
|
||||||
defaultDimensions[0][2]
|
|
||||||
};
|
|
||||||
int[] blockBounds = blockBounds(blockCenter,blockRadius);
|
|
||||||
int[] regionBounds = regionBoundsAddMargins(
|
|
||||||
regionBounds(blockBounds),
|
|
||||||
blockCenter,
|
|
||||||
blockRadius
|
|
||||||
);
|
|
||||||
int[] regionCenter = regionCenter(regionBounds);
|
|
||||||
//TODO
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================================
|
|
||||||
//this shit is only used when someone passes args to the command
|
|
||||||
//we're going to use the default dimensions so hardly any of this
|
|
||||||
//will get called
|
|
||||||
|
|
||||||
|
|
||||||
private static boolean isInteger(String arg){
|
|
||||||
int length = arg.length();
|
|
||||||
int i = 0;
|
|
||||||
if (arg.charAt(0) == '-')
|
|
||||||
if (length == 1) return false;
|
|
||||||
else i = 1;
|
|
||||||
for (; i < length; i++) {
|
|
||||||
char c = arg.charAt(i);
|
|
||||||
if (c < '0' || c > '9')
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static int blockRadius(String arg0)
|
|
||||||
{
|
|
||||||
int blockWidth = isInteger(arg0) ?
|
|
||||||
Integer.parseInt(arg0) : defaultDimensions[0][0];
|
|
||||||
return blockWidth/2;
|
|
||||||
}
|
|
||||||
private static int[] blockCenter(String arg1, String arg2)
|
|
||||||
{
|
|
||||||
int xBlock = isInteger(arg1) ? Integer.parseInt(arg1) : 0;
|
|
||||||
int zBlock = isInteger(arg2) ? Integer.parseInt(arg2) : 0;
|
|
||||||
return new int[] {xBlock,zBlock};
|
|
||||||
}
|
|
||||||
private static int[] blockBounds(int[] center, int blockRadius)
|
|
||||||
{
|
|
||||||
int xMinBlock = center[0] - blockRadius;
|
|
||||||
int xMaxBlock = center[0] + blockRadius;
|
|
||||||
int zMinBlock = center[1] - blockRadius;
|
|
||||||
int zMaxBlock = center[1] + blockRadius;
|
|
||||||
return new int[] {xMinBlock,xMaxBlock,zMinBlock,zMaxBlock};
|
|
||||||
}
|
|
||||||
private static int[] regionBounds(int[] blockBounds)
|
|
||||||
{
|
|
||||||
int xMinRegion = Math.floorDiv(blockBounds[0],512);
|
|
||||||
int xMaxRegion = Math.floorDiv(blockBounds[1],512);
|
|
||||||
int zMinRegion = Math.floorDiv(blockBounds[2],512);
|
|
||||||
int zMaxRegion = Math.floorDiv(blockBounds[3],512);
|
|
||||||
return new int[] {xMinRegion,xMaxRegion,zMinRegion,zMaxRegion};
|
|
||||||
}
|
|
||||||
private static int[] regionBoundsAddMargins(int[] regionBounds, int[] blockCenter, int blockRadius)
|
|
||||||
{
|
|
||||||
int[] regionBlockRadii = new int[4];
|
|
||||||
boolean[] marginAdded = new boolean[4];
|
|
||||||
|
|
||||||
//get block edge farthest from center
|
|
||||||
int xMinRegionBlockEdge = regionBounds[0] *512;
|
|
||||||
int xMaxRegionBlockEdge = (regionBounds[1]+1) *512 - 1;
|
|
||||||
int zMinRegionBlockEdge = regionBounds[2] *512;
|
|
||||||
int zMaxRegionBlockEdge = (regionBounds[3]+1) *512 - 1;
|
|
||||||
|
|
||||||
//get edge's block distance from center
|
|
||||||
regionBlockRadii[0] = Math.abs(blockCenter[0] - xMinRegionBlockEdge);
|
|
||||||
regionBlockRadii[1] = Math.abs(blockCenter[0] - xMaxRegionBlockEdge);
|
|
||||||
regionBlockRadii[2] = Math.abs(blockCenter[1] - zMinRegionBlockEdge);
|
|
||||||
regionBlockRadii[3] = Math.abs(blockCenter[1] - zMaxRegionBlockEdge);
|
|
||||||
|
|
||||||
//compare to original block radius, if difference is < 4 chunks add a region width
|
|
||||||
if (regionBlockRadii[0] - blockRadius < 64) { regionBounds[0] -= 1; marginAdded[0] = true; }
|
|
||||||
if (regionBlockRadii[1] - blockRadius < 64) { regionBounds[1] += 1; marginAdded[1] = true; }
|
|
||||||
if (regionBlockRadii[2] - blockRadius < 64) { regionBounds[2] -= 1; marginAdded[2] = true; }
|
|
||||||
if (regionBlockRadii[3] - blockRadius < 64) { regionBounds[3] += 1; marginAdded[3] = true; }
|
|
||||||
|
|
||||||
//resquare the selection
|
|
||||||
regionBounds = regionBoundsResquare(regionBounds,marginAdded,regionBlockRadii);
|
|
||||||
return regionBounds;
|
|
||||||
}
|
|
||||||
private static int[] regionCenter(int[] regionBounds){
|
|
||||||
int regionCenterX = regionBounds[0] - 1 + (regionBounds[1]-regionBounds[0] + 1)/2;
|
|
||||||
int regionCenterZ = regionBounds[2] - 1 + (regionBounds[3]-regionBounds[2] + 1)/2;
|
|
||||||
return new int[] {regionCenterX, regionCenterZ};
|
|
||||||
}
|
|
||||||
private static int[] regionBoundsResquare(int[] regionBounds, boolean[]marAdd, int[]radii){
|
|
||||||
if (!marAdd[0])
|
|
||||||
if (!marAdd[1])
|
|
||||||
if (!marAdd[2])
|
|
||||||
if (!marAdd[3])//0000
|
|
||||||
return regionBounds;
|
|
||||||
else//0001
|
|
||||||
{
|
|
||||||
int min = Math.min(radii[0], radii[1]);
|
|
||||||
if (min == radii[0])
|
|
||||||
regionBounds[0]++;
|
|
||||||
else
|
|
||||||
regionBounds[1]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (!marAdd[3])//0010
|
|
||||||
{
|
|
||||||
int min = Math.min(radii[0], radii[1]);
|
|
||||||
if (min == radii[0])
|
|
||||||
regionBounds[0]++;
|
|
||||||
else
|
|
||||||
regionBounds[1]++;
|
|
||||||
}
|
|
||||||
else//0011
|
|
||||||
{
|
|
||||||
regionBounds[0]++;
|
|
||||||
regionBounds[1]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (!marAdd[2])
|
|
||||||
if (!marAdd[3])//0100
|
|
||||||
{
|
|
||||||
int min = Math.min(radii[2], radii[3]);
|
|
||||||
if (min == radii[2])
|
|
||||||
regionBounds[2]++;
|
|
||||||
else
|
|
||||||
regionBounds[3]++;
|
|
||||||
}
|
|
||||||
else//0101
|
|
||||||
return regionBounds;
|
|
||||||
else
|
|
||||||
if (!marAdd[3])//0110
|
|
||||||
return regionBounds;
|
|
||||||
else//0111
|
|
||||||
regionBounds[0]++;
|
|
||||||
else
|
else
|
||||||
if (marAdd[1])
|
{
|
||||||
if (marAdd[2])
|
Dimensions d = new Dimensions(args);
|
||||||
if (marAdd[3])//1111
|
Main.process = new LoadSaveProcess( d.width, d.center, d.lowerleft, worldName );
|
||||||
return regionBounds;
|
}
|
||||||
else//1110
|
Main.task = Bukkit.getScheduler().runTaskTimer( plugin, Main.process, 0, 100 );
|
||||||
regionBounds[3]++;
|
return true;
|
||||||
else
|
|
||||||
if (marAdd[3])//1101
|
|
||||||
regionBounds[2]++;
|
|
||||||
else//1100
|
|
||||||
{
|
|
||||||
regionBounds[2]++;
|
|
||||||
regionBounds[3]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (marAdd[2])
|
|
||||||
if (marAdd[3])//1011
|
|
||||||
regionBounds[1]++;
|
|
||||||
else //1010
|
|
||||||
return regionBounds;
|
|
||||||
else //100
|
|
||||||
if (marAdd[3])//1001
|
|
||||||
return regionBounds;
|
|
||||||
else {//1000
|
|
||||||
int min = Math.min(radii[2], radii[3]);
|
|
||||||
if (min == radii[2])
|
|
||||||
regionBounds[0]++;
|
|
||||||
else
|
|
||||||
regionBounds[1]++;
|
|
||||||
};
|
|
||||||
return regionBounds;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,18 @@
|
||||||
package iieLoadSaveEntireWorld;
|
package iieLoadSaveEntireWorld;
|
||||||
|
|
||||||
public class StopCommand {
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
public class StopCommand implements CommandExecutor{
|
||||||
|
|
||||||
|
private static Main plugin;
|
||||||
|
StopCommand(Main Plugin){
|
||||||
|
plugin = Plugin;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command label, String command, String[] args) {
|
||||||
|
if (LoadSaveProcess.inProgress) Main.process.stop();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ public class UnusedPattern {
|
||||||
|
|
||||||
static int[] currentRegion;
|
static int[] currentRegion;
|
||||||
|
|
||||||
static RegionMap savedRegions;
|
static TranslatedCoordinates savedRegions;
|
||||||
|
|
||||||
static int[][][][][] allChunkCoords;
|
static int[][][][][] allChunkCoords;
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ public class UnusedPattern {
|
||||||
|
|
||||||
startRegion = new int[] {x,z};
|
startRegion = new int[] {x,z};
|
||||||
currentRegion = startRegion;
|
currentRegion = startRegion;
|
||||||
savedRegions = new RegionMap(width,lowX,lowZ);
|
savedRegions = new TranslatedCoordinates(width,lowX,lowZ);
|
||||||
generateAllChunkCoords(width,lowX,lowZ);
|
generateAllChunkCoords(width,lowX,lowZ);
|
||||||
if (even) regionPattern = new OutwardSpiralPattern();
|
if (even) regionPattern = new OutwardSpiralPattern();
|
||||||
else regionPattern = new CardinalPointsPattern();
|
else regionPattern = new CardinalPointsPattern();
|
||||||
|
@ -178,30 +178,25 @@ public class UnusedPattern {
|
||||||
//=================================UTIL=================================
|
//=================================UTIL=================================
|
||||||
|
|
||||||
//CUSTOM MAP CLASS FOR TRACKING SAVED REGIONS
|
//CUSTOM MAP CLASS FOR TRACKING SAVED REGIONS
|
||||||
static class RegionMap {
|
static class TranslatedCoordinates {
|
||||||
|
|
||||||
int xAdjust;
|
int xAdjust;
|
||||||
int zAdjust;
|
int zAdjust;
|
||||||
boolean[][] map;
|
boolean[][] savemap;
|
||||||
|
public TranslatedCoordinates(int w, int lowX, int lowZ)
|
||||||
public RegionMap(int d, int lowX, int lowZ){
|
{
|
||||||
xAdjust = 0 - lowX;
|
xAdjust = 0 - lowX;
|
||||||
zAdjust = 0 - lowZ;
|
zAdjust = 0 - lowZ;
|
||||||
d++;
|
savemap = new boolean[w][w];
|
||||||
map = new boolean[d][d];
|
|
||||||
}
|
|
||||||
void save(int x, int z){
|
|
||||||
x += xAdjust;
|
|
||||||
z += zAdjust;
|
|
||||||
map[x][z] = true;
|
|
||||||
}
|
|
||||||
boolean isSaved(int x, int z){
|
|
||||||
x += xAdjust;
|
|
||||||
z += zAdjust;
|
|
||||||
return map[x][z];
|
|
||||||
}
|
}
|
||||||
|
int x(int x){ return x + xAdjust; }
|
||||||
|
int z(int z){ return z + zAdjust; }
|
||||||
|
|
||||||
|
void save(int x, int z) { savemap[x(x)][z(z)] = true; }
|
||||||
|
boolean isSaved(int x, int z) { return savemap[x(x)][z(z)]; }
|
||||||
|
|
||||||
boolean allSaved(){
|
boolean allSaved(){
|
||||||
for (boolean[] xRow : map){
|
for (boolean[] xRow : savemap){
|
||||||
for (boolean region : xRow){
|
for (boolean region : xRow){
|
||||||
if (!region) return false;
|
if (!region) return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue