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

@@ -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<String> 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<String, String> getConfigurations() {
@@ -249,19 +250,26 @@ public class DefaultLauncher extends Launcher {
@Override
public ManagedProcess launch() throws IOException, InterruptedException {
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
ProcessBuilder builder = new ProcessBuilder(rawCommandLine);
// To guarantee that when failed to generate launch command line, we will not call pre-launch command
List<String> 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<ManagedProcess> 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";
}

View File

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

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 {
JVM_ERROR,
APPLICATION_ERROR,
NORMAL
NORMAL,
INTERRUPTED
}
}