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 982c6ea8e..b48bfef9b 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java @@ -25,6 +25,7 @@ import org.jackhuang.hmcl.task.TaskResult; import org.jackhuang.hmcl.util.*; import java.io.*; +import java.nio.file.Files; import java.util.*; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -35,9 +36,6 @@ import java.util.stream.Collectors; */ public class DefaultLauncher extends Launcher { - private List rawCommandLine; - protected final File nativeFolder; - public DefaultLauncher(GameRepository repository, String versionId, AuthInfo authInfo, LaunchOptions options) { 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) { super(repository, versionId, authInfo, options, listener, daemon); - - nativeFolder = repository.getNativeDirectory(versionId); } - @Override - public synchronized List getRawCommandLine() throws IOException { - if (rawCommandLine != null) - return Collections.unmodifiableList(rawCommandLine); - + private List generateCommandLine(File nativeFolder) throws IOException { List res = new LinkedList<>(); // Executable @@ -190,7 +182,7 @@ public class DefaultLauncher extends Launcher { if (StringUtils.isNotBlank(options.getMinecraftArgs())) res.addAll(StringUtils.tokenize(options.getMinecraftArgs())); - return rawCommandLine = res.stream() + return res.stream() .filter(it -> !getForbiddens().containsKey(it) || !getForbiddens().get(it).get()) .collect(Collectors.toList()); } @@ -228,11 +220,11 @@ public class DefaultLauncher extends Launcher { protected void appendJvmArgs(List result) { } - public void decompressNatives() throws IOException { + public void decompressNatives(File destination) throws IOException { for (Library library : version.getLibraries()) if (library.isNative()) CompressingUtils.unzip(repository.getLibraryFile(version, library), - nativeFolder, + destination, "", library.getExtract()::shouldExtract, false); @@ -256,18 +248,20 @@ 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(getRawCommandLine()); + ProcessBuilder builder = new ProcessBuilder(rawCommandLine); - decompressNatives(); + 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(), getRawCommandLine()); + ManagedProcess p = new ManagedProcess(builder.start(), rawCommandLine); if (listener == null) startMonitors(p); else @@ -283,12 +277,13 @@ public class DefaultLauncher extends Launcher { public void makeLaunchScript(File scriptFile) throws IOException { boolean isWindows = OperatingSystem.WINDOWS == OperatingSystem.CURRENT_OS; - decompressNatives(); + File nativeFolder = repository.getNativeDirectory(versionId); + decompressNatives(nativeFolder); 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")) - 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)) throw new IOException("Script file: " + scriptFile + " cannot be created."); @@ -305,7 +300,7 @@ public class DefaultLauncher extends Launcher { writer.write(options.getPrecalledCommand()); writer.newLine(); } - writer.write(StringUtils.makeCommand(getRawCommandLine())); + writer.write(StringUtils.makeCommand(generateCommandLine(nativeFolder))); } if (!scriptFile.setExecutable(true)) throw new IOException("Cannot make script file '" + scriptFile + "' executable."); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/Launcher.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/Launcher.java index 028ee0e54..ca11aef0d 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/Launcher.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/Launcher.java @@ -67,6 +67,4 @@ public abstract class Launcher { public abstract ManagedProcess launch() throws IOException, InterruptedException; - public abstract List getRawCommandLine() throws IOException; - }