commit 305f53278c26248900e20e1050c3e83ec9532fc6 Author: BuildTools Date: Mon Nov 21 22:10:31 2016 -0500 here's what I've got diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..be492a2 --- /dev/null +++ b/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/.project b/.project new file mode 100644 index 0000000..6d94092 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + iieLoadSaveEntireWorld + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..3a21537 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/src/iieLoadSaveEntireWorld/LoadSaveProcess.java b/src/iieLoadSaveEntireWorld/LoadSaveProcess.java new file mode 100644 index 0000000..3138976 --- /dev/null +++ b/src/iieLoadSaveEntireWorld/LoadSaveProcess.java @@ -0,0 +1,158 @@ +package iieLoadSaveEntireWorld; + +import org.bukkit.scheduler.BukkitTask; + +public class LoadSaveProcess implements Runnable { + + + //=============================STATIC FIELDS============================ + + static boolean inProgress = false; + + private static int[] startRegion; + + private static int[] currentRegion; + + private static TranslatedCoordinates map; + + private static int[][][][][] allChunkCoords; + + public LoadSaveProcess(int width, int[] center, int[] lowCorner){ + currentRegion = startRegion = new int[] {center[0],center[1]}; + map = new TranslatedCoordinates(width,lowCorner[0],lowCorner[1]); + generateAllChunkCoords(width,lowCorner[0],lowCorner[1]); + } + + + //===============================PATTERN================================ + + private static class SavePattern { + + /* The pattern: + * + * 3 | 36 35 34 33 32 31 + * | + * 2 | 17 16 15 14 13 30 + * | + * 1 | 18 05 04 03 12 29 + * | + * Z | 19 06 01 02 11 28 + * | + * -1 | 20 07 08 09 10 27 + * | + * -2 | 21 22 23 24 25 26 + * +----------------------- + * -2 -1 X 1 2 3 + * etc. + */ + + private static int n = 1; //number + private static int c = 1; //direction of travel: E,N,W,S - 1,2,3,4 + private static int D = 1; //distance to travel + private static int d = 0; //distance already traveled + private static boolean B = false; //OK to change direction? + static void reset() + { + c = 1; + D = 1; + d = 0; + 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() + { + n++; + if (d != D) d++; + else + { + d = 0; + D++; + switch (c){ + case 1 : currentRegion[0]++; + case 2 : currentRegion[1]++; + case 3 : currentRegion[0]--; + case 4 : + currentRegion[1]--; + c = B ? 1 : c + 1; + } + B = !B; + } + } + } + + + + //=================================UTIL================================= + + //TRACKER, COORDINATE TRANSLATOR + private static class TranslatedCoordinates { + + int xAdjust; + int zAdjust; + //boolean[][] savemap; + public TranslatedCoordinates(int w, int lowX, int lowZ) + { + xAdjust = 0 - lowX; + zAdjust = 0 - lowZ; + //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(){ + for (boolean[] xRow : savemap){ + for (boolean region : xRow){ + 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; + for (int[][][] region : xRowRegions){ + int chunkX = 0; + for (int[][] xRowChunks : region){ + int 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; + } + regionX++; + if (negX) + negX = regionX < 0; + } + } + + + //==================================RUN================================= + public void run() { + + } +} diff --git a/src/iieLoadSaveEntireWorld/Main.java b/src/iieLoadSaveEntireWorld/Main.java new file mode 100644 index 0000000..3158459 --- /dev/null +++ b/src/iieLoadSaveEntireWorld/Main.java @@ -0,0 +1,16 @@ +package iieLoadSaveEntireWorld; + +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitTask; + +public class Main extends JavaPlugin { + + static Main plugin; + static BukkitTask task; + + public void onEnable() { + plugin = this; + saveDefaultConfig(); + getCommand("loadsaveentireworld").setExecutor(new StartCommand(plugin)); + } +} diff --git a/src/iieLoadSaveEntireWorld/StartCommand.java b/src/iieLoadSaveEntireWorld/StartCommand.java new file mode 100644 index 0000000..8bb2ccf --- /dev/null +++ b/src/iieLoadSaveEntireWorld/StartCommand.java @@ -0,0 +1,230 @@ +package iieLoadSaveEntireWorld; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class StartCommand implements CommandExecutor { + private Main plugin; + StartCommand(Main Plugin){ + plugin = Plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command label, String command, String[] args) { + if (LoadSaveProcess.inProgress) + { + sender.sendMessage("a process is already running. /StopLoadSave to stop."); + return false; + } + else + LoadSaveProcess.inProgress = true; + Dimensions dimensions = new Dimensions(args); + Main.task = Bukkit.getScheduler().runTaskTimer + ( + 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 + 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 //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; + } +} diff --git a/src/iieLoadSaveEntireWorld/StopCommand.java b/src/iieLoadSaveEntireWorld/StopCommand.java new file mode 100644 index 0000000..296c814 --- /dev/null +++ b/src/iieLoadSaveEntireWorld/StopCommand.java @@ -0,0 +1,5 @@ +package iieLoadSaveEntireWorld; + +public class StopCommand { + +} diff --git a/src/iieLoadSaveEntireWorld/UnusedPattern.java b/src/iieLoadSaveEntireWorld/UnusedPattern.java new file mode 100644 index 0000000..6c2e96c --- /dev/null +++ b/src/iieLoadSaveEntireWorld/UnusedPattern.java @@ -0,0 +1,241 @@ +package iieLoadSaveEntireWorld; + +import org.bukkit.scheduler.BukkitTask; + +public class UnusedPattern { + + /* the contents of this class are static because + * loading and saving an entire world is an intensive process, + * and only one save process should be running at a time. + * + * so only one save process should be TRACKED at a time. + */ + + //=============================STATIC FIELDS============================ + + static BukkitTask task; + + static int[] startRegion; + + static int[] currentRegion; + + static RegionMap savedRegions; + + static int[][][][][] allChunkCoords; + + static RegionPattern regionPattern; + + //INITIALIZE FIELDS + static void init(int width, int x, int z){ + boolean even = width % 2 == 0; + int radius = Math.floorDiv(width,2); + if (even) radius -=1 ; + int lowX = x-radius; + int lowZ = z-radius; + + startRegion = new int[] {x,z}; + currentRegion = startRegion; + savedRegions = new RegionMap(width,lowX,lowZ); + generateAllChunkCoords(width,lowX,lowZ); + if (even) regionPattern = new OutwardSpiralPattern(); + else regionPattern = new CardinalPointsPattern(); + } + + + + //===============================PATTERNS=============================== + + //ABSTRACT PARENT CLASS + static abstract class RegionPattern { + static int n = 1; //iteration number + abstract void reset(); //reset fields + abstract void setNextRegion(); + } + + //EVEN DIAMETER: OUTWARD SPIRAL PATTERN + private static class OutwardSpiralPattern extends RegionPattern { + + /* The pattern: + * + * 3 | 36 35 34 33 32 31 + * | + * 2 | 17 16 15 14 13 30 + * | + * 1 | 18 05 04 03 12 29 + * | + * Z | 19 06 01 02 11 28 + * | + * -1 | 20 07 08 09 10 27 + * | + * -2 | 21 22 23 24 25 26 + * +----------------------- + * -2 -1 X 1 2 3 + * etc. + */ + + static int c; //direction of travel: E,N,W,S - 1,2,3,4 + static int D; //distance to travel + static int d; //distance already traveled + static boolean B; //OK to change direction? + + OutwardSpiralPattern(){ + c = 1; + D = 1; + d = 0; + B = false; + } + + + + //interface methods + public void reset() { + + } + public void setNextRegion() { + + } + } + + + //ODD DIAMETER: CARDINAL POINTS PATTERN + private static class CardinalPointsPattern extends RegionPattern { + + /* The pattern: + * + * 2 | 23 18 10 14 22 + * | + * 1 | 15 07 02 06 21 + * | + * Z | 11 03 01 05 13 + * | + * -1 | 19 08 04 09 17 + * | + * -2 | 24 16 12 20 25 + * +------------------- + * -2 -1 X 1 2 + * etc. + */ + + private static int[] cardinalPoints; //midpoint of each side + + private static int c; //side: N,W,S,E = 1,2,3,4 + private static int r; //radius from square center + + private static int d; //distance from cardinal point + private static boolean B; //direction from cardinal point + + private static void expR(){ //expand radius, cardinal points + r++; + cardinalPoints[0]++; + cardinalPoints[1]--; + cardinalPoints[2]--; + cardinalPoints[4]++; + } + + CardinalPointsPattern(){ + reset(); + } + + //interface methods + void reset(){ + cardinalPoints = new int[] { //each cardinal point contains + startRegion[1]+1, //only the dimension that moves + startRegion[0]-1, + startRegion[1]-1, + startRegion[0]+1 + }; + n = 1; + c = 1; + r = 1; + d = 0; + B = false; + } + void setNextRegion(){ + n++; + switch (c){ + case 1 : + if (B) currentRegion = new int[] {startRegion[0] + d, cardinalPoints[0]}; + else; currentRegion = new int[] {startRegion[0] - d, cardinalPoints[0]}; + case 2 : + if (B) currentRegion = new int[] {cardinalPoints[1], startRegion[0] + d}; + else; currentRegion = new int[] {cardinalPoints[1], startRegion[0] - d}; + case 3 : + if (B) currentRegion = new int[] {startRegion[0] - d, cardinalPoints[2]}; + else; currentRegion = new int[] {startRegion[0] + d, cardinalPoints[2]}; + case 4 : + if (B) currentRegion = new int[] {cardinalPoints[3], startRegion[0] - d}; + else; currentRegion = new int[] {cardinalPoints[3], startRegion[0] + d}; + + if (r == d) { expR(); d = 0; c = 1; } + else { d++; c++; B = !B; } + + } + } + } + + + + //=================================UTIL================================= + + //CUSTOM MAP CLASS FOR TRACKING SAVED REGIONS + static class RegionMap { + + int xAdjust; + int zAdjust; + boolean[][] map; + + public RegionMap(int d, int lowX, int lowZ){ + xAdjust = 0 - lowX; + zAdjust = 0 - lowZ; + d++; + 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]; + } + boolean allSaved(){ + for (boolean[] xRow : map){ + for (boolean region : xRow){ + if (!region) return false; + } + } + return true; + } + } + + //GENERATE ALL CHUNK COORDINATES + private static void generateAllChunkCoords(int d, int lowX, int lowZ) { + allChunkCoords = new int[d][d][32][32][2]; + int regionX = lowX; + boolean negX = true; + for (int[][][][] xRowRegions : allChunkCoords){ + int regionZ = lowZ; + boolean negZ = true; + for (int[][][] region : xRowRegions){ + int chunkX = 0; + for (int[][] xRowChunks : region){ + int 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; + } + regionX++; + if (negX) + negX = regionX < 0; + } + } +} diff --git a/target/config.yml b/target/config.yml new file mode 100644 index 0000000..e69de29 diff --git a/target/plugin.yml b/target/plugin.yml new file mode 100644 index 0000000..4d5b3c3 --- /dev/null +++ b/target/plugin.yml @@ -0,0 +1,6 @@ + main: iieLoadSaveEntireWorld.Main + version: 1.0.0 + name: LoadSaveEntireWorld + commands: + loadsaveentireworld: + description: loads and saves the entire map, in 32x32 chunk sections \ No newline at end of file