decompress natives to system temp directory

This commit is contained in:
huangyuhui 2018-02-02 11:13:10 +08:00
parent 7675347889
commit 0a4944f120
2 changed files with 15 additions and 22 deletions

View File

@ -25,6 +25,7 @@ import org.jackhuang.hmcl.task.TaskResult;
import org.jackhuang.hmcl.util.*; import org.jackhuang.hmcl.util.*;
import java.io.*; import java.io.*;
import java.nio.file.Files;
import java.util.*; import java.util.*;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -35,9 +36,6 @@ import java.util.stream.Collectors;
*/ */
public class DefaultLauncher extends Launcher { public class DefaultLauncher extends Launcher {
private List<String> rawCommandLine;
protected final File nativeFolder;
public DefaultLauncher(GameRepository repository, String versionId, AuthInfo authInfo, LaunchOptions options) { public DefaultLauncher(GameRepository repository, String versionId, AuthInfo authInfo, LaunchOptions options) {
this(repository, versionId, authInfo, options, null); this(repository, versionId, authInfo, options, null);
} }
@ -48,15 +46,9 @@ public class DefaultLauncher extends Launcher {
public DefaultLauncher(GameRepository repository, String versionId, AuthInfo authInfo, LaunchOptions options, ProcessListener listener, boolean daemon) { public DefaultLauncher(GameRepository repository, String versionId, AuthInfo authInfo, LaunchOptions options, ProcessListener listener, boolean daemon) {
super(repository, versionId, authInfo, options, listener, daemon); super(repository, versionId, authInfo, options, listener, daemon);
nativeFolder = repository.getNativeDirectory(versionId);
} }
@Override private List<String> generateCommandLine(File nativeFolder) throws IOException {
public synchronized List<String> getRawCommandLine() throws IOException {
if (rawCommandLine != null)
return Collections.unmodifiableList(rawCommandLine);
List<String> res = new LinkedList<>(); List<String> res = new LinkedList<>();
// Executable // Executable
@ -190,7 +182,7 @@ public class DefaultLauncher extends Launcher {
if (StringUtils.isNotBlank(options.getMinecraftArgs())) if (StringUtils.isNotBlank(options.getMinecraftArgs()))
res.addAll(StringUtils.tokenize(options.getMinecraftArgs())); res.addAll(StringUtils.tokenize(options.getMinecraftArgs()));
return rawCommandLine = res.stream() return res.stream()
.filter(it -> !getForbiddens().containsKey(it) || !getForbiddens().get(it).get()) .filter(it -> !getForbiddens().containsKey(it) || !getForbiddens().get(it).get())
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@ -228,11 +220,11 @@ public class DefaultLauncher extends Launcher {
protected void appendJvmArgs(List<String> result) { protected void appendJvmArgs(List<String> result) {
} }
public void decompressNatives() throws IOException { public void decompressNatives(File destination) throws IOException {
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),
nativeFolder, destination,
"", "",
library.getExtract()::shouldExtract, library.getExtract()::shouldExtract,
false); false);
@ -256,18 +248,20 @@ 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();
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 code, we will not call precalled command
ProcessBuilder builder = new ProcessBuilder(getRawCommandLine()); ProcessBuilder builder = new ProcessBuilder(rawCommandLine);
decompressNatives(); decompressNatives(nativeFolder);
if (StringUtils.isNotBlank(options.getPrecalledCommand())) if (StringUtils.isNotBlank(options.getPrecalledCommand()))
Runtime.getRuntime().exec(options.getPrecalledCommand()).waitFor(); Runtime.getRuntime().exec(options.getPrecalledCommand()).waitFor();
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(), getRawCommandLine()); ManagedProcess p = new ManagedProcess(builder.start(), rawCommandLine);
if (listener == null) if (listener == null)
startMonitors(p); startMonitors(p);
else else
@ -283,12 +277,13 @@ public class DefaultLauncher extends Launcher {
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;
decompressNatives(); File nativeFolder = repository.getNativeDirectory(versionId);
decompressNatives(nativeFolder);
if (isWindows && !FileUtils.getExtension(scriptFile).equals("bat")) if (isWindows && !FileUtils.getExtension(scriptFile).equals("bat"))
throw new IOException("The extension of " + scriptFile + " is not 'bat' in Windows"); throw new IllegalArgumentException("The extension of " + scriptFile + " is not 'bat' in Windows");
else if (!isWindows && !FileUtils.getExtension(scriptFile).equals("sh")) else if (!isWindows && !FileUtils.getExtension(scriptFile).equals("sh"))
throw new IOException("The extension of " + scriptFile + " is not 'sh' in macOS/Linux"); throw new IllegalArgumentException("The extension of " + scriptFile + " is not 'sh' in macOS/Linux");
if (!FileUtils.makeFile(scriptFile)) if (!FileUtils.makeFile(scriptFile))
throw new IOException("Script file: " + scriptFile + " cannot be created."); throw new IOException("Script file: " + scriptFile + " cannot be created.");
@ -305,7 +300,7 @@ public class DefaultLauncher extends Launcher {
writer.write(options.getPrecalledCommand()); writer.write(options.getPrecalledCommand());
writer.newLine(); writer.newLine();
} }
writer.write(StringUtils.makeCommand(getRawCommandLine())); 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 IOException("Cannot make script file '" + scriptFile + "' executable.");

View File

@ -67,6 +67,4 @@ public abstract class Launcher {
public abstract ManagedProcess launch() throws IOException, InterruptedException; public abstract ManagedProcess launch() throws IOException, InterruptedException;
public abstract List<String> getRawCommandLine() throws IOException;
} }