mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-08 19:35:36 -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 {
|
||||
//launch4jCmd = 'D:\\Develop\\Java\\Launch4j\\launch4j.exe'
|
||||
launch4jCmd = '/home/huangyuhui/softwares/launch4j/launch4j'
|
||||
launch4jCmd = 'D:\\Develop\\Java\\Launch4j\\launch4j.exe'
|
||||
//launch4jCmd = '/home/huangyuhui/softwares/launch4j/launch4j'
|
||||
supportUrl = 'http://www.mcbbs.net/thread-142335-1-1.html'
|
||||
jreMinVersion = '1.6.0'
|
||||
|
||||
|
@ -17,34 +17,21 @@
|
||||
*/
|
||||
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.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
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.ArrayList;
|
||||
import java.util.Arrays;
|
||||
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.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.GameLauncher;
|
||||
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.views.LogWindow;
|
||||
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.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.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;
|
||||
import rx.concurrency.Schedulers;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -104,7 +86,7 @@ public final class Main implements Runnable {
|
||||
}
|
||||
|
||||
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 Proxy PROXY;
|
||||
|
||||
@ -131,34 +113,8 @@ public final class Main implements Runnable {
|
||||
@SuppressWarnings( {"CallToPrintStackTrace", "UseSpecificCatch"})
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
if (IUpgrader.NOW_UPGRADER.parseArguments(new VersionNumber(firstVer, secondVer, thirdVer), args))
|
||||
return;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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())) {
|
||||
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());
|
||||
}
|
||||
});
|
||||
//PROXY = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(Settings.getInstance().getProxyHost(), Integer.parseInt(Settings.getInstance().getProxyPort())));
|
||||
} else {
|
||||
//PROXY = Proxy.NO_PROXY;
|
||||
}
|
||||
|
||||
try {
|
||||
@ -217,44 +172,6 @@ public final class Main implements Runnable {
|
||||
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() {
|
||||
MainFrame.INSTANCE.invokeUpdate();
|
||||
}
|
||||
|
@ -159,7 +159,9 @@ public abstract class AbstractMinecraftLoader implements IMinecraftLoader {
|
||||
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(":");
|
||||
res.add("--server");
|
||||
res.add(args[0]);
|
||||
|
@ -70,7 +70,7 @@ public final class Settings {
|
||||
e.checkFormat();
|
||||
|
||||
UPDATE_CHECKER = new UpdateChecker(new VersionNumber(Main.firstVer, Main.secondVer, Main.thirdVer),
|
||||
"hmcl", Main::invokeUpdate);
|
||||
"hmcl");
|
||||
|
||||
List<Java> temp = new ArrayList<>();
|
||||
temp.add(new Java("Default", System.getProperty("java.home")));
|
||||
@ -119,7 +119,8 @@ public final class Settings {
|
||||
}
|
||||
|
||||
public static Profile getProfile(String name) {
|
||||
if (name == null) return getProfiles().get("Default");
|
||||
if (name == null)
|
||||
return getProfiles().get("Default");
|
||||
return getProfiles().get(name);
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,8 @@ import javax.swing.SwingUtilities;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.Main;
|
||||
import org.jackhuang.hellominecraft.launcher.settings.Settings;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.UpdateChecker;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.views.LogWindow;
|
||||
@ -105,8 +105,8 @@ public class CrashReporter implements Thread.UncaughtExceptionHandler {
|
||||
System.out.println(text);
|
||||
|
||||
if (checkThrowable(e) && !System.getProperty("java.vm.name").contains("OpenJDK")) {
|
||||
SwingUtilities.invokeLater(() -> LogWindow.INSTANCE.showAsCrashWindow(UpdateChecker.OUT_DATED));
|
||||
if (!UpdateChecker.OUT_DATED)
|
||||
SwingUtilities.invokeLater(() -> LogWindow.INSTANCE.showAsCrashWindow(Settings.UPDATE_CHECKER.OUT_DATED));
|
||||
if (!Settings.UPDATE_CHECKER.OUT_DATED)
|
||||
reportToServer(text, s);
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
|
@ -52,7 +52,8 @@ public final class UserProfileProvider {
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
if (accessToken == null) accessToken = "0";
|
||||
if (accessToken == null)
|
||||
accessToken = "0";
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
@ -114,4 +115,13 @@ public final class UserProfileProvider {
|
||||
private String otherInfo = "";
|
||||
private String clientIdentifier = "";
|
||||
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 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.forge.ForgeInstaller;
|
||||
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");
|
||||
if (v.installer != null)
|
||||
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))
|
||||
.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;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
@ -28,7 +28,7 @@
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<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">
|
||||
<Component id="btnInstall" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
|
@ -18,7 +18,6 @@
|
||||
package org.jackhuang.hellominecraft.launcher.views;
|
||||
|
||||
import java.util.List;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
@ -104,7 +103,7 @@ public class InstallerPanel extends AnimatedPanel {
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
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()
|
||||
.addComponent(btnInstall)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
|
@ -41,7 +41,6 @@ import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.Main;
|
||||
import org.jackhuang.hellominecraft.launcher.settings.Settings;
|
||||
import org.jackhuang.hellominecraft.utils.UpdateChecker;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
import org.jackhuang.hellominecraft.views.DropShadowBorder;
|
||||
import org.jackhuang.hellominecraft.views.TintablePanel;
|
||||
@ -187,8 +186,7 @@ public final class MainFrame extends DraggableFrame {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (UpdateChecker.OUT_DATED)
|
||||
Main.update();
|
||||
Settings.UPDATE_CHECKER.checkOutdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -314,7 +312,7 @@ public final class MainFrame extends DraggableFrame {
|
||||
isShowedMessage = false;
|
||||
reloadColor();
|
||||
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) {
|
||||
super.paint(g);
|
||||
g.setColor(borderColor);
|
||||
int off = enableShadow ? 16 : 0;
|
||||
int width = 800;
|
||||
int height = header.getHeight() + 480 - 1;
|
||||
super.paint(g);
|
||||
g.setColor(borderColor);
|
||||
g.drawLine(off, off, off, 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.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -17,7 +17,6 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import javax.swing.SwingUtilities;
|
||||
@ -300,28 +299,16 @@ public class TaskWindow extends javax.swing.JDialog
|
||||
}
|
||||
|
||||
public boolean start() {
|
||||
Runnable r = () -> {
|
||||
return SwingUtils.invokeAndWait(() -> {
|
||||
synchronized (INSTANCE) {
|
||||
if (INSTANCE.isVisible()) {
|
||||
flag = false;
|
||||
return;
|
||||
}
|
||||
if (INSTANCE.isVisible())
|
||||
return false;
|
||||
TaskWindow tw = inst();
|
||||
for (Task t : ll)
|
||||
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_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:
|
||||
JOptionPane.showMessageDialog(null, Msg, Title, Option);
|
||||
SwingUtils.invokeAndWait(() -> JOptionPane.showMessageDialog(null, Msg, Title, Option));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -52,4 +53,28 @@ public class Pair<K, V> implements Map.Entry<K, V> {
|
||||
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;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.FontMetrics;
|
||||
import java.net.URI;
|
||||
import javax.swing.DefaultListModel;
|
||||
@ -28,6 +29,7 @@ import javax.swing.JTable;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.functions.NonFunction;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -47,8 +49,8 @@ public class SwingUtils {
|
||||
*/
|
||||
public static DefaultTableModel makeDefaultTableModel(String[] titleA, final Class[] typesA, final boolean[] canEditA) {
|
||||
return new DefaultTableModel(
|
||||
new Object[][] {},
|
||||
titleA) {
|
||||
new Object[][] {},
|
||||
titleA) {
|
||||
Class[] types = typesA;
|
||||
boolean[] canEdit = canEditA;
|
||||
|
||||
@ -131,7 +133,7 @@ public class SwingUtils {
|
||||
* Clear the JTable
|
||||
*
|
||||
* @param table JTable with DefaultTableModel.
|
||||
*
|
||||
*
|
||||
* @return To make the code succinct
|
||||
*/
|
||||
public static DefaultTableModel clearDefaultTable(JTable table) {
|
||||
@ -177,4 +179,24 @@ public class SwingUtils {
|
||||
}
|
||||
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,66 +20,74 @@ package org.jackhuang.hellominecraft.utils;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import rx.Observable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class UpdateChecker extends Thread {
|
||||
|
||||
public static boolean OUT_DATED = false;
|
||||
public final class UpdateChecker implements IUpdateChecker {
|
||||
|
||||
public boolean OUT_DATED = false;
|
||||
public VersionNumber base;
|
||||
public String versionString;
|
||||
public String type;
|
||||
public Runnable dl;
|
||||
public Map<String, String> download_link = null;
|
||||
|
||||
public UpdateChecker(VersionNumber base, String type, Runnable dl) {
|
||||
super("UpdateChecker");
|
||||
private Map<String, String> download_link = null;
|
||||
|
||||
public UpdateChecker(VersionNumber base, String type) {
|
||||
this.base = base;
|
||||
this.type = type;
|
||||
this.dl = dl;
|
||||
}
|
||||
|
||||
|
||||
VersionNumber value;
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
versionString = NetUtils.get("http://huangyuhui.duapp.com/info.php?type=" + type);
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Failed to get update url.", e);
|
||||
return;
|
||||
}
|
||||
value = VersionNumber.check(versionString);
|
||||
process(false);
|
||||
if (OUT_DATED)
|
||||
dl.run();
|
||||
public Observable<VersionNumber> process(boolean showMessage) {
|
||||
return Observable.createWithEmptySubscription(t -> {
|
||||
if (value == null) {
|
||||
try {
|
||||
versionString = NetUtils.get("http://huangyuhui.duapp.com/info.php?type=" + type);
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Failed to get update url.", e);
|
||||
return;
|
||||
}
|
||||
value = VersionNumber.check(versionString);
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
HMCLog.warn("Failed to check update...");
|
||||
if (showMessage)
|
||||
MessageBox.Show(C.i18n("update.failed"));
|
||||
} else if (VersionNumber.isOlder(base, value))
|
||||
OUT_DATED = true;
|
||||
if (OUT_DATED)
|
||||
t.onNext(value);
|
||||
});
|
||||
}
|
||||
|
||||
public void process(boolean showMessage) {
|
||||
if (value == null) {
|
||||
HMCLog.warn("Failed to check update...");
|
||||
if (showMessage)
|
||||
MessageBox.Show(C.i18n("update.failed"));
|
||||
} else if (VersionNumber.isOlder(base, value))
|
||||
OUT_DATED = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VersionNumber getNewVersion() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public synchronized void requestDownloadLink(Runnable finish) {
|
||||
new Thread(() -> {
|
||||
|
||||
@Override
|
||||
public synchronized Observable<Map<String, String>> requestDownloadLink() {
|
||||
return Observable.createWithEmptySubscription(t -> {
|
||||
if (download_link == null)
|
||||
try {
|
||||
download_link = C.gson.fromJson(NetUtils.get("http://huangyuhui.duapp.com/update_link.php?type=" + type), Map.class);
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Failed to get update link.", e);
|
||||
}
|
||||
finish.run();
|
||||
}).start();
|
||||
t.onNext(download_link);
|
||||
});
|
||||
}
|
||||
|
||||
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 byte firstVer, secondVer, thirdVer;
|
||||
public final byte firstVer, secondVer, thirdVer;
|
||||
public final String version;
|
||||
|
||||
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;
|
||||
secondVer = b;
|
||||
thirdVer = c;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public static VersionNumber check(String data) {
|
||||
@ -46,7 +52,7 @@ public final class VersionNumber implements Comparable<VersionNumber> {
|
||||
v1 = Byte.parseByte(ver[0]);
|
||||
v2 = Byte.parseByte(ver[1]);
|
||||
v3 = Byte.parseByte(ver[2]);
|
||||
ur = new VersionNumber(v1, v2, v3);
|
||||
ur = new VersionNumber(v1, v2, v3, data);
|
||||
return ur;
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Failed to parse the version", e);
|
||||
|
@ -112,6 +112,18 @@ public class IOUtils {
|
||||
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() {
|
||||
return new File(".");
|
||||
}
|
||||
@ -219,19 +231,19 @@ public class IOUtils {
|
||||
}
|
||||
|
||||
public static void write(byte[] data, OutputStream output)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
if (data != null)
|
||||
output.write(data);
|
||||
}
|
||||
|
||||
public static void write(String data, OutputStream output, String encoding)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
if (data != null)
|
||||
output.write(data.getBytes(encoding));
|
||||
}
|
||||
|
||||
public static FileInputStream openInputStream(File file)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
if (file.exists()) {
|
||||
if (file.isDirectory())
|
||||
throw new IOException("File '" + file + "' exists but is a directory");
|
||||
|
@ -26,7 +26,9 @@ import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.HashMap;
|
||||
import javax.swing.border.AbstractBorder;
|
||||
import org.jackhuang.hellominecraft.utils.Pair;
|
||||
|
||||
public class DropShadowBorder extends AbstractBorder {
|
||||
|
||||
@ -61,29 +63,37 @@ public class DropShadowBorder extends AbstractBorder {
|
||||
return getBorderInsets(c);
|
||||
}
|
||||
|
||||
private static final HashMap<Pair<Integer, Integer>, BufferedImage> CACHE = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
BufferedImage shadow = new BufferedImage(width, height, 2);
|
||||
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);
|
||||
|
||||
Graphics2D g2 = shadow.createGraphics();
|
||||
g2.setRenderingHints(this.hints);
|
||||
Composite oldComposite = g2.getComposite();
|
||||
AlphaComposite composite = AlphaComposite.getInstance(1, 0.0F);
|
||||
g2.setComposite(composite);
|
||||
g2.setColor(new Color(0, 0, 0, 0));
|
||||
g2.fillRect(0, 0, width, height);
|
||||
g2.setComposite(oldComposite);
|
||||
g2.setColor(this.color);
|
||||
int border = (int) (this.thickness * 4);
|
||||
g2.fillRect(border, border + border / 6, width - border * 2, height - border * 2);
|
||||
g2.dispose();
|
||||
Graphics2D g2 = shadow.createGraphics();
|
||||
g2.setRenderingHints(this.hints);
|
||||
Composite oldComposite = g2.getComposite();
|
||||
AlphaComposite composite = AlphaComposite.getInstance(1, 0.0F);
|
||||
g2.setComposite(composite);
|
||||
g2.setColor(new Color(0, 0, 0, 0));
|
||||
g2.fillRect(0, 0, width, height);
|
||||
g2.setComposite(oldComposite);
|
||||
g2.setColor(this.color);
|
||||
int border = (int) (this.thickness * 4);
|
||||
g2.fillRect(border, border + border / 6, width - border * 2, height - border * 2);
|
||||
g2.dispose();
|
||||
|
||||
FastBlurFilter blur = new FastBlurFilter(this.thickness);
|
||||
shadow = blur.filter(shadow, null);
|
||||
shadow = blur.filter(shadow, null);
|
||||
shadow = blur.filter(shadow, null);
|
||||
shadow = blur.filter(shadow, null);
|
||||
FastBlurFilter blur = new FastBlurFilter(this.thickness);
|
||||
shadow = blur.filter(shadow, null);
|
||||
shadow = blur.filter(shadow, null);
|
||||
shadow = blur.filter(shadow, null);
|
||||
shadow = blur.filter(shadow, null);
|
||||
|
||||
g.drawImage(shadow, x, y, width, height, null);
|
||||
CACHE.put(pair, shadow);
|
||||
g.drawImage(shadow, x, y, width, height, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user