feat(update): update channel is bound to build type.

This commit is contained in:
huanghongxun 2021-10-10 02:27:20 +08:00
parent 6221f4b616
commit f014f59cf2
9 changed files with 48 additions and 51 deletions

View File

@ -164,9 +164,6 @@ public final class Config implements Cloneable, Observable {
@SerializedName("authlibInjectorServers") @SerializedName("authlibInjectorServers")
private ObservableList<AuthlibInjectorServer> authlibInjectorServers = FXCollections.observableArrayList(server -> new Observable[] { server }); private ObservableList<AuthlibInjectorServer> authlibInjectorServers = FXCollections.observableArrayList(server -> new Observable[] { server });
@SerializedName("updateChannel")
private ObjectProperty<UpdateChannel> updateChannel = new SimpleObjectProperty<>(UpdateChannel.STABLE);
@SerializedName("_version") @SerializedName("_version")
private IntegerProperty configVersion = new SimpleIntegerProperty(0); private IntegerProperty configVersion = new SimpleIntegerProperty(0);
@ -536,18 +533,6 @@ public final class Config implements Cloneable, Observable {
return authlibInjectorServers; return authlibInjectorServers;
} }
public UpdateChannel getUpdateChannel() {
return updateChannel.get();
}
public ObjectProperty<UpdateChannel> updateChannelProperty() {
return updateChannel;
}
public void setUpdateChannel(UpdateChannel updateChannel) {
this.updateChannel.set(updateChannel);
}
public int getConfigVersion() { public int getConfigVersion() {
return configVersion.get(); return configVersion.get();
} }

View File

