mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-12 13:26:53 -04:00
Change update source
This commit is contained in:
parent
69c0382bd5
commit
c47dea94e3
@ -26,6 +26,7 @@ import java.net.PasswordAuthentication;
|
|||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@ -142,7 +143,7 @@ public final class Main {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
HMCLApi.HMCL_VERSION = VersionNumber.check(LAUNCHER_VERSION);
|
HMCLApi.HMCL_VERSION = VersionNumber.asVersion(LAUNCHER_VERSION);
|
||||||
|
|
||||||
PluginManager.getPlugin(DefaultPlugin.class);
|
PluginManager.getPlugin(DefaultPlugin.class);
|
||||||
for (String s : args)
|
for (String s : args)
|
||||||
@ -161,7 +162,7 @@ public final class Main {
|
|||||||
}
|
}
|
||||||
PluginManager.loadPlugins();
|
PluginManager.loadPlugins();
|
||||||
|
|
||||||
IUpgrader.NOW_UPGRADER.parseArguments(HMCLApi.HMCL_VERSION, args);
|
IUpgrader.NOW_UPGRADER.parseArguments(HMCLApi.HMCL_VERSION, Arrays.asList(args));
|
||||||
|
|
||||||
System.setProperty("awt.useSystemAAFontSettings", "on");
|
System.setProperty("awt.useSystemAAFontSettings", "on");
|
||||||
System.setProperty("swing.aatext", "true");
|
System.setProperty("swing.aatext", "true");
|
||||||
@ -231,12 +232,6 @@ public final class Main {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
unpackDefaultLog4jConfiguration();
|
|
||||||
} catch(IOException e) {
|
|
||||||
HMCLog.err("Failed to unpack log4j.xml, log window will not work well.", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
MainFrame.showMainFrame();
|
MainFrame.showMainFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -245,20 +240,6 @@ public final class Main {
|
|||||||
MainFrame.INSTANCE.invokeUpdate();
|
MainFrame.INSTANCE.invokeUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final File LOG4J_FILE = new File(MCUtils.getWorkingDirectory("hmcl"), "log4j.xml");
|
|
||||||
|
|
||||||
public static void unpackDefaultLog4jConfiguration() throws IOException {
|
|
||||||
LOG4J_FILE.getParentFile().mkdirs();
|
|
||||||
if (LOG4J_FILE.exists()) return;
|
|
||||||
LOG4J_FILE.createNewFile();
|
|
||||||
try (InputStream is = Main.class.getResourceAsStream("/org/jackhuang/hmcl/log4j.xml");
|
|
||||||
FileOutputStream fos = new FileOutputStream(LOG4J_FILE)) {
|
|
||||||
int b;
|
|
||||||
while ((b = is.read()) != -1)
|
|
||||||
fos.write(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ImageIcon getIcon(String path) {
|
public static ImageIcon getIcon(String path) {
|
||||||
try {
|
try {
|
||||||
return new ImageIcon(Main.class.getResource("/org/jackhuang/hmcl/" + path));
|
return new ImageIcon(Main.class.getResource("/org/jackhuang/hmcl/" + path));
|
||||||
|
@ -17,20 +17,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.util.upgrade;
|
package org.jackhuang.hmcl.util.upgrade;
|
||||||
|
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedActionException;
|
|
||||||
import java.security.PrivilegedExceptionAction;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.util.jar.JarOutputStream;
|
import java.util.jar.JarOutputStream;
|
||||||
@ -45,13 +44,13 @@ import org.jackhuang.hmcl.core.MCUtils;
|
|||||||
import org.jackhuang.hmcl.util.task.Task;
|
import org.jackhuang.hmcl.util.task.Task;
|
||||||
import org.jackhuang.hmcl.util.task.TaskWindow;
|
import org.jackhuang.hmcl.util.task.TaskWindow;
|
||||||
import org.jackhuang.hmcl.util.net.FileDownloadTask;
|
import org.jackhuang.hmcl.util.net.FileDownloadTask;
|
||||||
import org.jackhuang.hmcl.util.ArrayUtils;
|
|
||||||
import org.jackhuang.hmcl.util.ui.MessageBox;
|
import org.jackhuang.hmcl.util.ui.MessageBox;
|
||||||
import org.jackhuang.hmcl.util.Utils;
|
import org.jackhuang.hmcl.util.Utils;
|
||||||
import org.jackhuang.hmcl.api.VersionNumber;
|
import org.jackhuang.hmcl.api.VersionNumber;
|
||||||
import org.jackhuang.hmcl.util.StrUtils;
|
import org.jackhuang.hmcl.util.StrUtils;
|
||||||
import org.jackhuang.hmcl.util.sys.FileUtils;
|
import org.jackhuang.hmcl.util.sys.FileUtils;
|
||||||
import org.jackhuang.hmcl.util.sys.IOUtils;
|
import org.jackhuang.hmcl.util.sys.IOUtils;
|
||||||
|
import org.jackhuang.hmcl.util.sys.Java;
|
||||||
import org.jackhuang.hmcl.util.sys.OS;
|
import org.jackhuang.hmcl.util.sys.OS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,45 +59,49 @@ import org.jackhuang.hmcl.util.sys.OS;
|
|||||||
*/
|
*/
|
||||||
public class AppDataUpgrader extends IUpgrader {
|
public class AppDataUpgrader extends IUpgrader {
|
||||||
|
|
||||||
private boolean launchNewerVersion(String[] args, File jar) throws IOException, PrivilegedActionException {
|
private void launchNewerVersion(List<String> args, File jar) throws IOException, ReflectiveOperationException {
|
||||||
try (JarFile jarFile = new JarFile(jar)) {
|
try (JarFile jarFile = new JarFile(jar)) {
|
||||||
String mainClass = jarFile.getManifest().getMainAttributes().getValue("Main-Class");
|
String mainClass = jarFile.getManifest().getMainAttributes().getValue("Main-Class");
|
||||||
if (mainClass != null) {
|
if (mainClass == null)
|
||||||
ArrayList<String> al = new ArrayList<>(Arrays.asList(args));
|
throw new ClassNotFoundException("Main-Class not found in manifest");
|
||||||
|
ArrayList<String> al = new ArrayList<>(args);
|
||||||
al.add("--noupdate");
|
al.add("--noupdate");
|
||||||
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
|
ClassLoader pre = Thread.currentThread().getContextClassLoader();
|
||||||
new URLClassLoader(new URL[] { jar.toURI().toURL() },
|
try {
|
||||||
URLClassLoader.getSystemClassLoader().getParent()).loadClass(mainClass)
|
ClassLoader now = new URLClassLoader(new URL[] { jar.toURI().toURL() }, ClassLoader.getSystemClassLoader().getParent());
|
||||||
.getMethod("main", String[].class).invoke(null, new Object[] { al.toArray(new String[0]) });
|
Thread.currentThread().setContextClassLoader(now);
|
||||||
return null;
|
now.loadClass(mainClass).getMethod("main", String[].class).invoke(null, new Object[] { al.toArray(new String[0]) });
|
||||||
});
|
} finally {
|
||||||
return true;
|
Thread.currentThread().setContextClassLoader(pre);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void parseArguments(VersionNumber nowVersion, String[] args) {
|
public void parseArguments(VersionNumber nowVersion, List<String> args) {
|
||||||
File f = AppDataUpgraderPackGzTask.HMCL_VER_FILE;
|
File f = AppDataUpgraderPackGzTask.HMCL_VER_FILE;
|
||||||
if (!ArrayUtils.contains(args, "--noupdate"))
|
if (!args.contains("--noupdate"))
|
||||||
try {
|
try {
|
||||||
if (f.exists()) {
|
if (f.exists()) {
|
||||||
Map<String, String> m = C.GSON.fromJson(FileUtils.read(f), Map.class);
|
Map<String, String> m = C.GSON.fromJson(FileUtils.read(f), new TypeToken<Map<String, String>>() {
|
||||||
|
}.getType());
|
||||||
String s = m.get("ver");
|
String s = m.get("ver");
|
||||||
if (s != null && VersionNumber.check(s).compareTo(nowVersion) > 0) {
|
if (s != null && VersionNumber.asVersion(s).compareTo(nowVersion) > 0) {
|
||||||
String j = m.get("loc");
|
String j = m.get("loc");
|
||||||
if (j != null) {
|
if (j != null) {
|
||||||
File jar = new File(j);
|
File jar = new File(j);
|
||||||
if (jar.exists() && launchNewerVersion(args, jar))
|
if (jar.exists()) {
|
||||||
|
launchNewerVersion(args, jar);
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (JsonSyntaxException ex) {
|
}
|
||||||
|
} catch (JsonParseException ex) {
|
||||||
f.delete();
|
f.delete();
|
||||||
} catch (IOException | PrivilegedActionException t) {
|
} catch (IOException | ReflectiveOperationException t) {
|
||||||
HMCLog.err("Failed to execute newer version application", t);
|
HMCLog.err("Unable to execute newer version application", t);
|
||||||
|
AppDataUpgraderPackGzTask.HMCL_VER_FILE.delete(); // delete version json, let HMCL re-download the newer version.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,33 +109,49 @@ public class AppDataUpgrader extends IUpgrader {
|
|||||||
public void accept(SimpleEvent<VersionNumber> event) {
|
public void accept(SimpleEvent<VersionNumber> event) {
|
||||||
final VersionNumber version = event.getValue();
|
final VersionNumber version = event.getValue();
|
||||||
((UpdateChecker) event.getSource()).requestDownloadLink().reg(map -> {
|
((UpdateChecker) event.getSource()).requestDownloadLink().reg(map -> {
|
||||||
if (MessageBox.show(C.i18n("update.newest_version") + version.firstVer + "." + version.secondVer + "." + version.thirdVer + "\n"
|
boolean flag = false;
|
||||||
|
for (Java java : Java.JAVA)
|
||||||
|
if (java.getName().startsWith("1.8") || java.getName().startsWith("9") || java.getName().startsWith("10")) {
|
||||||
|
flag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!flag) {
|
||||||
|
MessageBox.show("请安装 Java 8");
|
||||||
|
try {
|
||||||
|
java.awt.Desktop.getDesktop().browse(new URI("https://java.com"));
|
||||||
|
} catch (URISyntaxException | IOException e) {
|
||||||
|
Utils.setClipboard("https://java.com");
|
||||||
|
MessageBox.show(C.i18n("update.no_browser"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MessageBox.show(C.i18n("update.newest_version") + version.toString() + "\n"
|
||||||
+ C.i18n("update.should_open_link"),
|
+ C.i18n("update.should_open_link"),
|
||||||
MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||||
if (map != null && map.containsKey("jar") && !StrUtils.isBlank(map.get("jar")))
|
if (map != null && map.containsKey("pack") && !StrUtils.isBlank(map.get("pack")))
|
||||||
try {
|
|
||||||
String hash = null;
|
|
||||||
if (map.containsKey("jarsha1"))
|
|
||||||
hash = map.get("jarsha1");
|
|
||||||
if (TaskWindow.factory().append(new AppDataUpgraderJarTask(map.get("jar"), version.version, hash)).execute()) {
|
|
||||||
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderJarTask.getSelf(version.version).getAbsolutePath() }).directory(new File("").getAbsoluteFile()).start();
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Main.LOGGER.log(Level.SEVERE, "Failed to create upgrader", ex);
|
|
||||||
}
|
|
||||||
else if (map != null && map.containsKey("pack") && !StrUtils.isBlank(map.get("pack")))
|
|
||||||
try {
|
try {
|
||||||
String hash = null;
|
String hash = null;
|
||||||
if (map.containsKey("packsha1"))
|
if (map.containsKey("packsha1"))
|
||||||
hash = map.get("packsha1");
|
hash = map.get("packsha1");
|
||||||
if (TaskWindow.factory().append(new AppDataUpgraderPackGzTask(map.get("pack"), version.version, hash)).execute()) {
|
if (TaskWindow.factory().append(new AppDataUpgraderPackGzTask(map.get("pack"), version.toString(), hash)).execute()) {
|
||||||
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderPackGzTask.getSelf(version.version).getAbsolutePath() }).directory(new File("").getAbsoluteFile()).start();
|
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderPackGzTask.getSelf(version.toString()).getAbsolutePath() }).directory(new File("").getAbsoluteFile()).start();
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
HMCLog.err("Failed to create upgrader", ex);
|
HMCLog.err("Failed to create upgrader", ex);
|
||||||
}
|
}
|
||||||
|
else if (map != null && map.containsKey("jar") && !StrUtils.isBlank(map.get("jar")))
|
||||||
|
try {
|
||||||
|
String hash = null;
|
||||||
|
if (map.containsKey("jarsha1"))
|
||||||
|
hash = map.get("jarsha1");
|
||||||
|
if (TaskWindow.factory().append(new AppDataUpgraderJarTask(map.get("jar"), version.toString(), hash)).execute()) {
|
||||||
|
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderJarTask.getSelf(version.toString()).getAbsolutePath() }).directory(new File("").getAbsoluteFile()).start();
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Main.LOGGER.log(Level.SEVERE, "Failed to create upgrader", ex);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
String url = C.URL_PUBLISH;
|
String url = C.URL_PUBLISH;
|
||||||
if (map != null)
|
if (map != null)
|
||||||
@ -153,6 +172,8 @@ public class AppDataUpgrader extends IUpgrader {
|
|||||||
}).execute();
|
}).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
public static class AppDataUpgraderPackGzTask extends Task {
|
public static class AppDataUpgraderPackGzTask extends Task {
|
||||||
|
|
||||||
public static final File BASE_FOLDER = MCUtils.getWorkingDirectory("hmcl");
|
public static final File BASE_FOLDER = MCUtils.getWorkingDirectory("hmcl");
|
||||||
@ -174,7 +195,7 @@ public class AppDataUpgrader extends IUpgrader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Task> getDependTasks() {
|
public Collection<Task> getDependTasks() {
|
||||||
return Arrays.asList(new FileDownloadTask(downloadLink, tempFile, expectedHash));
|
return Collections.singleton(new FileDownloadTask(downloadLink, tempFile, expectedHash));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -193,8 +214,9 @@ public class AppDataUpgrader extends IUpgrader {
|
|||||||
if (!f.createNewFile())
|
if (!f.createNewFile())
|
||||||
throw new IOException("Failed to create new file: " + f);
|
throw new IOException("Failed to create new file: " + f);
|
||||||
|
|
||||||
try (JarOutputStream jos = new JarOutputStream(FileUtils.openOutputStream(f))) {
|
try (GZIPInputStream in = new GZIPInputStream(FileUtils.openInputStream(tempFile));
|
||||||
Pack200.newUnpacker().unpack(new GZIPInputStream(FileUtils.openInputStream(tempFile)), jos);
|
JarOutputStream jos = new JarOutputStream(FileUtils.openOutputStream(f))) {
|
||||||
|
Pack200.newUnpacker().unpack(in, jos);
|
||||||
}
|
}
|
||||||
json.put("ver", newestVersion);
|
json.put("ver", newestVersion);
|
||||||
json.put("loc", f.getAbsolutePath());
|
json.put("loc", f.getAbsolutePath());
|
||||||
@ -230,7 +252,7 @@ public class AppDataUpgrader extends IUpgrader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Task> getDependTasks() {
|
public Collection<Task> getDependTasks() {
|
||||||
return Arrays.asList(new FileDownloadTask(downloadLink, tempFile, expectedHash));
|
return Collections.singleton(new FileDownloadTask(downloadLink, tempFile, expectedHash));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.util.upgrade;
|
package org.jackhuang.hmcl.util.upgrade;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||||
import org.jackhuang.hmcl.api.VersionNumber;
|
import org.jackhuang.hmcl.api.VersionNumber;
|
||||||
import org.jackhuang.hmcl.api.func.Consumer;
|
import org.jackhuang.hmcl.api.func.Consumer;
|
||||||
@ -35,7 +36,7 @@ public abstract class IUpgrader implements Consumer<SimpleEvent<VersionNumber>>
|
|||||||
* @param nowVersion now launcher version
|
* @param nowVersion now launcher version
|
||||||
* @param args Application CommandLine Arguments
|
* @param args Application CommandLine Arguments
|
||||||
*/
|
*/
|
||||||
public abstract void parseArguments(VersionNumber nowVersion, String[] args);
|
public abstract void parseArguments(VersionNumber nowVersion, List<String> args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just download the new app.
|
* Just download the new app.
|
||||||
|
@ -1,65 +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.hmcl.util.upgrade;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
|
||||||
import org.jackhuang.hmcl.api.HMCLog;
|
|
||||||
import org.jackhuang.hmcl.util.task.TaskWindow;
|
|
||||||
import org.jackhuang.hmcl.util.net.FileDownloadTask;
|
|
||||||
import org.jackhuang.hmcl.util.ArrayUtils;
|
|
||||||
import org.jackhuang.hmcl.api.VersionNumber;
|
|
||||||
import org.jackhuang.hmcl.util.sys.FileUtils;
|
|
||||||
import org.jackhuang.hmcl.util.sys.IOUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author huangyuhui
|
|
||||||
*/
|
|
||||||
public class NewFileUpgrader extends IUpgrader {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void accept(SimpleEvent<VersionNumber> event) {
|
|
||||||
String str = requestDownloadLink();
|
|
||||||
File newf = new File(FileUtils.getName(str));
|
|
||||||
if (TaskWindow.factory().append(new FileDownloadTask(str, newf)).execute()) {
|
|
||||||
try {
|
|
||||||
new ProcessBuilder(new String[] { newf.getCanonicalPath(), "--removeOldLauncher", IOUtils.getRealPath() }).directory(new File("").getAbsoluteFile()).start();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
HMCLog.err("Failed to start new app", ex);
|
|
||||||
}
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String requestDownloadLink() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -25,6 +25,7 @@ import com.google.gson.JsonSyntaxException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import org.jackhuang.hmcl.api.HMCLog;
|
import org.jackhuang.hmcl.api.HMCLog;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.jackhuang.hmcl.Main;
|
||||||
import org.jackhuang.hmcl.api.HMCLApi;
|
import org.jackhuang.hmcl.api.HMCLApi;
|
||||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||||
import org.jackhuang.hmcl.api.event.OutOfDateEvent;
|
import org.jackhuang.hmcl.api.event.OutOfDateEvent;
|
||||||
@ -61,15 +62,15 @@ public final class UpdateChecker implements IUpdateChecker {
|
|||||||
@Override
|
@Override
|
||||||
protected void work() throws Exception {
|
protected void work() throws Exception {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
versionString = NetUtils.get("http://huangyuhui.duapp.com/info.php?type=" + type);
|
versionString = NetUtils.get("http://hmcl.huangyuhui.net/api/update?version=" + Main.LAUNCHER_VERSION);
|
||||||
value = VersionNumber.check(versionString);
|
value = VersionNumber.asVersion(versionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 (base.compareTo(value) < 0)
|
||||||
outOfDate = true;
|
outOfDate = true;
|
||||||
if (outOfDate)
|
if (outOfDate)
|
||||||
publish(value);
|
publish(value);
|
||||||
@ -89,7 +90,7 @@ public final class UpdateChecker implements IUpdateChecker {
|
|||||||
protected void work() throws Exception {
|
protected void work() throws Exception {
|
||||||
if (download_link == null)
|
if (download_link == null)
|
||||||
try {
|
try {
|
||||||
download_link = C.GSON.<Map<String, String>>fromJson(NetUtils.get("http://huangyuhui.duapp.com/update_link.php?type=" + type), Map.class);
|
download_link = C.GSON.<Map<String, String>>fromJson(NetUtils.get("http://hmcl.huangyuhui.net/api/update_link?version=" + Main.LAUNCHER_VERSION), Map.class);
|
||||||
} catch (JsonSyntaxException | IOException e) {
|
} catch (JsonSyntaxException | IOException e) {
|
||||||
HMCLog.warn("Failed to get update link.", e);
|
HMCLog.warn("Failed to get update link.", e);
|
||||||
}
|
}
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Configuration status="WARN">
|
|
||||||
<Appenders>
|
|
||||||
<Console name="SysOut" target="SYSTEM_OUT">
|
|
||||||
<LegacyXMLLayout />
|
|
||||||
<XMLLayout />
|
|
||||||
</Console>
|
|
||||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
|
||||||
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
|
|
||||||
<Policies>
|
|
||||||
<TimeBasedTriggeringPolicy />
|
|
||||||
<OnStartupTriggeringPolicy />
|
|
||||||
</Policies>
|
|
||||||
</RollingRandomAccessFile>
|
|
||||||
</Appenders>
|
|
||||||
<Loggers>
|
|
||||||
<Root level="info">
|
|
||||||
<filters>
|
|
||||||
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL" />
|
|
||||||
</filters>
|
|
||||||
<AppenderRef ref="SysOut"/>
|
|
||||||
<AppenderRef ref="File"/>
|
|
||||||
</Root>
|
|
||||||
</Loggers>
|
|
||||||
</Configuration>
|
|
@ -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.hmcl.api;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a version string contains '-', a {@link ComposedVersionNumber}
|
||||||
|
* will be generated.
|
||||||
|
*
|
||||||
|
* Formats like 1.7.10-OptiFine, 1.12.2-Forge
|
||||||
|
*
|
||||||
|
* @author huangyuhui
|
||||||
|
*/
|
||||||
|
public final class ComposedVersionNumber extends VersionNumber {
|
||||||
|
List<VersionNumber> composed;
|
||||||
|
|
||||||
|
public static boolean isComposedVersionNumber(String version) {
|
||||||
|
return version.contains("-");
|
||||||
|
}
|
||||||
|
|
||||||
|
ComposedVersionNumber(String version) {
|
||||||
|
composed = Arrays.stream(version.split("-"))
|
||||||
|
.map(VersionNumber::asVersion)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(composed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return composed.stream().map(VersionNumber::toString).collect(Collectors.joining("-"));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* 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.hmcl.api;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a version string formats x.x.x.x, a {@code IntVersionNumber}
|
||||||
|
* will be generated.
|
||||||
|
*
|
||||||
|
* @author huangyuhui
|
||||||
|
*/
|
||||||
|
public final class IntVersionNumber extends VersionNumber {
|
||||||
|
|
||||||
|
final List<Integer> version;
|
||||||
|
|
||||||
|
public static boolean isIntVersionNumber(String version) {
|
||||||
|
if (version.contains("..")) return false;
|
||||||
|
if (version.trim().isEmpty()) return false;
|
||||||
|
for (char ch : version.toCharArray())
|
||||||
|
if (ch != '.' && (ch < '0' || ch > '9'))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntVersionNumber(String version) {
|
||||||
|
if (!isIntVersionNumber(version))
|
||||||
|
throw new IllegalArgumentException("The version " + version + " is malformed, only dots and digits are allowed.");
|
||||||
|
|
||||||
|
String[] slice = version.split("\\.");
|
||||||
|
List<Integer> versions = new LinkedList<>();
|
||||||
|
for (String str : slice) versions.add(Integer.parseInt(str));
|
||||||
|
while (!versions.isEmpty() && versions.get(versions.size() - 1) == 0)
|
||||||
|
versions.remove(versions.size() - 1);
|
||||||
|
|
||||||
|
this.version = versions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int get(int index) {
|
||||||
|
return version.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
List<String> seq = new LinkedList<>();
|
||||||
|
for (int str : version)
|
||||||
|
seq.add(Integer.toString(str));
|
||||||
|
return String.join(".", seq);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* 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.hmcl.api;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a version string contains alphabets, a {@code StringVersionNumber}
|
||||||
|
* will be constructed.
|
||||||
|
*
|
||||||
|
* @author huangyuhui
|
||||||
|
*/
|
||||||
|
public final class StringVersionNumber extends VersionNumber {
|
||||||
|
|
||||||
|
private final String version;
|
||||||
|
|
||||||
|
StringVersionNumber(String version) {
|
||||||
|
Objects.requireNonNull(version);
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return version.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -17,100 +17,85 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.api;
|
package org.jackhuang.hmcl.api;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* The formatted version number represents a version string.
|
||||||
*
|
*
|
||||||
* @author huangyuhui
|
* @author huangyuhui
|
||||||
*/
|
*/
|
||||||
public final class VersionNumber implements Comparable<VersionNumber> {
|
public abstract class VersionNumber implements Comparable<VersionNumber> {
|
||||||
|
|
||||||
public final byte firstVer, secondVer, thirdVer;
|
public static VersionNumber asVersion(String version) {
|
||||||
public final String version;
|
Objects.requireNonNull(version);
|
||||||
|
if (ComposedVersionNumber.isComposedVersionNumber(version))
|
||||||
public VersionNumber(byte a, byte b, byte c) {
|
return new ComposedVersionNumber(version);
|
||||||
this(a, b, c, null);
|
else if (IntVersionNumber.isIntVersionNumber(version))
|
||||||
|
return new IntVersionNumber(version);
|
||||||
|
else
|
||||||
|
return new StringVersionNumber(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VersionNumber(byte a, byte b, byte c, String version) {
|
public static Optional<String> parseVersion(String str) {
|
||||||
firstVer = a;
|
if (IntVersionNumber.isIntVersionNumber(str))
|
||||||
secondVer = b;
|
return Optional.of(new IntVersionNumber(str).toString());
|
||||||
thirdVer = c;
|
else
|
||||||
this.version = version;
|
return Optional.empty();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "" + firstVer + '.' + secondVer + '.' + thirdVer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static VersionNumber check(String data) {
|
|
||||||
while (!data.isEmpty() && ((data.charAt(0) < '0' || data.charAt(0) > '9') && data.charAt(0) != '.'))
|
|
||||||
data = data.substring(1);
|
|
||||||
if (data.isEmpty())
|
|
||||||
return null;
|
|
||||||
VersionNumber ur;
|
|
||||||
String[] ver = data.split("\\.");
|
|
||||||
if (ver.length >= 3) {
|
|
||||||
byte v1, v2, v3;
|
|
||||||
try {
|
|
||||||
v1 = Byte.parseByte(ver[0]);
|
|
||||||
v2 = Byte.parseByte(ver[1]);
|
|
||||||
v3 = Byte.parseByte(ver[2]);
|
|
||||||
ur = new VersionNumber(v1, v2, v3, data);
|
|
||||||
return ur;
|
|
||||||
} catch (Exception e) {
|
|
||||||
HMCLog.warn("Failed to parse the version", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isOlder(VersionNumber a, VersionNumber b) {
|
|
||||||
if (a.firstVer < b.firstVer)
|
|
||||||
return true;
|
|
||||||
else if (a.firstVer == b.firstVer)
|
|
||||||
if (a.secondVer < b.secondVer)
|
|
||||||
return true;
|
|
||||||
else if (a.secondVer == b.secondVer)
|
|
||||||
if (a.thirdVer < b.thirdVer)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int hash = 3;
|
|
||||||
hash = 83 * hash + this.firstVer;
|
|
||||||
hash = 83 * hash + this.secondVer;
|
|
||||||
hash = 83 * hash + this.thirdVer;
|
|
||||||
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 VersionNumber other = (VersionNumber) obj;
|
|
||||||
if (this.firstVer != other.firstVer)
|
|
||||||
return false;
|
|
||||||
if (this.secondVer != other.secondVer)
|
|
||||||
return false;
|
|
||||||
if (this.thirdVer != other.thirdVer)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(VersionNumber o) {
|
public int compareTo(VersionNumber o) {
|
||||||
if (isOlder(this, o))
|
return COMPARATOR.compare(this, o);
|
||||||
return -1;
|
|
||||||
else if (isOlder(o, this))
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == null) return false;
|
||||||
|
else return toString().equals(obj.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T extends Comparable<T>> int compareTo(List<T> a, List<T> b) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < a.size() && i < b.size(); ++i) {
|
||||||
|
int res = a.get(i).compareTo(b.get(i));
|
||||||
|
if (res != 0)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
if (i < a.size()) return 1;
|
||||||
|
else if (i < b.size()) return -1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Comparator<VersionNumber> COMPARATOR = new Comparator<VersionNumber>() {
|
||||||
|
@Override
|
||||||
|
public int compare(VersionNumber a, VersionNumber b) {
|
||||||
|
if (a == null || b == null)
|
||||||
|
return 0;
|
||||||
|
else {
|
||||||
|
if (a instanceof ComposedVersionNumber) {
|
||||||
|
if (b instanceof ComposedVersionNumber)
|
||||||
|
return compareTo(((ComposedVersionNumber) a).composed, ((ComposedVersionNumber) b).composed);
|
||||||
|
else
|
||||||
|
return compare(((ComposedVersionNumber) a).composed.get(0), b);
|
||||||
|
} else if (a instanceof IntVersionNumber) {
|
||||||
|
if (b instanceof ComposedVersionNumber)
|
||||||
|
return -compare(b, a);
|
||||||
|
else if (b instanceof IntVersionNumber)
|
||||||
|
return compareTo(((IntVersionNumber) a).version, ((IntVersionNumber) b).version);
|
||||||
|
else if (b instanceof StringVersionNumber)
|
||||||
|
return a.toString().compareTo(b.toString());
|
||||||
|
} else if (a instanceof StringVersionNumber) {
|
||||||
|
if (b instanceof ComposedVersionNumber)
|
||||||
|
return -compare(b, a);
|
||||||
|
else if (b instanceof StringVersionNumber)
|
||||||
|
return a.toString().compareTo(b.toString());
|
||||||
|
else if (b instanceof IntVersionNumber)
|
||||||
|
return a.toString().compareTo(b.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Unrecognized VersionNumber " + a + " and " + b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
}
|
}
|
@ -95,9 +95,9 @@ public class AssetsMojangLoader extends IAssetsHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isVersionAllowed(String formattedVersion) {
|
public boolean isVersionAllowed(String formattedVersion) {
|
||||||
VersionNumber ur = VersionNumber.check(formattedVersion);
|
VersionNumber ur = VersionNumber.asVersion(formattedVersion);
|
||||||
if (ur == null)
|
if (ur == null)
|
||||||
return false;
|
return false;
|
||||||
return VersionNumber.check("1.6.0").compareTo(ur) <= 0;
|
return VersionNumber.asVersion("1.6.0").compareTo(ur) <= 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ import java.io.OutputStream;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import org.jackhuang.hmcl.api.HMCLog;
|
import org.jackhuang.hmcl.api.HMCLog;
|
||||||
|
@ -390,7 +390,7 @@ update.no_browser=无法打开浏览器,网址已经复制到剪贴板了,
|
|||||||
update.should_open_link=是否更新?
|
update.should_open_link=是否更新?
|
||||||
update.newest_version=最新版本为:
|
update.newest_version=最新版本为:
|
||||||
update.failed=检查更新失败
|
update.failed=检查更新失败
|
||||||
update.found=(发现更新!)
|
update.found=(点击此处更新)
|
||||||
|
|
||||||
logwindow.terminate_game=结束游戏进程
|
logwindow.terminate_game=结束游戏进程
|
||||||
logwindow.title=日志
|
logwindow.title=日志
|
||||||
|
@ -390,7 +390,7 @@ update.no_browser=\u65e0\u6cd5\u6253\u5f00\u6d4f\u89c8\u5668\uff0c\u7f51\u5740\u
|
|||||||
update.should_open_link=\u662f\u5426\u66f4\u65b0\uff1f
|
update.should_open_link=\u662f\u5426\u66f4\u65b0\uff1f
|
||||||
update.newest_version=\u6700\u65b0\u7248\u672c\u4e3a\uff1a
|
update.newest_version=\u6700\u65b0\u7248\u672c\u4e3a\uff1a
|
||||||
update.failed=\u68c0\u67e5\u66f4\u65b0\u5931\u8d25
|
update.failed=\u68c0\u67e5\u66f4\u65b0\u5931\u8d25
|
||||||
update.found=(\u53d1\u73b0\u66f4\u65b0!)
|
update.found=(\u70b9\u51fb\u6b64\u5904\u66f4\u65b0)
|
||||||
|
|
||||||
logwindow.terminate_game=\u7ed3\u675f\u6e38\u620f\u8fdb\u7a0b
|
logwindow.terminate_game=\u7ed3\u675f\u6e38\u620f\u8fdb\u7a0b
|
||||||
logwindow.title=\u65e5\u5fd7
|
logwindow.title=\u65e5\u5fd7
|
||||||
|
Loading…
x
Reference in New Issue
Block a user