diff --git a/src/corrodias/minecraft/landgenerator/MLG_Misc.java b/src/corrodias/minecraft/landgenerator/MLG_Misc.java
new file mode 100644
index 0000000..9377b3c
--- /dev/null
+++ b/src/corrodias/minecraft/landgenerator/MLG_Misc.java
@@ -0,0 +1,65 @@
+package corrodias.minecraft.landgenerator;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import morlok8k.minecraft.landgenerator.Coordinates;
+import morlok8k.minecraft.landgenerator.MLG_FileRead;
+
+public class MLG_Misc {
+
+ //TODO: add description
+ /**
+ * @return
+ */
+ static boolean printSpawn() {
+ // ugh, sorry, this is an ugly hack, but it's a last-minute feature. this is a lot of duplicated code.
+ // - Fixed by Morlok8k
+
+ MLG_FileRead.readConf();
+ MLG_WorldVerify.verifyWorld();
+
+ File level = new File(Main.worldPath + Main.fileSeparator + "level.dat");
+ try {
+ Coordinates spawn = MLG_SpawnPoint.getSpawn(level);
+ Main.out("The current spawn point is: [X,Y,Z] " + spawn);
+ return true;
+ } catch (IOException ex) {
+ Main.err("Error while reading " + level.getPath());
+ return false;
+ }
+ }
+
+ /**
+ * I'd love to use nio, but it requires Java 7.
+ * I could use Apache Commons, but i don't want to include a library for one little thing.
+ * Copies src file to dst file.
+ * If the dst file does not exist, it is created
+ *
+ * @author Corrodias
+ * @param src
+ * @param dst
+ * @throws IOException
+ */
+ public static void copyFile(File src, File dst) throws IOException {
+ InputStream copyIn = new FileInputStream(src);
+ OutputStream copyOut = new FileOutputStream(dst);
+
+ // Transfer bytes from in to out
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = copyIn.read(buf)) >= 0) {
+ if (len > 0) {
+ copyOut.write(buf, 0, len);
+ }
+ }
+ copyIn.close();
+ copyOut.flush();
+ copyOut.close();
+ }
+
+}
diff --git a/src/corrodias/minecraft/landgenerator/MLG_Server.java b/src/corrodias/minecraft/landgenerator/MLG_Server.java
new file mode 100644
index 0000000..e86e6db
--- /dev/null
+++ b/src/corrodias/minecraft/landgenerator/MLG_Server.java
@@ -0,0 +1,300 @@
+package corrodias.minecraft.landgenerator;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+
+public class MLG_Server {
+
+ /**
+ * Starts the process in the given ProcessBuilder, monitors its output for a "[INFO] Done!" message, and sends it a "stop\r\n" message. One message is printed to the console before launching and
+ * one is printed to the console when the Done! message is detected. If "verbose" is true, the process's output will also be printed to the console.
+ *
+ * @param minecraft
+ *
+ * @throws IOException
+ * @author Corrodias
+ */
+ protected static boolean runMinecraft(boolean alternate) throws IOException {
+ if (Main.verbose) {
+ Main.out("Starting server.");
+ }
+ boolean serverSuccess = true;
+ boolean warning = false;
+ boolean warningsWeCanIgnore = false;
+ final boolean ignoreWarningsOriginal = Main.ignoreWarnings;
+
+ // monitor output and print to console where required.
+ // STOP the server when it's done.
+
+ if (alternate) { // Alternate - a replication (slightly stripped down) of MLG 1.3.0's code. simplest code possible.
+ Main.out("Alternate Launch");
+ Process process = Main.minecraft.start();
+
+ byte[] stop = { 's', 't', 'o', 'p', '\r', '\n' };
+
+ // monitor output and print to console where required.
+ // STOP the server when it's done.
+ BufferedReader pOut =
+ new BufferedReader(new InputStreamReader(process.getInputStream()));
+ String line;
+ while ((line = pOut.readLine()) != null) {
+
+ line = line.trim(); //Trim spaces off the beginning and end, if any.
+
+ System.out.println(line);
+ if (line.contains(Main.doneText)) { // EDITED By Morlok8k for Minecraft 1.3+ Beta
+ OutputStream outputStream = process.getOutputStream();
+
+ Main.out("Stopping server... (Please Wait...)");
+ outputStream.write(stop);
+ outputStream.flush();
+
+ }
+ }
+ // readLine() returns null when the process exits
+
+ } else { // start minecraft server normally!
+ Process process = Main.minecraft.start();
+ if (Main.verbose) {
+ Main.out("Started Server.");
+ }
+ BufferedReader pOut =
+ new BufferedReader(new InputStreamReader(process.getInputStream()));
+ if (Main.verbose) {
+ Main.out("Accessing Server Output...");
+ }
+
+ String line = null;
+ String shortLine = null;
+ String outTmp = "";
+ String outTmp2 = null;
+
+ byte[] stop = { 's', 't', 'o', 'p', '\r', '\n' }; // Moved here, so this code wont run every loop, thus Faster!
+ // and no, i can't use a string here!
+
+ byte[] saveAll = { 's', 'a', 'v', 'e', '-', 'a', 'l', 'l', '\r', '\n' };
+
+ boolean prepTextFirst = true;
+
+ OutputStream outputStream = process.getOutputStream(); // moved here to remove some redundancy
+
+ /*
+ 2012-02-29 03:50:28 [INFO] Converting map!
+ Scanning folders...
+ Total conversion count is 9
+ 2012-02-29 03:50:29 [INFO] Converting... 8%
+ 2012-02-29 03:50:30 [INFO] Converting... 9%
+ 2012-02-29 03:50:31 [INFO] Converting... 10%
+ 2012-02-29 03:50:32 [INFO] Converting... 12%
+ 2012-02-29 03:50:33 [INFO] Converting... 13%
+ */
+
+ boolean convertedMapFormattingFlag = false; // This allows MLG to track if we converted a map to a new format (such as Chunk-file -> McRegion, or McRegion -> Anvil)
+ // just so it gets a line ending after the % output finishes
+ while ((line = pOut.readLine()) != null) {
+
+ int posBracket = line.lastIndexOf("]");
+ if (posBracket != -1) {
+ shortLine = line.substring(posBracket + 2);
+ shortLine = shortLine.trim();
+ } else {
+ shortLine = line;
+ }
+
+ line = line.trim();
+
+ if (Main.verbose) {
+ Main.outS(shortLine);
+ } else if (line.toLowerCase().contains("saving")) {
+ Main.outS(shortLine);
+ } else if (line.contains(Main.preparingText) || line.contains("Converting...")) {
+ if (line.contains("Converting...")) {
+ convertedMapFormattingFlag = true;
+ }
+ outTmp2 = line.substring(line.length() - 3, line.length());
+ outTmp2 = outTmp2.trim(); //we are removing extra spaces here
+ if (outTmp.equals(outTmp2)) {
+ //instead of printing the same number, we add another dot
+ Main.outP(".");
+ } else {
+ outTmp = outTmp2;
+
+ if (prepTextFirst) {
+ Main.outP(Main.MLG + outTmp + "...");
+ prepTextFirst = false;
+ } else {
+ Main.outP(" " + outTmp + "...");
+ }
+
+ }
+
+ } else if (line.contains(Main.preparingLevel)) {
+ prepTextFirst = true;
+
+ if (convertedMapFormattingFlag == true) {
+ Main.outP(Main.newLine);
+ convertedMapFormattingFlag = false;
+ }
+
+ if (line.contains("level 0")) { // "Preparing start region for level 0"
+ Main.outP(Main.MLG + Main.worldName + ": " + Main.level_0 + ":" + Main.newLine);
+ } else if (line.contains("level 1")) { // "Preparing start region for level 1"
+ Main.outP(Main.newLine + Main.MLG + Main.worldName + ": " + Main.level_1 + ":" + Main.newLine);
+ } else if (line.contains("level 2")) { // "Preparing start region for level 2"
+ Main.outP(Main.newLine + Main.MLG + Main.worldName + ": " + Main.level_2 + ":" + Main.newLine);
+ } else if (line.contains("level 3")) { // "Preparing start region for level 3"
+ Main.outP(Main.newLine + Main.MLG + Main.worldName + ": " + Main.level_3 + ":" + Main.newLine);
+ } else if (line.contains("level 4")) { // "Preparing start region for level 4"
+ Main.outP(Main.newLine + Main.MLG + Main.worldName + ": " + Main.level_4 + ":" + Main.newLine);
+ } else if (line.contains("level 5")) { // "Preparing start region for level 5"
+ Main.outP(Main.newLine + Main.MLG + Main.worldName + ": " + Main.level_5 + ":" + Main.newLine);
+ } else if (line.contains("level 6")) { // "Preparing start region for level 6"
+ Main.outP(Main.newLine + Main.MLG + Main.worldName + ": " + Main.level_6 + ":" + Main.newLine);
+ } else if (line.contains("level 7")) { // "Preparing start region for level 7"
+ Main.outP(Main.newLine + Main.MLG + Main.worldName + ": " + Main.level_7 + ":" + Main.newLine);
+ } else if (line.contains("level 8")) { // "Preparing start region for level 8"
+ Main.outP(Main.newLine + Main.MLG + Main.worldName + ": " + Main.level_8 + ":" + Main.newLine);
+ } else if (line.contains("level 9")) { // "Preparing start region for level 9"
+ Main.outP(Main.newLine + Main.MLG + Main.worldName + ": " + Main.level_9 + ":" + Main.newLine);
+ } else {
+ Main.outP(Main.newLine + Main.MLG + shortLine);
+ }
+ } else if (line.contains("server version") || line.contains("Converting map!")) { //TODO: add to .conf
+ Main.outS(shortLine);
+
+ if (line.contains("server version") && Main.MC_Server_Version.isEmpty()) {
+ // if server version, save string to variable, for use in arraylist save file.
+ Main.MC_Server_Version = shortLine;
+ }
+
+ }
+
+ if (line.contains(Main.doneText)) { // now this is configurable!
+
+ Main.outP(Main.newLine);
+ Main.outS(line.substring(line.lastIndexOf("]") + 2, line.indexOf("!")));
+ if (Main.waitSave) {
+ Main.out("Waiting 30 seconds to save...");
+
+ int count = 1;
+ while (count <= 30) {
+ Main.outP(".");
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ count += 1;
+ }
+ Main.out("");
+ }
+ Main.out("Saving server data...");
+ outputStream.write(saveAll);
+ outputStream.flush();
+
+ Main.out("Stopping server... (Please Wait...)");
+ // OutputStream outputStream = process.getOutputStream();
+ outputStream.write(stop);
+ outputStream.flush();
+ // outputStream.close();
+
+ if (Main.waitSave) {
+ Main.out("Waiting 10 seconds to save.");
+ int count = 1;
+ while (count <= 10) {
+ Main.outP(".");
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ count += 1;
+ }
+ Main.out("");
+ }
+ }
+
+ //Here we want to ignore the most common warning: "Can't keep up!"
+ if (line.contains("Can't keep up!")) { //TODO: add to .conf
+ warningsWeCanIgnore = true; //[WARNING] Can't keep up! Did the system time change, or is the server overloaded?
+ Main.ignoreWarnings = true;
+ } else if (line.contains("[WARNING] To start the server with more ram")) {
+ if (Main.verbose == false) { // If verbose is true, we already displayed it.
+ Main.outS(line);
+ }
+ warningsWeCanIgnore = true; //we can safely ignore this...
+ Main.ignoreWarnings = true;
+ } else if (line.contains("Error occurred during initialization of VM")
+ || line.contains("Could not reserve enough space for object heap")) {
+ if (Main.verbose == false) { // If verbose is true, we already displayed it.
+ Main.outP("[Java Error] " + line);
+ }
+ warning = true;
+ }
+
+ if (Main.ignoreWarnings == false) {
+ if (line.contains("[WARNING]")) { // If we have a warning, stop...
+ Main.out("");
+ Main.out("Warning found: Stopping " + Main.PROG_NAME);
+ if (Main.verbose == false) { // If verbose is true, we already displayed it.
+ Main.outS(line);
+ }
+ Main.out("");
+ Main.out("Forcing Save...");
+ outputStream.write(saveAll);
+ outputStream.flush();
+ // OutputStream outputStream = process.getOutputStream();
+ outputStream.write(stop); // if the warning was a fail to bind to port, we may need to write stop twice!
+ outputStream.flush();
+ outputStream.write(stop);
+ outputStream.flush();
+ // outputStream.close();
+ warning = true;
+ // System.exit(1);
+ }
+ if (line.contains("[SEVERE]")) { // If we have a severe error, stop...
+ Main.out("");
+ Main.out("Severe error found: Stopping server.");
+ if (Main.verbose == false) { // If verbose is true, we already displayed it.
+ Main.outS(line);
+ }
+ Main.out("");
+ Main.out("Forcing Save...");
+ outputStream.write(saveAll);
+ outputStream.flush();
+ // OutputStream outputStream = process.getOutputStream();
+ outputStream.write(stop);
+ outputStream.flush();
+ outputStream.write(stop); // sometimes we need to do stop twice...
+ outputStream.flush();
+ // outputStream.close();
+ warning = true;
+ // System.exit(1);
+ // Quit!
+ }
+ }
+
+ if (warningsWeCanIgnore) {
+ Main.ignoreWarnings = ignoreWarningsOriginal;
+ }
+ }
+
+ if (warning == true) { // in 1.4.4 we had a issue. tried to write stop twice, but we had closed the stream already. this, and other lines should fix this.
+ outputStream.flush();
+ //outputStream.close();
+ //System.exit(1);
+ serverSuccess = false;
+ }
+
+ outputStream.close();
+ }
+
+ // readLine() returns null when the process exits
+ return serverSuccess;
+ }
+
+}
diff --git a/src/corrodias/minecraft/landgenerator/MLG_SpawnPoint.java b/src/corrodias/minecraft/landgenerator/MLG_SpawnPoint.java
new file mode 100644
index 0000000..e54f337
--- /dev/null
+++ b/src/corrodias/minecraft/landgenerator/MLG_SpawnPoint.java
@@ -0,0 +1,143 @@
+package corrodias.minecraft.landgenerator;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import morlok8k.minecraft.landgenerator.Coordinates;
+
+import org.jnbt.CompoundTag;
+import org.jnbt.IntTag;
+import org.jnbt.LongTag;
+import org.jnbt.NBTInputStream;
+import org.jnbt.NBTOutputStream;
+import org.jnbt.Tag;
+
+public class MLG_SpawnPoint {
+
+ /**
+ * Changes the spawn point in the given Alpha/Beta level to the given coordinates.
+ * Note that, in Minecraft levels, the Y coordinate is height.
+ * (We picture maps from above, but the game was made from a different perspective)
+ *
+ * @param level
+ * the level file to change the spawn point in
+ * @param xyz
+ * the Coordinates of the spawn point
+ * @throws IOException
+ * if there are any problems reading/writing the file
+ * @author Corrodias
+ */
+ protected static void setSpawn(File level, Coordinates xyz) throws IOException {
+
+ try {
+ NBTInputStream input = new NBTInputStream(new FileInputStream(level));
+ CompoundTag originalTopLevelTag = (CompoundTag) input.readTag();
+ input.close();
+
+ //@formatter:off
+
+ //Note: The Following Information is Old (from 2010), compared to the Data inside a current "level.dat".
+ //However, What we look at (SpawnX,Y,Z and RandomSeed) have not changed.
+
+ /*
+ * Structure:
+ *
+ *TAG_Compound("Data"): World data.
+ * * TAG_Long("Time"): Stores the current "time of day" in ticks. There are 20 ticks per real-life second, and 24000 ticks per Minecraft day, making the day length 20 minutes. 0 appears to be sunrise, 12000 sunset and 24000 sunrise again.
+ * * TAG_Long("LastPlayed"): Stores the Unix time stamp (in milliseconds) when the player saved the game.
+ * * TAG_Compound("Player"): Player entity information. See Entity Format and Mob Entity Format for details. Has additional elements:
+ * o TAG_List("Inventory"): Each TAG_Compound in this list defines an item the player is carrying, holding, or wearing as armor.
+ * + TAG_Compound: Inventory item data
+ * # TAG_Short("id"): Item or Block ID.
+ * # TAG_Short("Damage"): The amount of wear each item has suffered. 0 means undamaged. When the Damage exceeds the item's durability, it breaks and disappears. Only tools and armor accumulate damage normally.
+ * # TAG_Byte("Count"): Number of items stacked in this inventory slot. Any item can be stacked, including tools, armor, and vehicles. Range is 1-255. Values above 127 are not displayed in-game.
+ * # TAG_Byte("Slot"): Indicates which inventory slot this item is in.
+ * o TAG_Int("Score"): Current score, doesn't appear to be implemented yet. Always 0.
+ * * TAG_Int("SpawnX"): X coordinate of the player's spawn position. Default is 0.
+ * * TAG_Int("SpawnY"): Y coordinate of the player's spawn position. Default is 64.
+ * * TAG_Int("SpawnZ"): Z coordinate of the player's spawn position. Default is 0.
+ * * TAG_Byte("SnowCovered"): 1 enables, 0 disables, see Winter Mode
+ * * TAG_Long("SizeOnDisk"): Estimated size of the entire world in bytes.
+ * * TAG_Long("RandomSeed"): Random number providing the Random Seed for the terrain.
+ *
+ */
+
+ //@formatter:on
+
+ Map originalData =
+ ((CompoundTag) originalTopLevelTag.getValue().get("Data")).getValue();
+ // This is our map of data. It is an unmodifiable map, for some reason, so we have to make a copy.
+ Map newData = new LinkedHashMap(originalData);
+
+ // .get() a couple of values, just to make sure we're dealing with a valid level file, here. Good for debugging, too.
+ @SuppressWarnings("unused")
+ IntTag spawnX = (IntTag) newData.get("SpawnX"); // we never use these... Its only here for potential debugging.
+ @SuppressWarnings("unused")
+ IntTag spawnY = (IntTag) newData.get("SpawnY"); // but whatever... so I (Morlok8k) suppressed these warnings.
+ @SuppressWarnings("unused")
+ IntTag spawnZ = (IntTag) newData.get("SpawnZ"); // I don't want to remove existing code, either by myself (Morlok8k) or Corrodias
+
+ newData.put("SpawnX", new IntTag("SpawnX", xyz.getX())); // pulling the data out of the Coordinates,
+ newData.put("SpawnY", new IntTag("SpawnY", xyz.getY())); // and putting it into our IntTag's
+ newData.put("SpawnZ", new IntTag("SpawnZ", xyz.getZ()));
+
+ // Again, we can't modify the data map in the old Tag, so we have to make a new one.
+ CompoundTag newDataTag = new CompoundTag("Data", newData);
+ Map newTopLevelMap = new HashMap(1);
+ newTopLevelMap.put("Data", newDataTag);
+ CompoundTag newTopLevelTag = new CompoundTag("", newTopLevelMap);
+
+ NBTOutputStream output = new NBTOutputStream(new FileOutputStream(level));
+ output.writeTag(newTopLevelTag);
+ output.close();
+ } catch (ClassCastException ex) {
+ throw new IOException("Invalid level format.");
+ } catch (NullPointerException ex) {
+ throw new IOException("Invalid level format.");
+ }
+ }
+
+ //TODO: update this
+ /**
+ * @param level
+ * @return
+ * @throws IOException
+ * @author Corrodias
+ */
+ protected static Coordinates getSpawn(File level) throws IOException {
+ try {
+ NBTInputStream input = new NBTInputStream(new FileInputStream(level));
+ CompoundTag originalTopLevelTag = (CompoundTag) input.readTag();
+ input.close();
+
+ Map originalData =
+ ((CompoundTag) originalTopLevelTag.getValue().get("Data")).getValue();
+ // This is our map of data. It is an unmodifiable map, for some
+ // reason, so we have to make a copy.
+ Map newData = new LinkedHashMap(originalData);
+ // .get() a couple of values, just to make sure we're dealing with a
+ // valid level file, here. Good for debugging, too.
+ IntTag spawnX = (IntTag) newData.get("SpawnX");
+ IntTag spawnY = (IntTag) newData.get("SpawnY");
+ IntTag spawnZ = (IntTag) newData.get("SpawnZ");
+
+ LongTag Seed = (LongTag) newData.get("RandomSeed");
+ Main.randomSeed = Seed.getValue();
+ Main.out("Seed: " + Main.randomSeed); // lets output the seed, cause why not?
+
+ Coordinates ret =
+ new Coordinates(spawnX.getValue(), spawnY.getValue(), spawnZ.getValue());
+ return ret;
+ } catch (ClassCastException ex) {
+ throw new IOException("Invalid level format.");
+ } catch (NullPointerException ex) {
+ throw new IOException("Invalid level format.");
+ }
+ }
+
+}
diff --git a/src/corrodias/minecraft/landgenerator/MLG_WorldVerify.java b/src/corrodias/minecraft/landgenerator/MLG_WorldVerify.java
new file mode 100644
index 0000000..37e2af4
--- /dev/null
+++ b/src/corrodias/minecraft/landgenerator/MLG_WorldVerify.java
@@ -0,0 +1,117 @@
+package corrodias.minecraft.landgenerator;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class MLG_WorldVerify {
+
+ /**
+ *
+ */
+ static void verifyWorld() {
+ //TODO: element comment
+
+ // verify that we ended up with a good server path, either from the file or from an argument.
+ File file = new File(Main.serverPath);
+ if (!file.exists() || !file.isDirectory()) {
+ Main.err("The server directory is invalid: " + Main.serverPath);
+ return;
+ }
+
+ try {
+ // read the name of the current world from the server.properties file
+ BufferedReader props =
+ new BufferedReader(new FileReader(new File(Main.serverPath + Main.fileSeparator
+ + "server.properties")));
+ String line;
+ while ((line = props.readLine()) != null) {
+ String property = "";
+ String value = "";
+
+ int pos = line.indexOf('=');
+
+ int end = line.lastIndexOf('#'); // comments, ignored lines
+
+ if (end == -1) { // If we have no hash sign, then we read till the end of the line
+ end = line.length();
+
+ }
+ if (end <= (pos + 1)) { // If hash is before the '=', we may have an issue... it should be fine, cause we check for issues next, but lets make sure.
+ end = line.length();
+ pos = -1;
+ }
+
+ if (end == 0) { //hash is first char, meaning entire line is a comment
+ end = line.length();
+ pos = 0;
+ }
+
+ if (pos != -1) {
+ if (line.length() == 0) {
+ property = "";
+ value = "";
+ } else {
+ property = line.substring(0, pos).toLowerCase();
+ value = line.substring(pos + 1);
+ }
+
+ if (property.equals("level-name")) {
+ Main.worldPath = Main.serverPath + Main.fileSeparator + value;
+ Main.worldName = value;
+ }
+ if (Main.useRCON) {
+ if (property.equals("enable-rcon")) {
+
+ if (value.contains("true")) {
+ Main.rcon_Enabled = true;
+ Main.out("RCON is set to be Enabled on the server.");
+ } else {
+ Main.rcon_Enabled = false;
+ Main.useRCON = false;
+ Main.err("RCON is not Enabled on the server.");
+ }
+ } else if (property.equals("rcon.password")) {
+ Main.rcon_Password = value;
+ if (Main.rcon_Password.isEmpty()) {
+ Main.useRCON = false;
+ Main.err("RCON Needs a password!.");
+ }
+ Main.out("RCON Password:" + Main.rcon_Password);
+ } else if (property.equals("rcon.port")) {
+ Main.rcon_Port = value;
+ Main.out("RCON Port:" + Main.rcon_Port);
+ } else if (property.equals("server-ip")) {
+ String IP = value;
+ if (IP.isEmpty()) {
+ IP = "0.0.0.0";
+ }
+ Main.rcon_IPaddress = IP;
+
+ }
+ }
+
+ }
+ }
+
+ } catch (FileNotFoundException ex) {
+ Main.err("Could not open " + Main.serverPath + Main.fileSeparator + "server.properties");
+ return;
+ } catch (IOException ex) {
+ Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
+ return;
+ }
+
+ File level = new File(Main.worldPath + Main.fileSeparator + "level.dat");
+ if (!level.exists() || !level.isFile()) {
+ Main.err("The currently-configured world does not exist. Please launch the server once, first.");
+ return;
+ }
+
+ }
+
+}
diff --git a/src/corrodias/minecraft/landgenerator/Main.java b/src/corrodias/minecraft/landgenerator/Main.java
index bba1d98..3f4f393 100644
--- a/src/corrodias/minecraft/landgenerator/Main.java
+++ b/src/corrodias/minecraft/landgenerator/Main.java
@@ -1,44 +1,34 @@
package corrodias.minecraft.landgenerator;
import java.io.BufferedReader;
-import java.io.BufferedWriter;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.FileReader;
-import java.io.FileWriter;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
+import java.util.Iterator;
import java.util.Locale;
-import java.util.Map;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
+import morlok8k.minecraft.landgenerator.Coordinates;
+import morlok8k.minecraft.landgenerator.MLG_ArrayList;
import morlok8k.minecraft.landgenerator.MLG_DownloadFile;
+import morlok8k.minecraft.landgenerator.MLG_FileRead;
+import morlok8k.minecraft.landgenerator.MLG_FileWrite;
import morlok8k.minecraft.landgenerator.MLG_MD5;
import morlok8k.minecraft.landgenerator.MLG_Readme_and_HelpInfo;
+import morlok8k.minecraft.landgenerator.MLG_SelfAware;
import morlok8k.minecraft.landgenerator.MLG_StringArrayParse;
+import morlok8k.minecraft.landgenerator.MLG_Time;
import morlok8k.minecraft.landgenerator.MLG_Update;
import morlok8k.minecraft.landgenerator.MLG_input_CLI;
-import org.jnbt.CompoundTag;
-import org.jnbt.IntTag;
-import org.jnbt.LongTag;
-import org.jnbt.NBTInputStream;
-import org.jnbt.NBTOutputStream;
-import org.jnbt.Tag;
-
/**
*
* @author Corrodias, Morlok8k, pr0f1x
@@ -52,12 +42,14 @@ public class Main {
public static boolean testing = false; // display more output when debugging
public static final String PROG_NAME = "Minecraft Land Generator"; // Program Name
- public static final String VERSION = "1.6.9 (1.7pre)"; // Version Number!
+ public static final String VERSION = "1.6.99 (1.7.0 test3)"; // Version Number!
public static final String AUTHORS = "Corrodias, Morlok8k, pr0f1x"; // Authors
public static final String fileSeparator = System.getProperty("file.separator");
public static final String newLine = System.getProperty("line.separator");
+ public static String[] originalArgs = {};
+
public static String MLG = "[MLG] ";
public static String MLGe = "[MLG-ERROR] ";
@@ -69,51 +61,41 @@ public class Main {
public static final String MinecraftLandGeneratorConf = "MinecraftLandGenerator.conf";
public static final String defaultReadmeFile = "_MLG_Readme.txt";
- //
- //
- //Private Vars:
- private static int MinecraftServerChunkPlayerCache = 625;
- private static int increment = (int) (Math.sqrt(MinecraftServerChunkPlayerCache) * 16) - 20; //private int increment = 380;
- private static boolean incrementSwitch = false;
+ public static String doneText = null;
+ public static String preparingText = null;
+ public static String preparingLevel = null;
- private static ProcessBuilder minecraft = null;
- private static String javaLine = null;
- private static final String defaultJavaLine =
+ public static String level_0 = null; // the world
+ public static String level_1 = null; // the nether
+ public static String level_2 = null; // the end
+ public static String level_3 = null; // future worlds
+ public static String level_4 = null;
+ public static String level_5 = null;
+ public static String level_6 = null;
+ public static String level_7 = null;
+ public static String level_8 = null;
+ public static String level_9 = null;
+
+ public static ProcessBuilder minecraft = null;
+ public static String javaLine = null;
+ public static final String defaultJavaLine =
"java -Djava.awt.headless=true -Djline.terminal=jline.UnsupportedTerminal -Duser.language=en"
+ " -Xms1024m -Xmx1024m -Xincgc -jar minecraft_server.jar nogui";
- private static String serverPath = null;
- private static String worldPath = null;
- private static String worldName = null;
- private static String doneText = null;
- private static String preparingText = null;
- private static String preparingLevel = null;
+ public static String serverPath = null;
+ public static String worldPath = null;
+ public static String worldName = null;
- private static String level_0 = null; // the world
- private static String level_1 = null; // the nether
- private static String level_2 = null; // the end
- private static String level_3 = null; // future worlds
- private static String level_4 = null;
- private static String level_5 = null;
- private static String level_6 = null;
- private static String level_7 = null;
- private static String level_8 = null;
- private static String level_9 = null;
-
- private int xRange = 0;
- private int zRange = 0;
- private Integer xOffset = null;
- private Integer zOffset = null;
public static boolean verbose = false;
- private boolean alternate = false;
- private static boolean dontWait = false;
- private static boolean waitSave = false;
- private static boolean ignoreWarnings = false;
- private static LongTag randomSeed = null;
- private static DateFormat dateFormat = new SimpleDateFormat( // Lets get a nice Date format for display
+ public static boolean dontWait = false;
+ public static boolean waitSave = false;
+ public static boolean ignoreWarnings = false;
+ public static Long randomSeed = (long) 0;
+
+ public static DateFormat dateFormat = new SimpleDateFormat( // Lets get a nice Date format for display
"EEEE, MMMM d, yyyy 'at' h:mm a zzzz", Locale.ENGLISH);
- private static Date date = null; // date stuff
+ public static Date date = null; // date stuff
public static Long MLG_Last_Modified_Long = 0L;
public static final Class> cls = Main.class;
@@ -126,6 +108,8 @@ public class Main {
public static int inf_loop_protect_BuildID = 0;
public static boolean flag_downloadedBuildID = false;
+ public static String MC_Server_Version = "";
+
public static ArrayList timeStamps = new ArrayList();
public static final String MLG_JarFile = "MinecraftLandGenerator.jar";
@@ -136,19 +120,31 @@ public class Main {
public static final String github_MLG_BuildID_URL = github_URL + buildIDFile;
public static final String github_MLG_jar_URL = github_URL + MLG_JarFile;
+ //
+ //
+ //Private Vars:
+ private static int MinecraftServerChunkPlayerCache = 625; //You see this number when you first launch the server in GUI mode, after the world is loaded, but before anyone has connected.
+ private static int increment = (int) (Math.sqrt(MinecraftServerChunkPlayerCache) * 16) - 20; //private int increment = 380;
+
+ private int xRange = 0;
+ private int zRange = 0;
+ private Integer xOffset = null;
+ private Integer zOffset = null;
+
+ private boolean alternate = false;
+
private static Boolean recheckFlag = false;
private static long startTime = 0L;
+ private static boolean assertsEnabled = false; //debugging use... use java -ea -jar MinecraftlandGenerator.jar...
+
// RCON Stuff (not currently used yet...)
- private static boolean useRCON = false; //use RCON to communicate with server. ***Experimental***
- @SuppressWarnings("unused")
- private static boolean rcon_Enabled = false; //is server is set to use RCON?
+ public static boolean useRCON = false; //use RCON to communicate with server. ***Experimental***
+ public static boolean rcon_Enabled = false; //is server is set to use RCON?
public static String rcon_IPaddress = "0.0.0.0"; //default is 0.0.0.0
public static String rcon_Port = "25575"; //default is 25575, we are just initializing here.
public static String rcon_Password = "test"; //default is "", but a password must be entered.
- private static boolean assertsEnabled = false; //future debugging use...
-
//////////////////////////////////////////////////////////
// REMINDER: Because I always forget/mix up languages: //
// "static" in java means "global" to this class //
@@ -164,6 +160,8 @@ public class Main {
public static void main(String[] args) {
startTime = System.currentTimeMillis();
+ originalArgs = args;
+
// This is really just here for debugging...
// I plan on adding more asserts later, but for now, this will do.
// to enable this, run:
@@ -238,7 +236,7 @@ public class Main {
// Lets get the date, and our BuildID
date = new Date();
- readBuildID();
+ MLG_Update.readBuildID();
// The following displays no matter what happens, so we needed this date stuff to happen first.
@@ -280,7 +278,7 @@ public class Main {
if (args[0].equalsIgnoreCase("-version") || args[0].equalsIgnoreCase("-help")
|| args[0].equals("/?")) {
- showHelp(true);
+ MLG_Readme_and_HelpInfo.showHelp(true);
return;
}
@@ -294,7 +292,8 @@ public class Main {
if (args.length == 2) {
if (args[1].equalsIgnoreCase("download")) {
- boolean fileSuccess = downloadFile(github_MLG_Conf_URL, testing);
+ boolean fileSuccess =
+ MLG_DownloadFile.downloadFile(github_MLG_Conf_URL, testing);
if (fileSuccess) {
out(MinecraftLandGeneratorConf + " file downloaded.");
return;
@@ -302,35 +301,35 @@ public class Main {
}
}
- saveConf(true); //new conf file
+ MLG_FileWrite.saveConf(true); //new conf file
return;
} else if (args[0].equalsIgnoreCase("-ps") || args[0].equalsIgnoreCase("-printspawn")) {
// okay, sorry, this is an ugly hack, but it's just a last-minute feature.
- printSpawn();
- waitTenSec(false);
+ MLG_Misc.printSpawn();
+ MLG_Time.waitTenSec(false);
return;
} else if (args[0].equalsIgnoreCase("-build")) {
- buildID(false);
+ MLG_Update.buildID(false);
return;
} else if (args[0].equalsIgnoreCase("-update")) {
- updateMLG();
- waitTenSec(false);
+ MLG_Update.updateMLG();
+ MLG_Time.waitTenSec(false);
return;
} else if (args[0].equalsIgnoreCase("-readme")) {
if (args.length == 2) {
- readMe(args[1]);
+ MLG_Readme_and_HelpInfo.readMe(args[1]);
} else {
- readMe(null);
+ MLG_Readme_and_HelpInfo.readMe(null);
}
return;
} else if (args[0].equalsIgnoreCase("-downloadfile")) {
if (args.length == 2) {
- downloadFile(args[1], true);
+ MLG_DownloadFile.downloadFile(args[1], true);
} else {
out("No File to Download!");
- waitTenSec(false);
+ MLG_Time.waitTenSec(false);
}
return;
@@ -343,7 +342,7 @@ public class Main {
try {
File config = new File(args[1]);
try {
- origMD5 = fileMD5(config.toString());
+ origMD5 = MLG_MD5.fileMD5(config.toString());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
@@ -353,14 +352,14 @@ public class Main {
if (line.contains("###RECHECK###")) {
recheckFlag = !recheckFlag;
} else {
- downloadFile(line, true);
+ MLG_DownloadFile.downloadFile(line, true);
}
}
in.close();
if (recheckFlag == true) {
try {
- recheckMD5 = fileMD5(config.toString());
+ recheckMD5 = MLG_MD5.fileMD5(config.toString());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
@@ -372,7 +371,7 @@ public class Main {
if (line_recheck.contains("###RECHECK###")) {
recheckFlag = !recheckFlag;
} else {
- downloadFile(line_recheck, true);
+ MLG_DownloadFile.downloadFile(line_recheck, true);
}
}
in_recheck.close();
@@ -382,26 +381,26 @@ public class Main {
} catch (FileNotFoundException ex) {
System.err.println(args[1] + " - File not found");
- waitTenSec(false);
+ MLG_Time.waitTenSec(false);
return;
} catch (IOException ex) {
System.err.println(args[1] + " - Could not read file.");
- waitTenSec(false);
+ MLG_Time.waitTenSec(false);
return;
}
} else {
out("No File with links!");
- waitTenSec(false);
+ MLG_Time.waitTenSec(false);
}
return;
} else if (args.length == 1) {
out("For help, use java -jar " + MLGFileNameShort + " -help");
- waitTenSec(false);
+ MLG_Time.waitTenSec(false);
return;
}
- readConf();
+ MLG_FileRead.readConf();
boolean oldConf = false; // This next section checks to see if we have a old configuration file (or none!)
@@ -433,9 +432,9 @@ public class Main {
if (oldConf) {
err("Old Version of " + MinecraftLandGeneratorConf + " found. Updating...");
- saveConf(false); //old conf
+ MLG_FileWrite.saveConf(false); //old conf
- waitTenSec(false);
+ MLG_Time.waitTenSec(false);
return;
}
@@ -466,7 +465,6 @@ public class Main {
} else if (nextSwitch.startsWith("-i")) {
increment = Integer.parseInt(args[i + 2].substring(2));
- incrementSwitch = true;
out("Notice: Non-Default Increment: " + increment);
} else if (nextSwitch.startsWith("-w")) {
@@ -495,7 +493,7 @@ public class Main {
out("Notice: Z Offset: " + zOffset);
if (nextSwitch.startsWith("-y")) {
out("Notice: MLG now uses Z instead of Y. Please use the -z switch instead");
- waitTenSec(false);
+ MLG_Time.waitTenSec(false);
}
} else {
@@ -508,7 +506,7 @@ public class Main {
return;
}
- verifyWorld();
+ MLG_WorldVerify.verifyWorld();
{
File backupLevel = new File(worldPath + fileSeparator + "level_backup.dat");
@@ -516,7 +514,10 @@ public class Main {
err("There is a level_backup.dat file left over from a previous attempt that failed. You should go determine whether to keep the current level.dat"
+ " or restore the backup.");
err("You most likely will want to restore the backup!");
- waitTenSec(false);
+ MLG_Time.waitTenSec(false);
+
+ //TODO: use resume data
+
return;
}
}
@@ -533,7 +534,7 @@ public class Main {
// prepare our two ProcessBuilders
// minecraft = new ProcessBuilder(javaLine, "-Xms1024m", "-Xmx1024m", "-jar", jarFile, "nogui");
- minecraft = new ProcessBuilder(javaLine.split("\\s")); // is this always going to work? i don't know.
+ minecraft = new ProcessBuilder(javaLine.split("\\s")); // is this always going to work? i don't know. (most likely yes)
minecraft.directory(new File(serverPath));
minecraft.redirectErrorStream(true);
@@ -542,12 +543,18 @@ public class Main {
long generationStartTimeTracking = System.currentTimeMillis(); //Start of time remaining calculations.
- runMinecraft(alternate);
+ MLG_Server.runMinecraft(alternate);
if ((xRange == 0) & (zRange == 0)) { //If the server is launched with an X and a Z of zero, then we just shutdown MLG after the initial launch.
return;
}
+ MLG_FileWrite.AppendTxtFile(
+ worldPath + fileSeparator + "MinecraftLandGenerator.log",
+ "# " + PROG_NAME + " " + VERSION + " - " + MLG_SelfAware.JVMinfo() + newLine
+ + "# " + MC_Server_Version + newLine + "# Started: "
+ + dateFormat.format(generationStartTimeTracking) + newLine);
+
xRange = (int) (Math.ceil(((double) xRange) / ((double) 16))) * 16; //say xRange was entered as 1000. this changes it to be 1008, a multiple of 16. (the size of a chunk)
zRange = (int) (Math.ceil(((double) zRange) / ((double) 16))) * 16; //say zRange was entered as 2000. there is no change, as it already is a multiple of 16.
@@ -557,21 +564,24 @@ public class Main {
File backupLevel = new File(worldPath + fileSeparator + "level_backup.dat");
out("Backing up level.dat to level_backup.dat.");
- copyFile(serverLevel, backupLevel);
+ MLG_Misc.copyFile(serverLevel, backupLevel);
out("");
- Integer[] spawn = getSpawn(serverLevel);
- out("Spawn point detected: [X,Y,Z] [" + spawn[0] + ", " + spawn[1] + ", " + spawn[2]
- + "]");
+ Coordinates spawn = MLG_SpawnPoint.getSpawn(serverLevel);
+ out("Spawn point detected: [X,Y,Z] " + spawn);
+
+ MLG_FileWrite.AppendTxtFile(worldPath + fileSeparator + "MinecraftLandGenerator.log",
+ "# Seed: " + randomSeed + newLine + "# Spawn: " + spawn.toString() + newLine);
+
{
boolean overridden = false;
if (xOffset == null) {
- xOffset = spawn[0];
+ xOffset = spawn.getX();
} else {
overridden = true;
}
if (zOffset == null) {
- zOffset = spawn[2];
+ zOffset = spawn.getZ();
} else {
overridden = true;
}
@@ -582,70 +592,22 @@ public class Main {
}
out("");
- // new code to optimize the locations
- Integer incrementX, incrementZ;
- Double blah;
double xLoops, zLoops;
- //TODO: add code to check for user input for increment, and use that instead! (this should take priority)
-
- //TODO: have main loop make an arraylist of spawnpoints
+ // have main loop make an arraylist of spawnpoints
// read from a file if MLG has run before on this world. save to arraylist
// remove existing points from new list.
// run mlg on remaining list of spawn points.
// X
- blah = ((double) xRange / (double) increment); //How many loops do we need?
- xLoops = Math.ceil(blah); //round up to find out!
- blah = Math.floor(xRange / xLoops); //optimal distance calculations here
- incrementX = blah.intValue(); //save to an int
- blah = Math.floor(xRange / Math.ceil((xRange / ((double) increment + 20))));
- if (blah < increment) { //should we use 380 or 400 as our original increment? This decides it.
- incrementX = blah.intValue();
- }
- if (blah.isInfinite()) {
- incrementX = 0; // An Infinity error. this should never be less than (increment/2)!
- } else if (incrementX < (increment / 2)) {
- incrementX = 0; // Should never happen except for the Infinity error
- } else if (incrementX > increment) {
- incrementX = increment; // Should never happen. Just in case!
- }
+ xLoops = ((double) xRange / (double) increment); //How many loops do we need?
+ xLoops = Math.ceil(xLoops); //round up to find out!
// Z
- blah = ((double) zRange / (double) increment); //How many loops do we need?
- zLoops = Math.ceil(blah); //round up to find out!
- blah = Math.floor(zRange / zLoops); //optimal distance calculations here
- incrementZ = blah.intValue(); //save to an int
- blah = Math.floor(zRange / Math.ceil((zRange / ((double) increment + 20))));
- if (blah < increment) { //should we use 380 or 400 as our original increment? This decides it.
- incrementZ = blah.intValue();
- }
- if (blah.isInfinite()) {
- incrementZ = 0; // An Infinity error. this should never be less than (increment/2)!
- } else if (incrementZ < (increment / 2)) {
- incrementZ = 0; // Should never happen except for the Infinity error
- } else if (incrementZ > increment) {
- incrementZ = increment; // Should never happen. Just in case!
- }
+ zLoops = ((double) zRange / (double) increment); //How many loops do we need?
+ zLoops = Math.ceil(zLoops); //round up to find out!
- blah = null; // I'm done with this temporary variable now. I used it to make my code simplier,
- // and so I wouldn't need to constantly use casting
- // (as java will do it if one of the numbers is already a double)
-
- if (incrementSwitch) { //user input takes priority over any calculations we make!
- incrementX = increment;
- incrementZ = increment;
- }
-
- if (verbose) {
- if (incrementX != increment) {
- out("Optimized X increments from: " + increment + " to: " + incrementX);
- }
- if (incrementZ != increment) {
- out("Optimized Z increments from: " + increment + " to: " + incrementZ);
- }
- }
- // end new code for location optimizations
+ out("Calculating Spawn Points...");
int totalIterations = (int) (xLoops * zLoops);
int currentIteration = 0;
@@ -657,8 +619,10 @@ public class Main {
Long timeTracking = 0L;
- for (int currentX = (((0 - xRange) / 2) + (incrementX / 2)); currentX <= (xRange / 2); currentX +=
- incrementX) {
+ ArrayList launchList = new ArrayList(totalIterations);
+
+ for (int currentX = (int) ((Math.ceil((((0 - xRange) / 2) / increment))) * increment); currentX <= (xRange / 2); currentX +=
+ increment) {
curXloops++;
if (curXloops == 1) {
currentX = (((0 - xRange) / 2) + (increment / 2) + 16);
@@ -666,8 +630,9 @@ public class Main {
currentX = (xRange / 2) - (increment / 2);
}
- for (int currentZ = (((0 - zRange) / 2) + (incrementZ / 2)); currentZ <= (zRange / 2); currentZ +=
- incrementZ) {
+ for (int currentZ =
+ (int) ((Math.ceil((((0 - zRange) / 2) / increment))) * increment); currentZ <= (zRange / 2); currentZ +=
+ increment) {
currentIteration++;
curZloops++;
@@ -677,932 +642,111 @@ public class Main {
currentZ = (zRange / 2) - (increment / 2);
}
- String curX = Integer.toString(currentX + xOffset);
- //String curY = "64"; //Y is always set to 64
- String curZ = Integer.toString(currentZ + zOffset);
- String percentDone =
- Double.toString(((double) currentIteration / (double) totalIterations) * 100);
- int percentIndex =
- ((percentDone.indexOf(".") + 3) > percentDone.length()) ? percentDone
- .length() : (percentDone.indexOf(".") + 3); //fix index on numbers like 12.3
- percentDone =
- percentDone.substring(0,
- (percentDone.indexOf(".") == -1 ? percentDone.length()
- : percentIndex)); //Trim output, unless whole number
-
- out("Setting spawn to (X,Y,Z): [" + curX + ", 64, " + curZ + "] ("
- + currentIteration + "/" + totalIterations + ") " + percentDone
- + "% Done"); // Time Remaining estimate
-
- if (testing) {
- outD("X:" + curXloops + ", Z:" + curZloops);
- }
-
- timeTracking = System.currentTimeMillis();
-
- //NEW CODE:
- differenceTime =
- (timeTracking - generationStartTimeTracking) / (currentIteration + 1); // Updated. we now count all runs, instead of the last 4.
- differenceTime *= 1 + (totalIterations - currentIteration); // this should provide a more accurate result.
- out("Estimated time remaining: " + displayTime(differenceTime)); // I've noticed it gets pretty accurate after about 8 launches!
-
- // Set the spawn point
- setSpawn(serverLevel, currentX + xOffset, 64, currentZ + zOffset);
-
- // Launch the server
- runMinecraft(alternate);
- out("");
+ // add coords to arraylist here
+ Coordinates tempCoords =
+ new Coordinates(currentX + xOffset, 64, currentZ + zOffset);
+ launchList.add(tempCoords);
if (curZloops == 1) {
- currentZ = (((0 - zRange) / 2) + (incrementZ / 2));
+ currentZ =
+ (int) ((Math.ceil((((0 - zRange) / 2) / increment))) * increment);
}
}
curZloops = 0;
if (curXloops == 1) {
- currentX = (((0 - xRange) / 2) + (incrementX / 2));
+ currentX = (int) ((Math.ceil((((0 - xRange) / 2) / increment))) * increment);
}
}
- out("Finished generating chunks.");
- copyFile(backupLevel, serverLevel);
+ //get existing list, and remove this list from launchList
+ ArrayList removeList =
+ MLG_FileRead.readArrayListCoordLog(worldPath + fileSeparator
+ + "MinecraftLandGenerator.log");
+
+ if (!(removeList.isEmpty())) {
+ MLG_ArrayList.arrayListRemove(launchList, removeList);
+ }
+
+ int numRemoved = totalIterations - launchList.size();
+ if (numRemoved > 0) {
+ out("Reduced number of server launches by: " + numRemoved);
+ }
+
+ removeList.clear(); // we are done with this now.
+
+ System.gc(); //run the garbage collector - hopefully free up some memory!
+
+ currentIteration = 0;
+ totalIterations = launchList.size();
+ Coordinates xyz = null;
+ Iterator coordArrayIterator = launchList.iterator();
+ while (coordArrayIterator.hasNext()) {
+ currentIteration++;
+ xyz = coordArrayIterator.next();
+
+ //////// Start server launch code
+
+ String percentDone =
+ Double.toString(((double) currentIteration / (double) totalIterations) * 100);
+ int percentIndex =
+ ((percentDone.indexOf(".") + 3) > percentDone.length()) ? percentDone
+ .length() : (percentDone.indexOf(".") + 3); //fix index on numbers like 12.3
+ percentDone =
+ percentDone.substring(0,
+ (percentDone.indexOf(".") == -1 ? percentDone.length()
+ : percentIndex)); //Trim output, unless whole number
+
+ out("Setting spawn to [X,Y,Z]: " + xyz + " (" + currentIteration + " of "
+ + totalIterations + ") " + percentDone + "% Done"); // Time Remaining estimate
+
+ timeTracking = System.currentTimeMillis();
+
+ //NEW CODE:
+ differenceTime =
+ (timeTracking - generationStartTimeTracking) / (currentIteration + 1); // Updated. we now count all runs, instead of the last 4.
+ differenceTime *= 1 + (totalIterations - currentIteration); // this should provide a more accurate result.
+ out("Estimated time remaining: " + MLG_Time.displayTime(differenceTime)); // I've noticed it gets pretty accurate after about 8 launches!
+
+ // Set the spawn point
+ MLG_SpawnPoint.setSpawn(serverLevel, xyz);
+
+ // Launch the server
+ boolean serverSuccess = false;
+
+ serverSuccess = MLG_Server.runMinecraft(alternate);
+ out("");
+
+ //////// End server launch code
+
+ if (serverSuccess) {
+ // Write the current Coordinates to log file!
+ MLG_FileWrite.AppendTxtFile(worldPath + fileSeparator
+ + "MinecraftLandGenerator.log", xyz.toString() + newLine);
+ } else {
+ System.exit(1); // we got a warning or severe error
+ }
+
+ }
+
+ if (currentIteration == 0) {
+ out("Nothing to generate!");
+ } else {
+ out("Finished generating chunks.");
+ }
+
+ MLG_Misc.copyFile(backupLevel, serverLevel);
backupLevel.delete();
out("Restored original level.dat.");
//finishedImage(); //disabled, because I didn't care for it - it didn't flow well with MLG
- out("Generation complete in: " + displayTime(startTime, System.currentTimeMillis()));
- waitTenSec(false);
+ out("Generation complete in: "
+ + MLG_Time.displayTime(startTime, System.currentTimeMillis()));
+ MLG_Time.waitTenSec(false);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
- //TODO: update this
- /**
- * @param level
- * @return
- * @throws IOException
- * @author Corrodias
- */
- protected static Integer[] getSpawn(File level) throws IOException {
- try {
- NBTInputStream input = new NBTInputStream(new FileInputStream(level));
- CompoundTag originalTopLevelTag = (CompoundTag) input.readTag();
- input.close();
-
- Map originalData =
- ((CompoundTag) originalTopLevelTag.getValue().get("Data")).getValue();
- // This is our map of data. It is an unmodifiable map, for some
- // reason, so we have to make a copy.
- Map newData = new LinkedHashMap(originalData);
- // .get() a couple of values, just to make sure we're dealing with a
- // valid level file, here. Good for debugging, too.
- IntTag spawnX = (IntTag) newData.get("SpawnX");
- IntTag spawnY = (IntTag) newData.get("SpawnY");
- IntTag spawnZ = (IntTag) newData.get("SpawnZ");
-
- randomSeed = (LongTag) newData.get("RandomSeed");
- out("Seed: " + randomSeed.getValue()); // lets output the seed, cause why not?
-
- Integer[] ret =
- new Integer[] { spawnX.getValue(), spawnY.getValue(), spawnZ.getValue() };
- return ret;
- } catch (ClassCastException ex) {
- throw new IOException("Invalid level format.");
- } catch (NullPointerException ex) {
- throw new IOException("Invalid level format.");
- }
- }
-
- /**
- * Changes the spawn point in the given Alpha/Beta level to the given coordinates.
- * Note that, in Minecraft levels, the Y coordinate is height.
- * (We picture maps from above, but the game was made from a different perspective)
- *
- * @param level
- * the level file to change the spawn point in
- * @param x
- * the new X value
- * @param y
- * the new Y value
- * @param z
- * the new Z value
- * @throws IOException
- * if there are any problems reading/writing the file
- * @author Corrodias
- */
- protected static void setSpawn(File level, Integer x, Integer y, Integer z) throws IOException {
- try {
- NBTInputStream input = new NBTInputStream(new FileInputStream(level));
- CompoundTag originalTopLevelTag = (CompoundTag) input.readTag();
- input.close();
-
- //@formatter:off
-
- //Note: The Following Information is Old (from 2010), compared to the Data inside a current "level.dat".
- //However, What we look at (SpawnX,Y,Z and RandomSeed) have not changed.
-
- /*
- * Structure:
- *
- *TAG_Compound("Data"): World data.
- * * TAG_Long("Time"): Stores the current "time of day" in ticks. There are 20 ticks per real-life second, and 24000 ticks per Minecraft day, making the day length 20 minutes. 0 appears to be sunrise, 12000 sunset and 24000 sunrise again.
- * * TAG_Long("LastPlayed"): Stores the Unix time stamp (in milliseconds) when the player saved the game.
- * * TAG_Compound("Player"): Player entity information. See Entity Format and Mob Entity Format for details. Has additional elements:
- * o TAG_List("Inventory"): Each TAG_Compound in this list defines an item the player is carrying, holding, or wearing as armor.
- * + TAG_Compound: Inventory item data
- * # TAG_Short("id"): Item or Block ID.
- * # TAG_Short("Damage"): The amount of wear each item has suffered. 0 means undamaged. When the Damage exceeds the item's durability, it breaks and disappears. Only tools and armor accumulate damage normally.
- * # TAG_Byte("Count"): Number of items stacked in this inventory slot. Any item can be stacked, including tools, armor, and vehicles. Range is 1-255. Values above 127 are not displayed in-game.
- * # TAG_Byte("Slot"): Indicates which inventory slot this item is in.
- * o TAG_Int("Score"): Current score, doesn't appear to be implemented yet. Always 0.
- * * TAG_Int("SpawnX"): X coordinate of the player's spawn position. Default is 0.
- * * TAG_Int("SpawnY"): Y coordinate of the player's spawn position. Default is 64.
- * * TAG_Int("SpawnZ"): Z coordinate of the player's spawn position. Default is 0.
- * * TAG_Byte("SnowCovered"): 1 enables, 0 disables, see Winter Mode
- * * TAG_Long("SizeOnDisk"): Estimated size of the entire world in bytes.
- * * TAG_Long("RandomSeed"): Random number providing the Random Seed for the terrain.
- *
- */
-
- //@formatter:on
-
- Map originalData =
- ((CompoundTag) originalTopLevelTag.getValue().get("Data")).getValue();
- // This is our map of data. It is an unmodifiable map, for some reason, so we have to make a copy.
- Map newData = new LinkedHashMap(originalData);
- // .get() a couple of values, just to make sure we're dealing with a valid level file, here. Good for debugging, too.
-
- @SuppressWarnings("unused")
- IntTag spawnX = (IntTag) newData.get("SpawnX"); // we never use these... Its only here for potential debugging.
- @SuppressWarnings("unused")
- IntTag spawnY = (IntTag) newData.get("SpawnY"); // but whatever... so I (Morlok8k) suppressed these warnings.
- @SuppressWarnings("unused")
- IntTag spawnZ = (IntTag) newData.get("SpawnZ"); // I don't want to remove existing code, either by myself (Morlok8k) or Corrodias
-
- newData.put("SpawnX", new IntTag("SpawnX", x));
- newData.put("SpawnY", new IntTag("SpawnY", y));
- newData.put("SpawnZ", new IntTag("SpawnZ", z));
-
- // Again, we can't modify the data map in the old Tag, so we have to make a new one.
- CompoundTag newDataTag = new CompoundTag("Data", newData);
- Map newTopLevelMap = new HashMap(1);
- newTopLevelMap.put("Data", newDataTag);
- CompoundTag newTopLevelTag = new CompoundTag("", newTopLevelMap);
-
- NBTOutputStream output = new NBTOutputStream(new FileOutputStream(level));
- output.writeTag(newTopLevelTag);
- output.close();
- } catch (ClassCastException ex) {
- throw new IOException("Invalid level format.");
- } catch (NullPointerException ex) {
- throw new IOException("Invalid level format.");
- }
- }
-
- /**
- * Starts the process in the given ProcessBuilder, monitors its output for a "[INFO] Done!" message, and sends it a "stop\r\n" message. One message is printed to the console before launching and
- * one is printed to the console when the Done! message is detected. If "verbose" is true, the process's output will also be printed to the console.
- *
- * @param minecraft
- *
- * @throws IOException
- * @author Corrodias
- */
- protected static void runMinecraft(boolean alternate) throws IOException {
- if (verbose) {
- out("Starting server.");
- }
-
- boolean warning = false;
- boolean warningsWeCanIgnore = false;
- final boolean ignoreWarningsOriginal = ignoreWarnings;
-
- // monitor output and print to console where required.
- // STOP the server when it's done.
-
- if (alternate) { // Alternate - a replication (slightly stripped down) of MLG 1.3.0's code. simplest code possible.
- out("Alternate Launch");
- Process process = minecraft.start();
-
- byte[] stop = { 's', 't', 'o', 'p', '\r', '\n' };
-
- // monitor output and print to console where required.
- // STOP the server when it's done.
- BufferedReader pOut =
- new BufferedReader(new InputStreamReader(process.getInputStream()));
- String line;
- while ((line = pOut.readLine()) != null) {
-
- line = line.trim(); //Trim spaces off the beginning and end, if any.
-
- System.out.println(line);
- if (line.contains(doneText)) { // EDITED By Morlok8k for Minecraft 1.3+ Beta
- OutputStream outputStream = process.getOutputStream();
-
- out("Stopping server... (Please Wait...)");
- outputStream.write(stop);
- outputStream.flush();
-
- }
- }
- // readLine() returns null when the process exits
-
- } else { // start minecraft server normally!
- Process process = minecraft.start();
- if (verbose) {
- out("Started Server.");
- }
- BufferedReader pOut =
- new BufferedReader(new InputStreamReader(process.getInputStream()));
- if (verbose) {
- out("Accessing Server Output...");
- }
-
- String line = null;
- String shortLine = null;
- String outTmp = "";
- String outTmp2 = null;
-
- byte[] stop = { 's', 't', 'o', 'p', '\r', '\n' }; // Moved here, so this code wont run every loop, thus Faster!
- // and no, i can't use a string here!
-
- byte[] saveAll = { 's', 'a', 'v', 'e', '-', 'a', 'l', 'l', '\r', '\n' };
-
- boolean prepTextFirst = true;
-
- OutputStream outputStream = process.getOutputStream(); // moved here to remove some redundancy
-
- //TODO: add converting section:
- /*
- 2012-02-29 03:50:28 [INFO] Converting map!
- Scanning folders...
- Total conversion count is 9
- 2012-02-29 03:50:29 [INFO] Converting... 8%
- 2012-02-29 03:50:30 [INFO] Converting... 9%
- 2012-02-29 03:50:31 [INFO] Converting... 10%
- 2012-02-29 03:50:32 [INFO] Converting... 12%
- 2012-02-29 03:50:33 [INFO] Converting... 13%
- */
-
- boolean convertedMapFormattingFlag = false; // This allows MLG to track if we converted a map to a new format (such as Chunk-file -> McRegion, or McRegion -> Anvil)
- // just so it gets a line ending after the % output finishes
- while ((line = pOut.readLine()) != null) {
-
- int posBracket = line.lastIndexOf("]");
- if (posBracket != -1) {
- shortLine = line.substring(posBracket + 2);
- } else {
- shortLine = line;
- }
-
- line = line.trim();
-
- if (verbose) {
- outS(shortLine);
- } else if (line.toLowerCase().contains("saving")) {
- outS(shortLine);
- } else if (line.contains(preparingText) || line.contains("Converting...")) {
- if (line.contains("Converting...")) {
- convertedMapFormattingFlag = true;
- }
- outTmp2 = line.substring(line.length() - 3, line.length());
- outTmp2 = outTmp2.trim(); //we are removing extra spaces here
- if (outTmp.equals(outTmp2)) {
- //instead of printing the same number, we add another dot
- outP(".");
- } else {
- outTmp = outTmp2;
-
- if (prepTextFirst) {
- outP(MLG + outTmp + "...");
- prepTextFirst = false;
- } else {
- outP(" " + outTmp + "...");
- }
-
- }
-
- } else if (line.contains(preparingLevel)) {
- prepTextFirst = true;
-
- if (convertedMapFormattingFlag == true) {
- outP(newLine);
- convertedMapFormattingFlag = false;
- }
-
- if (line.contains("level 0")) { // "Preparing start region for level 0"
- outP(MLG + worldName + ": " + level_0 + ":" + newLine);
- } else if (line.contains("level 1")) { // "Preparing start region for level 1"
- outP(newLine + MLG + worldName + ": " + level_1 + ":" + newLine);
- } else if (line.contains("level 2")) { // "Preparing start region for level 2"
- outP(newLine + MLG + worldName + ": " + level_2 + ":" + newLine);
- } else if (line.contains("level 3")) { // "Preparing start region for level 3"
- outP(newLine + MLG + worldName + ": " + level_3 + ":" + newLine);
- } else if (line.contains("level 4")) { // "Preparing start region for level 4"
- outP(newLine + MLG + worldName + ": " + level_4 + ":" + newLine);
- } else if (line.contains("level 5")) { // "Preparing start region for level 5"
- outP(newLine + MLG + worldName + ": " + level_5 + ":" + newLine);
- } else if (line.contains("level 6")) { // "Preparing start region for level 6"
- outP(newLine + MLG + worldName + ": " + level_6 + ":" + newLine);
- } else if (line.contains("level 7")) { // "Preparing start region for level 7"
- outP(newLine + MLG + worldName + ": " + level_7 + ":" + newLine);
- } else if (line.contains("level 8")) { // "Preparing start region for level 8"
- outP(newLine + MLG + worldName + ": " + level_8 + ":" + newLine);
- } else if (line.contains("level 9")) { // "Preparing start region for level 9"
- outP(newLine + MLG + worldName + ": " + level_9 + ":" + newLine);
- } else {
- outP(newLine + MLG + shortLine);
- }
- } else if (line.contains("server version") || line.contains("Converting map!")) { //TODO: add to .conf
- outS(shortLine);
- //TODO: if server version, save string to some variable, for use in arraylist save file.
- }
-
- if (line.contains(doneText)) { // now this is configurable!
-
- outP(newLine);
- outS(line.substring(line.lastIndexOf("]") + 2, line.indexOf("!")));
- if (waitSave) {
- out("Waiting 30 seconds to save...");
-
- int count = 1;
- while (count <= 30) {
- outP(".");
-
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- count += 1;
- }
- out("");
- }
- out("Saving server data...");
- outputStream.write(saveAll);
- outputStream.flush();
-
- out("Stopping server... (Please Wait...)");
- // OutputStream outputStream = process.getOutputStream();
- outputStream.write(stop);
- outputStream.flush();
- // outputStream.close();
-
- if (waitSave) {
- out("Waiting 10 seconds to save.");
- int count = 1;
- while (count <= 10) {
- outP(".");
-
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- count += 1;
- }
- out("");
- }
- }
-
- //Here we want to ignore the most common warning: "Can't keep up!"
- if (line.contains("Can't keep up!")) { //TODO: add to .conf
- warningsWeCanIgnore = true; //[WARNING] Can't keep up! Did the system time change, or is the server overloaded?
- ignoreWarnings = true;
- } else if (line.contains("[WARNING] To start the server with more ram")) {
- if (verbose == false) { // If verbose is true, we already displayed it.
- outS(line);
- }
- warningsWeCanIgnore = true; //we can safely ignore this...
- ignoreWarnings = true;
- } else if (line.contains("Error occurred during initialization of VM")
- || line.contains("Could not reserve enough space for object heap")) {
- if (verbose == false) { // If verbose is true, we already displayed it.
- outP("[Java Error] " + line);
- }
- warning = true;
- }
-
- if (ignoreWarnings == false) {
- if (line.contains("[WARNING]")) { // If we have a warning, stop...
- out("");
- out("Warning found: Stopping " + PROG_NAME);
- if (verbose == false) { // If verbose is true, we already displayed it.
- outS(line);
- }
- out("");
- out("Forcing Save...");
- outputStream.write(saveAll);
- outputStream.flush();
- // OutputStream outputStream = process.getOutputStream();
- outputStream.write(stop); // if the warning was a fail to bind to port, we may need to write stop twice!
- outputStream.flush();
- outputStream.write(stop);
- outputStream.flush();
- // outputStream.close();
- warning = true;
- // System.exit(1);
- }
- if (line.contains("[SEVERE]")) { // If we have a severe error, stop...
- out("");
- out("Severe error found: Stopping server.");
- if (verbose == false) { // If verbose is true, we already displayed it.
- outS(line);
- }
- out("");
- out("Forcing Save...");
- outputStream.write(saveAll);
- outputStream.flush();
- // OutputStream outputStream = process.getOutputStream();
- outputStream.write(stop);
- outputStream.flush();
- outputStream.write(stop); // sometimes we need to do stop twice...
- outputStream.flush();
- // outputStream.close();
- warning = true;
- // System.exit(1);
- // Quit!
- }
- }
-
- if (warningsWeCanIgnore) {
- ignoreWarnings = ignoreWarningsOriginal;
- }
- }
-
- if (warning == true) { // in 1.4.4 we had a issue. tried to write stop twice, but we had closed the stream already. this, and other lines should fix this.
- outputStream.flush();
- outputStream.close();
- System.exit(1);
- }
-
- outputStream.close();
- }
-
- // readLine() returns null when the process exits
- }
-
- /**
- * I'd love to use nio, but it requires Java 7.
- * I could use Apache Commons, but i don't want to include a library for one little thing.
- * Copies src file to dst file.
- * If the dst file does not exist, it is created
- *
- * @author Corrodias
- * @param src
- * @param dst
- * @throws IOException
- */
- public static void copyFile(File src, File dst) throws IOException {
- InputStream copyIn = new FileInputStream(src);
- OutputStream copyOut = new FileOutputStream(dst);
-
- // Transfer bytes from in to out
- byte[] buf = new byte[1024];
- int len;
- while ((len = copyIn.read(buf)) >= 0) {
- if (len > 0) {
- copyOut.write(buf, 0, len);
- }
- }
- copyIn.close();
- copyOut.flush();
- copyOut.close();
- }
-
- //TODO: add description
- /**
- * @return
- */
- private static boolean printSpawn() {
- // ugh, sorry, this is an ugly hack, but it's a last-minute feature. this is a lot of duplicated code.
- // - Fixed by Morlok8k
-
- readConf();
- verifyWorld();
-
- File level = new File(worldPath + fileSeparator + "level.dat");
- try {
- Integer[] spawn = getSpawn(level);
- out("The current spawn point is: [X,Y,Z] [" + spawn[0] + ", " + spawn[1] + ", "
- + spawn[2] + "]");
- return true;
- } catch (IOException ex) {
- err("Error while reading " + level.getPath());
- return false;
- }
- }
-
- /**
- * Saves a Readme file.
- *
- * @param readmeFile
- * @author Morlok8k
- *
- */
- private static void readMe(String readmeFile) {
-
- MLG_Readme_and_HelpInfo.readMe(readmeFile);
-
- }
-
- /**
- * @author Morlok8k
- * @param URL
- * URL in a String
- * @param Output
- * Displays output if true
- * @return Boolean: true if download was successful, false if download wasn't
- */
- private static boolean downloadFile(String URL, boolean Output) {
- //This exists so I don't need to type "MLG_DownloadFile.downloadFile" every time.
- return MLG_DownloadFile.downloadFile(URL, Output);
- }
-
- /**
- * This is an "undocumented" function to create a BuildID file. It should only be used right after compiling a .jar file
- * The resulting BuildID file is uploaded to github, and also distributed with the program.
- * THE FILE SHOULD ONLY BE MADE FROM SCRATCH AT THE TIME OF PUBLISHING!
- * (Otherwise, the purpose is defeated!)
- *
- * The problem is that when a .jar file is downloaded from the internet, it gets a new date stamp - the time that it was downloaded. Only the original copy that was compiled on the original
- * computer will have the correct time stamp. (or possibly a copy from the original computer)
- *
- * This saves the hash and the timestamp (now known as the BuildID)
- *
- * @author Morlok8k
- */
- private static void buildID(boolean downloadOnly) {
- MLG_Update.buildID(downloadOnly);
- }
-
- /**
- * Gets the BuildID for MLG
- *
- * @author Morlok8k
- *
- */
- private static void readBuildID() {
- MLG_Update.readBuildID();
- }
-
- /**
- * Updates MLG to the Latest Version
- *
- * @author Morlok8k
- *
- */
- private static void updateMLG() {
-
- MLG_Update.updateMLG();
- }
-
- /**
- * This gets the MLG_MD5 of a file
- *
- * @author Morlok8k
- */
- public static String fileMD5(String fileName) throws NoSuchAlgorithmException,
- FileNotFoundException {
- return MLG_MD5.fileMD5(fileName);
- }
-
- /**
- * Displays or returns Help information
- *
- * @param SysOut
- *
- * Set TRUE to display info to System.out. (Returns null)
- * Set FALSE to return info as String.
- * @author Morlok8k
- */
- private static String showHelp(boolean SysOut) {
-
- return MLG_Readme_and_HelpInfo.showHelp(SysOut);
- }
-
- /**
- * .zip file Get Modification Time
- *
- * Takes a string of a path to a .zip file (or .jar), and and returns a Long of the latest "Last Time Modified".
- *
- *
- * Thanks to the following:
- * http://www.java-examples.com/get-modification-time-zip-entry-example
- * http://www.java-examples.com/get-crc-32-checksum-zip-entry-example
- *
- * @param zipFile
- * @param timeBuildID
- * @author Morlok8k
- */
- public static Long ZipGetModificationTime(String zipFile) {
- return MLG_Update.ZipGetModificationTime(zipFile);
- }
-
- /**
- *
- */
- private static void readConf() {
- //TODO: element comment
- //String errorMsg = "";
-
- try {
- File config = new File(MinecraftLandGeneratorConf);
- BufferedReader in = new BufferedReader(new FileReader(config));
- String line = "";
- String property = "";
- String value = "";
-
- while ((line = in.readLine()) != null) {
- int pos = line.indexOf('=');
-
- int end = line.lastIndexOf('#'); // comments, ignored lines
-
- if (end == -1) { // If we have no hash sign, then we read till the end of the line
- end = line.length();
-
- }
- if (end <= (pos + 1)) { // If hash is before the '=', we may have an issue... it should be fine, cause we check for issues next, but lets make sure.
- end = line.length();
- pos = -1;
- }
-
- if (end == 0) { //hash is first char, meaning entire line is a comment
- end = line.length();
- pos = 0;
- }
-
- if (pos != -1) {
- if (line.length() == 0) {
- property = "";
- value = "";
- } else {
- property = line.substring(0, pos).toLowerCase();
- value = line.substring(pos + 1, end);
- }
-
- if (property.equals("serverpath")) {
- serverPath = value;
- } else if (property.equals("java")) {
- javaLine = value;
- } else if (property.equals("done_text")) {
- doneText = value;
- } else if (property.equals("preparing_text")) {
- preparingText = value;
- } else if (property.equals("preparing_level")) {
- preparingLevel = value;
- } else if (property.equals("level-0")) {
- level_0 = value;
- } else if (property.equals("level-1")) {
- level_1 = value;
- } else if (property.equals("level-2")) {
- level_2 = value;
- } else if (property.equals("level-3")) {
- level_3 = value;
- } else if (property.equals("level-4")) {
- level_4 = value;
- } else if (property.equals("level-5")) {
- level_5 = value;
- } else if (property.equals("level-6")) {
- level_6 = value;
- } else if (property.equals("level-7")) {
- level_7 = value;
- } else if (property.equals("level-8")) {
- level_8 = value;
- } else if (property.equals("level-9")) {
- level_9 = value;
- } else if (property.equals("waitsave")) {
- if (value.toLowerCase().equals("true")) {
- waitSave = true;
- } else {
- waitSave = false;
- }
- }
- }
- }
- in.close();
-
- if (testing) {
- outD("Test Output: Reading of Config File ");
- outD(" serverPath: " + serverPath);
- outD(" javaLine: " + javaLine);
- outD(" doneText: " + doneText);
- outD(" preparingText: " + preparingText);
- outD("preparingLevel: " + preparingLevel);
- outD(" level_0: " + level_0);
- outD(" level_1: " + level_1);
- outD(" level_2: " + level_2);
- outD(" level_3: " + level_3);
- outD(" level_4: " + level_4);
- outD(" level_5: " + level_5);
- outD(" level_6: " + level_6);
- outD(" level_7: " + level_7);
- outD(" level_8: " + level_8);
- outD(" level_9: " + level_9);
- outD(" waitSave: " + waitSave);
- }
- } catch (FileNotFoundException ex) {
- out("Could not find "
- + MinecraftLandGeneratorConf
- + ". It is recommended that you run the application with the -conf option to create it.");
- return;
- } catch (IOException ex) {
- err("Could not read " + MinecraftLandGeneratorConf + ".");
- return;
- }
- }
-
- /**
- * Generates a Config File.
- *
- * @param newConf
- * true: Uses Default values. false: uses existing values
- * @author Morlok8k
- */
- private static void saveConf(boolean newConf) {
-
- String jL = null; //javaLine
- String sP = null; //serverPath
-
- if (newConf) {
- jL = defaultJavaLine; // reads the default from a constant, makes it easier!
- sP = "."; //
- } else {
- jL = javaLine; // we read these values from an existing Conf File.
- sP = serverPath; //
- }
-
- String txt = null;
- //@formatter:off
- txt = "#" + PROG_NAME + " Configuration File: Version: " + VERSION + newLine
- + "#Authors: " + AUTHORS + newLine
- + "#Auto-Generated: " + dateFormat.format(date) + newLine
- + newLine
- + "#Line to run server:" + newLine
- + "Java=" + jL // reads the default from a constant, makes it easier!
- + newLine
- + newLine
- + "#Location of server. use \".\" for the same folder as MLG" + newLine
- + "ServerPath=" + sP
- + newLine
- + newLine
- + "#Strings read from the server" + newLine
- + "Done_Text=[INFO] Done" + newLine
- + "Preparing_Text=[INFO] Preparing spawn area:" + newLine
- + "Preparing_Level=[INFO] Preparing start region for" + newLine
- + "Level-0=The Overworld" + newLine
- + "Level-1=The Nether" + newLine
- + "Level-2=The End" + newLine
- + "Level-3=Level 3 (Future Level)" + newLine
- + "Level-4=Level 4 (Future Level)" + newLine
- + "Level-5=Level 5 (Future Level)" + newLine
- + "Level-6=Level 6 (Future Level)" + newLine
- + "Level-7=Level 7 (Future Level)" + newLine
- + "Level-8=Level 8 (Future Level)" + newLine
- + "Level-9=Level 9 (Future Level)" + newLine
- + newLine
- + "#Optional: Wait a few seconds after saving." + newLine + "WaitSave=false";
- //@formatter:on
-
- writeTxtFile(MinecraftLandGeneratorConf, txt);
-
- return;
-
- }
-
- /**
- *
- */
- private static void verifyWorld() {
- //TODO: element comment
-
- // verify that we ended up with a good server path, either from the file or from an argument.
- File file = new File(serverPath);
- if (!file.exists() || !file.isDirectory()) {
- err("The server directory is invalid: " + serverPath);
- return;
- }
-
- try {
- // read the name of the current world from the server.properties file
- BufferedReader props =
- new BufferedReader(new FileReader(new File(serverPath + fileSeparator
- + "server.properties")));
- String line;
- while ((line = props.readLine()) != null) {
- String property = "";
- String value = "";
-
- int pos = line.indexOf('=');
-
- int end = line.lastIndexOf('#'); // comments, ignored lines
-
- if (end == -1) { // If we have no hash sign, then we read till the end of the line
- end = line.length();
-
- }
- if (end <= (pos + 1)) { // If hash is before the '=', we may have an issue... it should be fine, cause we check for issues next, but lets make sure.
- end = line.length();
- pos = -1;
- }
-
- if (end == 0) { //hash is first char, meaning entire line is a comment
- end = line.length();
- pos = 0;
- }
-
- if (pos != -1) {
- if (line.length() == 0) {
- property = "";
- value = "";
- } else {
- property = line.substring(0, pos).toLowerCase();
- value = line.substring(pos + 1);
- }
-
- if (property.equals("level-name")) {
- worldPath = serverPath + fileSeparator + value;
- worldName = value;
- }
- if (useRCON) {
- if (property.equals("enable-rcon")) {
-
- if (value.contains("true")) {
- rcon_Enabled = true;
- out("RCON is set to be Enabled on the server.");
- } else {
- rcon_Enabled = false;
- useRCON = false;
- err("RCON is not Enabled on the server.");
- }
- } else if (property.equals("rcon.password")) {
- rcon_Password = value;
- if (rcon_Password.isEmpty()) {
- useRCON = false;
- err("RCON Needs a password!.");
- }
- out("RCON Password:" + rcon_Password);
- } else if (property.equals("rcon.port")) {
- rcon_Port = value;
- out("RCON Port:" + rcon_Port);
- } else if (property.equals("server-ip")) {
- String IP = value;
- if (IP.isEmpty()) {
- IP = "0.0.0.0";
- }
- rcon_IPaddress = IP;
-
- }
- }
-
- }
- }
-
- } catch (FileNotFoundException ex) {
- err("Could not open " + serverPath + fileSeparator + "server.properties");
- return;
- } catch (IOException ex) {
- Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
- return;
- }
-
- File level = new File(worldPath + fileSeparator + "level.dat");
- if (!level.exists() || !level.isFile()) {
- err("The currently-configured world does not exist. Please launch the server once, first.");
- return;
- }
-
- }
-
- /**
- * @param file
- * @param txt
- */
- public static void writeTxtFile(String file, String txt) {
- //TODO: element comment
-
- /*
- * NOTE: I don't include a generic readTxtFile method, as that code depends on what I'm reading.
- * For things like that I make a special method for it, if its used in more than one place.
- * Like reading the config file.
- */
-
- try {
- File oFile = new File(file);
- BufferedWriter outFile = new BufferedWriter(new FileWriter(oFile));
- outFile.write(txt);
- outFile.newLine();
- outFile.close();
- out(file + " file created.");
- return;
- } catch (IOException ex) {
- err("Could not create " + MinecraftLandGeneratorConf + ".");
- ex.printStackTrace();
- return;
- }
-
- }
-
/**
* Outputs a formatted string to System.out as a line.
*
@@ -1643,7 +787,7 @@ public class Main {
* String to display and format
* @author Morlok8k
*/
- private static void outS(String str) {
+ static void outS(String str) {
System.out.println("[Server] " + str);
}
@@ -1658,100 +802,4 @@ public class Main {
System.out.println(MLG + "[DEBUG] " + str);
}
- /**
- * waits ten seconds. outputs 10%, 20%, etc after each second.
- *
- * @author Morlok8k
- */
- private static void waitTenSec(boolean output) {
-
- if (dontWait) { return; } //Don't wait!
-
- if (output) {
- outP(MLG); //here we wait 10 sec.
- }
-
- int count = 0;
- while (count <= 100) {
- if (output) {
- outP(count + "% ");
- }
-
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- count += 10;
- }
- if (output) {
- outP(newLine);
- }
- return;
-
- }
-
- /**
- * Returns the time in a readable format between two points of time given in Millis.
- *
- * @param startTimeMillis
- * @param endTimeMillis
- * @author Morlok8k
- * @return String of Readable Time
- */
- public static String displayTime(long startTimeMillis, long endTimeMillis) {
-
- long millis = (endTimeMillis - startTimeMillis);
- //I just duplicated displayTime to have a start & end times, because it just made things simpler to code.
- return (displayTime(millis));
- }
-
- /**
- * Returns the time in a readable format given a time in Millis.
- *
- * @param timeMillis
- * @author Morlok8k
- * @return String of Readable Time
- */
- public static String displayTime(long timeMillis) {
-
- long seconds = timeMillis / 1000;
- long minutes = seconds / 60;
- long hours = minutes / 60;
- long days = hours / 24;
- long years = days / 365;
-
- String took =
- (years > 0 ? String.format("%d " + ((years) == 1 ? "Year, " : "Years, "), years)
- : "")
- + (days > 0 ? String.format("%d "
- + ((days % 365) == 1 ? "Day, " : "Days, "), days % 365) : "")
- + (hours > 0 ? String.format("%d "
- + ((hours % 24) == 1 ? "Hour, " : "Hours, "), hours % 24) : "")
- + (minutes > 0 ? String.format("%d "
- + ((minutes % 60) == 1 ? "Minute, " : "Minutes, "), minutes % 60)
- : "")
- + String.format("%d " + ((seconds % 60) == 1 ? "Second" : "Seconds"),
- seconds % 60);
-
- if (!(verbose)) {
- int commaFirst = took.indexOf(",");
- int commaSecond = took.substring((commaFirst + 1), took.length()).indexOf(",");
- int end = (commaFirst + 1 + commaSecond);
-
- if (commaSecond == -1) {
- end = commaFirst;
- }
-
- if (commaFirst == -1) {
- end = took.length();
- }
-
- took = took.substring(0, end);
- }
-
- took.trim();
- return (took);
- }
-
}
diff --git a/src/morlok8k/minecraft/landgenerator/Coordinates.java b/src/morlok8k/minecraft/landgenerator/Coordinates.java
index 63c35b1..e60299a 100644
--- a/src/morlok8k/minecraft/landgenerator/Coordinates.java
+++ b/src/morlok8k/minecraft/landgenerator/Coordinates.java
@@ -10,7 +10,7 @@ package morlok8k.minecraft.landgenerator;
*/
public class Coordinates {
//FYI: int's (Integer's) are good enough for Minecraft. They have a range of -2,147,483,648 to 2,147,483,647
- // Minecraft starts failing around ± 12,550,820 and ends at either ± 30,000,000 or ± 32,000,000 (depending on the version).
+ // Minecraft starts failing around (+/-) 12,550,820 and ends at either (+/-) 30,000,000 or (+/-) 32,000,000 (depending on the version).
// See: http://www.minecraftwiki.net/wiki/Far_Lands for more info.
public int X = 0;
@@ -89,7 +89,7 @@ public class Coordinates {
public static Coordinates parseString(String StringOfCoords) {
//parse out string
- StringOfCoords.trim();
+ StringOfCoords = StringOfCoords.trim();
int x = 0, y = 0, z = 0;
@@ -108,13 +108,13 @@ public class Coordinates {
firstComma = StringOfCoords.indexOf(",");
secComma = StringOfCoords.lastIndexOf(",");
- System.out.println(start + " " + end + " " + firstComma + " " + secComma);
+ //System.out.println(start + " " + end + " " + firstComma + " " + secComma);
sX = StringOfCoords.substring(start + 1, firstComma);
sY = StringOfCoords.substring(firstComma + 1, secComma);
sZ = StringOfCoords.substring(secComma + 1, end);
- System.out.println(sX + " " + sY + " " + sZ);
+ //System.out.println(sX + " " + sY + " " + sZ);
x = Integer.parseInt(sX);
y = Integer.parseInt(sY);
diff --git a/src/morlok8k/minecraft/landgenerator/MLG_ArrayList.java b/src/morlok8k/minecraft/landgenerator/MLG_ArrayList.java
index 3367a07..82af88b 100644
--- a/src/morlok8k/minecraft/landgenerator/MLG_ArrayList.java
+++ b/src/morlok8k/minecraft/landgenerator/MLG_ArrayList.java
@@ -26,8 +26,4 @@ public class MLG_ArrayList {
return list;
}
- //TODO: add read arraylist file
-
- //TODO: add save arraylist file (save this file only after generation is complete)
-
}
diff --git a/src/morlok8k/minecraft/landgenerator/MLG_DownloadFile.java b/src/morlok8k/minecraft/landgenerator/MLG_DownloadFile.java
index a666bab..fe7c3d6 100644
--- a/src/morlok8k/minecraft/landgenerator/MLG_DownloadFile.java
+++ b/src/morlok8k/minecraft/landgenerator/MLG_DownloadFile.java
@@ -88,7 +88,7 @@ public class MLG_DownloadFile {
timeTracking[1] = System.currentTimeMillis();
//differenceTime = (timeTracking[1] - timeTracking[0]);
if (Output) {
- Main.out("Elapsed Time: " + Main.displayTime(timeTracking[0], timeTracking[1]));
+ Main.out("Elapsed Time: " + MLG_Time.displayTime(timeTracking[0], timeTracking[1]));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
diff --git a/src/morlok8k/minecraft/landgenerator/MLG_FileRead.java b/src/morlok8k/minecraft/landgenerator/MLG_FileRead.java
new file mode 100644
index 0000000..9e0d841
--- /dev/null
+++ b/src/morlok8k/minecraft/landgenerator/MLG_FileRead.java
@@ -0,0 +1,170 @@
+package morlok8k.minecraft.landgenerator;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import corrodias.minecraft.landgenerator.Main;
+
+public class MLG_FileRead {
+
+ public static ArrayList readArrayListCoordLog(String file) {
+
+ ArrayList Return = new ArrayList();
+
+ try {
+ BufferedReader in = new BufferedReader(new FileReader(new File(file)));
+ String line = "";
+
+ while ((line = in.readLine()) != null) {
+ int end = line.indexOf('#'); // comments, ignored lines
+ boolean ignoreLine = false;
+ Coordinates c = new Coordinates();
+
+ if (end == -1) { // If we have no hash sign, then we read till the end of the line
+ end = line.length();
+ }
+
+ if (end == 0) { //hash is first char, meaning entire line is a comment
+ ignoreLine = true;
+ }
+
+ if (!(ignoreLine)) {
+ c = Coordinates.parseString(line.substring(0, end));
+ Return.add(c);
+ } /* else {
+ // other future stuff may go here.
+ }
+ */
+
+ }
+ in.close();
+
+ } catch (FileNotFoundException ex) {
+ Main.out("Could not find " + file + ".");
+ return Return;
+ } catch (IOException ex) {
+ Main.err("Could not read " + file + ".");
+ return Return;
+ }
+
+ return Return;
+ }
+
+ /**
+ *
+ */
+ public static void readConf() {
+ //TODO: element comment
+ //String errorMsg = "";
+
+ try {
+ File config = new File(Main.MinecraftLandGeneratorConf);
+ BufferedReader in = new BufferedReader(new FileReader(config));
+ String line = "";
+ String property = "";
+ String value = "";
+
+ while ((line = in.readLine()) != null) {
+ int pos = line.indexOf('=');
+
+ int end = line.lastIndexOf('#'); // comments, ignored lines
+
+ if (end == -1) { // If we have no hash sign, then we read till the end of the line
+ end = line.length();
+
+ }
+ if (end <= (pos + 1)) { // If hash is before the '=', we may have an issue... it should be fine, cause we check for issues next, but lets make sure.
+ end = line.length();
+ pos = -1;
+ }
+
+ if (end == 0) { //hash is first char, meaning entire line is a comment
+ end = line.length();
+ pos = 0;
+ }
+
+ if (pos != -1) {
+ if (line.length() == 0) {
+ property = "";
+ value = "";
+ } else {
+ property = line.substring(0, pos).toLowerCase();
+ value = line.substring(pos + 1, end);
+ }
+
+ if (property.equals("serverpath")) {
+ Main.serverPath = value;
+ } else if (property.equals("java")) {
+ Main.javaLine = value;
+ } else if (property.equals("done_text")) {
+ Main.doneText = value;
+ } else if (property.equals("preparing_text")) {
+ Main.preparingText = value;
+ } else if (property.equals("preparing_level")) {
+ Main.preparingLevel = value;
+ } else if (property.equals("level-0")) {
+ Main.level_0 = value;
+ } else if (property.equals("level-1")) {
+ Main.level_1 = value;
+ } else if (property.equals("level-2")) {
+ Main.level_2 = value;
+ } else if (property.equals("level-3")) {
+ Main.level_3 = value;
+ } else if (property.equals("level-4")) {
+ Main.level_4 = value;
+ } else if (property.equals("level-5")) {
+ Main.level_5 = value;
+ } else if (property.equals("level-6")) {
+ Main.level_6 = value;
+ } else if (property.equals("level-7")) {
+ Main.level_7 = value;
+ } else if (property.equals("level-8")) {
+ Main.level_8 = value;
+ } else if (property.equals("level-9")) {
+ Main.level_9 = value;
+ } else if (property.equals("waitsave")) {
+ if (value.toLowerCase().equals("true")) {
+ Main.waitSave = true;
+ } else {
+ Main.waitSave = false;
+ }
+ }
+ }
+ }
+ in.close();
+
+ if (Main.testing) {
+ Main.outD("Test Output: Reading of Config File ");
+ Main.outD(" serverPath: " + Main.serverPath);
+ Main.outD(" javaLine: " + Main.javaLine);
+ Main.outD(" doneText: " + Main.doneText);
+ Main.outD(" preparingText: " + Main.preparingText);
+ Main.outD("preparingLevel: " + Main.preparingLevel);
+ Main.outD(" level_0: " + Main.level_0);
+ Main.outD(" level_1: " + Main.level_1);
+ Main.outD(" level_2: " + Main.level_2);
+ Main.outD(" level_3: " + Main.level_3);
+ Main.outD(" level_4: " + Main.level_4);
+ Main.outD(" level_5: " + Main.level_5);
+ Main.outD(" level_6: " + Main.level_6);
+ Main.outD(" level_7: " + Main.level_7);
+ Main.outD(" level_8: " + Main.level_8);
+ Main.outD(" level_9: " + Main.level_9);
+ Main.outD(" waitSave: " + Main.waitSave);
+ }
+ } catch (FileNotFoundException ex) {
+ Main.out("Could not find "
+ + Main.MinecraftLandGeneratorConf
+ + ". It is recommended that you run the application with the -conf option to create it.");
+ return;
+ } catch (IOException ex) {
+ Main.err("Could not read " + Main.MinecraftLandGeneratorConf + ".");
+ return;
+ }
+ }
+
+}
diff --git a/src/morlok8k/minecraft/landgenerator/MLG_FileWrite.java b/src/morlok8k/minecraft/landgenerator/MLG_FileWrite.java
new file mode 100644
index 0000000..db4b560
--- /dev/null
+++ b/src/morlok8k/minecraft/landgenerator/MLG_FileWrite.java
@@ -0,0 +1,123 @@
+package morlok8k.minecraft.landgenerator;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import corrodias.minecraft.landgenerator.Main;
+
+/**
+ * http://www.roseindia.net/java/example/java/io/java-append-to-file.shtml
+ * Append To File - Java Tutorial
+ */
+public class MLG_FileWrite {
+
+ public static final String newLine = Main.newLine;
+
+ /**
+ * @param file
+ * @param appendTxt
+ */
+ public static void AppendTxtFile(String file, String appendTxt) {
+ try {
+ // Create file
+ FileWriter fstream = new FileWriter(file, true);
+ BufferedWriter out = new BufferedWriter(fstream);
+ //String output = "Hello Java" + newLine;
+ out.write(appendTxt);
+ //Close the output stream
+ out.close();
+ } catch (Exception e) {//Catch exception if any
+ System.err.println("Error: " + e.getMessage());
+ }
+ }
+
+ /**
+ * @param file
+ * @param txt
+ */
+ public static void writeTxtFile(String file, String txt) {
+ //TODO: element comment
+
+ /*
+ * NOTE: I don't include a generic readTxtFile method, as that code depends on what I'm reading.
+ * For things like that I make a special method for it, if its used in more than one place.
+ * Like reading the config file.
+ */
+
+ try {
+ File oFile = new File(file);
+ BufferedWriter outFile = new BufferedWriter(new FileWriter(oFile));
+ outFile.write(txt);
+ outFile.newLine();
+ outFile.close();
+ Main.out(file + " file created.");
+ return;
+ } catch (IOException ex) {
+ Main.err("Could not create " + Main.MinecraftLandGeneratorConf + ".");
+ ex.printStackTrace();
+ return;
+ }
+
+ }
+
+ /**
+ * Generates a Config File.
+ *
+ * @param newConf
+ * true: Uses Default values. false: uses existing values
+ * @author Morlok8k
+ */
+ public static void saveConf(boolean newConf) {
+
+ String jL = null; //javaLine
+ String sP = null; //serverPath
+
+ if (newConf) {
+ jL = Main.defaultJavaLine; // reads the default from a constant, makes it easier!
+ sP = "."; //
+ } else {
+ jL = Main.javaLine; // we read these values from an existing Conf File.
+ sP = Main.serverPath; //
+ }
+
+ String txt = null;
+ //@formatter:off
+ txt = "#" + Main.PROG_NAME + " Configuration File: Version: " + Main.VERSION + Main.newLine
+ + "#Authors: " + Main.AUTHORS + Main.newLine
+ + "#Auto-Generated: " + Main.dateFormat.format(Main.date) + Main.newLine
+ + Main.newLine
+ + "#Line to run server:" + Main.newLine
+ + "Java=" + jL // reads the default from a constant, makes it easier!
+ + Main.newLine
+ + Main.newLine
+ + "#Location of server. use \".\" for the same folder as MLG" + Main.newLine
+ + "ServerPath=" + sP
+ + Main.newLine
+ + Main.newLine
+ + "#Strings read from the server" + Main.newLine
+ + "Done_Text=[INFO] Done" + Main.newLine
+ + "Preparing_Text=[INFO] Preparing spawn area:" + Main.newLine
+ + "Preparing_Level=[INFO] Preparing start region for" + Main.newLine
+ + "Level-0=The Overworld" + Main.newLine
+ + "Level-1=The Nether" + Main.newLine
+ + "Level-2=The End" + Main.newLine
+ + "Level-3=Level 3 (Future Level)" + Main.newLine
+ + "Level-4=Level 4 (Future Level)" + Main.newLine
+ + "Level-5=Level 5 (Future Level)" + Main.newLine
+ + "Level-6=Level 6 (Future Level)" + Main.newLine
+ + "Level-7=Level 7 (Future Level)" + Main.newLine
+ + "Level-8=Level 8 (Future Level)" + Main.newLine
+ + "Level-9=Level 9 (Future Level)" + Main.newLine
+ + Main.newLine
+ + "#Optional: Wait a few seconds after saving." + Main.newLine + "WaitSave=false";
+ //@formatter:on
+
+ writeTxtFile(Main.MinecraftLandGeneratorConf, txt);
+
+ return;
+
+ }
+
+}
diff --git a/src/morlok8k/minecraft/landgenerator/MLG_Readme_and_HelpInfo.java b/src/morlok8k/minecraft/landgenerator/MLG_Readme_and_HelpInfo.java
index e5ff115..06bc444 100644
--- a/src/morlok8k/minecraft/landgenerator/MLG_Readme_and_HelpInfo.java
+++ b/src/morlok8k/minecraft/landgenerator/MLG_Readme_and_HelpInfo.java
@@ -201,7 +201,7 @@ public class MLG_Readme_and_HelpInfo {
+ newLine;
//@formatter:on
- Main.writeTxtFile(readmeFile, ReadMeText + showHelpSTR);
+ MLG_FileWrite.writeTxtFile(readmeFile, ReadMeText + showHelpSTR);
}
@@ -304,4 +304,5 @@ public class MLG_Readme_and_HelpInfo {
return returnString;
}
+
}
diff --git a/src/morlok8k/minecraft/landgenerator/MLG_SelfAware.java b/src/morlok8k/minecraft/landgenerator/MLG_SelfAware.java
new file mode 100644
index 0000000..4a11a56
--- /dev/null
+++ b/src/morlok8k/minecraft/landgenerator/MLG_SelfAware.java
@@ -0,0 +1,36 @@
+package morlok8k.minecraft.landgenerator;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.util.List;
+
+import corrodias.minecraft.landgenerator.Main;
+
+public class MLG_SelfAware {
+
+ public static String JVMinfo() {
+
+ String Return = "";
+
+ RuntimeMXBean RuntimemxBean = ManagementFactory.getRuntimeMXBean();
+ List aList = RuntimemxBean.getInputArguments();
+
+ for (int i = 0; i < aList.size(); i++) {
+ Return = Return + (aList.get(i)) + " ";
+ }
+
+ Return = Return.trim();
+
+ Return =
+ "Launch info: JVM: " + Return + " JAR: " + System.getProperty("sun.java.command")
+ + " ARGS: ";
+
+ for (int i = 0; i < Main.originalArgs.length; i++) {
+ Return = Return + (Main.originalArgs[i]) + " ";
+ }
+
+ Return = Return.trim();
+ return Return;
+ }
+
+}
diff --git a/src/morlok8k/minecraft/landgenerator/MLG_Time.java b/src/morlok8k/minecraft/landgenerator/MLG_Time.java
new file mode 100644
index 0000000..ecbb09b
--- /dev/null
+++ b/src/morlok8k/minecraft/landgenerator/MLG_Time.java
@@ -0,0 +1,103 @@
+package morlok8k.minecraft.landgenerator;
+
+import corrodias.minecraft.landgenerator.Main;
+
+public class MLG_Time {
+
+ /**
+ * waits ten seconds. outputs 10%, 20%, etc after each second.
+ *
+ * @author Morlok8k
+ */
+ public static void waitTenSec(boolean output) {
+
+ if (Main.dontWait) { return; } //Don't wait!
+
+ if (output) {
+ Main.outP(Main.MLG); //here we wait 10 sec.
+ }
+
+ int count = 0;
+ while (count <= 100) {
+ if (output) {
+ Main.outP(count + "% ");
+ }
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ count += 10;
+ }
+ if (output) {
+ Main.outP(Main.newLine);
+ }
+ return;
+
+ }
+
+ /**
+ * Returns the time in a readable format between two points of time given in Millis.
+ *
+ * @param startTimeMillis
+ * @param endTimeMillis
+ * @author Morlok8k
+ * @return String of Readable Time
+ */
+ public static String displayTime(long startTimeMillis, long endTimeMillis) {
+
+ long millis = (endTimeMillis - startTimeMillis);
+ //I just duplicated displayTime to have a start & end times, because it just made things simpler to code.
+ return (MLG_Time.displayTime(millis));
+ }
+
+ /**
+ * Returns the time in a readable format given a time in Millis.
+ *
+ * @param timeMillis
+ * @author Morlok8k
+ * @return String of Readable Time
+ */
+ public static String displayTime(long timeMillis) {
+
+ long seconds = timeMillis / 1000;
+ long minutes = seconds / 60;
+ long hours = minutes / 60;
+ long days = hours / 24;
+ long years = days / 365;
+
+ String took =
+ (years > 0 ? String.format("%d " + ((years) == 1 ? "Year, " : "Years, "), years)
+ : "")
+ + (days > 0 ? String.format("%d "
+ + ((days % 365) == 1 ? "Day, " : "Days, "), days % 365) : "")
+ + (hours > 0 ? String.format("%d "
+ + ((hours % 24) == 1 ? "Hour, " : "Hours, "), hours % 24) : "")
+ + (minutes > 0 ? String.format("%d "
+ + ((minutes % 60) == 1 ? "Minute, " : "Minutes, "), minutes % 60)
+ : "")
+ + String.format("%d " + ((seconds % 60) == 1 ? "Second" : "Seconds"),
+ seconds % 60);
+
+ if (!(Main.verbose)) {
+ int commaFirst = took.indexOf(",");
+ int commaSecond = took.substring((commaFirst + 1), took.length()).indexOf(",");
+ int end = (commaFirst + 1 + commaSecond);
+
+ if (commaSecond == -1) {
+ end = commaFirst;
+ }
+
+ if (commaFirst == -1) {
+ end = took.length();
+ }
+
+ took = took.substring(0, end);
+ }
+
+ took = took.trim();
+ return (took);
+ }
+
+}
diff --git a/src/morlok8k/minecraft/landgenerator/MLG_Update.java b/src/morlok8k/minecraft/landgenerator/MLG_Update.java
index d37bd27..ec0352c 100644
--- a/src/morlok8k/minecraft/landgenerator/MLG_Update.java
+++ b/src/morlok8k/minecraft/landgenerator/MLG_Update.java
@@ -16,6 +16,7 @@ import java.util.Iterator;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
+import corrodias.minecraft.landgenerator.MLG_Misc;
import corrodias.minecraft.landgenerator.Main;
public class MLG_Update {
@@ -67,7 +68,7 @@ public class MLG_Update {
if (Main.MLG_Current_Hash == null) {
try {
- Main.MLG_Current_Hash = Main.fileMD5(Main.MLGFileName);
+ Main.MLG_Current_Hash = MLG_MD5.fileMD5(Main.MLGFileName);
// out(hash + " " + MLGFileName);
} catch (Exception e) {
Main.out("Error: MLG_MD5 from file failed");
@@ -127,7 +128,7 @@ public class MLG_Update {
Main.out("\"" + Main.buildIDFile + "\" file not Found. Generating New \""
+ Main.buildIDFile + "\" File");
- Main.writeTxtFile(Main.buildIDFile,
+ MLG_FileWrite.writeTxtFile(Main.buildIDFile,
Main.MLG_Current_Hash + "=" + String.valueOf(time.getTime()) + "#MLG v"
+ Main.VERSION + INFO);
@@ -173,7 +174,7 @@ public class MLG_Update {
if (Main.MLG_Current_Hash == null) {
try {
- Main.MLG_Current_Hash = Main.fileMD5(Main.MLGFileName);
+ Main.MLG_Current_Hash = MLG_MD5.fileMD5(Main.MLGFileName);
// out(hash + " " + MLGFileName);
} catch (Exception e) {
Main.out("Error: MLG_MD5 from file failed");
@@ -238,7 +239,8 @@ public class MLG_Update {
new Long(line.substring(pos + 1, end));
Main.MLG_Last_Modified_Date = new Date(Main.MLG_Last_Modified_Long);
- Long highestModTime = Main.ZipGetModificationTime(Main.MLGFileName);
+ Long highestModTime =
+ MLG_Update.ZipGetModificationTime(Main.MLGFileName);
long tCalc = Main.MLG_Last_Modified_Long - highestModTime;
if (Main.testing) {
@@ -339,7 +341,7 @@ public class MLG_Update {
e1.printStackTrace();
try {
- Main.copyFile(new File(Main.MLG_JarFile), new File(Main.MLG_JarFile
+ MLG_Misc.copyFile(new File(Main.MLG_JarFile), new File(Main.MLG_JarFile
+ ".old"));
File fileDelete = new File(Main.MLG_JarFile);
fileDelete.delete();