some untested 1.7.0 code. not ready yet, but most likely functional.
This commit is contained in:
parent
9de8c2164a
commit
7580fe546b
@ -12,30 +12,24 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLDecoder;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import morlok8k.minecraft.landgenerator.MLG_DownloadFile;
|
||||
import morlok8k.minecraft.landgenerator.MLG_MD5;
|
||||
import morlok8k.minecraft.landgenerator.MLG_Readme_and_HelpInfo;
|
||||
import morlok8k.minecraft.landgenerator.MLG_StringArrayParse;
|
||||
import morlok8k.minecraft.landgenerator.MLG_Update;
|
||||
import morlok8k.minecraft.landgenerator.MLG_input_CLI;
|
||||
|
||||
import org.jnbt.CompoundTag;
|
||||
@ -58,7 +52,7 @@ 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.3"; // Version Number!
|
||||
public static final String VERSION = "1.6.9 (1.7pre)"; // Version Number!
|
||||
public static final String AUTHORS = "Corrodias, Morlok8k, pr0f1x"; // Authors
|
||||
|
||||
public static final String fileSeparator = System.getProperty("file.separator");
|
||||
@ -80,6 +74,7 @@ public class Main {
|
||||
//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;
|
||||
|
||||
private static ProcessBuilder minecraft = null;
|
||||
private static String javaLine = null;
|
||||
@ -109,7 +104,7 @@ public class Main {
|
||||
private int zRange = 0;
|
||||
private Integer xOffset = null;
|
||||
private Integer zOffset = null;
|
||||
private static boolean verbose = false;
|
||||
public static boolean verbose = false;
|
||||
private boolean alternate = false;
|
||||
private static boolean dontWait = false;
|
||||
private static boolean waitSave = false;
|
||||
@ -119,27 +114,27 @@ public class Main {
|
||||
private 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
|
||||
private static Long MLG_Last_Modified_Long = 0L;
|
||||
public static Long MLG_Last_Modified_Long = 0L;
|
||||
|
||||
private static final Class<?> cls = Main.class;
|
||||
private static String MLGFileName = null;
|
||||
public static final Class<?> cls = Main.class;
|
||||
public static String MLGFileName = null;
|
||||
|
||||
private static final String rsrcError = "rsrcERROR";
|
||||
private static String buildIDFile = "MLG-BuildID";
|
||||
private static boolean isCompiledAsJar = false;
|
||||
private static String MLG_Current_Hash = null;
|
||||
private static int inf_loop_protect_BuildID = 0;
|
||||
private static boolean flag_downloadedBuildID = false;
|
||||
public static final String rsrcError = "rsrcERROR";
|
||||
public static String buildIDFile = "MLG-BuildID";
|
||||
public static boolean isCompiledAsJar = false;
|
||||
public static String MLG_Current_Hash = null;
|
||||
public static int inf_loop_protect_BuildID = 0;
|
||||
public static boolean flag_downloadedBuildID = false;
|
||||
|
||||
private static ArrayList<String> timeStamps = new ArrayList<String>();
|
||||
public static ArrayList<String> timeStamps = new ArrayList<String>();
|
||||
|
||||
private static final String MLG_JarFile = "MinecraftLandGenerator.jar";
|
||||
public static final String MLG_JarFile = "MinecraftLandGenerator.jar";
|
||||
|
||||
private static final String github_URL =
|
||||
public static final String github_URL =
|
||||
"https://raw.github.com/Morlok8k/MinecraftLandGenerator/master/bin/"; // just removing some redundancy
|
||||
private static final String github_MLG_Conf_URL = github_URL + MinecraftLandGeneratorConf;
|
||||
private static final String github_MLG_BuildID_URL = github_URL + buildIDFile;
|
||||
private static final String github_MLG_jar_URL = github_URL + MLG_JarFile;
|
||||
public static final String github_MLG_Conf_URL = github_URL + MinecraftLandGeneratorConf;
|
||||
public static final String github_MLG_BuildID_URL = github_URL + buildIDFile;
|
||||
public static final String github_MLG_jar_URL = github_URL + MLG_JarFile;
|
||||
|
||||
private static Boolean recheckFlag = false;
|
||||
private static long startTime = 0L;
|
||||
@ -186,10 +181,18 @@ public class Main {
|
||||
}
|
||||
|
||||
boolean GUI = false;
|
||||
boolean NOGUI = false;
|
||||
|
||||
String[] argsNOGUI = new String[args.length];
|
||||
argsNOGUI = args;
|
||||
argsNOGUI = MLG_StringArrayParse.Parse(argsNOGUI, "nogui"); //parse out "nogui"
|
||||
if (!(args.equals(argsNOGUI))) { //do the freshly parsed args match the original?
|
||||
args = argsNOGUI; //use the freshly parsed args for everything else now...
|
||||
NOGUI = true;
|
||||
}
|
||||
|
||||
//GUI Choosing code...
|
||||
if (!java.awt.GraphicsEnvironment.isHeadless()
|
||||
&& (args.length <= 0 || !args[0].equals("nogui"))) {
|
||||
if (!java.awt.GraphicsEnvironment.isHeadless() || (!NOGUI)) {
|
||||
GUI = true;
|
||||
if (testing) {
|
||||
outD("GUI: This is a graphical enviroment.");
|
||||
@ -342,7 +345,6 @@ public class Main {
|
||||
try {
|
||||
origMD5 = fileMD5(config.toString());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
BufferedReader in = new BufferedReader(new FileReader(config));
|
||||
@ -360,7 +362,6 @@ public class Main {
|
||||
try {
|
||||
recheckMD5 = fileMD5(config.toString());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@ -465,6 +466,7 @@ 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")) {
|
||||
@ -585,6 +587,13 @@ public class Main {
|
||||
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
|
||||
// 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!
|
||||
@ -623,6 +632,11 @@ public class Main {
|
||||
// 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);
|
||||
@ -1001,6 +1015,7 @@ public class Main {
|
||||
}
|
||||
} 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!
|
||||
@ -1138,7 +1153,7 @@ public class Main {
|
||||
* @param dst
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void copyFile(File src, File dst) throws IOException {
|
||||
public static void copyFile(File src, File dst) throws IOException {
|
||||
InputStream copyIn = new FileInputStream(src);
|
||||
OutputStream copyOut = new FileOutputStream(dst);
|
||||
|
||||
@ -1218,106 +1233,7 @@ public class Main {
|
||||
* @author Morlok8k
|
||||
*/
|
||||
private static void buildID(boolean downloadOnly) {
|
||||
|
||||
// download BuildID from Github.
|
||||
boolean fileSuccess = downloadFile(github_MLG_BuildID_URL, testing);
|
||||
if (fileSuccess) {
|
||||
out(buildIDFile + " file downloaded.");
|
||||
flag_downloadedBuildID = true;
|
||||
|
||||
if (downloadOnly) { return; }
|
||||
|
||||
}
|
||||
|
||||
if (downloadOnly) {
|
||||
err("Couldn't Download new " + buildIDFile);
|
||||
return;
|
||||
}
|
||||
|
||||
// If not available, create.
|
||||
// After downloading, check to see if it matches hash.
|
||||
|
||||
if (MLGFileName == null) {
|
||||
try {
|
||||
MLGFileName = getClassLoader(cls);
|
||||
} catch (Exception e) {
|
||||
out("Error: Finding file failed");
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (MLGFileName.equals(rsrcError)) { return; }
|
||||
}
|
||||
|
||||
if (MLG_Current_Hash == null) {
|
||||
|
||||
try {
|
||||
MLG_Current_Hash = fileMD5(MLGFileName);
|
||||
// out(hash + " " + MLGFileName);
|
||||
} catch (Exception e) {
|
||||
out("Error: MLG_MD5 from file failed");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
Date time = new Date(new Long(0));
|
||||
|
||||
try {
|
||||
time = getCompileTimeStamp(cls);
|
||||
} catch (Exception e) {
|
||||
out("Error: TimeStamp from file failed");
|
||||
e.printStackTrace();
|
||||
}
|
||||
// out(d.toString());
|
||||
|
||||
boolean notNew = false;
|
||||
String INFO = "";
|
||||
if (isCompiledAsJar == false) {
|
||||
INFO = " (Class File, Not .Jar)";
|
||||
}
|
||||
|
||||
try {
|
||||
String line;
|
||||
|
||||
BufferedReader inFile = new BufferedReader(new FileReader(buildIDFile));
|
||||
BufferedWriter outFile = new BufferedWriter(new FileWriter(buildIDFile + ".temp"));
|
||||
|
||||
while ((line = inFile.readLine()) != null) {
|
||||
|
||||
if (line.contains(MLG_Current_Hash)) {
|
||||
notNew = true;
|
||||
if (testing) {
|
||||
outD("NotNew");
|
||||
}
|
||||
}
|
||||
|
||||
outFile.write(line);
|
||||
outFile.newLine();
|
||||
}
|
||||
|
||||
if (notNew == false) {
|
||||
outFile.write(MLG_Current_Hash + "=" + String.valueOf(time.getTime()) + "# MLG v"
|
||||
+ VERSION + INFO);
|
||||
outFile.newLine();
|
||||
}
|
||||
outFile.close();
|
||||
inFile.close();
|
||||
|
||||
File fileDelete = new File(buildIDFile);
|
||||
fileDelete.delete();
|
||||
File fileRename = new File(buildIDFile + ".temp");
|
||||
fileRename.renameTo(new File(buildIDFile));
|
||||
|
||||
} catch (FileNotFoundException ex) {
|
||||
out("\"" + buildIDFile + "\" file not Found. Generating New \"" + buildIDFile
|
||||
+ "\" File");
|
||||
|
||||
writeTxtFile(buildIDFile, MLG_Current_Hash + "=" + String.valueOf(time.getTime())
|
||||
+ "#MLG v" + VERSION + INFO);
|
||||
|
||||
} catch (IOException ex) {
|
||||
err("Could not create \"" + buildIDFile + "\".");
|
||||
return;
|
||||
}
|
||||
|
||||
MLG_Update.buildID(downloadOnly);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1326,164 +1242,8 @@ public class Main {
|
||||
* @author Morlok8k
|
||||
*
|
||||
*/
|
||||
private void readBuildID() {
|
||||
|
||||
if (inf_loop_protect_BuildID > 10) {
|
||||
MLG_Last_Modified_Date = new Date(new Long(0)); //set the day to Jan 1, 1970 for failure
|
||||
return;
|
||||
}
|
||||
inf_loop_protect_BuildID++; // this is to prevent an infinite loop (however unlikely)
|
||||
|
||||
if (MLGFileName == null) {
|
||||
try {
|
||||
MLGFileName = getClassLoader(cls);
|
||||
} catch (Exception e) {
|
||||
out("Error: Finding file failed");
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (MLGFileName.equals(rsrcError)) { return; }
|
||||
}
|
||||
|
||||
MLGFileNameShort =
|
||||
MLGFileName.substring(MLGFileName.lastIndexOf(fileSeparator) + 1,
|
||||
MLGFileName.length());
|
||||
|
||||
if (testing) {
|
||||
outD("Currently Running as file:" + MLGFileNameShort);
|
||||
}
|
||||
|
||||
if (MLG_Current_Hash == null) {
|
||||
|
||||
try {
|
||||
MLG_Current_Hash = fileMD5(MLGFileName);
|
||||
// out(hash + " " + MLGFileName);
|
||||
} catch (Exception e) {
|
||||
out("Error: MLG_MD5 from file failed");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
int tsCount = 0;
|
||||
|
||||
timeStamps.clear();
|
||||
|
||||
if (MLG_Last_Modified_Date == null) {
|
||||
boolean foundLine = false;
|
||||
try {
|
||||
BufferedReader in = new BufferedReader(new FileReader(buildIDFile));
|
||||
String line;
|
||||
|
||||
if (testing) {
|
||||
outD("TimeStamps in buildIDFile:");
|
||||
}
|
||||
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) {
|
||||
timeStamps.add(line.substring(pos + 1, end));
|
||||
}
|
||||
}
|
||||
|
||||
//timeStamps.add(line.substring(pos + 1, end));
|
||||
|
||||
if (testing) {
|
||||
outD(timeStamps.get(tsCount));
|
||||
}
|
||||
|
||||
tsCount++;
|
||||
|
||||
if (line.contains(MLG_Current_Hash)) {
|
||||
// out("[DEBUG] Found!");
|
||||
foundLine = true;
|
||||
|
||||
if (pos != -1) {
|
||||
if (line.substring(0, pos).equals(MLG_Current_Hash)) {
|
||||
MLG_Last_Modified_Long = new Long(line.substring(pos + 1, end));
|
||||
MLG_Last_Modified_Date = new Date(MLG_Last_Modified_Long);
|
||||
|
||||
Long highestModTime = ZipGetModificationTime(MLGFileName);
|
||||
long tCalc = MLG_Last_Modified_Long - highestModTime;
|
||||
|
||||
if (testing) {
|
||||
outD("tCalc\tMLG_Last_Modified_Long\thighestModTime" + newLine
|
||||
+ tCalc + "\t" + MLG_Last_Modified_Long + "\t"
|
||||
+ highestModTime);
|
||||
}
|
||||
|
||||
if (highestModTime == 0L) {
|
||||
|
||||
err("Archive Intergrity Check Failed: .zip/.jar file Issue.");
|
||||
err("Archive Intergrity Check Failed: (MLG will still run. Just note that this may not be an official version.)");
|
||||
|
||||
} else {
|
||||
if (tCalc < -15000L) {
|
||||
|
||||
//time is newer? (.zip file is newer than BuildID)
|
||||
err("Archive Intergrity Check Failed: .zip file is newer than BuildID. Offset: "
|
||||
+ (tCalc / 1000) + "sec.");
|
||||
err("Archive Intergrity Check Failed: (MLG will still run. Just note that this may not be an official version.)");
|
||||
}
|
||||
|
||||
if (tCalc < 15000L) {
|
||||
|
||||
//times are within 30 seconds (+/- 15 seconds) of each other. (typically 1-2 seconds, but left room for real-world error)
|
||||
if (testing | flag_downloadedBuildID) {
|
||||
out("Archive Intergrity Check Passed. Offset: "
|
||||
+ (tCalc / 1000) + "sec.");
|
||||
}
|
||||
|
||||
} else {
|
||||
//times dont match. (.zip file is older than specified BuildID)
|
||||
err("Archive Intergrity Check Failed: .zip file is older than BuildID. Offset: "
|
||||
+ (tCalc / 1000) + "sec.");
|
||||
err("Archive Intergrity Check Failed: (MLG will still run. Just note that this may not be an official version.)");
|
||||
}
|
||||
}
|
||||
//return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
in.close();
|
||||
|
||||
if (foundLine == false) {
|
||||
// out("[DEBUG] FoundLine False");
|
||||
buildID(false);
|
||||
readBuildID(); // yes I'm calling the function from itself. potential infinite loop? possibly. I haven't encountered it yet!
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
err("Cant Read " + buildIDFile + "!");
|
||||
err(e.getLocalizedMessage());
|
||||
err("");
|
||||
// e.printStackTrace();
|
||||
buildID(false);
|
||||
readBuildID();
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void readBuildID() {
|
||||
MLG_Update.readBuildID();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1492,117 +1252,9 @@ public class Main {
|
||||
* @author Morlok8k
|
||||
*
|
||||
*/
|
||||
private void updateMLG() {
|
||||
private static void updateMLG() {
|
||||
|
||||
buildID(true); //get latest BuildID file.
|
||||
MLG_Last_Modified_Date = null;
|
||||
readBuildID();
|
||||
|
||||
Iterator<String> e = timeStamps.iterator();
|
||||
String s;
|
||||
int diff;
|
||||
|
||||
//boolean renameFailed = false;
|
||||
|
||||
while (e.hasNext()) {
|
||||
s = e.next();
|
||||
diff = MLG_Last_Modified_Date.compareTo(new Date(new Long(s)));
|
||||
//out(diff);
|
||||
|
||||
if (diff < 0) { // if this is less than 0, there is a new version of MLG on the Internet!
|
||||
out("There is a NEW VERSION Of " + PROG_NAME + " available online!");
|
||||
|
||||
try {
|
||||
File fileRename = new File(MLG_JarFile);
|
||||
fileRename.renameTo(new File(MLG_JarFile + ".old"));
|
||||
} catch (Exception e1) {
|
||||
out("Rename attempt #1 failed!");
|
||||
e1.printStackTrace();
|
||||
|
||||
try {
|
||||
copyFile(new File(MLG_JarFile), new File(MLG_JarFile + ".old"));
|
||||
File fileDelete = new File(MLG_JarFile);
|
||||
fileDelete.delete();
|
||||
} catch (Exception e2) {
|
||||
out("Rename attempt #2 failed!");
|
||||
e2.printStackTrace();
|
||||
//renameFailed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boolean fileSuccess = downloadFile(github_MLG_jar_URL, true);
|
||||
if (fileSuccess) {
|
||||
out(MLG_JarFile + " downloaded.");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets the filename of a .jar (typically this one!)
|
||||
*
|
||||
* @author Morlok8k
|
||||
*/
|
||||
private static String getClassLoader(Class<?> classFile) throws IOException {
|
||||
ClassLoader loader = classFile.getClassLoader();
|
||||
String filename = classFile.getName().replace('.', '/') + ".class";
|
||||
URL resource =
|
||||
(loader != null) ? loader.getResource(filename) : ClassLoader
|
||||
.getSystemResource(filename);
|
||||
filename = URLDecoder.decode(resource.toString(), "UTF-8");
|
||||
// out(filename);
|
||||
|
||||
// START Garbage removal:
|
||||
int bang = filename.indexOf("!"); // remove everything after xxxx.jar
|
||||
if (bang == -1) { // a real example:
|
||||
bang = filename.length(); // jar:file:/home/morlok8k/test.jar!/me/Morlok8k/test/Main.class
|
||||
}
|
||||
int file = filename.indexOf("file:"); // removes junk from the beginning of the path
|
||||
file = file + 5;
|
||||
if (file == -1) {
|
||||
file = 0;
|
||||
}
|
||||
if (filename.contains("rsrc:")) {
|
||||
err("THIS WAS COMPILED USING \"org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader\"! ");
|
||||
err("DO NOT PACKAGE YOUR .JAR'S WITH THIS CLASSLOADER CODE!");
|
||||
err("(Your Libraries need to be extracted.)");
|
||||
return rsrcError;
|
||||
}
|
||||
if (filename.contains(".jar")) {
|
||||
isCompiledAsJar = true;
|
||||
}
|
||||
filename = filename.replace('/', File.separatorChar);
|
||||
String returnString = filename.substring(file, bang);
|
||||
// END Garbage removal
|
||||
return returnString;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets the TimeStamp (last modified date) of a class file (typically this one!) <br>
|
||||
* <br>
|
||||
* Thanks to Roedy Green at <br>
|
||||
* <a href="http://mindprod.com/jgloss/compiletimestamp.html">http://mindprod .com/jgloss/compiletimestamp.html</a>
|
||||
*
|
||||
* @author Morlok8k
|
||||
*/
|
||||
private static Date getCompileTimeStamp(Class<?> classFile) throws IOException {
|
||||
ClassLoader loader = classFile.getClassLoader();
|
||||
String filename = classFile.getName().replace('.', '/') + ".class";
|
||||
// get the corresponding class file as a Resource.
|
||||
URL resource =
|
||||
(loader != null) ? loader.getResource(filename) : ClassLoader
|
||||
.getSystemResource(filename);
|
||||
URLConnection connection = resource.openConnection();
|
||||
// Note, we are using Connection.getLastModified not File.lastModifed.
|
||||
// This will then work both or members of jars or standalone class files.
|
||||
// NOTE: NOT TRUE! IT READS THE JAR, NOT THE FILES INSIDE!
|
||||
long time = connection.getLastModified();
|
||||
return (time != 0L) ? new Date(time) : null;
|
||||
MLG_Update.updateMLG();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1610,7 +1262,7 @@ public class Main {
|
||||
*
|
||||
* @author Morlok8k
|
||||
*/
|
||||
private static String fileMD5(String fileName) throws NoSuchAlgorithmException,
|
||||
public static String fileMD5(String fileName) throws NoSuchAlgorithmException,
|
||||
FileNotFoundException {
|
||||
return MLG_MD5.fileMD5(fileName);
|
||||
}
|
||||
@ -1643,59 +1295,13 @@ public class Main {
|
||||
* @param timeBuildID
|
||||
* @author Morlok8k
|
||||
*/
|
||||
private static Long ZipGetModificationTime(String zipFile) {
|
||||
|
||||
Long highestModTime = 0L;
|
||||
|
||||
try {
|
||||
|
||||
ZipFile zipF = new ZipFile(zipFile);
|
||||
|
||||
/*
|
||||
* Get list of zip entries using entries method of ZipFile class.
|
||||
*/
|
||||
|
||||
Enumeration<? extends ZipEntry> e = zipF.entries();
|
||||
|
||||
if (testing) {
|
||||
outD("File Name\t\tCRC\t\tModification Time\n---------------------------------\n");
|
||||
}
|
||||
|
||||
while (e.hasMoreElements()) {
|
||||
ZipEntry entry = e.nextElement();
|
||||
|
||||
Long modTime = entry.getTime();
|
||||
|
||||
if (entry.getName().toUpperCase().contains("MAIN.JAVA")) { //ignore highest timestamp for the source code, as that can be injected into the .jar file much later after compiling.
|
||||
modTime = 0L;
|
||||
}
|
||||
|
||||
if (highestModTime < modTime) {
|
||||
highestModTime = modTime;
|
||||
}
|
||||
|
||||
if (testing) {
|
||||
|
||||
String entryName = entry.getName();
|
||||
Date modificationTime = new Date(modTime);
|
||||
String CRC = Long.toHexString(entry.getCrc());
|
||||
|
||||
outD(entryName + "\t" + CRC + "\t" + modificationTime + "\t"
|
||||
+ modTime.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
zipF.close();
|
||||
|
||||
return highestModTime;
|
||||
|
||||
} catch (IOException ioe) {
|
||||
out("Error opening zip file" + ioe);
|
||||
return 0L; //return Jan. 1, 1970 12:00 GMT for failures
|
||||
}
|
||||
public static Long ZipGetModificationTime(String zipFile) {
|
||||
return MLG_Update.ZipGetModificationTime(zipFile);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static void readConf() {
|
||||
//TODO: element comment
|
||||
//String errorMsg = "";
|
||||
@ -1864,6 +1470,9 @@ public class Main {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static void verifyWorld() {
|
||||
//TODO: element comment
|
||||
|
||||
@ -1965,6 +1574,10 @@ public class Main {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file
|
||||
* @param txt
|
||||
*/
|
||||
public static void writeTxtFile(String file, String txt) {
|
||||
//TODO: element comment
|
||||
|
||||
@ -2078,31 +1691,6 @@ public class Main {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
private static void finishedImage() {
|
||||
System.out.println(newLine + " .l0kkKMl lMKkk0l. " + newLine
|
||||
+ ".;kMc ;KK; .,,lkkkkkkkl,,. ;KK, cMk,." + newLine
|
||||
+ "KKxkc..lKK;.oKKxxl,;;;;lkkKKo.,KKl..ckkKK" + newLine
|
||||
+ "Mx. ...;x0OOl'. .'lOOOx:... .xM" + newLine
|
||||
+ "lKKk0l. ,KK; ,KK, .l0xKKl" + newLine
|
||||
+ " .'',xOxOWl lMOxOx,''. " + newLine
|
||||
+ " .,xWl lWx;. " + newLine
|
||||
+ " lMl ,. ., lMl " + newLine
|
||||
+ " ;XO';Odl:,.. .',:ldO;'OX; " + newLine
|
||||
+ " ,KK,cxkkkc...ckxkx:,KK, " + newLine
|
||||
+ " lMc .,,. .o. .,,. cMl " + newLine
|
||||
+ " .lO;;' .lkl. ';;Ol. " + newLine
|
||||
+ " .;;kMk. .kMk;;. " + newLine
|
||||
+ " .lKKK0kl;;.......;,lk0KKKl. " + newLine
|
||||
+ " .;llxOx;.'Ox;llxxldlxxll;xO'.;xOxll;. " + newLine
|
||||
+ " ,KKcll. .l0KKl... ...lKK0l. .llcKK, " + newLine
|
||||
+ " lMx'''..lXX;:X0:'. .':OX;,XXl..'''xMl " + newLine
|
||||
+ " .lxXk. ,KM; .lkKKxkkKKkl. ,MK, .kXxl. " + newLine
|
||||
+ " oKl;;kMk. .,,,,;. .kMk,,lKo " + newLine
|
||||
+ " .0MMMMO' .OMMMMO. ");
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the time in a readable format between two points of time given in Millis.
|
||||
*
|
||||
@ -2147,13 +1735,22 @@ public class Main {
|
||||
seconds % 60);
|
||||
|
||||
if (!(verbose)) {
|
||||
int end = took.indexOf(",");
|
||||
if (end == -1) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
200
src/morlok8k/minecraft/landgenerator/Coordinates.java
Normal file
200
src/morlok8k/minecraft/landgenerator/Coordinates.java
Normal file
@ -0,0 +1,200 @@
|
||||
package morlok8k.minecraft.landgenerator;
|
||||
|
||||
/**
|
||||
* Coordinates are in the form of [X,Y,Z] or (X,Z)<br>
|
||||
* <br>
|
||||
* x-axis (longitude): the distance east (positive) or west (negative) of the origin point<br>
|
||||
* z-axis (latitude): the distance south (positive) or north (negative) of the origin point<br>
|
||||
* y-axis (elevation): how high or low (from 0 to 255 (previously 128), with 64 being sea level) <br>
|
||||
* The origin point: When both X and Z are both zero. (elevation is irrelevant)<br>
|
||||
*/
|
||||
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).
|
||||
// See: http://www.minecraftwiki.net/wiki/Far_Lands for more info.
|
||||
|
||||
public int X = 0;
|
||||
public int Y = 0;
|
||||
public int Z = 0;
|
||||
|
||||
/**
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
*/
|
||||
public Coordinates(int x, int y, int z) {
|
||||
super();
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Someone created a new blank Coordinate! Lets set it to be [0,0,0].
|
||||
*/
|
||||
public Coordinates() {
|
||||
clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the x
|
||||
*/
|
||||
public int getX() {
|
||||
return X;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the y
|
||||
*/
|
||||
public int getY() {
|
||||
return Y;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the z
|
||||
*/
|
||||
public int getZ() {
|
||||
return Z;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param x
|
||||
* the x to set
|
||||
*/
|
||||
public void setX(int x) {
|
||||
X = x;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param y
|
||||
* the y to set
|
||||
*/
|
||||
public void setY(int y) {
|
||||
Y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param z
|
||||
* the z to set
|
||||
*/
|
||||
public void setZ(int z) {
|
||||
Z = z;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
X = 0;
|
||||
Y = 0;
|
||||
Z = 0;
|
||||
}
|
||||
|
||||
public static Coordinates parseString(String StringOfCoords) {
|
||||
//parse out string
|
||||
StringOfCoords.trim();
|
||||
|
||||
int x = 0, y = 0, z = 0;
|
||||
|
||||
//TODO: add validity checks:
|
||||
//TODO: add short version... (Y = 0)
|
||||
|
||||
int start = 0, end = 0, firstComma = 0, secComma = 0;
|
||||
|
||||
String sX = "", sY = "", sZ = "";
|
||||
|
||||
start = StringOfCoords.indexOf("[");
|
||||
end = StringOfCoords.indexOf("]");
|
||||
|
||||
StringOfCoords = StringOfCoords.substring(start, end);
|
||||
|
||||
firstComma = StringOfCoords.indexOf(",");
|
||||
secComma = StringOfCoords.lastIndexOf(",");
|
||||
|
||||
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);
|
||||
|
||||
x = Integer.parseInt(sX);
|
||||
y = Integer.parseInt(sY);
|
||||
z = Integer.parseInt(sZ);
|
||||
|
||||
return new Coordinates(x, y, z);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// Java Language Specific Crap Below... Stuff *gotta* be there so Java won't cry... //
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
// I am overriding the inherited toString method.
|
||||
// Because it doesn't know how to deal with my custom data.
|
||||
// So instead of getting "blahblahblah.Coordinates@745f"
|
||||
// (the location of the class and the hexstring of the hashcode)
|
||||
// I return "[X,Y,Z]"
|
||||
|
||||
return ("[" + X + "," + Y + "," + Z + "]");
|
||||
|
||||
}
|
||||
|
||||
public String toString(boolean Short) {
|
||||
if (Short) { // We are overloading toString with an additional option:
|
||||
return ("(" + X + "," + Z + ")"); // Basically just an option to return just X and Z (formatted differently as well: "(X,Z)")
|
||||
}
|
||||
return toString(); // Idiot catch. default to: "[X,Y,Z]"
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
// I am overriding the inherited hashCode method.
|
||||
// Because it doesn't know how to deal with my custom data.
|
||||
// So instead of getting who knows what, we return valid data
|
||||
|
||||
final int prime = 31; // My hard coded prime number
|
||||
int result = 1; // The hard coded number I start with
|
||||
result = prime * result + X; // Add the X data
|
||||
result = prime * result + Y; // Add the Y data
|
||||
result = prime * result + Z; // Add the Z data
|
||||
return result; //this result will consistently give the same result for the same data.
|
||||
// [0,0,0] will always give 29791. [1,2,3] will always give 30817.
|
||||
//yes, If I was lazy, I could just do a "return 0;" and it would still be technically valid.
|
||||
//but if I'm going override the method, I might as well do it right...
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
// I am overriding the inherited equals method.
|
||||
// Because it doesn't know how to deal with my custom data.
|
||||
// So instead of always failing, it actually works!
|
||||
// (by default it gets the memory addresses of each object.)
|
||||
|
||||
// An object must equal itself
|
||||
if (this == obj) return true;
|
||||
|
||||
// No object equals null
|
||||
if (obj == null) return false;
|
||||
if (this == null) return false;
|
||||
|
||||
// Objects of different types are never equal
|
||||
if (getClass() != obj.getClass()) return false;
|
||||
|
||||
// Cast to an Coordinates, then compare the data
|
||||
Coordinates c = (Coordinates) obj;
|
||||
if (X != c.X) return false;
|
||||
if (Y != c.Y) return false;
|
||||
if (Z != c.Z) return false;
|
||||
return true; // If none of the above returned something, they must be equal!
|
||||
}
|
||||
}
|
33
src/morlok8k/minecraft/landgenerator/MLG_ArrayList.java
Normal file
33
src/morlok8k/minecraft/landgenerator/MLG_ArrayList.java
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package morlok8k.minecraft.landgenerator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import corrodias.minecraft.landgenerator.Main;
|
||||
|
||||
/**
|
||||
* @author morlok8k
|
||||
*
|
||||
*/
|
||||
public class MLG_ArrayList {
|
||||
|
||||
public static ArrayList<Coordinates> arrayListRemove(ArrayList<Coordinates> list,
|
||||
ArrayList<Coordinates> remove) {
|
||||
|
||||
boolean changed = false;
|
||||
changed = list.removeAll(remove);
|
||||
|
||||
if (Main.verbose) {
|
||||
System.out.println("ArrayList changed: " + changed);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
//TODO: add read arraylist file
|
||||
|
||||
//TODO: add save arraylist file (save this file only after generation is complete)
|
||||
|
||||
}
|
@ -62,6 +62,12 @@ public class MLG_Readme_and_HelpInfo {
|
||||
+ newLine
|
||||
+ "Version History:" + newLine
|
||||
+ "Morlok8k:" + newLine
|
||||
+ "1.7.0" + newLine
|
||||
+ "- Major Code Optimization" + newLine
|
||||
+ "- Drastically reduced the amount of time it takes for MLG to expand a world after it has already done so before!" + newLine
|
||||
+ "- (To do this, I needed to rewrite the Main loop of the program, and add my own Coordinate object)" + newLine
|
||||
+ "- Updated Time Output yet again." + newLine
|
||||
+ "- Misc. Tweaks." + newLine
|
||||
+ "1.6.3" + newLine
|
||||
+ "- Minor Code Optimization" + newLine
|
||||
+ "- Finely got on the ball and added the JNBT source and everything (as an internal .zip) to be completely faithful to his license" + newLine
|
||||
|
@ -18,7 +18,7 @@ public class MLG_StringArrayParse {
|
||||
int ii = 0;
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
workingArray[ii] = array[i]; // copy
|
||||
if ((array[i].equals(ParseOut)) && (removed == false)) { // we only remove the first match!
|
||||
if ((array[i].contains(ParseOut)) && (removed == false)) { // we only remove the first match!
|
||||
workingArray[ii] = null; // we make sure this is set to null (if the last arg is the match it would otherwise be copied... granted it would later be removed... but whatever.)
|
||||
ii = ii - 1; // we just simply move back one
|
||||
removed = true; // set our flag
|
||||
|
495
src/morlok8k/minecraft/landgenerator/MLG_Update.java
Normal file
495
src/morlok8k/minecraft/landgenerator/MLG_Update.java
Normal file
@ -0,0 +1,495 @@
|
||||
package morlok8k.minecraft.landgenerator;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import corrodias.minecraft.landgenerator.Main;
|
||||
|
||||
public class MLG_Update {
|
||||
|
||||
/**
|
||||
* This is an "undocumented" function to create a BuildID file. It should only be used right after compiling a .jar file<br>
|
||||
* The resulting BuildID file is uploaded to github, and also distributed with the program.<br>
|
||||
* <b>THE FILE SHOULD ONLY BE MADE FROM SCRATCH AT THE TIME OF PUBLISHING!</b><br>
|
||||
* (Otherwise, the purpose is defeated!)<br>
|
||||
* <br>
|
||||
* 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)<br>
|
||||
* <br>
|
||||
* This saves the hash and the timestamp (now known as the BuildID)
|
||||
*
|
||||
* @author Morlok8k
|
||||
*/
|
||||
public static void buildID(boolean downloadOnly) {
|
||||
|
||||
// download BuildID from Github.
|
||||
boolean fileSuccess =
|
||||
MLG_DownloadFile.downloadFile(Main.github_MLG_BuildID_URL, Main.testing);
|
||||
if (fileSuccess) {
|
||||
Main.out(Main.buildIDFile + " file downloaded.");
|
||||
Main.flag_downloadedBuildID = true;
|
||||
|
||||
if (downloadOnly) { return; }
|
||||
|
||||
}
|
||||
|
||||
if (downloadOnly) {
|
||||
Main.err("Couldn't Download new " + Main.buildIDFile);
|
||||
return;
|
||||
}
|
||||
|
||||
// If not available, create.
|
||||
// After downloading, check to see if it matches hash.
|
||||
|
||||
if (Main.MLGFileName == null) {
|
||||
try {
|
||||
Main.MLGFileName = getClassLoader(Main.cls);
|
||||
} catch (Exception e) {
|
||||
Main.out("Error: Finding file failed");
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (Main.MLGFileName.equals(Main.rsrcError)) { return; }
|
||||
}
|
||||
|
||||
if (Main.MLG_Current_Hash == null) {
|
||||
|
||||
try {
|
||||
Main.MLG_Current_Hash = Main.fileMD5(Main.MLGFileName);
|
||||
// out(hash + " " + MLGFileName);
|
||||
} catch (Exception e) {
|
||||
Main.out("Error: MLG_MD5 from file failed");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
Date time = new Date(new Long(0));
|
||||
|
||||
try {
|
||||
time = getCompileTimeStamp(Main.cls);
|
||||
} catch (Exception e) {
|
||||
Main.out("Error: TimeStamp from file failed");
|
||||
e.printStackTrace();
|
||||
}
|
||||
// out(d.toString());
|
||||
|
||||
boolean notNew = false;
|
||||
String INFO = "";
|
||||
if (Main.isCompiledAsJar == false) {
|
||||
INFO = " (Class File, Not .Jar)";
|
||||
}
|
||||
|
||||
try {
|
||||
String line;
|
||||
|
||||
BufferedReader inFile = new BufferedReader(new FileReader(Main.buildIDFile));
|
||||
BufferedWriter outFile = new BufferedWriter(new FileWriter(Main.buildIDFile + ".temp"));
|
||||
|
||||
while ((line = inFile.readLine()) != null) {
|
||||
|
||||
if (line.contains(Main.MLG_Current_Hash)) {
|
||||
notNew = true;
|
||||
if (Main.testing) {
|
||||
Main.outD("NotNew");
|
||||
}
|
||||
}
|
||||
|
||||
outFile.write(line);
|
||||
outFile.newLine();
|
||||
}
|
||||
|
||||
if (notNew == false) {
|
||||
outFile.write(Main.MLG_Current_Hash + "=" + String.valueOf(time.getTime())
|
||||
+ "# MLG v" + Main.VERSION + INFO);
|
||||
outFile.newLine();
|
||||
}
|
||||
outFile.close();
|
||||
inFile.close();
|
||||
|
||||
File fileDelete = new File(Main.buildIDFile);
|
||||
fileDelete.delete();
|
||||
File fileRename = new File(Main.buildIDFile + ".temp");
|
||||
fileRename.renameTo(new File(Main.buildIDFile));
|
||||
|
||||
} catch (FileNotFoundException ex) {
|
||||
Main.out("\"" + Main.buildIDFile + "\" file not Found. Generating New \""
|
||||
+ Main.buildIDFile + "\" File");
|
||||
|
||||
Main.writeTxtFile(Main.buildIDFile,
|
||||
Main.MLG_Current_Hash + "=" + String.valueOf(time.getTime()) + "#MLG v"
|
||||
+ Main.VERSION + INFO);
|
||||
|
||||
} catch (IOException ex) {
|
||||
Main.err("Could not create \"" + Main.buildIDFile + "\".");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the BuildID for MLG
|
||||
*
|
||||
* @author Morlok8k
|
||||
*
|
||||
*/
|
||||
public static void readBuildID() {
|
||||
|
||||
if (Main.inf_loop_protect_BuildID > 10) {
|
||||
Main.MLG_Last_Modified_Date = new Date(new Long(0)); //set the day to Jan 1, 1970 for failure
|
||||
return;
|
||||
}
|
||||
Main.inf_loop_protect_BuildID++; // this is to prevent an infinite loop (however unlikely)
|
||||
|
||||
if (Main.MLGFileName == null) {
|
||||
try {
|
||||
Main.MLGFileName = getClassLoader(Main.cls);
|
||||
} catch (Exception e) {
|
||||
Main.out("Error: Finding file failed");
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (Main.MLGFileName.equals(Main.rsrcError)) { return; }
|
||||
}
|
||||
|
||||
Main.MLGFileNameShort =
|
||||
Main.MLGFileName.substring(Main.MLGFileName.lastIndexOf(Main.fileSeparator) + 1,
|
||||
Main.MLGFileName.length());
|
||||
|
||||
if (Main.testing) {
|
||||
Main.outD("Currently Running as file:" + Main.MLGFileNameShort);
|
||||
}
|
||||
|
||||
if (Main.MLG_Current_Hash == null) {
|
||||
|
||||
try {
|
||||
Main.MLG_Current_Hash = Main.fileMD5(Main.MLGFileName);
|
||||
// out(hash + " " + MLGFileName);
|
||||
} catch (Exception e) {
|
||||
Main.out("Error: MLG_MD5 from file failed");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
int tsCount = 0;
|
||||
|
||||
Main.timeStamps.clear();
|
||||
|
||||
if (Main.MLG_Last_Modified_Date == null) {
|
||||
boolean foundLine = false;
|
||||
try {
|
||||
BufferedReader in = new BufferedReader(new FileReader(Main.buildIDFile));
|
||||
String line;
|
||||
|
||||
if (Main.testing) {
|
||||
Main.outD("TimeStamps in buildIDFile:");
|
||||
}
|
||||
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) {
|
||||
Main.timeStamps.add(line.substring(pos + 1, end));
|
||||
}
|
||||
}
|
||||
|
||||
//timeStamps.add(line.substring(pos + 1, end));
|
||||
|
||||
if (Main.testing) {
|
||||
Main.outD(Main.timeStamps.get(tsCount));
|
||||
}
|
||||
|
||||
tsCount++;
|
||||
|
||||
if (line.contains(Main.MLG_Current_Hash)) {
|
||||
// out("[DEBUG] Found!");
|
||||
foundLine = true;
|
||||
|
||||
if (pos != -1) {
|
||||
if (line.substring(0, pos).equals(Main.MLG_Current_Hash)) {
|
||||
Main.MLG_Last_Modified_Long =
|
||||
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 tCalc = Main.MLG_Last_Modified_Long - highestModTime;
|
||||
|
||||
if (Main.testing) {
|
||||
Main.outD("tCalc\tMLG_Last_Modified_Long\thighestModTime"
|
||||
+ Main.newLine + tCalc + "\t"
|
||||
+ Main.MLG_Last_Modified_Long + "\t" + highestModTime);
|
||||
}
|
||||
|
||||
if (highestModTime == 0L) {
|
||||
|
||||
Main.err("Archive Intergrity Check Failed: .zip/.jar file Issue.");
|
||||
Main.err("Archive Intergrity Check Failed: (MLG will still run. Just note that this may not be an official version.)");
|
||||
|
||||
} else {
|
||||
if (tCalc < -15000L) {
|
||||
|
||||
//time is newer? (.zip file is newer than BuildID)
|
||||
Main.err("Archive Intergrity Check Failed: .zip file is newer than BuildID. Offset: "
|
||||
+ (tCalc / 1000) + "sec.");
|
||||
Main.err("Archive Intergrity Check Failed: (MLG will still run. Just note that this may not be an official version.)");
|
||||
}
|
||||
|
||||
if (tCalc < 15000L) {
|
||||
|
||||
//times are within 30 seconds (+/- 15 seconds) of each other. (typically 1-2 seconds, but left room for real-world error)
|
||||
if (Main.testing | Main.flag_downloadedBuildID) {
|
||||
Main.out("Archive Intergrity Check Passed. Offset: "
|
||||
+ (tCalc / 1000) + "sec.");
|
||||
}
|
||||
|
||||
} else {
|
||||
//times dont match. (.zip file is older than specified BuildID)
|
||||
Main.err("Archive Intergrity Check Failed: .zip file is older than BuildID. Offset: "
|
||||
+ (tCalc / 1000) + "sec.");
|
||||
Main.err("Archive Intergrity Check Failed: (MLG will still run. Just note that this may not be an official version.)");
|
||||
}
|
||||
}
|
||||
//return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
in.close();
|
||||
|
||||
if (foundLine == false) {
|
||||
// out("[DEBUG] FoundLine False");
|
||||
buildID(false);
|
||||
readBuildID(); // yes I'm calling the function from itself. potential infinite loop? possibly. I haven't encountered it yet!
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Main.err("Cant Read " + Main.buildIDFile + "!");
|
||||
Main.err(e.getLocalizedMessage());
|
||||
Main.err("");
|
||||
// e.printStackTrace();
|
||||
buildID(false);
|
||||
readBuildID();
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates MLG to the Latest Version
|
||||
*
|
||||
* @author Morlok8k
|
||||
*
|
||||
*/
|
||||
public static void updateMLG() {
|
||||
|
||||
buildID(true); //get latest BuildID file.
|
||||
Main.MLG_Last_Modified_Date = null;
|
||||
readBuildID();
|
||||
|
||||
Iterator<String> e = Main.timeStamps.iterator();
|
||||
String s;
|
||||
int diff;
|
||||
|
||||
//boolean renameFailed = false;
|
||||
|
||||
while (e.hasNext()) {
|
||||
s = e.next();
|
||||
diff = Main.MLG_Last_Modified_Date.compareTo(new Date(new Long(s)));
|
||||
//out(diff);
|
||||
|
||||
if (diff < 0) { // if this is less than 0, there is a new version of MLG on the Internet!
|
||||
Main.out("There is a NEW VERSION Of " + Main.PROG_NAME + " available online!");
|
||||
|
||||
try {
|
||||
File fileRename = new File(Main.MLG_JarFile);
|
||||
fileRename.renameTo(new File(Main.MLG_JarFile + ".old"));
|
||||
} catch (Exception e1) {
|
||||
Main.out("Rename attempt #1 failed!");
|
||||
e1.printStackTrace();
|
||||
|
||||
try {
|
||||
Main.copyFile(new File(Main.MLG_JarFile), new File(Main.MLG_JarFile
|
||||
+ ".old"));
|
||||
File fileDelete = new File(Main.MLG_JarFile);
|
||||
fileDelete.delete();
|
||||
} catch (Exception e2) {
|
||||
Main.out("Rename attempt #2 failed!");
|
||||
e2.printStackTrace();
|
||||
//renameFailed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boolean fileSuccess = MLG_DownloadFile.downloadFile(Main.github_MLG_jar_URL, true);
|
||||
if (fileSuccess) {
|
||||
Main.out(Main.MLG_JarFile + " downloaded.");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets the filename of a .jar (typically this one!)
|
||||
*
|
||||
* @author Morlok8k
|
||||
*/
|
||||
public static String getClassLoader(Class<?> classFile) throws IOException {
|
||||
ClassLoader loader = classFile.getClassLoader();
|
||||
String filename = classFile.getName().replace('.', '/') + ".class";
|
||||
URL resource =
|
||||
(loader != null) ? loader.getResource(filename) : ClassLoader
|
||||
.getSystemResource(filename);
|
||||
filename = URLDecoder.decode(resource.toString(), "UTF-8");
|
||||
// out(filename);
|
||||
|
||||
// START Garbage removal:
|
||||
int bang = filename.indexOf("!"); // remove everything after xxxx.jar
|
||||
if (bang == -1) { // a real example:
|
||||
bang = filename.length(); // jar:file:/home/morlok8k/test.jar!/me/Morlok8k/test/Main.class
|
||||
}
|
||||
int file = filename.indexOf("file:"); // removes junk from the beginning of the path
|
||||
file = file + 5;
|
||||
if (file == -1) {
|
||||
file = 0;
|
||||
}
|
||||
if (filename.contains("rsrc:")) {
|
||||
Main.err("THIS WAS COMPILED USING \"org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader\"! ");
|
||||
Main.err("DO NOT PACKAGE YOUR .JAR'S WITH THIS CLASSLOADER CODE!");
|
||||
Main.err("(Your Libraries need to be extracted.)");
|
||||
return Main.rsrcError;
|
||||
}
|
||||
if (filename.contains(".jar")) {
|
||||
Main.isCompiledAsJar = true;
|
||||
}
|
||||
filename = filename.replace('/', File.separatorChar);
|
||||
String returnString = filename.substring(file, bang);
|
||||
// END Garbage removal
|
||||
return returnString;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets the TimeStamp (last modified date) of a class file (typically this one!) <br>
|
||||
* <br>
|
||||
* Thanks to Roedy Green at <br>
|
||||
* <a href="http://mindprod.com/jgloss/compiletimestamp.html">http://mindprod .com/jgloss/compiletimestamp.html</a>
|
||||
*
|
||||
* @author Morlok8k
|
||||
*/
|
||||
public static Date getCompileTimeStamp(Class<?> classFile) throws IOException {
|
||||
ClassLoader loader = classFile.getClassLoader();
|
||||
String filename = classFile.getName().replace('.', '/') + ".class";
|
||||
// get the corresponding class file as a Resource.
|
||||
URL resource =
|
||||
(loader != null) ? loader.getResource(filename) : ClassLoader
|
||||
.getSystemResource(filename);
|
||||
URLConnection connection = resource.openConnection();
|
||||
// Note, we are using Connection.getLastModified not File.lastModifed.
|
||||
// This will then work both or members of jars or standalone class files.
|
||||
// NOTE: NOT TRUE! IT READS THE JAR, NOT THE FILES INSIDE!
|
||||
long time = connection.getLastModified();
|
||||
return (time != 0L) ? new Date(time) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>.zip file Get Modification Time</b><br>
|
||||
*
|
||||
* Takes a string of a path to a .zip file (or .jar), and and returns a Long of the latest "Last Time Modified". <br>
|
||||
* <br>
|
||||
*
|
||||
* Thanks to the following:<br>
|
||||
* <a href="http://www.java-examples.com/get-modification-time-zip-entry-example">http://www.java-examples.com/get-modification-time-zip-entry-example</a><br>
|
||||
* <a href="http://www.java-examples.com/get-crc-32-checksum-zip-entry-example">http://www.java-examples.com/get-crc-32-checksum-zip-entry-example</a>
|
||||
*
|
||||
* @param zipFile
|
||||
* @param timeBuildID
|
||||
* @author Morlok8k
|
||||
*/
|
||||
public static Long ZipGetModificationTime(String zipFile) {
|
||||
|
||||
Long highestModTime = 0L;
|
||||
|
||||
try {
|
||||
|
||||
ZipFile zipF = new ZipFile(zipFile);
|
||||
|
||||
/*
|
||||
* Get list of zip entries using entries method of ZipFile class.
|
||||
*/
|
||||
|
||||
Enumeration<? extends ZipEntry> e = zipF.entries();
|
||||
|
||||
if (Main.testing) {
|
||||
Main.outD("File Name\t\tCRC\t\tModification Time\n---------------------------------\n");
|
||||
}
|
||||
|
||||
while (e.hasMoreElements()) {
|
||||
ZipEntry entry = e.nextElement();
|
||||
|
||||
Long modTime = entry.getTime();
|
||||
|
||||
if (!(entry.getName().toUpperCase().contains(".CLASS"))) { //ignore highest timestamp for non .class files, as they can be injected into the .jar file much later after compiling.
|
||||
modTime = 0L;
|
||||
}
|
||||
|
||||
if (highestModTime < modTime) {
|
||||
highestModTime = modTime;
|
||||
}
|
||||
|
||||
if (Main.testing) {
|
||||
|
||||
String entryName = entry.getName();
|
||||
Date modificationTime = new Date(modTime);
|
||||
String CRC = Long.toHexString(entry.getCrc());
|
||||
|
||||
Main.outD(entryName + "\t" + CRC + "\t" + modificationTime + "\t"
|
||||
+ modTime.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
zipF.close();
|
||||
|
||||
return highestModTime;
|
||||
|
||||
} catch (IOException ioe) {
|
||||
Main.out("Error opening zip file" + ioe);
|
||||
return 0L; //return Jan. 1, 1970 12:00 GMT for failures
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user