Fix OptiFine installation

This commit is contained in:
huanghongxun
2019-08-19 00:18:34 +08:00
parent fb24516b90
commit c5919f2719
4 changed files with 93 additions and 29 deletions

View File

@@ -35,11 +35,10 @@ import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.platform.CommandBuilder;
import org.jackhuang.hmcl.util.platform.JavaVersion;
import org.jackhuang.hmcl.util.platform.OperatingSystem;
import org.jackhuang.hmcl.util.platform.SystemUtils;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -241,13 +240,7 @@ public class ForgeNewInstallTask extends Task<Version> {
command.addAll(args);
LOG.info("Executing external processor " + processor.getJar().toString() + ", command line: " + new CommandBuilder().addAll(command).toString());
Process process = new ProcessBuilder(command).start();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
for (String line; (line = reader.readLine()) != null;) {
System.out.println(line);
}
}
int exitCode = process.waitFor();
int exitCode = SystemUtils.callExternalProcess(command);
if (exitCode != 0)
throw new IllegalStateException("Game processor exited abnormally");

View File

@@ -21,6 +21,7 @@ import org.jackhuang.hmcl.download.DefaultDependencyManager;
import org.jackhuang.hmcl.download.LibraryAnalyzer;
import org.jackhuang.hmcl.download.VersionMismatchException;
import org.jackhuang.hmcl.game.Arguments;
import org.jackhuang.hmcl.game.DefaultGameRepository;
import org.jackhuang.hmcl.game.GameVersion;
import org.jackhuang.hmcl.game.LibrariesDownloadInfo;
import org.jackhuang.hmcl.game.Library;
@@ -31,6 +32,8 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.io.CompressingUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.io.NetworkUtils;
import org.jackhuang.hmcl.util.platform.JavaVersion;
import org.jackhuang.hmcl.util.platform.SystemUtils;
import org.jenkinsci.constant_pool_scanner.ConstantPool;
import org.jenkinsci.constant_pool_scanner.ConstantPoolScanner;
import org.jenkinsci.constant_pool_scanner.ConstantType;
@@ -42,7 +45,6 @@ import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
@@ -57,15 +59,17 @@ import static org.jackhuang.hmcl.util.Lang.getOrDefault;
*/
public final class OptiFineInstallTask extends Task<Version> {
private final DefaultGameRepository gameRepository;
private final DefaultDependencyManager dependencyManager;
private final Version version;
private final OptiFineRemoteVersion remote;
private final Path installer;
private final List<Task<?>> dependents = new LinkedList<>();
private final List<Task<?>> dependencies = new LinkedList<>();
private final File dest;
private Path dest;
private final Library optiFineLibrary;
private final Library optiFineInstallerLibrary;
public OptiFineInstallTask(DefaultDependencyManager dependencyManager, Version version, OptiFineRemoteVersion remoteVersion) {
this(dependencyManager, version, remoteVersion, null);
@@ -73,20 +77,21 @@ public final class OptiFineInstallTask extends Task<Version> {
public OptiFineInstallTask(DefaultDependencyManager dependencyManager, Version version, OptiFineRemoteVersion remoteVersion, Path installer) {
this.dependencyManager = dependencyManager;
this.gameRepository = dependencyManager.getGameRepository();
this.version = version;
this.remote = remoteVersion;
this.installer = installer;
String mavenVersion = remote.getGameVersion() + "_" + remote.getSelfVersion();
optiFineLibrary = new Library(
"optifine", "OptiFine", mavenVersion, null, null,
optiFineLibrary = new Library("optifine", "OptiFine", mavenVersion);
optiFineInstallerLibrary = new Library(
"optifine", "OptiFine", mavenVersion, "installer", null,
new LibrariesDownloadInfo(new LibraryDownloadInfo(
"optifine/OptiFine/" + mavenVersion + "/OptiFine-" + mavenVersion + ".jar",
"optifine/OptiFine/" + mavenVersion + "/OptiFine-" + mavenVersion + "-installer.jar",
remote.getUrl()))
);
dest = dependencyManager.getGameRepository().getLibraryFile(version, optiFineLibrary);
}
@Override
@@ -96,18 +101,14 @@ public final class OptiFineInstallTask extends Task<Version> {
@Override
public void preExecute() throws Exception {
if (!Arrays.asList("net.minecraft.client.main.Main",
"net.minecraft.launchwrapper.Launch")
.contains(version.resolve(dependencyManager.getGameRepository()).getMainClass()))
throw new UnsupportedOptiFineInstallationException();
dest = Files.createTempFile("optifine-installer", ".jar");
if (installer == null) {
dependents.add(new FileDownloadTask(NetworkUtils.toURL(remote.getUrl()), dest)
dependents.add(new FileDownloadTask(NetworkUtils.toURL(remote.getUrl()), dest.toFile())
.setCacheRepository(dependencyManager.getCacheRepository())
.setCaching(true));
} else {
FileUtils.copyFile(installer, dest.toPath());
FileUtils.copyFile(installer, dest);
}
}
@@ -127,13 +128,31 @@ public final class OptiFineInstallTask extends Task<Version> {
}
@Override
public void execute() throws IOException {
public void execute() throws Exception {
List<Library> libraries = new LinkedList<>();
libraries.add(optiFineLibrary);
FileUtils.copyFile(dest, gameRepository.getLibraryFile(version, optiFineInstallerLibrary).toPath());
// Install launch wrapper modified by OptiFine
boolean hasLaunchWrapper = false;
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(dest.toPath())) {
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(dest)) {
if (Files.exists(fs.getPath("optifine/Patcher.class"))) {
int exitCode = SystemUtils.callExternalProcess(
JavaVersion.fromCurrentEnvironment().getBinary().toString(),
"-cp",
dest.toString(),
"optifine.Patcher",
gameRepository.getVersionJar(version).getAbsolutePath(),
dest.toString(),
gameRepository.getLibraryFile(version, optiFineLibrary).toString()
);
if (exitCode != 0)
throw new IllegalStateException("OptiFine patcher failed");
} else {
FileUtils.copyFile(dest, gameRepository.getLibraryFile(version, optiFineLibrary).toPath());
}
Path launchWrapperVersionText = fs.getPath("launchwrapper-of.txt");
if (Files.exists(launchWrapperVersionText)) {
String launchWrapperVersion = FileUtils.readText(launchWrapperVersionText).trim();
@@ -142,24 +161,24 @@ public final class OptiFineInstallTask extends Task<Version> {
Library launchWrapper = new Library("optifine", "launchwrapper-of", launchWrapperVersion);
if (Files.exists(launchWrapperJar)) {
File launchWrapperFile = dependencyManager.getGameRepository().getLibraryFile(version, launchWrapper);
File launchWrapperFile = gameRepository.getLibraryFile(version, launchWrapper);
FileUtils.makeDirectory(launchWrapperFile.getAbsoluteFile().getParentFile());
FileUtils.copyFile(launchWrapperJar, launchWrapperFile.toPath());
hasLaunchWrapper = true;
libraries.add(0, launchWrapper);
libraries.add(launchWrapper);
}
}
}
if (!hasLaunchWrapper) {
libraries.add(0, new Library("net.minecraft", "launchwrapper", "1.12"));
libraries.add(new Library("net.minecraft", "launchwrapper", "1.12"));
}
setResult(new Version(
LibraryAnalyzer.LibraryType.OPTIFINE.getPatchId(),
remote.getSelfVersion(),
90000,
10000,
new Arguments().addGameArguments("--tweakClass", "optifine.OptiFineTweaker"),
"net.minecraft.launchwrapper.Launch",
libraries

View File

@@ -17,6 +17,7 @@
*/
package org.jackhuang.hmcl.util;
import org.jackhuang.hmcl.util.function.ExceptionalRunnable;
import org.jackhuang.hmcl.util.function.ExceptionalSupplier;
import java.util.*;
@@ -57,6 +58,15 @@ public final class Lang {
return Collections.unmodifiableList(Arrays.asList(elements));
}
public static boolean test(ExceptionalRunnable<?> r) {
try {
r.run();
return true;
} catch (Exception e) {
return false;
}
}
public static <E extends Exception> boolean test(ExceptionalSupplier<Boolean, E> r) {
try {
return r.get();

View File

@@ -0,0 +1,42 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2019 huangyuhui <huanghongxun2008@126.com> and contributors
*
* 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 <https://www.gnu.org/licenses/>.
*/
package org.jackhuang.hmcl.util.platform;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
public final class SystemUtils {
private SystemUtils() {}
public static int callExternalProcess(String... command) throws IOException, InterruptedException {
return callExternalProcess(Arrays.asList(command));
}
public static int callExternalProcess(List<String> command) throws IOException, InterruptedException {
Process process = new ProcessBuilder(command).start();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
for (String line; (line = reader.readLine()) != null;) {
System.out.println(line);
}
}
return process.waitFor();
}
}