Reset the java directory when javadir is wrong.

This commit is contained in:
huanghongxun
2015-08-25 09:11:29 +08:00
parent 9fc1470a63
commit 10bb60f998
27 changed files with 302 additions and 259 deletions

View File

@@ -22,8 +22,6 @@ import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.SwingUtilities;
import org.jackhuang.hellominecraft.C;
import org.jackhuang.hellominecraft.HMCLog;
@@ -91,6 +89,9 @@ public final class Launcher {
SwingUtilities.invokeLater(() -> LogWindow.instance.setVisible(true));
}
if (!JdkVersion.isJava64Bit() && Platform.getPlatform() == Platform.BIT_64)
MessageBox.Show(C.i18n("advice.os64butjdk32"));
URL[] urls = new URL[len];
try {
@@ -103,12 +104,9 @@ public final class Launcher {
return;
}
if (!JdkVersion.isJava64Bit() && Platform.getPlatform() == Platform.BIT_64)
MessageBox.Show(C.i18n("advice.os64butjdk32"));
Method minecraftMain;
try {
minecraftMain = new URLClassLoader(urls).loadClass(mainClass).getMethod("main", String[].class);
minecraftMain = new URLClassLoader(urls, URLClassLoader.getSystemClassLoader().getParent()).loadClass(mainClass).getMethod("main", String[].class);
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException t) {
MessageBox.Show(C.i18n("crash.main_class_not_found"));
println("Minecraft main class not found.");

View File

@@ -26,19 +26,22 @@ import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.GeneralSecurityException;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.util.Map;
import java.util.jar.JarFile;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;
import javax.swing.ImageIcon;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.jackhuang.hellominecraft.C;
import org.jackhuang.hellominecraft.utils.functions.NonConsumer;
import org.jackhuang.hellominecraft.HMCLog;
import org.jackhuang.hellominecraft.launcher.launch.GameLauncher;
import org.jackhuang.hellominecraft.launcher.utils.CrashReporter;
@@ -47,18 +50,24 @@ import org.jackhuang.hellominecraft.logging.appender.ConsoleAppender;
import org.jackhuang.hellominecraft.logging.layout.DefaultLayout;
import org.jackhuang.hellominecraft.views.LogWindow;
import org.jackhuang.hellominecraft.launcher.settings.Settings;
import org.jackhuang.hellominecraft.launcher.utils.upgrade.Upgrader;
import org.jackhuang.hellominecraft.launcher.views.MainFrame;
import org.jackhuang.hellominecraft.lookandfeel.HelloMinecraftLookAndFeel;
import org.jackhuang.hellominecraft.tasks.TaskWindow;
import org.jackhuang.hellominecraft.utils.ArrayUtils;
import org.jackhuang.hellominecraft.utils.system.MessageBox;
import org.jackhuang.hellominecraft.utils.StrUtils;
import org.jackhuang.hellominecraft.utils.VersionNumber;
import org.jackhuang.hellominecraft.utils.system.FileUtils;
import org.jackhuang.hellominecraft.utils.system.IOUtils;
import org.jackhuang.hellominecraft.utils.system.OS;
/**
*
* @author huangyuhui
*/
public final class Main implements NonConsumer {
public final class Main implements Runnable {
private static final X509TrustManager xtm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
@@ -91,7 +100,7 @@ public final class Main implements NonConsumer {
}
public static String launcherName = "Hello Minecraft! Launcher";
public static byte firstVer = 2, secondVer = 3, thirdVer = 4, forthVer = 12;
public static byte firstVer = 2, secondVer = 3, thirdVer = 4, forthVer = 13;
public static int minimumLauncherVersion = 16;
/**
@@ -116,6 +125,31 @@ public final class Main implements NonConsumer {
public static void main(String[] args) {
{
if (!ArrayUtils.contains(args, "nofound"))
try {
File f = Upgrader.HMCL_VER_FILE;
if (f.exists()) {
Map<String, String> m = C.gson.fromJson(FileUtils.readFileToString(f), Map.class);
String s = m.get("ver");
if (s != null && VersionNumber.check(s).compareTo(new VersionNumber(firstVer, secondVer, thirdVer)) > 0) {
String j = m.get("loc");
if (j != null) {
File jar = new File(j);
if (jar.exists()) {
JarFile jarFile = new JarFile(jar);
String mainClass = jarFile.getManifest().getMainAttributes().getValue("Main-Class");
if (mainClass != null) {
new URLClassLoader(new URL[]{jar.toURI().toURL()}, URLClassLoader.getSystemClassLoader().getParent()).loadClass(mainClass).getMethod("main", String[].class).invoke(null, new Object[]{new String[]{"nofound"}});
return;
}
}
}
}
}
} catch (Throwable t) {
t.printStackTrace();
}
Thread.setDefaultUncaughtExceptionHandler(new CrashReporter(true));
try {
@@ -152,43 +186,54 @@ public final class Main implements NonConsumer {
}
});
}
MainFrame.showMainFrame(Settings.isFirstLoad());
}
}
@Override
public void onDone() {
public void run() {
GameLauncher.PROCESS_MANAGER.stopAllProcesses();
}
public static void update() {
if (MessageBox.Show(C.i18n("update.newest_version") + Settings.UPDATE_CHECKER.getNewVersion().firstVer + "." + Settings.UPDATE_CHECKER.getNewVersion().secondVer + "." + Settings.UPDATE_CHECKER.getNewVersion().thirdVer + "\n"
+ C.i18n("update.should_open_link"),
MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) {
Map<String, String> map = Settings.UPDATE_CHECKER.download_link;
String url = C.URL_PUBLISH;
if (map != null)
if (map.containsKey(OS.os().checked_name))
url = map.get(OS.os().checked_name);
else if (map.containsKey(OS.UNKOWN.checked_name))
url = map.get(OS.UNKOWN.checked_name);
if (url == null) url = C.URL_PUBLISH;
try {
java.awt.Desktop.getDesktop().browse(new URI(url));
} catch (URISyntaxException | IOException e) {
HMCLog.warn("Failed to browse uri: " + url, e);
Settings.UPDATE_CHECKER.requestDownloadLink(() -> {
SwingUtilities.invokeLater(() -> {
Map<String, String> map = Settings.UPDATE_CHECKER.download_link;
if (map != null && map.containsKey("pack"))
try {
if (TaskWindow.getInstance().addTask(new Upgrader(map.get("pack"), Settings.UPDATE_CHECKER.versionString)).start()) {
new ProcessBuilder(new String[]{IOUtils.getJavaDir(), "-jar", Upgrader.getSelf(Settings.UPDATE_CHECKER.versionString).getAbsolutePath()}).directory(new File(".")).start();
System.exit(0);
}
} catch (IOException ex) {
HMCLog.warn("Failed to create upgrader", ex);
}
if (MessageBox.Show(C.i18n("update.newest_version") + Settings.UPDATE_CHECKER.getNewVersion().firstVer + "." + Settings.UPDATE_CHECKER.getNewVersion().secondVer + "." + Settings.UPDATE_CHECKER.getNewVersion().thirdVer + "\n"
+ C.i18n("update.should_open_link"),
MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) {
String url = C.URL_PUBLISH;
if (map != null)
if (map.containsKey(OS.os().checked_name))
url = map.get(OS.os().checked_name);
else if (map.containsKey(OS.UNKOWN.checked_name))
url = map.get(OS.UNKOWN.checked_name);
if (url == null) url = C.URL_PUBLISH;
try {
java.awt.Desktop.getDesktop().browse(new URI(url));
} catch (URISyntaxException | IOException e) {
HMCLog.warn("Failed to browse uri: " + url, e);
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
cb.setContents(new StringSelection(url), null);
MessageBox.Show(C.i18n("update.no_browser"));
}
} else
Settings.getInstance().setCheckUpdate(false);
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
cb.setContents(new StringSelection(url), null);
MessageBox.Show(C.i18n("update.no_browser"));
}
}
});
});
}
public static void invokeUpdate() {
if (Settings.getInstance().isCheckUpdate()) update();
MainFrame.instance.invokeUpdate();
}

View File

@@ -58,6 +58,11 @@ public abstract class AbstractMinecraftLoader implements IMinecraftLoader {
HMCLog.log("On making head command.");
String str = v.getJavaDir();
if(!v.getJavaDirFile().exists()) {
MessageBox.Show(C.i18n("launch.wrong_javadir"));
v.setJava(null);
str = v.getJavaDir();
}
JdkVersion jv = new JdkVersion(str);
if (Settings.getInstance().getJava().contains(jv))
jv = Settings.getInstance().getJava().get(Settings.getInstance().getJava().indexOf(jv));

View File

@@ -133,6 +133,7 @@ public class GameLauncher {
HMCLog.warn("Failed to invoke precalled command", ex);
}
}
HMCLog.log("Starting process");
ProcessBuilder builder = new ProcessBuilder(str);
builder.directory(provider.getRunDirectory(get.getSelectedMinecraftVersion().id))
.environment().put("APPDATA", get.getCanonicalGameDirFile().getPath());

View File

@@ -49,6 +49,7 @@ public class LaunchFinisher implements Event<List<String>> {
System.exit(0);
return true;
});
jpm.start();
return true;
});
obj.launch(str);

View File

@@ -20,10 +20,7 @@ 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 java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.jar.JarEntry;
@@ -31,8 +28,7 @@ import java.util.jar.JarOutputStream;
import java.util.jar.Pack200;
import org.jackhuang.hellominecraft.C;
import org.jackhuang.hellominecraft.HMCLog;
import org.jackhuang.hellominecraft.tasks.Task;
import org.jackhuang.hellominecraft.tasks.download.NetException;
import org.jackhuang.hellominecraft.tasks.download.FileDownloadTask;
import org.jackhuang.hellominecraft.utils.system.IOUtils;
import org.tukaani.xz.XZInputStream;
@@ -40,13 +36,12 @@ import org.tukaani.xz.XZInputStream;
*
* @author huangyuhui
*/
public class LibraryDownloadTask extends Task {
private static final int MAX_BUFFER_SIZE = 2048;
public class LibraryDownloadTask extends FileDownloadTask {
GameLauncher.DownloadLibraryJob job;
public LibraryDownloadTask(GameLauncher.DownloadLibraryJob job) {
super();
this.job = job;
}
@@ -76,95 +71,11 @@ public class LibraryDownloadTask extends Task {
return false;
}
}
InputStream stream;
RandomAccessFile file;
boolean shouldContinue = true;
int size = -1;
boolean download(URL url, File filePath) {
HMCLog.log("Downloading: " + url + " to " + filePath);
size = -1;
int downloaded = 0;
for (int repeat = 0; repeat < 6; repeat++) {
if (repeat > 0)
HMCLog.warn("Failed to download, repeat: " + repeat);
try {
// Open connection to URL.
HttpURLConnection connection
= (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setRequestProperty("User-Agent", "Hello Minecraft! Launcher");
// Connect to server.
connection.connect();
// Make sure response code is in the 200 range.
if (connection.getResponseCode() / 100 != 2) {
setFailReason(new NetException(C.i18n("download.not_200") + " " + connection.getResponseCode()));
return false;
}
// Check for valid content length.
int contentLength = connection.getContentLength();
if (contentLength < 1) {
setFailReason(new NetException("The content length is invalid."));
return false;
}
// Set the size for this download if it hasn't been already set.
if (size == -1)
size = contentLength;
filePath.getParentFile().mkdirs();
File tempFile = new File(filePath.getAbsolutePath() + ".hmd");
if (!tempFile.exists())
tempFile.createNewFile();
// Open file and seek to the end of it.
file = new RandomAccessFile(tempFile, "rw");
file.seek(downloaded);
stream = connection.getInputStream();
while (true) {
// Size buffer according to how much of the file is left to download.
if (!shouldContinue) {
closeFiles();
filePath.delete();
break;
}
byte buffer[] = new byte[MAX_BUFFER_SIZE];
// Read from server into buffer.
int read = stream.read(buffer);
if (read == -1)
break;
// Write buffer to file.
file.write(buffer, 0, read);
downloaded += read;
if (ppl != null)
ppl.setProgress(this, downloaded, size);
}
closeFiles();
if (aborted)
tempFile.delete();
else
tempFile.renameTo(filePath);
if (ppl != null)
ppl.onProgressProviderDone(this);
return true;
} catch (Exception e) {
setFailReason(new NetException(C.i18n("download.failed") + " " + url, e));
} finally {
closeFiles();
}
}
return false;
this.url = url;
this.filePath = filePath;
return super.executeTask();
}
public static void unpackLibrary(File output, File input)
@@ -211,33 +122,6 @@ public class LibraryDownloadTask extends Task {
temp.delete();
}
private void closeFiles() {
// Close file.
if (file != null)
try {
file.close();
file = null;
} catch (IOException e) {
HMCLog.warn("Failed to close file", e);
}
// Close connection to server.
if (stream != null)
try {
stream.close();
stream = null;
} catch (IOException e) {
HMCLog.warn("Failed to close stream", e);
}
}
@Override
public boolean abort() {
shouldContinue = false;
aborted = true;
return true;
}
@Override
public String getInfo() {
return C.i18n("download") + ": " + job.name;

View File

@@ -125,15 +125,6 @@ public final class Config {
return configurations;
}
public boolean isCheckUpdate() {
return checkUpdate;
}
public void setCheckUpdate(boolean checkUpdate) {
this.checkUpdate = checkUpdate;
Settings.save();
}
public Map getYggdrasilConfig() {
return yggdrasil;
}
@@ -149,8 +140,6 @@ public final class Config {
private int downloadtype;
@SerializedName("configurations")
private TreeMap<String, Profile> configurations;
@SerializedName("checkUpdate")
private boolean checkUpdate;
@SerializedName("yggdrasil")
private Map yggdrasil;
@@ -158,7 +147,6 @@ public final class Config {
clientToken = UUID.randomUUID().toString();
username = "";
logintype = downloadtype = 0;
checkUpdate = true;
configurations = new TreeMap<>();
Profile profile = new Profile();
configurations.put(profile.getName(), profile);

View File

@@ -165,9 +165,13 @@ public final class Profile {
}
public void setJava(Java java) {
int idx = Settings.JAVA.indexOf(java);
if (idx == -1) return;
this.java = java.getName();
if (java == null)
this.java = Settings.JAVA.get(0).getName();
else {
int idx = Settings.JAVA.indexOf(java);
if (idx == -1) return;
this.java = java.getName();
}
Settings.save();
}

View File

@@ -69,7 +69,7 @@ public final class Settings {
e.checkFormat();
UPDATE_CHECKER = new UpdateChecker(new VersionNumber(Main.firstVer, Main.secondVer, Main.thirdVer),
"hmcl", settings.isCheckUpdate(), Main::invokeUpdate);
"hmcl", Main::invokeUpdate);
List<Java> temp = new ArrayList<>();
temp.add(new Java("Default", System.getProperty("java.home")));

View File

@@ -20,15 +20,8 @@ import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.jackhuang.hellominecraft.C;
import org.jackhuang.hellominecraft.HMCLog;
import org.jackhuang.hellominecraft.launcher.utils.assets.AssetsIndex;
import org.jackhuang.hellominecraft.launcher.utils.assets.AssetsObject;
@@ -42,7 +35,6 @@ import org.jackhuang.hellominecraft.utils.system.FileUtils;
import org.jackhuang.hellominecraft.utils.system.IOUtils;
import org.jackhuang.hellominecraft.version.MinecraftVersionRequest;
import org.jackhuang.hellominecraft.utils.NetUtils;
import org.jackhuang.hellominecraft.utils.Pair;
import org.jackhuang.hellominecraft.utils.system.OS;
/**
@@ -188,30 +180,33 @@ public final class MCUtils {
}
}
public static File getLocation() {
String baseName = "minecraft";
String str1 = System.getProperty("user.home", ".");
public static File getWorkingDirectory(String baseName) {
String userhome = System.getProperty("user.home", ".");
File file;
switch (OS.os()) {
case LINUX:
file = new File(str1, '.' + (String) baseName + '/');
file = new File(userhome, '.' + baseName + '/');
break;
case WINDOWS:
String str2;
if ((str2 = System.getenv("APPDATA")) != null)
file = new File(str2, "." + baseName + '/');
String appdata = System.getenv("APPDATA");
if (appdata != null)
file = new File(appdata, "." + baseName + '/');
else
file = new File(str1, '.' + baseName + '/');
file = new File(userhome, '.' + baseName + '/');
break;
case OSX:
file = new File(str1, "Library/Application Support/" + baseName);
file = new File(userhome, "Library/Application Support/" + baseName);
break;
default:
file = new File(str1, baseName + '/');
file = new File(userhome, baseName + '/');
}
return file;
}
public static File getLocation() {
return getWorkingDirectory("minecraft");
}
public static boolean is16Folder(String path) {
path = IOUtils.addSeparator(path);
return new File(path, "versions").exists();
@@ -252,7 +247,7 @@ public final class MCUtils {
}
return null;
}
public static boolean downloadMinecraftJar(File gameDir, String id, DownloadType sourceType) {
String vurl = sourceType.getProvider().getVersionsDownloadURL() + id + "/";
File vpath = new File(gameDir, "versions/" + id);

View File

@@ -0,0 +1,91 @@
/*
* Copyright 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.
*/
package org.jackhuang.hellominecraft.launcher.utils.upgrade;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.jar.JarOutputStream;
import java.util.jar.Pack200;
import org.jackhuang.hellominecraft.C;
import org.jackhuang.hellominecraft.launcher.utils.MCUtils;
import org.jackhuang.hellominecraft.tasks.Task;
import org.jackhuang.hellominecraft.tasks.download.FileDownloadTask;
import org.jackhuang.hellominecraft.utils.system.FileUtils;
import org.tukaani.xz.XZInputStream;
/**
*
* @author huangyuhui
*/
public class Upgrader extends Task {
public static final File BASE_FOLDER = MCUtils.getWorkingDirectory("hmcl");
public static final File HMCL_VER_FILE = new File(BASE_FOLDER, "hmclver.json");
public static File getSelf(String ver) {
return new File(BASE_FOLDER, "HMCL-" + ver + ".jar");
}
private final String downloadLink, newestVersion;
File tempFile;
public Upgrader(String downloadLink, String newestVersion) throws IOException {
this.downloadLink = downloadLink;
this.newestVersion = newestVersion;
tempFile = File.createTempFile("hmcl", ".pack.xz");
}
@Override
public Collection<Task> getDependTasks() {
return Arrays.asList(new FileDownloadTask(downloadLink, tempFile));
}
@Override
public boolean executeTask() {
HashMap<String, String> json = new HashMap<>();
File f = getSelf(newestVersion);
try {
if (!f.getParentFile().exists()) f.getParentFile().mkdirs();
for (int i = 0; f.exists(); i++) f = new File(BASE_FOLDER, "HMCL-" + newestVersion + (i > 0 ? "-" + i : "") + ".jar");
f.createNewFile();
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(f))) {
Pack200.newUnpacker().unpack(new XZInputStream(new FileInputStream(tempFile)), jos);
}
json.put("ver", newestVersion);
json.put("loc", f.getAbsolutePath());
String result = C.gson.toJson(json);
FileUtils.write(HMCL_VER_FILE, result);
return true;
} catch (IOException e) {
setFailReason(e);
return false;
}
}
@Override
public String getInfo() {
return "Upgrade";
}
}

View File

@@ -372,7 +372,6 @@ public final class MainFrame extends DraggableFrame {
}
public void invokeUpdate() {
if (!isVisible()) return;
defaultTitle = defaultTitle + C.i18n("update.found");
if (!isShowedMessage) {
windowTitle.setText(defaultTitle);

View File

@@ -238,8 +238,8 @@ public class MainPagePanel extends javax.swing.JPanel {
.addComponent(pnlPassword, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(pnlMoreLayout.createSequentialGroup()
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel10)
.addComponent(jLabel1))
.addComponent(jLabel10, javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jLabel1, javax.swing.GroupLayout.Alignment.TRAILING))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(cboProfiles, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)