Change update source

This commit is contained in:
huangyuhui 2018-08-15 03:05:55 +08:00
parent 69c0382bd5
commit c47dea94e3
14 changed files with 327 additions and 249 deletions

View File

@ -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 {

View File

@ -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

View File

@ -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.

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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>

View File

@ -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("-"));
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
};
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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=日志

View File

@ -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