mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-16 07:16:27 -04:00
Remove upgrade feature
This commit is contained in:
parent
1371206323
commit
25a90fc481
@ -25,11 +25,7 @@ import javafx.application.Platform;
|
|||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.task.Schedulers;
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
|
||||||
import org.jackhuang.hmcl.ui.Controllers;
|
import org.jackhuang.hmcl.ui.Controllers;
|
||||||
import org.jackhuang.hmcl.upgrade.AppDataUpgrader;
|
|
||||||
import org.jackhuang.hmcl.upgrade.IUpgrader;
|
|
||||||
import org.jackhuang.hmcl.upgrade.UpdateChecker;
|
|
||||||
import org.jackhuang.hmcl.util.*;
|
import org.jackhuang.hmcl.util.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -37,7 +33,6 @@ import java.net.URISyntaxException;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -56,12 +51,15 @@ public final class Launcher extends Application {
|
|||||||
primaryStage.setResizable(false);
|
primaryStage.setResizable(false);
|
||||||
primaryStage.setScene(Controllers.getScene());
|
primaryStage.setScene(Controllers.getScene());
|
||||||
|
|
||||||
|
/*
|
||||||
|
UPDATE: check update
|
||||||
UPDATE_CHECKER.process(false)
|
UPDATE_CHECKER.process(false)
|
||||||
.then(Task.of(Schedulers.javafx(), () -> {
|
.then(Task.of(Schedulers.javafx(), () -> {
|
||||||
if (UPDATE_CHECKER.isOutOfDate())
|
if (UPDATE_CHECKER.isOutOfDate())
|
||||||
Controllers.showUpdate();
|
Controllers.showUpdate();
|
||||||
}))
|
}))
|
||||||
.start();
|
.start();
|
||||||
|
*/
|
||||||
|
|
||||||
primaryStage.show();
|
primaryStage.show();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@ -80,7 +78,6 @@ public final class Launcher extends Application {
|
|||||||
|
|
||||||
// NetworkUtils.setUserAgentSupplier(() -> "Hello Minecraft! Launcher");
|
// NetworkUtils.setUserAgentSupplier(() -> "Hello Minecraft! Launcher");
|
||||||
Constants.UI_THREAD_SCHEDULER = Constants.JAVAFX_UI_THREAD_SCHEDULER;
|
Constants.UI_THREAD_SCHEDULER = Constants.JAVAFX_UI_THREAD_SCHEDULER;
|
||||||
UPGRADER.parseArguments(VersionNumber.asVersion(VERSION), Arrays.asList(args));
|
|
||||||
|
|
||||||
LOG.info("*** " + TITLE + " ***");
|
LOG.info("*** " + TITLE + " ***");
|
||||||
LOG.info("Operating System: " + System.getProperty("os.name") + ' ' + OperatingSystem.SYSTEM_VERSION);
|
LOG.info("Operating System: " + System.getProperty("os.name") + ' ' + OperatingSystem.SYSTEM_VERSION);
|
||||||
@ -149,8 +146,6 @@ public final class Launcher extends Application {
|
|||||||
public static final String VERSION = System.getProperty("hmcl.version.override", "@HELLO_MINECRAFT_LAUNCHER_VERSION_FOR_GRADLE_REPLACING@");
|
public static final String VERSION = System.getProperty("hmcl.version.override", "@HELLO_MINECRAFT_LAUNCHER_VERSION_FOR_GRADLE_REPLACING@");
|
||||||
public static final String NAME = "HMCL";
|
public static final String NAME = "HMCL";
|
||||||
public static final String TITLE = NAME + " " + VERSION;
|
public static final String TITLE = NAME + " " + VERSION;
|
||||||
public static final UpdateChecker UPDATE_CHECKER = new UpdateChecker(VersionNumber.asVersion(VERSION));
|
|
||||||
public static final IUpgrader UPGRADER = new AppDataUpgrader();
|
|
||||||
public static final CrashReporter CRASH_REPORTER = new CrashReporter();
|
public static final CrashReporter CRASH_REPORTER = new CrashReporter();
|
||||||
|
|
||||||
public static final String UPDATE_SERVER = "https://www.huangyuhui.net";
|
public static final String UPDATE_SERVER = "https://www.huangyuhui.net";
|
||||||
|
@ -39,6 +39,8 @@ import org.jackhuang.hmcl.setting.ConfigHolder;
|
|||||||
public final class Main {
|
public final class Main {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
/* UPDATE: perform auto-update from local source */
|
||||||
|
|
||||||
checkJavaFX();
|
checkJavaFX();
|
||||||
checkDirectoryPath();
|
checkDirectoryPath();
|
||||||
checkDSTRootCAX3();
|
checkDSTRootCAX3();
|
||||||
|
@ -39,7 +39,7 @@ public class CrashWindow extends Stage {
|
|||||||
|
|
||||||
public CrashWindow(String text) {
|
public CrashWindow(String text) {
|
||||||
Label lblCrash = new Label();
|
Label lblCrash = new Label();
|
||||||
if (Launcher.UPDATE_CHECKER.isOutOfDate())
|
if (false/* UPDATE: current version is outdated */)
|
||||||
lblCrash.setText(i18n("launcher.crash_out_dated"));
|
lblCrash.setText(i18n("launcher.crash_out_dated"));
|
||||||
else
|
else
|
||||||
lblCrash.setText(i18n("launcher.crash"));
|
lblCrash.setText(i18n("launcher.crash"));
|
||||||
|
@ -37,7 +37,6 @@ import javafx.scene.layout.Pane;
|
|||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.scene.text.Font;
|
import javafx.scene.text.Font;
|
||||||
import org.jackhuang.hmcl.Launcher;
|
|
||||||
import org.jackhuang.hmcl.setting.*;
|
import org.jackhuang.hmcl.setting.*;
|
||||||
import org.jackhuang.hmcl.ui.construct.FontComboBox;
|
import org.jackhuang.hmcl.ui.construct.FontComboBox;
|
||||||
import org.jackhuang.hmcl.ui.construct.MultiFileItem;
|
import org.jackhuang.hmcl.ui.construct.MultiFileItem;
|
||||||
@ -238,10 +237,10 @@ public final class SettingsPage extends StackPane implements DecoratorPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void checkUpdate() {
|
public void checkUpdate() {
|
||||||
btnUpdate.setVisible(Launcher.UPDATE_CHECKER.isOutOfDate());
|
btnUpdate.setVisible(false /* UPDATE: current version is outdated */);
|
||||||
|
|
||||||
if (Launcher.UPDATE_CHECKER.isOutOfDate()) {
|
if (false /* UPDATE: current version is outdated */) {
|
||||||
lblUpdateSub.setText(i18n("update.newest_version", Launcher.UPDATE_CHECKER.getNewVersion().toString()));
|
lblUpdateSub.setText(i18n("update.newest_version", /* UPDATE: latest version number */""));
|
||||||
lblUpdateSub.getStyleClass().setAll("update-label");
|
lblUpdateSub.getStyleClass().setAll("update-label");
|
||||||
|
|
||||||
lblUpdate.setText(i18n("update.found"));
|
lblUpdate.setText(i18n("update.found"));
|
||||||
@ -257,6 +256,6 @@ public final class SettingsPage extends StackPane implements DecoratorPage {
|
|||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void onUpdate() {
|
private void onUpdate() {
|
||||||
Launcher.UPDATE_CHECKER.checkOutdate();
|
/* UPDATE: Launcher.UPDATE_CHECKER.checkOutdate();*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,253 +0,0 @@
|
|||||||
/*
|
|
||||||
* Hello Minecraft! Launcher.
|
|
||||||
* Copyright (C) 2018 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.upgrade;
|
|
||||||
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
import com.jfoenix.concurrency.JFXUtilities;
|
|
||||||
import javafx.scene.layout.Region;
|
|
||||||
import org.jackhuang.hmcl.Launcher;
|
|
||||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
|
||||||
import org.jackhuang.hmcl.task.FileDownloadTask.IntegrityCheck;
|
|
||||||
import org.jackhuang.hmcl.task.Task;
|
|
||||||
import org.jackhuang.hmcl.task.TaskExecutor;
|
|
||||||
import org.jackhuang.hmcl.ui.Controllers;
|
|
||||||
import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
|
|
||||||
import org.jackhuang.hmcl.ui.construct.MessageBox;
|
|
||||||
import org.jackhuang.hmcl.util.*;
|
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.*;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
import java.util.jar.JarFile;
|
|
||||||
import java.util.jar.JarOutputStream;
|
|
||||||
import java.util.jar.Pack200;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author huangyuhui
|
|
||||||
*/
|
|
||||||
public class AppDataUpgrader extends IUpgrader {
|
|
||||||
|
|
||||||
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)
|
|
||||||
throw new ClassNotFoundException("Main-Class not found in manifest");
|
|
||||||
ArrayList<String> al = new ArrayList<>(args);
|
|
||||||
al.add("--noupdate");
|
|
||||||
ClassLoader pre = Thread.currentThread().getContextClassLoader();
|
|
||||||
try {
|
|
||||||
Logging.stop();
|
|
||||||
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 {
|
|
||||||
Logging.start(Launcher.LOG_DIRECTORY);
|
|
||||||
Thread.currentThread().setContextClassLoader(pre);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void parseArguments(VersionNumber nowVersion, List<String> args) {
|
|
||||||
File f = AppDataUpgraderPackGzTask.HMCL_VER_FILE;
|
|
||||||
if (!args.contains("--noupdate"))
|
|
||||||
try {
|
|
||||||
if (f.exists()) {
|
|
||||||
Map<String, String> m = Constants.GSON.fromJson(FileUtils.readText(f), new TypeToken<Map<String, String>>() {
|
|
||||||
}.getType());
|
|
||||||
String s = m.get("ver");
|
|
||||||
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);
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (JsonParseException ex) {
|
|
||||||
f.delete();
|
|
||||||
} catch (IOException | ReflectiveOperationException t) {
|
|
||||||
Logging.LOG.log(Level.SEVERE, "Unable to execute newer version application", t);
|
|
||||||
AppDataUpgraderPackGzTask.HMCL_VER_FILE.delete(); // delete version json, let HMCL re-download the newer version.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void download(UpdateChecker checker, VersionNumber ver) {
|
|
||||||
if (!(ver instanceof IntVersionNumber))
|
|
||||||
return;
|
|
||||||
IntVersionNumber version = (IntVersionNumber) ver;
|
|
||||||
checker.requestDownloadLink().then(Task.of(variables -> {
|
|
||||||
Map<String, String> map = variables.get(UpdateChecker.REQUEST_DOWNLOAD_LINK_ID);
|
|
||||||
|
|
||||||
if (map != null && map.containsKey("jar") && !StringUtils.isBlank(map.get("jar")))
|
|
||||||
try {
|
|
||||||
String hash = null;
|
|
||||||
if (map.containsKey("jarsha1"))
|
|
||||||
hash = map.get("jarsha1");
|
|
||||||
Task task = new AppDataUpgraderJarTask(NetworkUtils.toURL(map.get("jar")), version.toString(), hash);
|
|
||||||
TaskExecutor executor = task.executor();
|
|
||||||
AtomicReference<Region> region = new AtomicReference<>();
|
|
||||||
JFXUtilities.runInFX(() -> region.set(Controllers.taskDialog(executor, i18n("message.downloading"), "", null)));
|
|
||||||
if (executor.test()) {
|
|
||||||
new ProcessBuilder(JavaVersion.fromCurrentEnvironment().getBinary().getAbsolutePath(), "-jar", AppDataUpgraderJarTask.getSelf(version.toString()).getAbsolutePath())
|
|
||||||
.directory(new File("").getAbsoluteFile()).start();
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
JFXUtilities.runInFX(() -> region.get().fireEvent(new DialogCloseEvent()));
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Logging.LOG.log(Level.SEVERE, "Failed to create upgrader", ex);
|
|
||||||
}
|
|
||||||
else if (map != null && map.containsKey("pack") && !StringUtils.isBlank(map.get("pack")))
|
|
||||||
try {
|
|
||||||
String hash = null;
|
|
||||||
if (map.containsKey("packsha1"))
|
|
||||||
hash = map.get("packsha1");
|
|
||||||
Task task = new AppDataUpgraderPackGzTask(NetworkUtils.toURL(map.get("pack")), version.toString(), hash);
|
|
||||||
TaskExecutor executor = task.executor();
|
|
||||||
AtomicReference<Region> region = new AtomicReference<>();
|
|
||||||
JFXUtilities.runInFX(() -> region.set(Controllers.taskDialog(executor, i18n("message.downloading"), "", null)));
|
|
||||||
if (executor.test()) {
|
|
||||||
new ProcessBuilder(JavaVersion.fromCurrentEnvironment().getBinary().getAbsolutePath(), "-jar", AppDataUpgraderPackGzTask.getSelf(version.toString()).getAbsolutePath())
|
|
||||||
.directory(new File("").getAbsoluteFile()).start();
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
JFXUtilities.runInFX(() -> region.get().fireEvent(new DialogCloseEvent()));
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Logging.LOG.log(Level.SEVERE, "Failed to create upgrader", ex);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
String url = Launcher.PUBLISH;
|
|
||||||
if (map != null)
|
|
||||||
if (map.containsKey(OperatingSystem.CURRENT_OS.getCheckedName()))
|
|
||||||
url = map.get(OperatingSystem.CURRENT_OS.getCheckedName());
|
|
||||||
else if (map.containsKey(OperatingSystem.UNKNOWN.getCheckedName()))
|
|
||||||
url = map.get(OperatingSystem.UNKNOWN.getCheckedName());
|
|
||||||
try {
|
|
||||||
java.awt.Desktop.getDesktop().browse(new URI(url));
|
|
||||||
} catch (URISyntaxException | IOException e) {
|
|
||||||
Logging.LOG.log(Level.SEVERE, "Failed to browse uri: " + url, e);
|
|
||||||
OperatingSystem.setClipboard(url);
|
|
||||||
MessageBox.show(i18n("update.no_browser"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class AppDataUpgraderPackGzTask extends Task {
|
|
||||||
|
|
||||||
public static final File BASE_FOLDER = Launcher.HMCL_DIRECTORY;
|
|
||||||
public static final File HMCL_VER_FILE = new File(BASE_FOLDER, "hmclver.json");
|
|
||||||
|
|
||||||
public static File getSelf(String ver) {
|
|
||||||
return new File(BASE_FOLDER, "HMCL-" + ver + ".jar");
|
|
||||||
}
|
|
||||||
|
|
||||||
private final URL downloadLink;
|
|
||||||
private final String newestVersion, hash;
|
|
||||||
File tempFile;
|
|
||||||
|
|
||||||
public AppDataUpgraderPackGzTask(URL downloadLink, String newestVersion, String hash) throws IOException {
|
|
||||||
this.downloadLink = downloadLink;
|
|
||||||
this.newestVersion = newestVersion;
|
|
||||||
this.hash = hash;
|
|
||||||
tempFile = File.createTempFile("hmcl", ".pack.gz");
|
|
||||||
|
|
||||||
setName("Upgrade");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Task> getDependents() {
|
|
||||||
return Collections.singleton(new FileDownloadTask(downloadLink, tempFile, new IntegrityCheck("SHA-1", hash)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute() throws Exception {
|
|
||||||
HashMap<String, String> json = new HashMap<>();
|
|
||||||
File f = getSelf(newestVersion);
|
|
||||||
if (!FileUtils.makeDirectory(f.getParentFile()))
|
|
||||||
throw new IOException("Failed to make directories: " + f.getParent());
|
|
||||||
|
|
||||||
for (int i = 0; f.exists() && !f.delete(); i++)
|
|
||||||
f = new File(BASE_FOLDER, "HMCL-" + newestVersion + (i > 0 ? "-" + i : "") + ".jar");
|
|
||||||
if (!f.createNewFile())
|
|
||||||
throw new IOException("Failed to create new file: " + f);
|
|
||||||
|
|
||||||
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(f))) {
|
|
||||||
Pack200.newUnpacker().unpack(new GZIPInputStream(new FileInputStream(tempFile)), jos);
|
|
||||||
}
|
|
||||||
json.put("ver", newestVersion);
|
|
||||||
json.put("loc", f.getAbsolutePath());
|
|
||||||
String result = Constants.GSON.toJson(json);
|
|
||||||
FileUtils.writeText(HMCL_VER_FILE, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class AppDataUpgraderJarTask extends Task {
|
|
||||||
|
|
||||||
public static final File BASE_FOLDER = OperatingSystem.getWorkingDirectory("hmcl");
|
|
||||||
public static final File HMCL_VER_FILE = new File(BASE_FOLDER, "hmclver.json");
|
|
||||||
|
|
||||||
public static File getSelf(String ver) {
|
|
||||||
return new File(BASE_FOLDER, "HMCL-" + ver + ".jar");
|
|
||||||
}
|
|
||||||
|
|
||||||
private final URL downloadLink;
|
|
||||||
private final String newestVersion, hash;
|
|
||||||
File tempFile;
|
|
||||||
|
|
||||||
public AppDataUpgraderJarTask(URL downloadLink, String newestVersion, String hash) throws IOException {
|
|
||||||
this.downloadLink = downloadLink;
|
|
||||||
this.newestVersion = newestVersion;
|
|
||||||
this.hash = hash;
|
|
||||||
tempFile = File.createTempFile("hmcl", ".jar");
|
|
||||||
|
|
||||||
setName("Upgrade");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Task> getDependents() {
|
|
||||||
return Collections.singleton(new FileDownloadTask(downloadLink, tempFile, new IntegrityCheck("SHA-1", hash)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute() throws Exception {
|
|
||||||
HashMap<String, String> json = new HashMap<>();
|
|
||||||
File f = getSelf(newestVersion);
|
|
||||||
FileUtils.copyFile(tempFile, f);
|
|
||||||
json.put("ver", newestVersion);
|
|
||||||
json.put("loc", f.getAbsolutePath());
|
|
||||||
String result = Constants.GSON.toJson(json);
|
|
||||||
FileUtils.writeText(HMCL_VER_FILE, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Hello Minecraft! Launcher.
|
|
||||||
* Copyright (C) 2018 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.upgrade;
|
|
||||||
|
|
||||||
import org.jackhuang.hmcl.util.VersionNumber;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author huangyuhui
|
|
||||||
*/
|
|
||||||
public abstract class IUpgrader {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Paring arguments to decide on whether the upgrade is needed.
|
|
||||||
*
|
|
||||||
* @param nowVersion now launcher version
|
|
||||||
* @param args Application CommandLine Arguments
|
|
||||||
*/
|
|
||||||
public abstract void parseArguments(VersionNumber nowVersion, List<String> args);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Just download the new app.
|
|
||||||
*
|
|
||||||
* @param checker Should be VersionChecker
|
|
||||||
* @param version the newest version
|
|
||||||
*/
|
|
||||||
public abstract void download(UpdateChecker checker, VersionNumber version);
|
|
||||||
}
|
|
@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
* Hello Minecraft! Launcher.
|
|
||||||
* Copyright (C) 2018 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.upgrade;
|
|
||||||
|
|
||||||
import com.jfoenix.concurrency.JFXUtilities;
|
|
||||||
import javafx.scene.layout.Region;
|
|
||||||
|
|
||||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
|
||||||
import org.jackhuang.hmcl.task.Task;
|
|
||||||
import org.jackhuang.hmcl.task.TaskExecutor;
|
|
||||||
import org.jackhuang.hmcl.ui.Controllers;
|
|
||||||
import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
|
|
||||||
import org.jackhuang.hmcl.util.Logging;
|
|
||||||
import org.jackhuang.hmcl.util.VersionNumber;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author huangyuhui
|
|
||||||
*/
|
|
||||||
public class NewFileUpgrader extends IUpgrader {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void parseArguments(VersionNumber nowVersion, List<String> args) {
|
|
||||||
int i = args.indexOf("--removeOldLauncher");
|
|
||||||
if (i != -1 && i < args.size() - 1) {
|
|
||||||
File f = new File(args.get(i + 1));
|
|
||||||
if (f.exists())
|
|
||||||
f.deleteOnExit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void download(UpdateChecker checker, VersionNumber version) {
|
|
||||||
URL url = requestDownloadLink();
|
|
||||||
if (url == null) return;
|
|
||||||
File newf = new File(url.getFile());
|
|
||||||
Controllers.dialog(i18n("message.downloading"));
|
|
||||||
Task task = new FileDownloadTask(url, newf);
|
|
||||||
TaskExecutor executor = task.executor();
|
|
||||||
AtomicReference<Region> region = new AtomicReference<>();
|
|
||||||
JFXUtilities.runInFX(() -> region.set(Controllers.taskDialog(executor, i18n("message.downloading"), "", null)));
|
|
||||||
if (executor.test()) {
|
|
||||||
try {
|
|
||||||
new ProcessBuilder(newf.getCanonicalPath(), "--removeOldLauncher", getRealPath())
|
|
||||||
.directory(new File("").getAbsoluteFile())
|
|
||||||
.start();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Logging.LOG.log(Level.SEVERE, "Failed to start new app", ex);
|
|
||||||
}
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
JFXUtilities.runInFX(() -> region.get().fireEvent(new DialogCloseEvent()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getRealPath() {
|
|
||||||
String realPath = NewFileUpgrader.class.getClassLoader().getResource("").getFile();
|
|
||||||
File file = new File(realPath);
|
|
||||||
realPath = file.getAbsolutePath();
|
|
||||||
try {
|
|
||||||
realPath = java.net.URLDecoder.decode(realPath, UTF_8.name());
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return realPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
private URL requestDownloadLink() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,160 +0,0 @@
|
|||||||
/*
|
|
||||||
* Hello Minecraft! Launcher.
|
|
||||||
* Copyright (C) 2018 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.upgrade;
|
|
||||||
|
|
||||||
import com.google.gson.JsonSyntaxException;
|
|
||||||
import org.jackhuang.hmcl.Launcher;
|
|
||||||
import org.jackhuang.hmcl.event.Event;
|
|
||||||
import org.jackhuang.hmcl.event.EventBus;
|
|
||||||
import org.jackhuang.hmcl.event.OutOfDateEvent;
|
|
||||||
import org.jackhuang.hmcl.task.GetTask;
|
|
||||||
import org.jackhuang.hmcl.task.Task;
|
|
||||||
import org.jackhuang.hmcl.task.TaskResult;
|
|
||||||
import org.jackhuang.hmcl.ui.construct.MessageBox;
|
|
||||||
import org.jackhuang.hmcl.util.Constants;
|
|
||||||
import org.jackhuang.hmcl.util.NetworkUtils;
|
|
||||||
import org.jackhuang.hmcl.util.VersionNumber;
|
|
||||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author huangyuhui
|
|
||||||
*/
|
|
||||||
public final class UpdateChecker {
|
|
||||||
|
|
||||||
private volatile boolean outOfDate = false;
|
|
||||||
private final VersionNumber base;
|
|
||||||
private String versionString;
|
|
||||||
private Map<String, String> download_link = null;
|
|
||||||
|
|
||||||
public UpdateChecker(VersionNumber base) {
|
|
||||||
this.base = base;
|
|
||||||
}
|
|
||||||
|
|
||||||
private VersionNumber value;
|
|
||||||
|
|
||||||
public boolean isOutOfDate() {
|
|
||||||
return outOfDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Download the version number synchronously. When you execute this method
|
|
||||||
* first, should leave "showMessage" false.
|
|
||||||
*
|
|
||||||
* @param showMessage If it is requested to warn the user that there is a
|
|
||||||
* new version.
|
|
||||||
*
|
|
||||||
* @return the process observable.
|
|
||||||
*/
|
|
||||||
public TaskResult<VersionNumber> process(final boolean showMessage) {
|
|
||||||
return new TaskResult<VersionNumber>() {
|
|
||||||
GetTask http = new GetTask(NetworkUtils.toURL(Launcher.UPDATE_SERVER + "/hmcl/update.php?version=" + Launcher.VERSION));
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<? extends Task> getDependents() {
|
|
||||||
return value == null ? Collections.singleton(http) : Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute() throws Exception {
|
|
||||||
if (isDevelopmentVersion(Launcher.VERSION)) {
|
|
||||||
LOG.info("Current version is a development version, skip updating");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value == null) {
|
|
||||||
versionString = http.getResult();
|
|
||||||
value = VersionNumber.asVersion(versionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value == null) {
|
|
||||||
LOG.warning("Unable to check update...");
|
|
||||||
if (showMessage)
|
|
||||||
MessageBox.show(i18n("update.failed"));
|
|
||||||
} else if (base.compareTo(value) < 0)
|
|
||||||
outOfDate = true;
|
|
||||||
if (outOfDate)
|
|
||||||
setResult(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return "update_checker.process";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isDevelopmentVersion(String version) {
|
|
||||||
return version.contains("@") || // eg. @HELLO_MINECRAFT_LAUNCHER_VERSION_FOR_GRADLE_REPLACING@
|
|
||||||
version.contains("SNAPSHOT"); // eg. 3.1.SNAPSHOT
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the <b>cached</b> newest version number, use "process" method to
|
|
||||||
* download!
|
|
||||||
*
|
|
||||||
* @return the newest version number
|
|
||||||
*
|
|
||||||
* @see #process(boolean)
|
|
||||||
*/
|
|
||||||
public VersionNumber getNewVersion() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the download links.
|
|
||||||
*
|
|
||||||
* @return a JSON, which contains the server response.
|
|
||||||
*/
|
|
||||||
public synchronized TaskResult<Map<String, String>> requestDownloadLink() {
|
|
||||||
return new TaskResult<Map<String, String>>() {
|
|
||||||
@Override
|
|
||||||
public void execute() {
|
|
||||||
if (download_link == null) {
|
|
||||||
try {
|
|
||||||
download_link = Constants.GSON.<Map<String, String>>fromJson(NetworkUtils.doGet(NetworkUtils.toURL(Launcher.UPDATE_SERVER + "/hmcl/update_link.php")), Map.class);
|
|
||||||
} catch (JsonSyntaxException | IOException e) {
|
|
||||||
LOG.log(Level.SEVERE, "Failed to get update link.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setResult(download_link);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return "update_checker.request_download_link";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final String REQUEST_DOWNLOAD_LINK_ID = "update_checker.request_download_link";
|
|
||||||
|
|
||||||
public void checkOutdate() {
|
|
||||||
if (outOfDate)
|
|
||||||
if (EventBus.EVENT_BUS.fireEvent(new OutOfDateEvent(this, getNewVersion())) != Event.Result.DENY) {
|
|
||||||
Launcher.UPGRADER.download(this, getNewVersion());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -104,9 +104,10 @@ public class CrashReporter implements Thread.UncaughtExceptionHandler {
|
|||||||
|
|
||||||
if (checkThrowable(e)) {
|
if (checkThrowable(e)) {
|
||||||
Platform.runLater(() -> new CrashWindow(text).show());
|
Platform.runLater(() -> new CrashWindow(text).show());
|
||||||
if (!Launcher.UPDATE_CHECKER.isOutOfDate())
|
if (true /* UPDATE: current version is not outdated */) {
|
||||||
reportToServer(text);
|
reportToServer(text);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (Throwable handlingException) {
|
} catch (Throwable handlingException) {
|
||||||
LOG.log(Level.SEVERE, "Unable to handle uncaught exception", handlingException);
|
LOG.log(Level.SEVERE, "Unable to handle uncaught exception", handlingException);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user