@ -24,28 +24,28 @@ import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView; import javafx.scene.web.WebView;
import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.Metadata;
import org.jackhuang.hmcl.ui.construct.DialogCloseEvent; import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
import org.jackhuang.hmcl.upgrade.RemoteVersion;
import java.util.logging.Level; import java.util.logging.Level;
import static org.jackhuang.hmcl.Metadata.CHANGELOG_URL; import static org.jackhuang.hmcl.Metadata.CHANGELOG_URL;
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed; import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed;
import static org.jackhuang.hmcl.util.Logging.LOG; import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class UpgradeDialog extends JFXDialogLayout { public class UpgradeDialog extends JFXDialogLayout {
public UpgradeDialog(Runnable updateRunnable) { public UpgradeDialog(RemoteVersion remoteVersion, Runnable updateRunnable) {
{ {
setHeading(new Label(i18n("update.changelog"))); setHeading(new Label(i18n("update.changelog")));
} }
{ {
String url = CHANGELOG_URL + config().getUpdateChannel().channelName + ".html"; String url = CHANGELOG_URL + remoteVersion.getChannel().channelName + ".html";
WebView webView = new WebView(); WebView webView = new WebView();
webView.getEngine().setUserDataDirectory(Metadata.HMCL_DIRECTORY.toFile()); webView.getEngine().setUserDataDirectory(Metadata.HMCL_DIRECTORY.toFile());
try { try {
WebEngine engine = webView.getEngine(); WebEngine engine = webView.getEngine();
engine.load(CHANGELOG_URL + config().getUpdateChannel().channelName); engine.load(CHANGELOG_URL + remoteVersion.getChannel().channelName);
engine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> { engine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
String viewURL = engine.getLoadWorker().getMessage().trim(); String viewURL = engine.getLoadWorker().getMessage().trim();
if (!viewURL.startsWith(CHANGELOG_URL)) { if (!viewURL.startsWith(CHANGELOG_URL)) {

View File

@ -21,6 +21,7 @@ import javafx.application.Platform;
import javafx.beans.InvalidationListener; import javafx.beans.InvalidationListener;
import javafx.beans.WeakInvalidationListener; import javafx.beans.WeakInvalidationListener;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.scene.control.ToggleGroup; import javafx.scene.control.ToggleGroup;
import org.jackhuang.hmcl.setting.Settings; import org.jackhuang.hmcl.setting.Settings;
import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.Controllers;
@ -104,7 +105,11 @@ public final class SettingsPage extends SettingsView {
chkUpdateDev.setUserData(UpdateChannel.DEVELOPMENT); chkUpdateDev.setUserData(UpdateChannel.DEVELOPMENT);
chkUpdateStable.setToggleGroup(updateChannelGroup); chkUpdateStable.setToggleGroup(updateChannelGroup);
chkUpdateStable.setUserData(UpdateChannel.STABLE); chkUpdateStable.setUserData(UpdateChannel.STABLE);
selectedItemPropertyFor(updateChannelGroup, UpdateChannel.class).bindBidirectional(config().updateChannelProperty()); ObjectProperty<UpdateChannel> updateChannel = selectedItemPropertyFor(updateChannelGroup, UpdateChannel.class);
updateChannel.set(UpdateChannel.getChannel());
updateChannel.addListener((a, b, newValue) -> {
UpdateChecker.requestCheckUpdate(newValue);
});
// ==== // ====
} }

View File

@ -30,7 +30,7 @@ import java.util.Optional;
public class RemoteVersion { public class RemoteVersion {
public static RemoteVersion fetch(String url) throws IOException { public static RemoteVersion fetch(UpdateChannel channel, String url) throws IOException {
try { try {
JsonObject response = JsonUtils.fromNonNullJson(NetworkUtils.doGet(NetworkUtils.toURL(url)), JsonObject.class); JsonObject response = JsonUtils.fromNonNullJson(NetworkUtils.doGet(NetworkUtils.toURL(url)), JsonObject.class);
String version = Optional.ofNullable(response.get("version")).map(JsonElement::getAsString).orElseThrow(() -> new IOException("version is missing")); String version = Optional.ofNullable(response.get("version")).map(JsonElement::getAsString).orElseThrow(() -> new IOException("version is missing"));
@ -39,9 +39,9 @@ public class RemoteVersion {
String packXZUrl = Optional.ofNullable(response.get("packxz")).map(JsonElement::getAsString).orElse(null); String packXZUrl = Optional.ofNullable(response.get("packxz")).map(JsonElement::getAsString).orElse(null);
String packXZHash = Optional.ofNullable(response.get("packxzsha1")).map(JsonElement::getAsString).orElse(null); String packXZHash = Optional.ofNullable(response.get("packxzsha1")).map(JsonElement::getAsString).orElse(null);
if (Pack200Utils.isSupported() && packXZUrl != null && packXZHash != null) { if (Pack200Utils.isSupported() && packXZUrl != null && packXZHash != null) {
return new RemoteVersion(version, packXZUrl, Type.PACK_XZ, new IntegrityCheck("SHA-1", packXZHash)); return new RemoteVersion(channel, version, packXZUrl, Type.PACK_XZ, new IntegrityCheck("SHA-1", packXZHash));
} else if (jarUrl != null && jarHash != null) { } else if (jarUrl != null && jarHash != null) {
return new RemoteVersion(version, jarUrl, Type.JAR, new IntegrityCheck("SHA-1", jarHash)); return new RemoteVersion(channel, version, jarUrl, Type.JAR, new IntegrityCheck("SHA-1", jarHash));
} else { } else {
throw new IOException("No download url is available"); throw new IOException("No download url is available");
} }
@ -50,18 +50,24 @@ public class RemoteVersion {
} }
} }
private String version; private final UpdateChannel channel;
private String url; private final String version;
private Type type; private final String url;
private IntegrityCheck integrityCheck; private final Type type;
private final IntegrityCheck integrityCheck;
public RemoteVersion(String version, String url, Type type, IntegrityCheck integrityCheck) { public RemoteVersion(UpdateChannel channel, String version, String url, Type type, IntegrityCheck integrityCheck) {
this.channel = channel;
this.version = version; this.version = version;
this.url = url; this.url = url;
this.type = type; this.type = type;
this.integrityCheck = integrityCheck; this.integrityCheck = integrityCheck;
} }
public UpdateChannel getChannel() {
return channel;
}
public String getVersion() { public String getVersion() {
return version; return version;
} }

View File

@ -17,13 +17,26 @@
*/ */
package org.jackhuang.hmcl.upgrade; package org.jackhuang.hmcl.upgrade;
import org.jackhuang.hmcl.Metadata;
public enum UpdateChannel { public enum UpdateChannel {
STABLE("stable"), STABLE("stable"),
DEVELOPMENT("dev"); DEVELOPMENT("dev"),
NIGHTLY("nightly");
public final String channelName; public final String channelName;
UpdateChannel(String channelName) { UpdateChannel(String channelName) {
this.channelName = channelName; this.channelName = channelName;
} }
public static UpdateChannel getChannel() {
if (Metadata.isDev()) {
return DEVELOPMENT;
} else if (Metadata.isNightly()) {
return NIGHTLY;
} else {
return STABLE;
}
}
} }

View File

@ -23,14 +23,11 @@ import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.*; import javafx.beans.property.*;
import javafx.beans.value.ObservableBooleanValue; import javafx.beans.value.ObservableBooleanValue;
import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.Metadata;
import org.jackhuang.hmcl.setting.ConfigHolder;
import org.jackhuang.hmcl.util.io.NetworkUtils; import org.jackhuang.hmcl.util.io.NetworkUtils;
import java.io.IOException; import java.io.IOException;
import java.util.logging.Level; import java.util.logging.Level;
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.ui.FXUtils.onInvalidating;
import static org.jackhuang.hmcl.util.Lang.mapOf; import static org.jackhuang.hmcl.util.Lang.mapOf;
import static org.jackhuang.hmcl.util.Lang.thread; import static org.jackhuang.hmcl.util.Lang.thread;
import static org.jackhuang.hmcl.util.Logging.LOG; import static org.jackhuang.hmcl.util.Logging.LOG;
@ -47,15 +44,16 @@ public final class UpdateChecker {
if (latest == null || isDevelopmentVersion(Metadata.VERSION)) { if (latest == null || isDevelopmentVersion(Metadata.VERSION)) {
return false; return false;
} else { } else {
return asVersion(latest.getVersion()).compareTo(asVersion(Metadata.VERSION)) > 0; // We can update from development version to stable version,
// which can be downgrading.
return asVersion(latest.getVersion()).compareTo(asVersion(Metadata.VERSION)) != 0;
} }
}, },
latestVersion); latestVersion);
private static ReadOnlyBooleanWrapper checkingUpdate = new ReadOnlyBooleanWrapper(false); private static ReadOnlyBooleanWrapper checkingUpdate = new ReadOnlyBooleanWrapper(false);
public static void init() { public static void init() {
ConfigHolder.config().updateChannelProperty().addListener(onInvalidating(UpdateChecker::requestCheckUpdate)); requestCheckUpdate(UpdateChannel.getChannel());
requestCheckUpdate();
} }
public static RemoteVersion getLatestVersion() { public static RemoteVersion getLatestVersion() {
@ -91,7 +89,7 @@ public final class UpdateChecker {
pair("version", Metadata.VERSION), pair("version", Metadata.VERSION),
pair("channel", channel.channelName))); pair("channel", channel.channelName)));
return RemoteVersion.fetch(url); return RemoteVersion.fetch(channel, url);
} }
private static boolean isDevelopmentVersion(String version) { private static boolean isDevelopmentVersion(String version) {
@ -99,12 +97,11 @@ public final class UpdateChecker {
version.contains("SNAPSHOT"); // eg. 3.1.SNAPSHOT version.contains("SNAPSHOT"); // eg. 3.1.SNAPSHOT
} }
public static void requestCheckUpdate() { public static void requestCheckUpdate(UpdateChannel channel) {
Platform.runLater(() -> { Platform.runLater(() -> {
if (isCheckingUpdate()) if (isCheckingUpdate())
return; return;
checkingUpdate.set(true); checkingUpdate.set(true);
UpdateChannel channel = config().getUpdateChannel();
thread(() -> { thread(() -> {
RemoteVersion result = null; RemoteVersion result = null;
@ -119,13 +116,7 @@ public final class UpdateChecker {
Platform.runLater(() -> { Platform.runLater(() -> {
checkingUpdate.set(false); checkingUpdate.set(false);
if (finalResult != null) { if (finalResult != null) {
if (channel.equals(config().getUpdateChannel())) {
latestVersion.set(finalResult); latestVersion.set(finalResult);
} else {
// the channel has been changed during the period
// check update again
requestCheckUpdate();
}
} }
}); });
}, "Update Checker", true); }, "Update Checker", true);

View File

@ -891,14 +891,13 @@ update.channel.dev.hint=You are using the beta version, which may include some e
If you met some problems, you can go to <a href="hmcl://settings/feedback">the feedback page</a> to report them, or join chat <a href="https://discord.gg/jVvC7HfM6U">Discord</a> or <a href="https://kaihei.co/Kx7n3t">KaiHeiLa</a> to report problems.\n\n\ If you met some problems, you can go to <a href="hmcl://settings/feedback">the feedback page</a> to report them, or join chat <a href="https://discord.gg/jVvC7HfM6U">Discord</a> or <a href="https://kaihei.co/Kx7n3t">KaiHeiLa</a> to report problems.\n\n\
To hide this hint, you need to <a href="https://hmcl.huangyuhui.net/api/redirect/sponsor">donate</a> or make impressive contribution in feedback. To hide this hint, you need to <a href="https://hmcl.huangyuhui.net/api/redirect/sponsor">donate</a> or make impressive contribution in feedback.
update.channel.dev.title=Hints for beta version update.channel.dev.title=Hints for beta version
update.channel.dev.update=Update to beta version
update.channel.nightly=Alpha update.channel.nightly=Alpha
update.channel.nightly.hint=You are using the alpha version, which may include some extra functionalities compared to the beta and release version, only used for testing.\n\ update.channel.nightly.hint=You are using the alpha version, which may include some extra functionalities compared to the beta and release version, only used for testing.\n\
Alpha version should be unstable!\n\ Alpha version should be unstable!\n\
If you met some problems, you can go to <a href="hmcl://settings/feedback">the feedback page</a> to report them, or join chat <a href="https://discord.gg/jVvC7HfM6U">Discord</a> or <a href="https://kaihei.co/Kx7n3t">KaiHeiLa</a> to report problems.\n\n\ If you met some problems, you can go to <a href="hmcl://settings/feedback">the feedback page</a> to report them, or join chat <a href="https://discord.gg/jVvC7HfM6U">Discord</a> or <a href="https://kaihei.co/Kx7n3t">KaiHeiLa</a> to report problems.\n\n\
To hide this hint, you need to <a href="https://hmcl.huangyuhui.net/api/redirect/sponsor">donate</a> or make impressive contribution in feedback. To hide this hint, you need to <a href="https://hmcl.huangyuhui.net/api/redirect/sponsor">donate</a> or make impressive contribution in feedback.
update.channel.nightly.title=Hints for alpha version update.channel.nightly.title=Hints for alpha version
update.channel.stable.update=Update to release version update.channel.stable=Release
update.checking=Checking for updates update.checking=Checking for updates
update.failed=Failed to perform update update.failed=Failed to perform update
update.found=Update Available! update.found=Update Available!

View File

@ -890,14 +890,13 @@ update.channel.dev.hint=你正在使用測試版。測試版包含一些未在
如果你遇到了使用問題,可以在設置的 <a href="hmcl://settings/feedback">回饋頁面</a> 中進行回饋,或加入回饋頁面中提供的 <a href="https://discord.gg/jVvC7HfM6U">Discord</a> 或 <a href="https://kaihei.co/Kx7n3t">開黑啦</a>群以回饋問題。\n\n\ 如果你遇到了使用問題,可以在設置的 <a href="hmcl://settings/feedback">回饋頁面</a> 中進行回饋,或加入回饋頁面中提供的 <a href="https://discord.gg/jVvC7HfM6U">Discord</a> 或 <a href="https://kaihei.co/Kx7n3t">開黑啦</a>群以回饋問題。\n\n\
你需要 <a href="https://hmcl.huangyuhui.net/api/redirect/sponsor">贊助</a> 或在回饋過程中作出貢獻以隱藏本提示。 你需要 <a href="https://hmcl.huangyuhui.net/api/redirect/sponsor">贊助</a> 或在回饋過程中作出貢獻以隱藏本提示。
update.channel.dev.title=測試版提示 update.channel.dev.title=測試版提示
update.channel.dev.update=更新到開發版
update.channel.nightly=預覽版 update.channel.nightly=預覽版
update.channel.nightly.hint=你正在使用預覽版。預覽版可能會每天更新一次,包含一些未在正式版和測試版中包含的測試性功能,僅用於體驗新功能\n\ update.channel.nightly.hint=你正在使用預覽版。預覽版可能會每天更新一次,包含一些未在正式版和測試版中包含的測試性功能,僅用於體驗新功能\n\
使\n\ 使\n\
如果你遇到了使用問題,可以在設置的 <a href="hmcl://settings/feedback">回饋頁面</a> 中進行回饋,或加入回饋頁面中提供的 <a href="https://discord.gg/jVvC7HfM6U">Discord</a> 或 <a href="https://kaihei.co/Kx7n3t">開黑啦</a>群以回饋問題。\n\n\ 如果你遇到了使用問題,可以在設置的 <a href="hmcl://settings/feedback">回饋頁面</a> 中進行回饋,或加入回饋頁面中提供的 <a href="https://discord.gg/jVvC7HfM6U">Discord</a> 或 <a href="https://kaihei.co/Kx7n3t">開黑啦</a>群以回饋問題。\n\n\
你需要 <a href="https://hmcl.huangyuhui.net/api/redirect/sponsor">贊助</a> 或在回饋過程中作出貢獻以隱藏本提示。 你需要 <a href="https://hmcl.huangyuhui.net/api/redirect/sponsor">贊助</a> 或在回饋過程中作出貢獻以隱藏本提示。
update.channel.nightly.title=預覽版提示 update.channel.nightly.title=預覽版提示
update.channel.stable.update=更新到建議版本 update.channel.stable=建議版本
update.checking=正在檢查更新 update.checking=正在檢查更新
update.failed=更新失敗 update.failed=更新失敗
update.found=發現到更新 update.found=發現到更新

View File

@ -890,14 +890,13 @@ update.channel.dev.hint=你正在使用测试版。测试版包含一些未在
如果你遇到了使用问题,可以在设置的 <a href="hmcl://settings/feedback">反馈页面</a> 中进行反馈,或加入反馈页面中提供的 <a href="https://discord.gg/jVvC7HfM6U">Discord</a> 或 <a href="https://kaihei.co/Kx7n3t">开黑啦</a>群以反馈问题。\n\n\ 如果你遇到了使用问题,可以在设置的 <a href="hmcl://settings/feedback">反馈页面</a> 中进行反馈,或加入反馈页面中提供的 <a href="https://discord.gg/jVvC7HfM6U">Discord</a> 或 <a href="https://kaihei.co/Kx7n3t">开黑啦</a>群以反馈问题。\n\n\
你需要 <a href="https://hmcl.huangyuhui.net/api/redirect/sponsor">赞助</a> 或在反馈过程中作出贡献以隐藏本提示。 你需要 <a href="https://hmcl.huangyuhui.net/api/redirect/sponsor">赞助</a> 或在反馈过程中作出贡献以隐藏本提示。
update.channel.dev.title=测试版提示 update.channel.dev.title=测试版提示
update.channel.dev.update=更新到开发版
update.channel.nightly=预览版 update.channel.nightly=预览版
update.channel.nightly.hint=你正在使用预览版。预览版可能会每天更新一次,包含一些未在正式版和测试版中包含的测试性功能,仅用于体验新功能。\n\ update.channel.nightly.hint=你正在使用预览版。预览版可能会每天更新一次,包含一些未在正式版和测试版中包含的测试性功能,仅用于体验新功能。\n\
测试版功能未受充分验证,使用起来可能不稳定!<a href="https://hmcl.huangyuhui.net/download">下载稳定版</a>\n\ 测试版功能未受充分验证,使用起来可能不稳定!<a href="https://hmcl.huangyuhui.net/download">下载稳定版</a>\n\
如果你遇到了使用问题,可以在设置的 <a href="hmcl://settings/feedback">反馈页面</a> 中进行反馈,或加入反馈页面中提供的 <a href="https://discord.gg/jVvC7HfM6U">Discord</a> 或 <a href="https://kaihei.co/Kx7n3t">开黑啦</a>群以反馈问题。\n\n\ 如果你遇到了使用问题,可以在设置的 <a href="hmcl://settings/feedback">反馈页面</a> 中进行反馈,或加入反馈页面中提供的 <a href="https://discord.gg/jVvC7HfM6U">Discord</a> 或 <a href="https://kaihei.co/Kx7n3t">开黑啦</a>群以反馈问题。\n\n\
你需要 <a href="https://hmcl.huangyuhui.net/api/redirect/sponsor">赞助</a> 或在反馈过程中作出贡献以隐藏本提示。 你需要 <a href="https://hmcl.huangyuhui.net/api/redirect/sponsor">赞助</a> 或在反馈过程中作出贡献以隐藏本提示。
update.channel.nightly.title=预览版提示 update.channel.nightly.title=预览版提示
update.channel.stable.update=更新到推荐版本 update.channel.stable=推荐版本
update.checking=正在检查更新 update.checking=正在检查更新
update.failed=更新失败 update.failed=更新失败
update.found=发现更新 update.found=发现更新