mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-03-25 18:00:27 +08: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.security.GeneralSecurityException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
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);
|
||||
for (String s : args)
|
||||
@ -161,7 +162,7 @@ public final class Main {
|
||||
}
|
||||
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("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();
|
||||
}
|
||||
}
|
||||
@ -244,20 +239,6 @@ public final class Main {
|
||||
public static void 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) {
|
||||
try {
|
||||
|
@ -17,20 +17,19 @@
|
||||
*/
|
||||
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.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarFile;
|
||||
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.TaskWindow;
|
||||
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.Utils;
|
||||
import org.jackhuang.hmcl.api.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.StrUtils;
|
||||
import org.jackhuang.hmcl.util.sys.FileUtils;
|
||||
import org.jackhuang.hmcl.util.sys.IOUtils;
|
||||
import org.jackhuang.hmcl.util.sys.Java;
|
||||
import org.jackhuang.hmcl.util.sys.OS;
|
||||
|
||||
/**
|
||||
@ -60,45 +59,49 @@ import org.jackhuang.hmcl.util.sys.OS;
|
||||
*/
|
||||
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)) {
|
||||
String mainClass = jarFile.getManifest().getMainAttributes().getValue("Main-Class");
|
||||
if (mainClass != null) {
|
||||
ArrayList<String> al = new ArrayList<>(Arrays.asList(args));
|
||||
al.add("--noupdate");
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
|
||||
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 null;
|
||||
});
|
||||
return true;
|
||||
if (mainClass == null)
|
||||
throw new ClassNotFoundException("Main-Class not found in manifest");
|
||||
ArrayList<String> al = new ArrayList<>(args);
|
||||
al.add("--noupdate");
|
||||
ClassLoader pre = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
ClassLoader now = new URLClassLoader(new URL[] { jar.toURI().toURL() }, ClassLoader.getSystemClassLoader().getParent());
|
||||
Thread.currentThread().setContextClassLoader(now);
|
||||
now.loadClass(mainClass).getMethod("main", String[].class).invoke(null, new Object[] { al.toArray(new String[0]) });
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(pre);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseArguments(VersionNumber nowVersion, String[] args) {
|
||||
public void parseArguments(VersionNumber nowVersion, List<String> args) {
|
||||
File f = AppDataUpgraderPackGzTask.HMCL_VER_FILE;
|
||||
if (!ArrayUtils.contains(args, "--noupdate"))
|
||||
if (!args.contains("--noupdate"))
|
||||
try {
|
||||
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");
|
||||
if (s != null && VersionNumber.check(s).compareTo(nowVersion) > 0) {
|
||||
if (s != null && VersionNumber.asVersion(s).compareTo(nowVersion) > 0) {
|
||||
String j = m.get("loc");
|
||||
if (j != null) {
|
||||
File jar = new File(j);
|
||||
if (jar.exists() && launchNewerVersion(args, jar))
|
||||
if (jar.exists()) {
|
||||
launchNewerVersion(args, jar);
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (JsonSyntaxException ex) {
|
||||
} catch (JsonParseException ex) {
|
||||
f.delete();
|
||||
} catch (IOException | PrivilegedActionException t) {
|
||||
HMCLog.err("Failed to execute newer version application", t);
|
||||
} catch (IOException | ReflectiveOperationException 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) {
|
||||
final VersionNumber version = event.getValue();
|
||||
((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"),
|
||||
MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
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.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")))
|
||||
if (map != null && map.containsKey("pack") && !StrUtils.isBlank(map.get("pack")))
|
||||
try {
|
||||
String hash = null;
|
||||
if (map.containsKey("packsha1"))
|
||||
hash = map.get("packsha1");
|
||||
if (TaskWindow.factory().append(new AppDataUpgraderPackGzTask(map.get("pack"), version.version, hash)).execute()) {
|
||||
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderPackGzTask.getSelf(version.version).getAbsolutePath() }).directory(new File("").getAbsoluteFile()).start();
|
||||
if (TaskWindow.factory().append(new AppDataUpgraderPackGzTask(map.get("pack"), version.toString(), hash)).execute()) {
|
||||
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderPackGzTask.getSelf(version.toString()).getAbsolutePath() }).directory(new File("").getAbsoluteFile()).start();
|
||||
System.exit(0);
|
||||
}
|
||||
} catch (IOException 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 {
|
||||
String url = C.URL_PUBLISH;
|
||||
if (map != null)
|
||||
@ -153,6 +172,8 @@ public class AppDataUpgrader extends IUpgrader {
|
||||
}).execute();
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
public static class AppDataUpgraderPackGzTask extends Task {
|
||||
|
||||
public static final File BASE_FOLDER = MCUtils.getWorkingDirectory("hmcl");
|
||||
@ -174,7 +195,7 @@ public class AppDataUpgrader extends IUpgrader {
|
||||
|
||||
@Override
|
||||
public Collection<Task> getDependTasks() {
|
||||
return Arrays.asList(new FileDownloadTask(downloadLink, tempFile, expectedHash));
|
||||
return Collections.singleton(new FileDownloadTask(downloadLink, tempFile, expectedHash));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -193,8 +214,9 @@ public class AppDataUpgrader extends IUpgrader {
|
||||
if (!f.createNewFile())
|
||||
throw new IOException("Failed to create new file: " + f);
|
||||
|
||||
try (JarOutputStream jos = new JarOutputStream(FileUtils.openOutputStream(f))) {
|
||||
Pack200.newUnpacker().unpack(new GZIPInputStream(FileUtils.openInputStream(tempFile)), jos);
|
||||
try (GZIPInputStream in = new GZIPInputStream(FileUtils.openInputStream(tempFile));
|
||||
JarOutputStream jos = new JarOutputStream(FileUtils.openOutputStream(f))) {
|
||||
Pack200.newUnpacker().unpack(in, jos);
|
||||
}
|
||||
json.put("ver", newestVersion);
|
||||
json.put("loc", f.getAbsolutePath());
|
||||
@ -230,7 +252,7 @@ public class AppDataUpgrader extends IUpgrader {
|
||||
|
||||
@Override
|
||||
public Collection<Task> getDependTasks() {
|
||||
return Arrays.asList(new FileDownloadTask(downloadLink, tempFile, expectedHash));
|
||||
return Collections.singleton(new FileDownloadTask(downloadLink, tempFile, expectedHash));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.util.upgrade;
|
||||
|
||||
import java.util.List;
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
import org.jackhuang.hmcl.api.VersionNumber;
|
||||
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 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.
|
||||
|
@ -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 org.jackhuang.hmcl.api.HMCLog;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hmcl.Main;
|
||||
import org.jackhuang.hmcl.api.HMCLApi;
|
||||
import org.jackhuang.hmcl.api.event.SimpleEvent;
|
||||
import org.jackhuang.hmcl.api.event.OutOfDateEvent;
|
||||
@ -61,15 +62,15 @@ public final class UpdateChecker implements IUpdateChecker {
|
||||
@Override
|
||||
protected void work() throws Exception {
|
||||
if (value == null) {
|
||||
versionString = NetUtils.get("http://huangyuhui.duapp.com/info.php?type=" + type);
|
||||
value = VersionNumber.check(versionString);
|
||||
versionString = NetUtils.get("http://hmcl.huangyuhui.net/api/update?version=" + Main.LAUNCHER_VERSION);
|
||||
value = VersionNumber.asVersion(versionString);
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
HMCLog.warn("Failed to check update...");
|
||||
if (showMessage)
|
||||
MessageBox.show(C.i18n("update.failed"));
|
||||
} else if (VersionNumber.isOlder(base, value))
|
||||
} else if (base.compareTo(value) < 0)
|
||||
outOfDate = true;
|
||||
if (outOfDate)
|
||||
publish(value);
|
||||
@ -89,7 +90,7 @@ public final class UpdateChecker implements IUpdateChecker {
|
||||
protected void work() throws Exception {
|
||||
if (download_link == null)
|
||||
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) {
|
||||
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;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* The formatted version number represents a version string.
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class VersionNumber implements Comparable<VersionNumber> {
|
||||
public abstract class VersionNumber implements Comparable<VersionNumber> {
|
||||
|
||||
public final byte firstVer, secondVer, thirdVer;
|
||||
public final String version;
|
||||
|
||||
public VersionNumber(byte a, byte b, byte c) {
|
||||
this(a, b, c, null);
|
||||
public static VersionNumber asVersion(String version) {
|
||||
Objects.requireNonNull(version);
|
||||
if (ComposedVersionNumber.isComposedVersionNumber(version))
|
||||
return new ComposedVersionNumber(version);
|
||||
else if (IntVersionNumber.isIntVersionNumber(version))
|
||||
return new IntVersionNumber(version);
|
||||
else
|
||||
return new StringVersionNumber(version);
|
||||
}
|
||||
|
||||
public VersionNumber(byte a, byte b, byte c, String version) {
|
||||
firstVer = a;
|
||||
secondVer = b;
|
||||
thirdVer = c;
|
||||
this.version = version;
|
||||
public static Optional<String> parseVersion(String str) {
|
||||
if (IntVersionNumber.isIntVersionNumber(str))
|
||||
return Optional.of(new IntVersionNumber(str).toString());
|
||||
else
|
||||
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;
|
||||
public int compareTo(VersionNumber o) {
|
||||
return COMPARATOR.compare(this, o);
|
||||
}
|
||||
|
||||
@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
|
||||
public int compareTo(VersionNumber o) {
|
||||
if (isOlder(this, o))
|
||||
return -1;
|
||||
else if (isOlder(o, this))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
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
|
||||
public boolean isVersionAllowed(String formattedVersion) {
|
||||
VersionNumber ur = VersionNumber.check(formattedVersion);
|
||||
VersionNumber ur = VersionNumber.asVersion(formattedVersion);
|
||||
if (ur == null)
|
||||
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.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
|
@ -390,7 +390,7 @@ update.no_browser=无法打开浏览器,网址已经复制到剪贴板了,
|
||||
update.should_open_link=是否更新?
|
||||
update.newest_version=最新版本为:
|
||||
update.failed=检查更新失败
|
||||
update.found=(发现更新!)
|
||||
update.found=(点击此处更新)
|
||||
|
||||
logwindow.terminate_game=结束游戏进程
|
||||
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.newest_version=\u6700\u65b0\u7248\u672c\u4e3a\uff1a
|
||||
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.title=\u65e5\u5fd7
|
||||
|
Loading…
x
Reference in New Issue
Block a user