Launching messages

This commit is contained in:
huangyuhui 2018-02-02 13:44:53 +08:00
parent 0a4944f120
commit f144dd888d
12 changed files with 295 additions and 65 deletions

View File

@ -24,8 +24,7 @@ import org.jackhuang.hmcl.auth.Account;
import org.jackhuang.hmcl.auth.AuthInfo; import org.jackhuang.hmcl.auth.AuthInfo;
import org.jackhuang.hmcl.auth.AuthenticationException; import org.jackhuang.hmcl.auth.AuthenticationException;
import org.jackhuang.hmcl.download.DefaultDependencyManager; import org.jackhuang.hmcl.download.DefaultDependencyManager;
import org.jackhuang.hmcl.launch.DefaultLauncher; import org.jackhuang.hmcl.launch.*;
import org.jackhuang.hmcl.launch.ProcessListener;
import org.jackhuang.hmcl.mod.CurseCompletionTask; import org.jackhuang.hmcl.mod.CurseCompletionTask;
import org.jackhuang.hmcl.setting.LauncherVisibility; import org.jackhuang.hmcl.setting.LauncherVisibility;
import org.jackhuang.hmcl.setting.Profile; 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.task.*;
import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.DialogController; 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.construct.TaskExecutorDialogPane;
import org.jackhuang.hmcl.ui.LogWindow; import org.jackhuang.hmcl.ui.LogWindow;
import org.jackhuang.hmcl.ui.construct.MessageBox; import org.jackhuang.hmcl.ui.construct.MessageBox;
@ -62,10 +62,12 @@ public final class LauncherHelper {
Version version = repository.getVersion(selectedVersion); Version version = repository.getVersion(selectedVersion);
VersionSetting setting = profile.getVersionSetting(selectedVersion); VersionSetting setting = profile.getVersionSetting(selectedVersion);
Platform.runLater(() -> {
try { try {
checkGameState(profile, setting, version, () -> launch0(selectedVersion, scriptFile)); checkGameState(profile, setting, version, () -> Schedulers.newThread().schedule(() -> launch0(selectedVersion, scriptFile)));
} catch (InterruptedException ignore) { } catch (InterruptedException ignore) {
} }
});
} }
private void launch0(String selectedVersion, File scriptFile) { private void launch0(String selectedVersion, File scriptFile) {
@ -97,20 +99,31 @@ public final class LauncherHelper {
)); ));
})) }))
.then(variables -> { .then(variables -> {
DefaultLauncher launcher = variables.<DefaultLauncher>get("launcher");
if (scriptFile == null) { if (scriptFile == null) {
return variables.<DefaultLauncher>get("launcher").launchAsync().setName(Main.i18n("version.launch")); return new LaunchTask<>(launcher::launch).setName(Main.i18n("version.launch"));
} else { } else {
return variables.<DefaultLauncher>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 -> { .then(Task.of(variables -> {
if (scriptFile == null) { 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) if (setting.getLauncherVisibility() == LauncherVisibility.CLOSE)
Main.stopApplication(); Main.stopApplication();
else
launchingStepsPane.setCancel(() -> {
process.stop();
Controllers.closeDialog();
});
} else } else
Platform.runLater(() -> Platform.runLater(() ->
Controllers.dialog(Main.i18n("version.launch_script.success", scriptFile.getAbsolutePath()))); Controllers.dialog(Main.i18n("version.launch_script.success", scriptFile.getAbsolutePath())));
})) }))
.executor(); .executor();
@ -129,7 +142,9 @@ public final class LauncherHelper {
@Override @Override
public void onTerminate() { public void onTerminate() {
Platform.runLater(() -> { 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 { 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))); VersionNumber gameVersion = VersionNumber.asVersion(GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version)));
JavaVersion java = setting.getJavaVersion(); 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")) { 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); Controllers.dialog(Main.i18n("launch.advice.java9"), Main.i18n("message.error"), MessageBox.ERROR_MESSAGE, null);
suggest = false;
flag = true; flag = true;
} }
@ -174,7 +190,10 @@ public final class LauncherHelper {
flag = true; flag = true;
} }
if (!flag) if (flag) {
if (suggest && Controllers.getDialogContent() instanceof MessageDialogPane)
((MessageDialogPane) Controllers.getDialogContent()).disableClosingDialog();
} else
onAccept.run(); onAccept.run();
} }
@ -215,6 +234,34 @@ public final class LauncherHelper {
} }
} }
class LaunchTask<T> extends TaskResult<T> {
private final ExceptionalSupplier<T, ?> supplier;
public LaunchTask(ExceptionalSupplier<T, ?> 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. * The managed process listener.
* Guarantee that one [JavaProcess], one [HMCLProcessListener]. * Guarantee that one [JavaProcess], one [HMCLProcessListener].
@ -302,9 +349,22 @@ public final class LauncherHelper {
@Override @Override
public void onExit(int exitCode, ExitType exitType) { public void onExit(int exitCode, ExitType exitType) {
if (exitType == ExitType.INTERRUPTED)
return;
if (exitType != ExitType.NORMAL && logWindow == null) if (exitType != ExitType.NORMAL && logWindow == null)
Platform.runLater(() -> { Platform.runLater(() -> {
logWindow = new LogWindow(); 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.show();
logWindow.onDone.register(() -> { logWindow.onDone.register(() -> {
for (Map.Entry<String, Log4jLevel> entry : logs) for (Map.Entry<String, Log4jLevel> entry : logs)

View File

@ -33,6 +33,8 @@ public final class MessageDialogPane extends StackPane {
private final String text; private final String text;
private final JFXDialog dialog; private final JFXDialog dialog;
private boolean closingDialog = true;
@FXML @FXML
private JFXButton acceptButton; private JFXButton acceptButton;
@FXML @FXML
@ -57,6 +59,7 @@ public final class MessageDialogPane extends StackPane {
content.setText(text); content.setText(text);
acceptButton.setOnMouseClicked(e -> { acceptButton.setOnMouseClicked(e -> {
if (closingDialog)
dialog.close(); dialog.close();
Optional.ofNullable(onAccept).ifPresent(Runnable::run); Optional.ofNullable(onAccept).ifPresent(Runnable::run);
}); });
@ -84,6 +87,7 @@ public final class MessageDialogPane extends StackPane {
cancelButton.setVisible(true); cancelButton.setVisible(true);
cancelButton.setOnMouseClicked(e -> { cancelButton.setOnMouseClicked(e -> {
if (closingDialog)
dialog.close(); dialog.close();
Optional.ofNullable(onCancel).ifPresent(Runnable::run); Optional.ofNullable(onCancel).ifPresent(Runnable::run);
}); });
@ -95,4 +99,8 @@ public final class MessageDialogPane extends StackPane {
graphic.setGraphic(SVG.help_circle("black", 40, 40)); graphic.setGraphic(SVG.help_circle("black", 40, 40));
} }
public void disableClosingDialog() {
closingDialog = false;
}
} }

View File

@ -17,6 +17,7 @@
*/ */
package org.jackhuang.hmcl.ui.construct; package org.jackhuang.hmcl.ui.construct;
import com.jfoenix.concurrency.JFXUtilities;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXProgressBar; import com.jfoenix.controls.JFXProgressBar;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
@ -30,6 +31,7 @@ import java.util.Optional;
public class TaskExecutorDialogPane extends StackPane { public class TaskExecutorDialogPane extends StackPane {
private TaskExecutor executor; private TaskExecutor executor;
private Runnable onCancel;
@FXML @FXML
private JFXProgressBar progressBar; private JFXProgressBar progressBar;
@ -48,12 +50,11 @@ public class TaskExecutorDialogPane extends StackPane {
FXUtils.limitHeight(this, 200); FXUtils.limitHeight(this, 200);
FXUtils.limitWidth(this, 400); FXUtils.limitWidth(this, 400);
if (cancel == null) setCancel(cancel);
btnCancel.setDisable(true);
btnCancel.setOnMouseClicked(e -> { btnCancel.setOnMouseClicked(e -> {
Optional.ofNullable(executor).ifPresent(TaskExecutor::cancel); Optional.ofNullable(executor).ifPresent(TaskExecutor::cancel);
cancel.run(); onCancel.run();
}); });
} }
@ -92,4 +93,10 @@ public class TaskExecutorDialogPane extends StackPane {
else else
progressBar.setProgress(progress); progressBar.setProgress(progress);
} }
public void setCancel(Runnable onCancel) {
this.onCancel = onCancel;
JFXUtilities.runInFX(() -> btnCancel.setDisable(onCancel == null));
}
} }

View File

@ -0,0 +1,44 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 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;
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);
}
}

View File

@ -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.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.circular_dependency_versions=Found circular dependency versions, please check if your client has been modified.
launch.failed=Unable to launch 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.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.decompressing_natives=Did not finish decompressing native libraries, continue launching game? 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.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.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.prelaunch_command=Prelaunch command fail.
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.state.dependencies=Decompressing natives launch.state.dependencies=Decompressing natives
launch.state.done=Done launch.state.done=Done
launch.state.logging_in=Logging In launch.state.logging_in=Logging In
@ -366,8 +366,8 @@ version.game.old_beta=Beta
version.game.release=Release version.game.release=Release
version.game.snapshot=Snapshot version.game.snapshot=Snapshot
version.launch=Play version.launch=Play
version.launch_script=Make Launching Script. version.launch_script=Make Launching Script
version.launch_script.failed=Failed to make script. version.launch_script.failed=Unable to make launch script.
version.launch_script.save=Save the launch script version.launch_script.save=Save the launch script
version.launch_script.success=Finished script creation, %s. version.launch_script.success=Finished script creation, %s.
version.manage.redownload_assets_index=Redownload Assets Index version.manage.redownload_assets_index=Redownload Assets Index

View File

@ -146,12 +146,12 @@ launch.advice.too_large_memory_for_32bit=您设置的内存大小过大,由于
launch.circular_dependency_versions=发现游戏版本循环引用,请确认您的客户端未被修改或修改导致出现此问题。 launch.circular_dependency_versions=发现游戏版本循环引用,请确认您的客户端未被修改或修改导致出现此问题。
launch.failed=启动失败 launch.failed=启动失败
launch.failed.cannot_create_jvm=截获到无法创建Java虚拟机可能是Java参数有问题可以在设置中开启无参数模式启动 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.downloading_libraries=未完成游戏依赖库的下载,还要继续启动游戏吗?
launch.failed.executable_permission=未能为启动文件添加执行权限
launch.failed.exited_abnormally=游戏非正常退出,请查看日志文件,或联系他人寻求帮助。 launch.failed.exited_abnormally=游戏非正常退出,请查看日志文件,或联系他人寻求帮助。
launch.failed.packing_jar=在打包jar时发生错误 launch.failed.prelaunch_command=启动前执行命令执行失败。
launch.failed.sh_permission=为启动文件添加权限时发生错误
launch.failed_creating_process=启动失败在创建新进程时发生错误可能是Java路径错误。
launch.state.dependencies=正在处理游戏依赖 launch.state.dependencies=正在处理游戏依赖
launch.state.done=启动完成 launch.state.done=启动完成
launch.state.logging_in=登录中 launch.state.logging_in=登录中

View File

@ -19,9 +19,6 @@ package org.jackhuang.hmcl.launch;
import org.jackhuang.hmcl.auth.AuthInfo; import org.jackhuang.hmcl.auth.AuthInfo;
import org.jackhuang.hmcl.game.*; 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 org.jackhuang.hmcl.util.*;
import java.io.*; import java.io.*;
@ -220,7 +217,8 @@ public class DefaultLauncher extends Launcher {
protected void appendJvmArgs(List<String> result) { protected void appendJvmArgs(List<String> result) {
} }
public void decompressNatives(File destination) throws IOException { public void decompressNatives(File destination) throws NotDecompressingNativesException {
try {
for (Library library : version.getLibraries()) for (Library library : version.getLibraries())
if (library.isNative()) if (library.isNative())
CompressingUtils.unzip(repository.getLibraryFile(version, library), CompressingUtils.unzip(repository.getLibraryFile(version, library),
@ -228,6 +226,9 @@ public class DefaultLauncher extends Launcher {
"", "",
library.getExtract()::shouldExtract, library.getExtract()::shouldExtract,
false); false);
} catch (IOException e) {
throw new NotDecompressingNativesException(e);
}
} }
protected Map<String, String> getConfigurations() { protected Map<String, String> getConfigurations() {
@ -249,19 +250,26 @@ public class DefaultLauncher extends Launcher {
@Override @Override
public ManagedProcess launch() throws IOException, InterruptedException { public ManagedProcess launch() throws IOException, InterruptedException {
File nativeFolder = Files.createTempDirectory("minecraft").toFile(); File nativeFolder = Files.createTempDirectory("minecraft").toFile();
List<String> rawCommandLine = generateCommandLine(nativeFolder);
// To guarantee that when failed to generate code, we will not call precalled command // To guarantee that when failed to generate launch command line, we will not call pre-launch command
ProcessBuilder builder = new ProcessBuilder(rawCommandLine); List<String> rawCommandLine = generateCommandLine(nativeFolder);
decompressNatives(nativeFolder); decompressNatives(nativeFolder);
if (StringUtils.isNotBlank(options.getPrecalledCommand())) if (StringUtils.isNotBlank(options.getPrecalledCommand()))
Runtime.getRuntime().exec(options.getPrecalledCommand()).waitFor(); Runtime.getRuntime().exec(options.getPrecalledCommand()).waitFor();
Process process;
try {
ProcessBuilder builder = new ProcessBuilder(rawCommandLine);
builder.directory(repository.getRunDirectory(version.getId())) builder.directory(repository.getRunDirectory(version.getId()))
.environment().put("APPDATA", options.getGameDir().getAbsoluteFile().getParent()); .environment().put("APPDATA", options.getGameDir().getAbsoluteFile().getParent());
ManagedProcess p = new ManagedProcess(builder.start(), rawCommandLine); process = builder.start();
} catch (IOException e) {
throw new ProcessCreationException(e);
}
ManagedProcess p = new ManagedProcess(process, rawCommandLine);
if (listener == null) if (listener == null)
startMonitors(p); startMonitors(p);
else else
@ -269,10 +277,6 @@ public class DefaultLauncher extends Launcher {
return p; return p;
} }
public final TaskResult<ManagedProcess> launchAsync() {
return new SimpleTaskResult<>(LAUNCH_ASYNC_ID, this::launch);
}
@Override @Override
public void makeLaunchScript(File scriptFile) throws IOException { public void makeLaunchScript(File scriptFile) throws IOException {
boolean isWindows = OperatingSystem.WINDOWS == OperatingSystem.CURRENT_OS; boolean isWindows = OperatingSystem.WINDOWS == OperatingSystem.CURRENT_OS;
@ -303,11 +307,7 @@ public class DefaultLauncher extends Launcher {
writer.write(StringUtils.makeCommand(generateCommandLine(nativeFolder))); writer.write(StringUtils.makeCommand(generateCommandLine(nativeFolder)));
} }
if (!scriptFile.setExecutable(true)) if (!scriptFile.setExecutable(true))
throw new IOException("Cannot make script file '" + scriptFile + "' executable."); throw new PermissionException();
}
public final Task makeLaunchScriptAsync(File file) {
return Task.of(() -> makeLaunchScript(file));
} }
private void startMonitors(ManagedProcess managedProcess) { private void startMonitors(ManagedProcess managedProcess) {
@ -362,7 +362,4 @@ public class DefaultLauncher extends Launcher {
managedProcess.addRelatedThread(stderr); managedProcess.addRelatedThread(stderr);
managedProcess.addRelatedThread(Lang.thread(new ExitWaiter(managedProcess, Arrays.asList(stdout, stderr), (exitCode, exitType) -> processListener.onExit(exitCode, exitType)), "exit-waiter", isDaemon)); 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";
} }

View File

@ -65,16 +65,15 @@ final class ExitWaiter implements Runnable {
ProcessListener.ExitType exitType; ProcessListener.ExitType exitType;
// LaunchWrapper will catch the exception logged and will exit normally. // LaunchWrapper will catch the exception logged and will exit normally.
if (exitCode != 0 || StringUtils.containsOne(errorLines, "Unable to launch")) { if (exitCode != 0 && StringUtils.containsOne(errorLines,
EventBus.EVENT_BUS.fireEvent(new ProcessExitedAbnormallyEvent(this, process));
exitType = ProcessListener.ExitType.APPLICATION_ERROR;
} else if (exitCode != 0 && StringUtils.containsOne(errorLines,
"Could not create the Java Virtual Machine.", "Could not create the Java Virtual Machine.",
"Error occurred during initialization of VM", "Error occurred during initialization of VM",
"A fatal exception has occurred. Program will exit.", "A fatal exception has occurred. Program will exit.")) {
"Unable to launch")) {
EventBus.EVENT_BUS.fireEvent(new JVMLaunchFailedEvent(this, process)); EventBus.EVENT_BUS.fireEvent(new JVMLaunchFailedEvent(this, process));
exitType = ProcessListener.ExitType.JVM_ERROR; 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 } else
exitType = ProcessListener.ExitType.NORMAL; exitType = ProcessListener.ExitType.NORMAL;
@ -82,7 +81,7 @@ final class ExitWaiter implements Runnable {
watcher.accept(exitCode, exitType); watcher.accept(exitCode, exitType);
} catch (InterruptedException e) { } catch (InterruptedException e) {
watcher.accept(1, ProcessListener.ExitType.NORMAL); watcher.accept(1, ProcessListener.ExitType.INTERRUPTED);
} }
} }

View File

@ -0,0 +1,37 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 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.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);
}
}

View File

@ -0,0 +1,40 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 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.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);
}
}

View File

@ -0,0 +1,37 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 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.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);
}
}

View File

@ -52,6 +52,7 @@ public interface ProcessListener {
enum ExitType { enum ExitType {
JVM_ERROR, JVM_ERROR,
APPLICATION_ERROR, APPLICATION_ERROR,
NORMAL NORMAL,
INTERRUPTED
} }
} }