mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-10 12:26:16 -04:00
Reconstruct codes
This commit is contained in:
parent
b3fb372e3b
commit
713a0171cc
0
Apache License 2.0~
Normal file
0
Apache License 2.0~
Normal file
@ -80,8 +80,8 @@ jar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
launch4j {
|
launch4j {
|
||||||
//launch4jCmd = 'D:\\Develop\\Java\\Launch4j\\launch4j.exe'
|
launch4jCmd = 'D:\\Develop\\Java\\Launch4j\\launch4j.exe'
|
||||||
launch4jCmd = '/home/huangyuhui/softwares/launch4j/launch4j'
|
//launch4jCmd = '/home/huangyuhui/softwares/launch4j/launch4j'
|
||||||
supportUrl = 'http://www.mcbbs.net/thread-142335-1-1.html'
|
supportUrl = 'http://www.mcbbs.net/thread-142335-1-1.html'
|
||||||
jreMinVersion = '1.6.0'
|
jreMinVersion = '1.6.0'
|
||||||
|
|
||||||
|
@ -17,34 +17,21 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hellominecraft.launcher;
|
package org.jackhuang.hellominecraft.launcher;
|
||||||
|
|
||||||
import java.awt.Toolkit;
|
|
||||||
import java.awt.datatransfer.Clipboard;
|
|
||||||
import java.awt.datatransfer.StringSelection;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Authenticator;
|
import java.net.Authenticator;
|
||||||
import java.net.PasswordAuthentication;
|
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.GeneralSecurityException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.jar.JarFile;
|
|
||||||
import javax.net.ssl.HostnameVerifier;
|
import javax.net.ssl.HostnameVerifier;
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.X509TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.UnsupportedLookAndFeelException;
|
import javax.swing.UnsupportedLookAndFeelException;
|
||||||
import org.jackhuang.hellominecraft.C;
|
|
||||||
import org.jackhuang.hellominecraft.HMCLog;
|
import org.jackhuang.hellominecraft.HMCLog;
|
||||||
import org.jackhuang.hellominecraft.launcher.launch.GameLauncher;
|
import org.jackhuang.hellominecraft.launcher.launch.GameLauncher;
|
||||||
import org.jackhuang.hellominecraft.launcher.utils.CrashReporter;
|
import org.jackhuang.hellominecraft.launcher.utils.CrashReporter;
|
||||||
@ -53,18 +40,13 @@ import org.jackhuang.hellominecraft.logging.appender.ConsoleAppender;
|
|||||||
import org.jackhuang.hellominecraft.logging.layout.DefaultLayout;
|
import org.jackhuang.hellominecraft.logging.layout.DefaultLayout;
|
||||||
import org.jackhuang.hellominecraft.views.LogWindow;
|
import org.jackhuang.hellominecraft.views.LogWindow;
|
||||||
import org.jackhuang.hellominecraft.launcher.settings.Settings;
|
import org.jackhuang.hellominecraft.launcher.settings.Settings;
|
||||||
import org.jackhuang.hellominecraft.launcher.utils.upgrade.Upgrader;
|
import org.jackhuang.hellominecraft.launcher.utils.upgrade.IUpgrader;
|
||||||
import org.jackhuang.hellominecraft.launcher.views.MainFrame;
|
import org.jackhuang.hellominecraft.launcher.views.MainFrame;
|
||||||
import org.jackhuang.hellominecraft.lookandfeel.HelloMinecraftLookAndFeel;
|
import org.jackhuang.hellominecraft.lookandfeel.HelloMinecraftLookAndFeel;
|
||||||
import org.jackhuang.hellominecraft.tasks.TaskWindow;
|
|
||||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
|
||||||
import org.jackhuang.hellominecraft.utils.MathUtils;
|
import org.jackhuang.hellominecraft.utils.MathUtils;
|
||||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
|
||||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||||
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
import rx.concurrency.Schedulers;
|
||||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
|
||||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -104,7 +86,7 @@ public final class Main implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String launcherName = "Hello Minecraft! Launcher";
|
public static String launcherName = "Hello Minecraft! Launcher";
|
||||||
public static byte firstVer = 2, secondVer = 3, thirdVer = 5, forthVer = 6;
|
public static byte firstVer = 2, secondVer = 3, thirdVer = 1, forthVer = 6;
|
||||||
public static int minimumLauncherVersion = 16;
|
public static int minimumLauncherVersion = 16;
|
||||||
//public static Proxy PROXY;
|
//public static Proxy PROXY;
|
||||||
|
|
||||||
@ -131,34 +113,8 @@ public final class Main implements Runnable {
|
|||||||
@SuppressWarnings( {"CallToPrintStackTrace", "UseSpecificCatch"})
|
@SuppressWarnings( {"CallToPrintStackTrace", "UseSpecificCatch"})
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
{
|
{
|
||||||
if (!ArrayUtils.contains(args, "nofound"))
|
if (IUpgrader.NOW_UPGRADER.parseArguments(new VersionNumber(firstVer, secondVer, thirdVer), args))
|
||||||
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) {
|
|
||||||
ArrayList<String> al = new ArrayList<>(Arrays.asList(args));
|
|
||||||
al.add("notfound");
|
|
||||||
new URLClassLoader(new URL[] {jar.toURI().toURL()},
|
|
||||||
URLClassLoader.getSystemClassLoader().getParent()).loadClass(mainClass)
|
|
||||||
.getMethod("main", String[].class).invoke(null, new Object[] {al.toArray(new String[0])});
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
|
||||||
t.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
System.setProperty("sun.java2d.noddraw", "true");
|
System.setProperty("sun.java2d.noddraw", "true");
|
||||||
|
|
||||||
@ -185,7 +141,9 @@ public final class Main implements Runnable {
|
|||||||
HMCLog.warn("Failed to set look and feel...", ex);
|
HMCLog.warn("Failed to set look and feel...", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings.UPDATE_CHECKER.start();
|
Settings.UPDATE_CHECKER.outdated.register(IUpgrader.NOW_UPGRADER);
|
||||||
|
Settings.UPDATE_CHECKER.process(false).subscribeOn(Schedulers.newThread()).subscribe(t ->
|
||||||
|
Main.invokeUpdate());
|
||||||
|
|
||||||
if (StrUtils.isNotBlank(Settings.getInstance().getProxyHost()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPort()) && MathUtils.canParseInt(Settings.getInstance().getProxyPort())) {
|
if (StrUtils.isNotBlank(Settings.getInstance().getProxyHost()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPort()) && MathUtils.canParseInt(Settings.getInstance().getProxyPort())) {
|
||||||
HMCLog.log("Initializing customized proxy");
|
HMCLog.log("Initializing customized proxy");
|
||||||
@ -198,9 +156,6 @@ public final class Main implements Runnable {
|
|||||||
return new PasswordAuthentication(Settings.getInstance().getProxyUserName(), Settings.getInstance().getProxyPassword().toCharArray());
|
return new PasswordAuthentication(Settings.getInstance().getProxyUserName(), Settings.getInstance().getProxyPassword().toCharArray());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
//PROXY = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(Settings.getInstance().getProxyHost(), Integer.parseInt(Settings.getInstance().getProxyPort())));
|
|
||||||
} else {
|
|
||||||
//PROXY = Proxy.NO_PROXY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -217,44 +172,6 @@ public final class Main implements Runnable {
|
|||||||
GameLauncher.PROCESS_MANAGER.stopAllProcesses();
|
GameLauncher.PROCESS_MANAGER.stopAllProcesses();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void update() {
|
|
||||||
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"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void invokeUpdate() {
|
public static void invokeUpdate() {
|
||||||
MainFrame.INSTANCE.invokeUpdate();
|
MainFrame.INSTANCE.invokeUpdate();
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,9 @@ public abstract class AbstractMinecraftLoader implements IMinecraftLoader {
|
|||||||
res.add(v.getWidth());
|
res.add(v.getWidth());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StrUtils.isNotBlank(v.getServerIp())) {
|
String serverIp = v.getServerIp();
|
||||||
|
if (lr.getServerIp() != null) serverIp = lr.getServerIp();
|
||||||
|
if (StrUtils.isNotBlank(serverIp)) {
|
||||||
String[] args = v.getServerIp().split(":");
|
String[] args = v.getServerIp().split(":");
|
||||||
res.add("--server");
|
res.add("--server");
|
||||||
res.add(args[0]);
|
res.add(args[0]);
|
||||||
|
@ -70,7 +70,7 @@ public final class Settings {
|
|||||||
e.checkFormat();
|
e.checkFormat();
|
||||||
|
|
||||||
UPDATE_CHECKER = new UpdateChecker(new VersionNumber(Main.firstVer, Main.secondVer, Main.thirdVer),
|
UPDATE_CHECKER = new UpdateChecker(new VersionNumber(Main.firstVer, Main.secondVer, Main.thirdVer),
|
||||||
"hmcl", Main::invokeUpdate);
|
"hmcl");
|
||||||
|
|
||||||
List<Java> temp = new ArrayList<>();
|
List<Java> temp = new ArrayList<>();
|
||||||
temp.add(new Java("Default", System.getProperty("java.home")));
|
temp.add(new Java("Default", System.getProperty("java.home")));
|
||||||
@ -119,7 +119,8 @@ public final class Settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Profile getProfile(String name) {
|
public static Profile getProfile(String name) {
|
||||||
if (name == null) return getProfiles().get("Default");
|
if (name == null)
|
||||||
|
return getProfiles().get("Default");
|
||||||
return getProfiles().get(name);
|
return getProfiles().get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@ import javax.swing.SwingUtilities;
|
|||||||
import org.jackhuang.hellominecraft.C;
|
import org.jackhuang.hellominecraft.C;
|
||||||
import org.jackhuang.hellominecraft.HMCLog;
|
import org.jackhuang.hellominecraft.HMCLog;
|
||||||
import org.jackhuang.hellominecraft.launcher.Main;
|
import org.jackhuang.hellominecraft.launcher.Main;
|
||||||
|
import org.jackhuang.hellominecraft.launcher.settings.Settings;
|
||||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||||
import org.jackhuang.hellominecraft.utils.UpdateChecker;
|
|
||||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||||
import org.jackhuang.hellominecraft.views.LogWindow;
|
import org.jackhuang.hellominecraft.views.LogWindow;
|
||||||
@ -105,8 +105,8 @@ public class CrashReporter implements Thread.UncaughtExceptionHandler {
|
|||||||
System.out.println(text);
|
System.out.println(text);
|
||||||
|
|
||||||
if (checkThrowable(e) && !System.getProperty("java.vm.name").contains("OpenJDK")) {
|
if (checkThrowable(e) && !System.getProperty("java.vm.name").contains("OpenJDK")) {
|
||||||
SwingUtilities.invokeLater(() -> LogWindow.INSTANCE.showAsCrashWindow(UpdateChecker.OUT_DATED));
|
SwingUtilities.invokeLater(() -> LogWindow.INSTANCE.showAsCrashWindow(Settings.UPDATE_CHECKER.OUT_DATED));
|
||||||
if (!UpdateChecker.OUT_DATED)
|
if (!Settings.UPDATE_CHECKER.OUT_DATED)
|
||||||
reportToServer(text, s);
|
reportToServer(text, s);
|
||||||
}
|
}
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
|
@ -52,7 +52,8 @@ public final class UserProfileProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setAccessToken(String accessToken) {
|
public void setAccessToken(String accessToken) {
|
||||||
if (accessToken == null) accessToken = "0";
|
if (accessToken == null)
|
||||||
|
accessToken = "0";
|
||||||
this.accessToken = accessToken;
|
this.accessToken = accessToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,4 +115,13 @@ public final class UserProfileProvider {
|
|||||||
private String otherInfo = "";
|
private String otherInfo = "";
|
||||||
private String clientIdentifier = "";
|
private String clientIdentifier = "";
|
||||||
private String userType = "Offline";
|
private String userType = "Offline";
|
||||||
|
private String serverIp = "";
|
||||||
|
|
||||||
|
public String getServerIp() {
|
||||||
|
return serverIp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServerIp(String serverIp) {
|
||||||
|
this.serverIp = serverIp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ package org.jackhuang.hellominecraft.launcher.utils.installers;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import org.jackhuang.hellominecraft.launcher.settings.Profile;
|
import org.jackhuang.hellominecraft.launcher.settings.Profile;
|
||||||
import org.jackhuang.hellominecraft.launcher.settings.Settings;
|
|
||||||
import org.jackhuang.hellominecraft.launcher.utils.installers.InstallerVersionList.InstallerVersion;
|
import org.jackhuang.hellominecraft.launcher.utils.installers.InstallerVersionList.InstallerVersion;
|
||||||
import org.jackhuang.hellominecraft.launcher.utils.installers.forge.ForgeInstaller;
|
import org.jackhuang.hellominecraft.launcher.utils.installers.forge.ForgeInstaller;
|
||||||
import org.jackhuang.hellominecraft.launcher.utils.installers.liteloader.LiteLoaderInstaller;
|
import org.jackhuang.hellominecraft.launcher.utils.installers.liteloader.LiteLoaderInstaller;
|
||||||
@ -64,7 +63,7 @@ public final class InstallerService {
|
|||||||
File filepath = IOUtils.tryGetCanonicalFile(IOUtils.currentDirWithSeparator() + "forge-installer.jar");
|
File filepath = IOUtils.tryGetCanonicalFile(IOUtils.currentDirWithSeparator() + "forge-installer.jar");
|
||||||
if (v.installer != null)
|
if (v.installer != null)
|
||||||
TaskWindow.getInstance()
|
TaskWindow.getInstance()
|
||||||
.addTask(new FileDownloadTask(Settings.getInstance().getDownloadSource().getProvider().getParsedLibraryDownloadURL(v.installer), filepath).setTag("forge"))
|
.addTask(new FileDownloadTask(p.getDownloadType().getProvider().getParsedLibraryDownloadURL(v.installer), filepath).setTag("forge"))
|
||||||
.addTask(new ForgeInstaller(p.getMinecraftProvider(), filepath, v))
|
.addTask(new ForgeInstaller(p.getMinecraftProvider(), filepath, v))
|
||||||
.start();
|
.start();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 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 3 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. If not, see {http://www.gnu.org/licenses/}.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hellominecraft.launcher.utils.upgrade;
|
||||||
|
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.datatransfer.Clipboard;
|
||||||
|
import java.awt.datatransfer.StringSelection;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.jar.JarFile;
|
||||||
|
import java.util.jar.JarOutputStream;
|
||||||
|
import java.util.jar.Pack200;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
import org.jackhuang.hellominecraft.C;
|
||||||
|
import org.jackhuang.hellominecraft.HMCLog;
|
||||||
|
import org.jackhuang.hellominecraft.launcher.utils.MCUtils;
|
||||||
|
import org.jackhuang.hellominecraft.tasks.Task;
|
||||||
|
import org.jackhuang.hellominecraft.tasks.TaskWindow;
|
||||||
|
import org.jackhuang.hellominecraft.tasks.download.FileDownloadTask;
|
||||||
|
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||||
|
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||||
|
import org.jackhuang.hellominecraft.utils.UpdateChecker;
|
||||||
|
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;
|
||||||
|
import rx.concurrency.Schedulers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author huangyuhui
|
||||||
|
*/
|
||||||
|
public class AppDataUpgrader extends IUpgrader {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean parseArguments(VersionNumber nowVersion, String[] args) {
|
||||||
|
if (!ArrayUtils.contains(args, "nofound"))
|
||||||
|
try {
|
||||||
|
File f = AppDataUpgraderTask.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(nowVersion) > 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) {
|
||||||
|
ArrayList<String> al = new ArrayList<>(Arrays.asList(args));
|
||||||
|
al.add("notfound");
|
||||||
|
new URLClassLoader(new URL[] {jar.toURI().toURL()},
|
||||||
|
URLClassLoader.getSystemClassLoader().getParent()).loadClass(mainClass)
|
||||||
|
.getMethod("main", String[].class).invoke(null, new Object[] {al.toArray(new String[0])});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean call(Object sender, VersionNumber number) {
|
||||||
|
((UpdateChecker) sender).requestDownloadLink().subscribeOn(Schedulers.newThread()).observeOn(Schedulers.eventQueue()).subscribe(map -> {
|
||||||
|
if (map != null && map.containsKey("pack"))
|
||||||
|
try {
|
||||||
|
if (TaskWindow.getInstance().addTask(new AppDataUpgraderTask(map.get("pack"), number.version)).start()) {
|
||||||
|
new ProcessBuilder(new String[] {IOUtils.getJavaDir(), "-jar", AppDataUpgraderTask.getSelf(number.version).getAbsolutePath()}).directory(new File(".")).start();
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
HMCLog.err("Failed to create upgrader", ex);
|
||||||
|
}
|
||||||
|
if (MessageBox.Show(C.i18n("update.newest_version") + number.firstVer + "." + number.secondVer + "." + number.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"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AppDataUpgraderTask 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 AppDataUpgraderTask(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 void executeTask() throws Exception {
|
||||||
|
HashMap<String, String> json = new HashMap<>();
|
||||||
|
File f = getSelf(newestVersion);
|
||||||
|
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 GZIPInputStream(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getInfo() {
|
||||||
|
return "Upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 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 3 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. If not, see {http://www.gnu.org/licenses/}.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hellominecraft.launcher.utils.upgrade;
|
||||||
|
|
||||||
|
import org.jackhuang.hellominecraft.utils.Event;
|
||||||
|
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author huangyuhui
|
||||||
|
*/
|
||||||
|
public abstract class IUpgrader implements Event<VersionNumber> {
|
||||||
|
|
||||||
|
public static final IUpgrader NOW_UPGRADER = new AppDataUpgrader();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paring arguments to decide on whether the upgrade is needed.
|
||||||
|
*
|
||||||
|
* @param nowVersion now launcher version
|
||||||
|
* @param args Application CommandLine Arguments
|
||||||
|
* @return true if it is needed to break the main thread to shutdown this
|
||||||
|
* application.
|
||||||
|
*/
|
||||||
|
public abstract boolean parseArguments(VersionNumber nowVersion, String[] args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just download the new app.
|
||||||
|
*
|
||||||
|
* @param sender Should be VersionChecker
|
||||||
|
* @param number the newest version
|
||||||
|
* @return should return true
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public abstract boolean call(Object sender, VersionNumber number);
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 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 3 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. If not, see {http://www.gnu.org/licenses/}.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hellominecraft.launcher.utils.upgrade;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import org.jackhuang.hellominecraft.HMCLog;
|
||||||
|
import org.jackhuang.hellominecraft.tasks.TaskWindow;
|
||||||
|
import org.jackhuang.hellominecraft.tasks.download.FileDownloadTask;
|
||||||
|
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||||
|
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||||
|
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||||
|
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author huangyuhui
|
||||||
|
*/
|
||||||
|
public class NewFileUpgrader extends IUpgrader {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean parseArguments(VersionNumber nowVersion, String[] args) {
|
||||||
|
int i = ArrayUtils.indexOf(args, "--removeOldLauncher");
|
||||||
|
if (i != -1 && i < args.length - 1) {
|
||||||
|
File f = new File(args[i + 1]);
|
||||||
|
if (f.exists())
|
||||||
|
f.deleteOnExit();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean call(Object sender, VersionNumber number) {
|
||||||
|
String str = requestDownloadLink();
|
||||||
|
File newf = new File(FileUtils.getName(str));
|
||||||
|
if (TaskWindow.getInstance().addTask(new FileDownloadTask(str, newf)).start()) {
|
||||||
|
try {
|
||||||
|
new ProcessBuilder(new String[] {IOUtils.tryGetCanonicalFilePath(newf), "--removeOldLauncher", IOUtils.getRealPath()}).directory(new File(".")).start();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
HMCLog.err("Failed to start new app", ex);
|
||||||
|
}
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String requestDownloadLink() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* Hello Minecraft! Launcher.
|
|
||||||
* Copyright (C) 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 3 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. If not, see {http://www.gnu.org/licenses/}.
|
|
||||||
*/
|
|
||||||
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 void executeTask() throws Exception {
|
|
||||||
HashMap<String, String> json = new HashMap<>();
|
|
||||||
File f = getSelf(newestVersion);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getInfo() {
|
|
||||||
return "Upgrade";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -18,7 +18,6 @@
|
|||||||
package org.jackhuang.hellominecraft.launcher.views;
|
package org.jackhuang.hellominecraft.launcher.views;
|
||||||
|
|
||||||
import java.awt.AlphaComposite;
|
import java.awt.AlphaComposite;
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
<DimensionLayout dim="1">
|
<DimensionLayout dim="1">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="jScrollPane12" pref="308" max="32767" attributes="0"/>
|
<Component id="jScrollPane12" pref="147" max="32767" attributes="0"/>
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<Component id="btnInstall" min="-2" max="-2" attributes="0"/>
|
<Component id="btnInstall" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
package org.jackhuang.hellominecraft.launcher.views;
|
package org.jackhuang.hellominecraft.launcher.views;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.swing.JTable;
|
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.table.DefaultTableModel;
|
import javax.swing.table.DefaultTableModel;
|
||||||
import org.jackhuang.hellominecraft.C;
|
import org.jackhuang.hellominecraft.C;
|
||||||
@ -104,7 +103,7 @@ public class InstallerPanel extends AnimatedPanel {
|
|||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(jScrollPane12, javax.swing.GroupLayout.DEFAULT_SIZE, 308, Short.MAX_VALUE)
|
.addComponent(jScrollPane12, javax.swing.GroupLayout.DEFAULT_SIZE, 147, Short.MAX_VALUE)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(btnInstall)
|
.addComponent(btnInstall)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
@ -41,7 +41,6 @@ import org.jackhuang.hellominecraft.C;
|
|||||||
import org.jackhuang.hellominecraft.HMCLog;
|
import org.jackhuang.hellominecraft.HMCLog;
|
||||||
import org.jackhuang.hellominecraft.launcher.Main;
|
import org.jackhuang.hellominecraft.launcher.Main;
|
||||||
import org.jackhuang.hellominecraft.launcher.settings.Settings;
|
import org.jackhuang.hellominecraft.launcher.settings.Settings;
|
||||||
import org.jackhuang.hellominecraft.utils.UpdateChecker;
|
|
||||||
import org.jackhuang.hellominecraft.utils.Utils;
|
import org.jackhuang.hellominecraft.utils.Utils;
|
||||||
import org.jackhuang.hellominecraft.views.DropShadowBorder;
|
import org.jackhuang.hellominecraft.views.DropShadowBorder;
|
||||||
import org.jackhuang.hellominecraft.views.TintablePanel;
|
import org.jackhuang.hellominecraft.views.TintablePanel;
|
||||||
@ -187,8 +186,7 @@ public final class MainFrame extends DraggableFrame {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseClicked(MouseEvent e) {
|
public void mouseClicked(MouseEvent e) {
|
||||||
if (UpdateChecker.OUT_DATED)
|
Settings.UPDATE_CHECKER.checkOutdate();
|
||||||
Main.update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -314,7 +312,7 @@ public final class MainFrame extends DraggableFrame {
|
|||||||
isShowedMessage = false;
|
isShowedMessage = false;
|
||||||
reloadColor();
|
reloadColor();
|
||||||
windowTitle.setText(defaultTitle);
|
windowTitle.setText(defaultTitle);
|
||||||
windowTitle.setForeground(UpdateChecker.OUT_DATED ? Color.red : Color.white);
|
windowTitle.setForeground(Settings.UPDATE_CHECKER.OUT_DATED ? Color.red : Color.white);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,14 +352,15 @@ public final class MainFrame extends DraggableFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void paintImpl(Graphics g) {
|
private void paintImpl(Graphics g) {
|
||||||
super.paint(g);
|
|
||||||
g.setColor(borderColor);
|
|
||||||
int off = enableShadow ? 16 : 0;
|
int off = enableShadow ? 16 : 0;
|
||||||
int width = 800;
|
int width = 800;
|
||||||
int height = header.getHeight() + 480 - 1;
|
int height = header.getHeight() + 480 - 1;
|
||||||
|
super.paint(g);
|
||||||
|
g.setColor(borderColor);
|
||||||
g.drawLine(off, off, off, height + off + 1);
|
g.drawLine(off, off, off, height + off + 1);
|
||||||
g.drawLine(off + width + 1, off, off + width + 1, height + off + 1);
|
g.drawLine(off + width + 1, off, off + width + 1, height + off + 1);
|
||||||
g.drawLine(off, height + off + 1, off + width + 1, height + off + 1);
|
g.drawLine(off, height + off + 1, off + width + 1, height + off + 1);
|
||||||
|
g.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hellominecraft.tasks;
|
package org.jackhuang.hellominecraft.tasks;
|
||||||
|
|
||||||
import java.awt.EventQueue;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
@ -300,28 +299,16 @@ public class TaskWindow extends javax.swing.JDialog
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean start() {
|
public boolean start() {
|
||||||
Runnable r = () -> {
|
return SwingUtils.invokeAndWait(() -> {
|
||||||
synchronized (INSTANCE) {
|
synchronized (INSTANCE) {
|
||||||
if (INSTANCE.isVisible()) {
|
if (INSTANCE.isVisible())
|
||||||
flag = false;
|
return false;
|
||||||
return;
|
|
||||||
}
|
|
||||||
TaskWindow tw = inst();
|
TaskWindow tw = inst();
|
||||||
for (Task t : ll)
|
for (Task t : ll)
|
||||||
tw.addTask(t);
|
tw.addTask(t);
|
||||||
flag = tw.start();
|
return tw.start();
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
if (EventQueue.isDispatchThread())
|
|
||||||
r.run();
|
|
||||||
else
|
|
||||||
try {
|
|
||||||
EventQueue.invokeAndWait(r);
|
|
||||||
} catch (Exception e) {
|
|
||||||
HMCLog.err("Failed to invokeAndWait, the UI will work abnormally.", e);
|
|
||||||
r.run();
|
|
||||||
}
|
|
||||||
return flag;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 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 3 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. If not, see {http://www.gnu.org/licenses/}.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hellominecraft.utils;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import rx.Observable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author huangyuhui
|
||||||
|
*/
|
||||||
|
public interface IUpdateChecker {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void checkOutdate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the <b>cached</b> newest version number, use "process" method to download!
|
||||||
|
* @return the newest version number
|
||||||
|
* @see process
|
||||||
|
*/
|
||||||
|
VersionNumber getNewVersion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download the version number synchronously.
|
||||||
|
* When you execute this method first, should leave "showMessage" false.
|
||||||
|
* @param showMessage If it is requested to warn the user that there is a new version.
|
||||||
|
* @return the process observable.
|
||||||
|
*/
|
||||||
|
Observable process(boolean showMessage);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the download links.
|
||||||
|
* @return a JSON, which contains the server response.
|
||||||
|
*/
|
||||||
|
Observable<Map<String, String>> requestDownloadLink();
|
||||||
|
|
||||||
|
}
|
@ -97,9 +97,9 @@ public class MessageBox {
|
|||||||
case YES_NO_OPTION:
|
case YES_NO_OPTION:
|
||||||
case YES_NO_CANCEL_OPTION:
|
case YES_NO_CANCEL_OPTION:
|
||||||
case OK_CANCEL_OPTION:
|
case OK_CANCEL_OPTION:
|
||||||
return JOptionPane.showConfirmDialog(null, Msg, Title, Option - 10);
|
return SwingUtils.invokeAndWait(() -> JOptionPane.showConfirmDialog(null, Msg, Title, Option - 10));
|
||||||
default:
|
default:
|
||||||
JOptionPane.showMessageDialog(null, Msg, Title, Option);
|
SwingUtils.invokeAndWait(() -> JOptionPane.showMessageDialog(null, Msg, Title, Option));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
package org.jackhuang.hellominecraft.utils;
|
package org.jackhuang.hellominecraft.utils;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -52,4 +53,28 @@ public class Pair<K, V> implements Map.Entry<K, V> {
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 5;
|
||||||
|
hash = 29 * hash + Objects.hashCode(this.key);
|
||||||
|
hash = 29 * hash + Objects.hashCode(this.value);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
final Pair<?, ?> other = (Pair<?, ?>) obj;
|
||||||
|
if (!Objects.equals(this.key, other.key))
|
||||||
|
return false;
|
||||||
|
if (!Objects.equals(this.value, other.value))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hellominecraft.utils;
|
package org.jackhuang.hellominecraft.utils;
|
||||||
|
|
||||||
|
import java.awt.EventQueue;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import javax.swing.DefaultListModel;
|
import javax.swing.DefaultListModel;
|
||||||
@ -28,6 +29,7 @@ import javax.swing.JTable;
|
|||||||
import javax.swing.JTextArea;
|
import javax.swing.JTextArea;
|
||||||
import javax.swing.table.DefaultTableModel;
|
import javax.swing.table.DefaultTableModel;
|
||||||
import org.jackhuang.hellominecraft.HMCLog;
|
import org.jackhuang.hellominecraft.HMCLog;
|
||||||
|
import org.jackhuang.hellominecraft.utils.functions.NonFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -177,4 +179,24 @@ public class SwingUtils {
|
|||||||
}
|
}
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final ThreadLocal<Object> THREAD_LOCAL = new ThreadLocal<>();
|
||||||
|
|
||||||
|
public static <T> T invokeAndWait(NonFunction<T> x) {
|
||||||
|
Runnable r = () -> THREAD_LOCAL.set(x.apply());
|
||||||
|
invokeAndWait(r);
|
||||||
|
return (T) THREAD_LOCAL.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void invokeAndWait(Runnable r) {
|
||||||
|
if (EventQueue.isDispatchThread())
|
||||||
|
r.run();
|
||||||
|
else
|
||||||
|
try {
|
||||||
|
EventQueue.invokeAndWait(r);
|
||||||
|
} catch (Exception e) {
|
||||||
|
HMCLog.err("Failed to invokeAndWait, the UI will work abnormally.", e);
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,32 +20,31 @@ package org.jackhuang.hellominecraft.utils;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.jackhuang.hellominecraft.C;
|
import org.jackhuang.hellominecraft.C;
|
||||||
import org.jackhuang.hellominecraft.HMCLog;
|
import org.jackhuang.hellominecraft.HMCLog;
|
||||||
|
import rx.Observable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author huangyuhui
|
* @author huangyuhui
|
||||||
*/
|
*/
|
||||||
public final class UpdateChecker extends Thread {
|
public final class UpdateChecker implements IUpdateChecker {
|
||||||
|
|
||||||
public static boolean OUT_DATED = false;
|
public boolean OUT_DATED = false;
|
||||||
public VersionNumber base;
|
public VersionNumber base;
|
||||||
public String versionString;
|
public String versionString;
|
||||||
public String type;
|
public String type;
|
||||||
public Runnable dl;
|
private Map<String, String> download_link = null;
|
||||||
public Map<String, String> download_link = null;
|
|
||||||
|
|
||||||
public UpdateChecker(VersionNumber base, String type, Runnable dl) {
|
public UpdateChecker(VersionNumber base, String type) {
|
||||||
super("UpdateChecker");
|
|
||||||
this.base = base;
|
this.base = base;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.dl = dl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VersionNumber value;
|
VersionNumber value;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public Observable<VersionNumber> process(boolean showMessage) {
|
||||||
|
return Observable.createWithEmptySubscription(t -> {
|
||||||
|
if (value == null) {
|
||||||
try {
|
try {
|
||||||
versionString = NetUtils.get("http://huangyuhui.duapp.com/info.php?type=" + type);
|
versionString = NetUtils.get("http://huangyuhui.duapp.com/info.php?type=" + type);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -53,33 +52,42 @@ public final class UpdateChecker extends Thread {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
value = VersionNumber.check(versionString);
|
value = VersionNumber.check(versionString);
|
||||||
process(false);
|
|
||||||
if (OUT_DATED)
|
|
||||||
dl.run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void process(boolean showMessage) {
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
HMCLog.warn("Failed to check update...");
|
HMCLog.warn("Failed to check update...");
|
||||||
if (showMessage)
|
if (showMessage)
|
||||||
MessageBox.Show(C.i18n("update.failed"));
|
MessageBox.Show(C.i18n("update.failed"));
|
||||||
} else if (VersionNumber.isOlder(base, value))
|
} else if (VersionNumber.isOlder(base, value))
|
||||||
OUT_DATED = true;
|
OUT_DATED = true;
|
||||||
|
if (OUT_DATED)
|
||||||
|
t.onNext(value);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public VersionNumber getNewVersion() {
|
public VersionNumber getNewVersion() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void requestDownloadLink(Runnable finish) {
|
@Override
|
||||||
new Thread(() -> {
|
public synchronized Observable<Map<String, String>> requestDownloadLink() {
|
||||||
|
return Observable.createWithEmptySubscription(t -> {
|
||||||
if (download_link == null)
|
if (download_link == null)
|
||||||
try {
|
try {
|
||||||
download_link = C.gson.fromJson(NetUtils.get("http://huangyuhui.duapp.com/update_link.php?type=" + type), Map.class);
|
download_link = C.gson.fromJson(NetUtils.get("http://huangyuhui.duapp.com/update_link.php?type=" + type), Map.class);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
HMCLog.warn("Failed to get update link.", e);
|
HMCLog.warn("Failed to get update link.", e);
|
||||||
}
|
}
|
||||||
finish.run();
|
t.onNext(download_link);
|
||||||
}).start();
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public final EventHandler<VersionNumber> outdated = new EventHandler<>(this);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkOutdate() {
|
||||||
|
if (OUT_DATED)
|
||||||
|
outdated.execute(getNewVersion());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,12 +25,18 @@ import org.jackhuang.hellominecraft.HMCLog;
|
|||||||
*/
|
*/
|
||||||
public final class VersionNumber implements Comparable<VersionNumber> {
|
public final class VersionNumber implements Comparable<VersionNumber> {
|
||||||
|
|
||||||
public byte firstVer, secondVer, thirdVer;
|
public final byte firstVer, secondVer, thirdVer;
|
||||||
|
public final String version;
|
||||||
|
|
||||||
public VersionNumber(byte a, byte b, byte c) {
|
public VersionNumber(byte a, byte b, byte c) {
|
||||||
|
this(a, b, c, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VersionNumber(byte a, byte b, byte c, String version) {
|
||||||
firstVer = a;
|
firstVer = a;
|
||||||
secondVer = b;
|
secondVer = b;
|
||||||
thirdVer = c;
|
thirdVer = c;
|
||||||
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VersionNumber check(String data) {
|
public static VersionNumber check(String data) {
|
||||||
@ -46,7 +52,7 @@ public final class VersionNumber implements Comparable<VersionNumber> {
|
|||||||
v1 = Byte.parseByte(ver[0]);
|
v1 = Byte.parseByte(ver[0]);
|
||||||
v2 = Byte.parseByte(ver[1]);
|
v2 = Byte.parseByte(ver[1]);
|
||||||
v3 = Byte.parseByte(ver[2]);
|
v3 = Byte.parseByte(ver[2]);
|
||||||
ur = new VersionNumber(v1, v2, v3);
|
ur = new VersionNumber(v1, v2, v3, data);
|
||||||
return ur;
|
return ur;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
HMCLog.warn("Failed to parse the version", e);
|
HMCLog.warn("Failed to parse the version", e);
|
||||||
|
@ -112,6 +112,18 @@ public class IOUtils {
|
|||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getRealPath() {
|
||||||
|
String realPath = IOUtils.class.getClassLoader().getResource("").getFile();
|
||||||
|
java.io.File file = new java.io.File(realPath);
|
||||||
|
realPath = file.getAbsolutePath();
|
||||||
|
try {
|
||||||
|
realPath = java.net.URLDecoder.decode(realPath, "utf-8");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return realPath;
|
||||||
|
}
|
||||||
|
|
||||||
public static File currentDir() {
|
public static File currentDir() {
|
||||||
return new File(".");
|
return new File(".");
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,9 @@ import java.awt.Graphics2D;
|
|||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
import java.awt.RenderingHints;
|
import java.awt.RenderingHints;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.HashMap;
|
||||||
import javax.swing.border.AbstractBorder;
|
import javax.swing.border.AbstractBorder;
|
||||||
|
import org.jackhuang.hellominecraft.utils.Pair;
|
||||||
|
|
||||||
public class DropShadowBorder extends AbstractBorder {
|
public class DropShadowBorder extends AbstractBorder {
|
||||||
|
|
||||||
@ -61,8 +63,14 @@ public class DropShadowBorder extends AbstractBorder {
|
|||||||
return getBorderInsets(c);
|
return getBorderInsets(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final HashMap<Pair<Integer, Integer>, BufferedImage> CACHE = new HashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||||
|
Pair<Integer, Integer> pair = new Pair<>(width, height);
|
||||||
|
if (CACHE.containsKey(pair))
|
||||||
|
g.drawImage(CACHE.get(pair), x, y, width, height, null);
|
||||||
|
else {
|
||||||
BufferedImage shadow = new BufferedImage(width, height, 2);
|
BufferedImage shadow = new BufferedImage(width, height, 2);
|
||||||
|
|
||||||
Graphics2D g2 = shadow.createGraphics();
|
Graphics2D g2 = shadow.createGraphics();
|
||||||
@ -84,6 +92,8 @@ public class DropShadowBorder extends AbstractBorder {
|
|||||||
shadow = blur.filter(shadow, null);
|
shadow = blur.filter(shadow, null);
|
||||||
shadow = blur.filter(shadow, null);
|
shadow = blur.filter(shadow, null);
|
||||||
|
|
||||||
|
CACHE.put(pair, shadow);
|
||||||
g.drawImage(shadow, x, y, width, height, null);
|
g.drawImage(shadow, x, y, width, height, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user