From f144dd888d2034f2b8773e5b067c89e8ee1b1d18 Mon Sep 17 00:00:00 2001 From: huangyuhui Date: Fri, 2 Feb 2018 13:44:53 +0800 Subject: [PATCH] Launching messages --- .../jackhuang/hmcl/game/LauncherHelper.java | 84 ++++++++++++++++--- .../hmcl/ui/construct/MessageDialogPane.java | 12 ++- .../ui/construct/TaskExecutorDialogPane.java | 13 ++- .../jackhuang/hmcl/util/I18nException.java | 44 ++++++++++ .../resources/assets/lang/I18N.properties | 14 ++-- .../assets/lang/I18N_zh_CN.properties | 8 +- .../hmcl/launch/DefaultLauncher.java | 55 ++++++------ .../org/jackhuang/hmcl/launch/ExitWaiter.java | 13 ++- .../NotDecompressingNativesException.java | 37 ++++++++ .../hmcl/launch/PermissionException.java | 40 +++++++++ .../hmcl/launch/ProcessCreationException.java | 37 ++++++++ .../hmcl/launch/ProcessListener.java | 3 +- 12 files changed, 295 insertions(+), 65 deletions(-) create mode 100644 HMCL/src/main/java/org/jackhuang/hmcl/util/I18nException.java create mode 100644 HMCLCore/src/main/java/org/jackhuang/hmcl/launch/NotDecompressingNativesException.java create mode 100644 HMCLCore/src/main/java/org/jackhuang/hmcl/launch/PermissionException.java create mode 100644 HMCLCore/src/main/java/org/jackhuang/hmcl/launch/ProcessCreationException.java diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java index 011394717..9da24c44d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java @@ -24,8 +24,7 @@ import org.jackhuang.hmcl.auth.Account; import org.jackhuang.hmcl.auth.AuthInfo; import org.jackhuang.hmcl.auth.AuthenticationException; import org.jackhuang.hmcl.download.DefaultDependencyManager; -import org.jackhuang.hmcl.launch.DefaultLauncher; -import org.jackhuang.hmcl.launch.ProcessListener; +import org.jackhuang.hmcl.launch.*; import org.jackhuang.hmcl.mod.CurseCompletionTask; import org.jackhuang.hmcl.setting.LauncherVisibility; import org.jackhuang.hmcl.setting.Profile; @@ -34,6 +33,7 @@ import org.jackhuang.hmcl.setting.VersionSetting; import org.jackhuang.hmcl.task.*; import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.DialogController; +import org.jackhuang.hmcl.ui.construct.MessageDialogPane; import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane; import org.jackhuang.hmcl.ui.LogWindow; import org.jackhuang.hmcl.ui.construct.MessageBox; @@ -62,10 +62,12 @@ public final class LauncherHelper { Version version = repository.getVersion(selectedVersion); VersionSetting setting = profile.getVersionSetting(selectedVersion); - try { - checkGameState(profile, setting, version, () -> launch0(selectedVersion, scriptFile)); - } catch (InterruptedException ignore) { - } + Platform.runLater(() -> { + try { + checkGameState(profile, setting, version, () -> Schedulers.newThread().schedule(() -> launch0(selectedVersion, scriptFile))); + } catch (InterruptedException ignore) { + } + }); } private void launch0(String selectedVersion, File scriptFile) { @@ -97,20 +99,31 @@ public final class LauncherHelper { )); })) .then(variables -> { + DefaultLauncher launcher = variables.get("launcher"); if (scriptFile == null) { - return variables.get("launcher").launchAsync().setName(Main.i18n("version.launch")); + return new LaunchTask<>(launcher::launch).setName(Main.i18n("version.launch")); } else { - return variables.get("launcher").makeLaunchScriptAsync(scriptFile).setName(Main.i18n("version.launch")); + return new LaunchTask<>(() -> { + launcher.makeLaunchScript(scriptFile); + return null; + }).setName(Main.i18n("version.launch_script")); } }) .then(Task.of(variables -> { if (scriptFile == null) { - PROCESSES.add(variables.get(DefaultLauncher.LAUNCH_ASYNC_ID)); + ManagedProcess process = variables.get(LaunchTask.LAUNCH_ID); + PROCESSES.add(process); if (setting.getLauncherVisibility() == LauncherVisibility.CLOSE) Main.stopApplication(); + else + launchingStepsPane.setCancel(() -> { + process.stop(); + Controllers.closeDialog(); + }); } else Platform.runLater(() -> Controllers.dialog(Main.i18n("version.launch_script.success", scriptFile.getAbsolutePath()))); + })) .executor(); @@ -129,7 +142,9 @@ public final class LauncherHelper { @Override public void onTerminate() { Platform.runLater(() -> { - Controllers.dialog(StringUtils.getStackTrace(executor.getLastException()), Main.i18n("launch.failed"), MessageBox.ERROR_MESSAGE, Controllers::closeDialog); + Controllers.dialog(I18nException.getStackTrace(executor.getLastException()), + scriptFile == null ? Main.i18n("launch.failed") : Main.i18n("version.launch_script.failed"), + MessageBox.ERROR_MESSAGE, Controllers::closeDialog); }); } }); @@ -138,7 +153,7 @@ public final class LauncherHelper { } private static void checkGameState(Profile profile, VersionSetting setting, Version version, Runnable onAccept) throws InterruptedException { - boolean flag = false; + boolean flag = false, suggest = true; VersionNumber gameVersion = VersionNumber.asVersion(GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version))); JavaVersion java = setting.getJavaVersion(); @@ -156,6 +171,7 @@ public final class LauncherHelper { if (java.getParsedVersion() >= JavaVersion.JAVA_9 && gameVersion.compareTo(VersionNumber.asVersion("1.12.5")) < 0 && version.getMainClass().contains("launchwrapper")) { Controllers.dialog(Main.i18n("launch.advice.java9"), Main.i18n("message.error"), MessageBox.ERROR_MESSAGE, null); + suggest = false; flag = true; } @@ -174,7 +190,10 @@ public final class LauncherHelper { flag = true; } - if (!flag) + if (flag) { + if (suggest && Controllers.getDialogContent() instanceof MessageDialogPane) + ((MessageDialogPane) Controllers.getDialogContent()).disableClosingDialog(); + } else onAccept.run(); } @@ -215,6 +234,34 @@ public final class LauncherHelper { } } + class LaunchTask extends TaskResult { + private final ExceptionalSupplier supplier; + + public LaunchTask(ExceptionalSupplier supplier) { + this.supplier = supplier; + } + + @Override + public void execute() throws Exception { + try { + setResult(supplier.get()); + } catch (PermissionException e) { + throw new I18nException(Main.i18n("launch.failed.executable_permission"), e); + } catch (ProcessCreationException e) { + throw new I18nException(Main.i18n("launch.failed.creating_process") + e.getLocalizedMessage(), e); + } catch (NotDecompressingNativesException e) { + throw new I18nException(Main.i18n("launch.failed.decompressing_natives") + e.getLocalizedMessage(), e); + } + } + + @Override + public String getId() { + return LAUNCH_ID; + } + + static final String LAUNCH_ID = "launch"; + } + /** * The managed process listener. * Guarantee that one [JavaProcess], one [HMCLProcessListener]. @@ -302,9 +349,22 @@ public final class LauncherHelper { @Override public void onExit(int exitCode, ExitType exitType) { + if (exitType == ExitType.INTERRUPTED) + return; + if (exitType != ExitType.NORMAL && logWindow == null) Platform.runLater(() -> { logWindow = new LogWindow(); + + switch (exitType) { + case JVM_ERROR: + logWindow.setTitle(Main.i18n("launch.failed.cannot_create_jvm")); + break; + case APPLICATION_ERROR: + logWindow.setTitle(Main.i18n("launch.failed.exited_abnormally")); + break; + } + logWindow.show(); logWindow.onDone.register(() -> { for (Map.Entry entry : logs) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MessageDialogPane.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MessageDialogPane.java index c59e9c06b..54e99765b 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MessageDialogPane.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MessageDialogPane.java @@ -33,6 +33,8 @@ public final class MessageDialogPane extends StackPane { private final String text; private final JFXDialog dialog; + private boolean closingDialog = true; + @FXML private JFXButton acceptButton; @FXML @@ -57,7 +59,8 @@ public final class MessageDialogPane extends StackPane { content.setText(text); acceptButton.setOnMouseClicked(e -> { - dialog.close(); + if (closingDialog) + dialog.close(); Optional.ofNullable(onAccept).ifPresent(Runnable::run); }); @@ -84,7 +87,8 @@ public final class MessageDialogPane extends StackPane { cancelButton.setVisible(true); cancelButton.setOnMouseClicked(e -> { - dialog.close(); + if (closingDialog) + dialog.close(); Optional.ofNullable(onCancel).ifPresent(Runnable::run); }); @@ -95,4 +99,8 @@ public final class MessageDialogPane extends StackPane { graphic.setGraphic(SVG.help_circle("black", 40, 40)); } + + public void disableClosingDialog() { + closingDialog = false; + } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskExecutorDialogPane.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskExecutorDialogPane.java index 5874c5c80..78b7cd3ea 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskExecutorDialogPane.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskExecutorDialogPane.java @@ -17,6 +17,7 @@ */ package org.jackhuang.hmcl.ui.construct; +import com.jfoenix.concurrency.JFXUtilities; import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXProgressBar; import javafx.beans.property.StringProperty; @@ -30,6 +31,7 @@ import java.util.Optional; public class TaskExecutorDialogPane extends StackPane { private TaskExecutor executor; + private Runnable onCancel; @FXML private JFXProgressBar progressBar; @@ -48,12 +50,11 @@ public class TaskExecutorDialogPane extends StackPane { FXUtils.limitHeight(this, 200); FXUtils.limitWidth(this, 400); - if (cancel == null) - btnCancel.setDisable(true); + setCancel(cancel); btnCancel.setOnMouseClicked(e -> { Optional.ofNullable(executor).ifPresent(TaskExecutor::cancel); - cancel.run(); + onCancel.run(); }); } @@ -92,4 +93,10 @@ public class TaskExecutorDialogPane extends StackPane { else progressBar.setProgress(progress); } + + public void setCancel(Runnable onCancel) { + this.onCancel = onCancel; + + JFXUtilities.runInFX(() -> btnCancel.setDisable(onCancel == null)); + } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/util/I18nException.java b/HMCL/src/main/java/org/jackhuang/hmcl/util/I18nException.java new file mode 100644 index 000000000..db951dc64 --- /dev/null +++ b/HMCL/src/main/java/org/jackhuang/hmcl/util/I18nException.java @@ -0,0 +1,44 @@ +/* + * Hello Minecraft! Launcher. + * Copyright (C) 2017 huangyuhui + * + * 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; + +public class I18nException extends Exception { + private final String localizedMessage; + + public I18nException(String localizedMessage) { + this.localizedMessage = localizedMessage; + } + + public I18nException(String localizedMessage, Throwable suppressed) { + addSuppressed(suppressed); + + this.localizedMessage = localizedMessage; + } + + @Override + public String getLocalizedMessage() { + return localizedMessage; + } + + public static String getStackTrace(Throwable e) { + if (e instanceof I18nException) + return e.getLocalizedMessage(); + else + return StringUtils.getStackTrace(e); + } +} diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index fb1604e9d..f6806f519 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -145,13 +145,13 @@ launch.advice.not_enough_space=You have allocated too much memory, because the p launch.advice.too_large_memory_for_32bit=You have allocated too much memory, because of your 32-Bit Java Runtime Environment, your game probably crash. The maximum memory is 1024MB. The launcher will try to launch it. launch.circular_dependency_versions=Found circular dependency versions, please check if your client has been modified. launch.failed=Unable to launch -launch.failed.cannot_create_jvm=We find that it cannot create java virutal machine. The Java argements may have problems. You can enable the no args mode in the settings. -launch.failed.decompressing_natives=Did not finish decompressing native libraries, continue launching game? +launch.failed.cannot_create_jvm=Java virtual machine cannot be created. Java arguments may have problems. You can enable the no args mode in the settings. +launch.failed.creating_process=Failed to create process, maybe your java path is wrong, please modify your java path. +launch.failed.decompressing_natives=Unable to decompress native libraries. launch.failed.downloading_libraries=Did not finish downloading libraries, continue launching game? +launch.failed.executable_permission=Unable to add permission to the launch script launch.failed.exited_abnormally=Game exited abnormally, please visit the log, or ask someone for help. -launch.failed.packing_jar=Failed to pack the jar. -launch.failed.sh_permission=Failed to add permission to the launch script. -launch.failed_creating_process=Failed to create process, maybe your java path is wrong, please modify your java path. +launch.failed.prelaunch_command=Prelaunch command fail. launch.state.dependencies=Decompressing natives launch.state.done=Done launch.state.logging_in=Logging In @@ -366,8 +366,8 @@ version.game.old_beta=Beta version.game.release=Release version.game.snapshot=Snapshot version.launch=Play -version.launch_script=Make Launching Script. -version.launch_script.failed=Failed to make script. +version.launch_script=Make Launching Script +version.launch_script.failed=Unable to make launch script. version.launch_script.save=Save the launch script version.launch_script.success=Finished script creation, %s. version.manage.redownload_assets_index=Redownload Assets Index diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index 7feb286f2..6bc5dc7ca 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -146,12 +146,12 @@ launch.advice.too_large_memory_for_32bit=您设置的内存大小过大,由于 launch.circular_dependency_versions=发现游戏版本循环引用,请确认您的客户端未被修改或修改导致出现此问题。 launch.failed=启动失败 launch.failed.cannot_create_jvm=截获到无法创建Java虚拟机,可能是Java参数有问题,可以在设置中开启无参数模式启动 -launch.failed.decompressing_natives=未能解压游戏本地库,还要继续启动游戏吗? +launch.failed.creating_process=启动失败,在创建新进程时发生错误,可能是Java路径错误。 +launch.failed.decompressing_natives=未能解压游戏本地库。 launch.failed.downloading_libraries=未完成游戏依赖库的下载,还要继续启动游戏吗? +launch.failed.executable_permission=未能为启动文件添加执行权限 launch.failed.exited_abnormally=游戏非正常退出,请查看日志文件,或联系他人寻求帮助。 -launch.failed.packing_jar=在打包jar时发生错误 -launch.failed.sh_permission=为启动文件添加权限时发生错误 -launch.failed_creating_process=启动失败,在创建新进程时发生错误,可能是Java路径错误。 +launch.failed.prelaunch_command=启动前执行命令执行失败。 launch.state.dependencies=正在处理游戏依赖 launch.state.done=启动完成 launch.state.logging_in=登录中 diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java index b48bfef9b..ebbc0a9a1 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java @@ -19,9 +19,6 @@ package org.jackhuang.hmcl.launch; import org.jackhuang.hmcl.auth.AuthInfo; import org.jackhuang.hmcl.game.*; -import org.jackhuang.hmcl.task.SimpleTaskResult; -import org.jackhuang.hmcl.task.Task; -import org.jackhuang.hmcl.task.TaskResult; import org.jackhuang.hmcl.util.*; import java.io.*; @@ -220,14 +217,18 @@ public class DefaultLauncher extends Launcher { protected void appendJvmArgs(List result) { } - public void decompressNatives(File destination) throws IOException { - for (Library library : version.getLibraries()) - if (library.isNative()) - CompressingUtils.unzip(repository.getLibraryFile(version, library), - destination, - "", - library.getExtract()::shouldExtract, - false); + public void decompressNatives(File destination) throws NotDecompressingNativesException { + try { + for (Library library : version.getLibraries()) + if (library.isNative()) + CompressingUtils.unzip(repository.getLibraryFile(version, library), + destination, + "", + library.getExtract()::shouldExtract, + false); + } catch (IOException e) { + throw new NotDecompressingNativesException(e); + } } protected Map getConfigurations() { @@ -249,19 +250,26 @@ public class DefaultLauncher extends Launcher { @Override public ManagedProcess launch() throws IOException, InterruptedException { File nativeFolder = Files.createTempDirectory("minecraft").toFile(); - List rawCommandLine = generateCommandLine(nativeFolder); - // To guarantee that when failed to generate code, we will not call precalled command - ProcessBuilder builder = new ProcessBuilder(rawCommandLine); + // To guarantee that when failed to generate launch command line, we will not call pre-launch command + List rawCommandLine = generateCommandLine(nativeFolder); decompressNatives(nativeFolder); if (StringUtils.isNotBlank(options.getPrecalledCommand())) Runtime.getRuntime().exec(options.getPrecalledCommand()).waitFor(); - builder.directory(repository.getRunDirectory(version.getId())) - .environment().put("APPDATA", options.getGameDir().getAbsoluteFile().getParent()); - ManagedProcess p = new ManagedProcess(builder.start(), rawCommandLine); + Process process; + try { + ProcessBuilder builder = new ProcessBuilder(rawCommandLine); + builder.directory(repository.getRunDirectory(version.getId())) + .environment().put("APPDATA", options.getGameDir().getAbsoluteFile().getParent()); + process = builder.start(); + } catch (IOException e) { + throw new ProcessCreationException(e); + } + + ManagedProcess p = new ManagedProcess(process, rawCommandLine); if (listener == null) startMonitors(p); else @@ -269,10 +277,6 @@ public class DefaultLauncher extends Launcher { return p; } - public final TaskResult launchAsync() { - return new SimpleTaskResult<>(LAUNCH_ASYNC_ID, this::launch); - } - @Override public void makeLaunchScript(File scriptFile) throws IOException { boolean isWindows = OperatingSystem.WINDOWS == OperatingSystem.CURRENT_OS; @@ -303,11 +307,7 @@ public class DefaultLauncher extends Launcher { writer.write(StringUtils.makeCommand(generateCommandLine(nativeFolder))); } if (!scriptFile.setExecutable(true)) - throw new IOException("Cannot make script file '" + scriptFile + "' executable."); - } - - public final Task makeLaunchScriptAsync(File file) { - return Task.of(() -> makeLaunchScript(file)); + throw new PermissionException(); } private void startMonitors(ManagedProcess managedProcess) { @@ -362,7 +362,4 @@ public class DefaultLauncher extends Launcher { managedProcess.addRelatedThread(stderr); managedProcess.addRelatedThread(Lang.thread(new ExitWaiter(managedProcess, Arrays.asList(stdout, stderr), (exitCode, exitType) -> processListener.onExit(exitCode, exitType)), "exit-waiter", isDaemon)); } - - public static final String LAUNCH_ASYNC_ID = "process"; - public static final String LAUNCH_SCRIPT_ASYNC_ID = "script"; } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/ExitWaiter.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/ExitWaiter.java index aacd4817f..728c37dbb 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/ExitWaiter.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/ExitWaiter.java @@ -65,16 +65,15 @@ final class ExitWaiter implements Runnable { ProcessListener.ExitType exitType; // LaunchWrapper will catch the exception logged and will exit normally. - if (exitCode != 0 || StringUtils.containsOne(errorLines, "Unable to launch")) { - EventBus.EVENT_BUS.fireEvent(new ProcessExitedAbnormallyEvent(this, process)); - exitType = ProcessListener.ExitType.APPLICATION_ERROR; - } else if (exitCode != 0 && StringUtils.containsOne(errorLines, + if (exitCode != 0 && StringUtils.containsOne(errorLines, "Could not create the Java Virtual Machine.", "Error occurred during initialization of VM", - "A fatal exception has occurred. Program will exit.", - "Unable to launch")) { + "A fatal exception has occurred. Program will exit.")) { EventBus.EVENT_BUS.fireEvent(new JVMLaunchFailedEvent(this, process)); exitType = ProcessListener.ExitType.JVM_ERROR; + } else if (exitCode != 0 || StringUtils.containsOne(errorLines, "Unable to launch")) { + EventBus.EVENT_BUS.fireEvent(new ProcessExitedAbnormallyEvent(this, process)); + exitType = ProcessListener.ExitType.APPLICATION_ERROR; } else exitType = ProcessListener.ExitType.NORMAL; @@ -82,7 +81,7 @@ final class ExitWaiter implements Runnable { watcher.accept(exitCode, exitType); } catch (InterruptedException e) { - watcher.accept(1, ProcessListener.ExitType.NORMAL); + watcher.accept(1, ProcessListener.ExitType.INTERRUPTED); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/NotDecompressingNativesException.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/NotDecompressingNativesException.java new file mode 100644 index 000000000..f7ab07176 --- /dev/null +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/NotDecompressingNativesException.java @@ -0,0 +1,37 @@ +/* + * Hello Minecraft! Launcher. + * Copyright (C) 2017 huangyuhui + * + * 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.launch; + +import java.io.IOException; + +public class NotDecompressingNativesException extends IOException { + public NotDecompressingNativesException() { + } + + public NotDecompressingNativesException(String message) { + super(message); + } + + public NotDecompressingNativesException(String message, Throwable cause) { + super(message, cause); + } + + public NotDecompressingNativesException(Throwable cause) { + super(cause); + } +} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/PermissionException.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/PermissionException.java new file mode 100644 index 000000000..0c7f21168 --- /dev/null +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/PermissionException.java @@ -0,0 +1,40 @@ +/* + * Hello Minecraft! Launcher. + * Copyright (C) 2017 huangyuhui + * + * 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.launch; + +import java.io.IOException; + +/** + * Threw if unable to make file executable. + */ +public class PermissionException extends IOException { + public PermissionException() { + } + + public PermissionException(String message) { + super(message); + } + + public PermissionException(String message, Throwable cause) { + super(message, cause); + } + + public PermissionException(Throwable cause) { + super(cause); + } +} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/ProcessCreationException.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/ProcessCreationException.java new file mode 100644 index 000000000..69674008f --- /dev/null +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/ProcessCreationException.java @@ -0,0 +1,37 @@ +/* + * Hello Minecraft! Launcher. + * Copyright (C) 2017 huangyuhui + * + * 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.launch; + +import java.io.IOException; + +public class ProcessCreationException extends IOException { + public ProcessCreationException() { + } + + public ProcessCreationException(String message) { + super(message); + } + + public ProcessCreationException(String message, Throwable cause) { + super(message, cause); + } + + public ProcessCreationException(Throwable cause) { + super(cause); + } +} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/ProcessListener.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/ProcessListener.java index e30de6e17..cd5cecd19 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/ProcessListener.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/ProcessListener.java @@ -52,6 +52,7 @@ public interface ProcessListener { enum ExitType { JVM_ERROR, APPLICATION_ERROR, - NORMAL + NORMAL, + INTERRUPTED } }