mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-13 22:07:01 -04:00
修复自动安装在 1.20.4 的严重问题 (#3023)
* Fix: OptiFine and Forge has compatible problem on 1.20.4 . Fix: Forge changes it's main class on 1.20.4 .
* Fix: HMCL cannot display the analyed versions installed by external launchers.
* Refuse to configure installable widgets when it's from external process.
* Add javadoc about LibraryStatus
* Adapt to the new change of Forge: b8270cd9ff
* Re-arrange entries.
* Fix.
This commit is contained in:
parent
b43c8ceae5
commit
6b78f56298
@ -270,10 +270,12 @@ public class InstallerItem extends Control {
|
||||
return i18n("install.installer.incompatible", i18n("install.installer." + incompatibleWith));
|
||||
} else if (version == null) {
|
||||
return i18n("install.installer.not_installed");
|
||||
} else {
|
||||
} else if (control.id.equals(MINECRAFT.getPatchId()) || control.removable.get() || control.upgradable.get()) {
|
||||
return i18n("install.installer.version", version);
|
||||
} else {
|
||||
return i18n("install.installer.external_version", version);
|
||||
}
|
||||
}, control.incompatibleLibraryName, control.incompatibleWithGame, control.libraryVersion));
|
||||
}, control.incompatibleLibraryName, control.incompatibleWithGame, control.libraryVersion, control.installable, control.removable, control.upgradable));
|
||||
BorderPane.setMargin(statusLabel, new Insets(0, 0, 0, 8));
|
||||
BorderPane.setAlignment(statusLabel, Pos.CENTER_LEFT);
|
||||
|
||||
@ -297,8 +299,9 @@ public class InstallerItem extends Control {
|
||||
control.upgradable));
|
||||
arrowButton.getStyleClass().add("toggle-icon4");
|
||||
arrowButton.visibleProperty().bind(Bindings.createBooleanBinding(
|
||||
() -> control.installable.get() && control.incompatibleLibraryName.get() == null,
|
||||
control.installable, control.incompatibleLibraryName));
|
||||
() -> control.installable.get() && control.libraryVersion.get() == null && control.incompatibleLibraryName.get() == null,
|
||||
control.installable, control.libraryVersion, control.incompatibleLibraryName
|
||||
));
|
||||
arrowButton.managedProperty().bind(arrowButton.visibleProperty());
|
||||
arrowButton.onMouseClickedProperty().bind(control.action);
|
||||
buttonsContainer.getChildren().add(arrowButton);
|
||||
|
@ -30,7 +30,6 @@ import org.jackhuang.hmcl.task.TaskExecutor;
|
||||
import org.jackhuang.hmcl.task.TaskListener;
|
||||
import org.jackhuang.hmcl.ui.*;
|
||||
import org.jackhuang.hmcl.ui.download.UpdateInstallerWizardProvider;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.TaskCancellationAction;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
|
||||
@ -90,13 +89,15 @@ public class InstallerListPage extends ListPageBase<InstallerItem> implements Ve
|
||||
for (InstallerItem installerItem : group.getLibraries()) {
|
||||
String libraryId = installerItem.getLibraryId();
|
||||
String libraryVersion = analyzer.getVersion(libraryId).orElse(null);
|
||||
boolean libraryConfigurable = libraryVersion != null && analyzer.getLibraryStatus(libraryId) == LibraryAnalyzer.LibraryMark.LibraryStatus.CLEAR;
|
||||
|
||||
installerItem.libraryVersion.set(libraryVersion);
|
||||
installerItem.upgradable.set(libraryVersion != null);
|
||||
installerItem.upgradable.set(libraryConfigurable);
|
||||
installerItem.installable.set(true);
|
||||
installerItem.action.set(e -> {
|
||||
Controllers.getDecorator().startWizard(new UpdateInstallerWizardProvider(profile, gameVersion, version, libraryId, libraryVersion));
|
||||
});
|
||||
boolean removable = !LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId().equals(libraryId) && libraryVersion != null;
|
||||
boolean removable = !LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId().equals(libraryId) && libraryConfigurable;
|
||||
installerItem.removable.set(removable);
|
||||
if (removable) {
|
||||
Runnable action = removeAction.apply(libraryId);
|
||||
@ -119,17 +120,10 @@ public class InstallerListPage extends ListPageBase<InstallerItem> implements Ve
|
||||
InstallerItem installerItem = new InstallerItem(libraryId);
|
||||
installerItem.libraryVersion.set(libraryVersion);
|
||||
installerItem.installable.set(false);
|
||||
installerItem.upgradable.bind(installerItem.installable);
|
||||
installerItem.upgradable.set(false);
|
||||
installerItem.removable.set(true);
|
||||
installerItem.removeAction.set(e -> action.run());
|
||||
|
||||
if (libraryVersion != null && Lang.test(() -> profile.getDependency().getVersionList(libraryId))) {
|
||||
installerItem.installable.set(true);
|
||||
installerItem.action.set(e -> {
|
||||
Controllers.getDecorator().startWizard(new UpdateInstallerWizardProvider(profile, gameVersion, version, libraryId, libraryVersion));
|
||||
});
|
||||
}
|
||||
|
||||
itemsProperty().add(installerItem);
|
||||
}
|
||||
}, Platform::runLater);
|
||||
@ -175,7 +169,8 @@ public class InstallerListPage extends ListPageBase<InstallerItem> implements Ve
|
||||
@Override
|
||||
protected List<Node> initializeToolbar(InstallerListPage skinnable) {
|
||||
return Collections.singletonList(
|
||||
createToolbarButton2(i18n("install.installer.install_offline"), SVG.PLUS, skinnable::installOffline));
|
||||
createToolbarButton2(i18n("install.installer.install_offline"), SVG.PLUS, skinnable::installOffline)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -637,6 +637,7 @@ install.installer.optifine=OptiFine
|
||||
install.installer.quilt=Quilt
|
||||
install.installer.quilt-api=QSL/QFAPI
|
||||
install.installer.version=%s
|
||||
install.installer.external_version=%s Installed by external process, which cannot be configured
|
||||
install.modpack=Install a Modpack
|
||||
install.new_game=Add a New Instance
|
||||
install.new_game.already_exists=This instance already exists. Please use another name.
|
||||
|
@ -521,6 +521,7 @@ install.installer.optifine=OptiFine
|
||||
install.installer.quilt=Quilt
|
||||
install.installer.quilt-api=QSL/QFAPI
|
||||
install.installer.version=%s
|
||||
install.installer.external_version=%s 由外部安裝的版本,無法解除安裝或更換
|
||||
install.modpack=安裝模組包
|
||||
install.new_game=安裝新遊戲版本
|
||||
install.new_game.already_exists=此版本已經存在,請重新命名
|
||||
|
@ -520,6 +520,7 @@ install.installer.optifine=OptiFine
|
||||
install.installer.quilt=Quilt
|
||||
install.installer.quilt-api=QSL/QFAPI
|
||||
install.installer.version=%s
|
||||
install.installer.external_version=%s 由外部安装的版本,无法卸载或更换
|
||||
install.modpack=安装整合包
|
||||
install.new_game=安装新游戏版本
|
||||
install.new_game.already_exists=此版本已经存在,请换一个名字
|
||||
|
@ -19,7 +19,10 @@ package org.jackhuang.hmcl.download;
|
||||
|
||||
import org.jackhuang.hmcl.game.*;
|
||||
import org.jackhuang.hmcl.mod.ModLoaderType;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.Pair;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionRange;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -51,6 +54,15 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
|
||||
return Optional.ofNullable(libraries.get(type.getPatchId())).map(Pair::getKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a library is provided in $.patches, it's structure is so clear that we can do any operation.
|
||||
* Otherwise, we must guess how are these libraries mixed.
|
||||
* Maybe a guessing implementation will be provided in the future. But by now, we simply set it to JUST_EXISTED.
|
||||
*/
|
||||
public LibraryMark.LibraryStatus getLibraryStatus(String type) {
|
||||
return version.hasPatch(type) ? LibraryMark.LibraryStatus.CLEAR : LibraryMark.LibraryStatus.JUST_EXISTED;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<LibraryMark> iterator() {
|
||||
@ -65,7 +77,7 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
|
||||
@Override
|
||||
public LibraryMark next() {
|
||||
Map.Entry<String, Pair<Library, String>> entry = impl.next();
|
||||
return new LibraryMark(entry.getKey(), entry.getValue().getValue());
|
||||
return new LibraryMark(entry.getKey(), entry.getValue().getValue(), getLibraryStatus(entry.getKey()));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -85,13 +97,9 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
|
||||
}
|
||||
|
||||
public boolean hasModLauncher() {
|
||||
final String modLauncher = "cpw.mods.modlauncher.Launcher";
|
||||
return modLauncher.equals(version.getMainClass()) || version.getPatches().stream().anyMatch(patch -> modLauncher.equals(patch.getMainClass()));
|
||||
}
|
||||
|
||||
public boolean hasBootstrapLauncher() {
|
||||
final String bootstrapLauncher = "cpw.mods.bootstraplauncher.BootstrapLauncher";
|
||||
return bootstrapLauncher.equals(version.getMainClass()) || version.getPatches().stream().anyMatch(patch -> bootstrapLauncher.equals(patch.getMainClass()));
|
||||
return LibraryAnalyzer.MOD_LAUNCHER_MAIN.equals(version.getMainClass()) || version.getPatches().stream().anyMatch(
|
||||
patch -> LibraryAnalyzer.MOD_LAUNCHER_MAIN.equals(patch.getMainClass())
|
||||
);
|
||||
}
|
||||
|
||||
private Version removingMatchedLibrary(Version version, String libraryId) {
|
||||
@ -184,7 +192,7 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
|
||||
private final Pattern FORGE_VERSION_MATCHER = Pattern.compile("^([0-9.]+)-(?<forge>[0-9.]+)(-([0-9.]+))?$");
|
||||
|
||||
@Override
|
||||
public String patchVersion(Version gameVersion, String libraryVersion) {
|
||||
protected String patchVersion(Version gameVersion, String libraryVersion) {
|
||||
Matcher matcher = FORGE_VERSION_MATCHER.matcher(libraryVersion);
|
||||
if (matcher.find()) {
|
||||
return matcher.group("forge");
|
||||
@ -193,7 +201,7 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchLibrary(Library library, List<Library> libraries) {
|
||||
protected boolean matchLibrary(Library library, List<Library> libraries) {
|
||||
for (Library l : libraries) {
|
||||
if (NEO_FORGE.matchLibrary(l, libraries)) {
|
||||
return false;
|
||||
@ -206,7 +214,7 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
|
||||
private final Pattern NEO_FORGE_VERSION_MATCHER = Pattern.compile("^([0-9.]+)-(?<forge>[0-9.]+)(-([0-9.]+))?$");
|
||||
|
||||
@Override
|
||||
public String patchVersion(Version gameVersion, String libraryVersion) {
|
||||
protected String patchVersion(Version gameVersion, String libraryVersion) {
|
||||
Matcher matcher = NEO_FORGE_VERSION_MATCHER.matcher(libraryVersion);
|
||||
if (matcher.find()) {
|
||||
return matcher.group("forge");
|
||||
@ -289,22 +297,37 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean matchLibrary(Library library, List<Library> libraries) {
|
||||
protected boolean matchLibrary(Library library, List<Library> libraries) {
|
||||
return group.matcher(library.getGroupId()).matches() && artifact.matcher(library.getArtifactId()).matches();
|
||||
}
|
||||
|
||||
public String patchVersion(Version gameVersion, String libraryVersion) {
|
||||
protected String patchVersion(Version gameVersion, String libraryVersion) {
|
||||
return libraryVersion;
|
||||
}
|
||||
}
|
||||
|
||||
public static class LibraryMark {
|
||||
public final static class LibraryMark {
|
||||
/**
|
||||
* If a library is provided in $.patches, it's structure is so clear that we can do any operation.
|
||||
* Otherwise, we must guess how are these libraries mixed.
|
||||
* Maybe a guessing implementation will be provided in the future. But by now, we simply set it to JUST_EXISTED.
|
||||
*/
|
||||
public enum LibraryStatus {
|
||||
CLEAR, UNSURE, JUST_EXISTED
|
||||
}
|
||||
|
||||
private final String libraryId;
|
||||
private final String libraryVersion;
|
||||
/**
|
||||
* If this version is installed by HMCL, instead of external process,
|
||||
* which means $.patches contains this library, structureClear is true.
|
||||
*/
|
||||
private final LibraryStatus status;
|
||||
|
||||
public LibraryMark(@NotNull String libraryId, @Nullable String libraryVersion) {
|
||||
private LibraryMark(@NotNull String libraryId, @Nullable String libraryVersion, LibraryStatus status) {
|
||||
this.libraryId = libraryId;
|
||||
this.libraryVersion = libraryVersion;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -316,12 +339,27 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
|
||||
public String getLibraryVersion() {
|
||||
return libraryVersion;
|
||||
}
|
||||
|
||||
public LibraryStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
public static final String VANILLA_MAIN = "net.minecraft.client.main.Main";
|
||||
public static final String LAUNCH_WRAPPER_MAIN = "net.minecraft.launchwrapper.Launch";
|
||||
public static final String MOD_LAUNCHER_MAIN = "cpw.mods.modlauncher.Launcher";
|
||||
public static final String BOOTSTRAP_LAUNCHER_MAIN = "cpw.mods.bootstraplauncher.BootstrapLauncher";
|
||||
public static final String FORGE_BOOTSTRAP_MAIN = "net.minecraftforge.bootstrap.ForgeBootstrap";
|
||||
|
||||
public static final Set<String> FORGE_OPTIFINE_MAIN = new HashSet<>(Lang.immutableListOf(
|
||||
LibraryAnalyzer.VANILLA_MAIN,
|
||||
LibraryAnalyzer.LAUNCH_WRAPPER_MAIN,
|
||||
LibraryAnalyzer.MOD_LAUNCHER_MAIN,
|
||||
LibraryAnalyzer.BOOTSTRAP_LAUNCHER_MAIN,
|
||||
LibraryAnalyzer.FORGE_BOOTSTRAP_MAIN
|
||||
));
|
||||
|
||||
public static final VersionRange<VersionNumber> FORGE_OPTIFINE_BROKEN_RANGE = VersionNumber.between("48.0.0", "49.0.50");
|
||||
|
||||
public static final String[] FORGE_TWEAKERS = new String[]{
|
||||
"net.minecraftforge.legacy._1_5_2.LibraryFixerTweaker", // 1.5.2
|
||||
|
@ -76,7 +76,9 @@ public class MaintainTask extends Task<Version> {
|
||||
}
|
||||
|
||||
List<Library> libraries = version.getLibraries();
|
||||
if (libraries.size() > 0) {
|
||||
if (!libraries.isEmpty()) {
|
||||
// HMCL once use log4j-patch to prevent virus. But now, we only modify log4j2.xml.
|
||||
// Therefore, we remove this library.
|
||||
Library library = libraries.get(0);
|
||||
if ("org.glavo".equals(library.getGroupId())
|
||||
&& ("log4j-patch".equals(library.getArtifactId()) || "log4j-patch-beta9".equals(library.getArtifactId()))
|
||||
@ -161,8 +163,8 @@ public class MaintainTask extends Task<Version> {
|
||||
Path libraryPath = repository.getLibraryFile(version, hmclTransformerDiscoveryService).toPath();
|
||||
try (InputStream input = MaintainTask.class.getResourceAsStream("/assets/game/HMCLTransformerDiscoveryService-1.0.jar")) {
|
||||
Files.createDirectories(libraryPath.getParent());
|
||||
Files.copy(input, libraryPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
Files.copy(Objects.requireNonNull(input, "Bundled HMCLTransformerDiscoveryService is missing."), libraryPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException | NullPointerException e) {
|
||||
LOG.warning("Unable to unpack HMCLTransformerDiscoveryService", e);
|
||||
}
|
||||
});
|
||||
@ -282,13 +284,6 @@ public class MaintainTask extends Task<Version> {
|
||||
return version.setLibraries(libraries.stream().filter(Objects::nonNull).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public static boolean isPurePatched(Version version) {
|
||||
if (!version.isResolvedPreservingPatches())
|
||||
throw new IllegalArgumentException("isPurePatched requires a version resolved preserving patches");
|
||||
|
||||
return version.hasPatch("game");
|
||||
}
|
||||
|
||||
public static Version unique(Version version) {
|
||||
List<Library> libraries = new ArrayList<>();
|
||||
|
||||
|
@ -102,18 +102,10 @@ public final class ForgeInstallTask extends Task<Version> {
|
||||
String originalMainClass = version.resolve(dependencyManager.getGameRepository()).getMainClass();
|
||||
if (GameVersionNumber.compare("1.13", remote.getGameVersion()) <= 0) {
|
||||
// Forge 1.13 is not compatible with fabric.
|
||||
if (!LibraryAnalyzer.VANILLA_MAIN.equals(originalMainClass)
|
||||
&& !LibraryAnalyzer.MOD_LAUNCHER_MAIN.equals(originalMainClass)
|
||||
&& !LibraryAnalyzer.LAUNCH_WRAPPER_MAIN.equals(originalMainClass)
|
||||
&& !LibraryAnalyzer.BOOTSTRAP_LAUNCHER_MAIN.equals(originalMainClass))
|
||||
if (!LibraryAnalyzer.FORGE_OPTIFINE_MAIN.contains(originalMainClass))
|
||||
throw new UnsupportedInstallationException(UNSUPPORTED_LAUNCH_WRAPPER);
|
||||
} else {
|
||||
// Forge 1.12 and older versions is compatible with vanilla and launchwrapper.
|
||||
// if (!"net.minecraft.client.main.Main".equals(originalMainClass) && !"net.minecraft.launchwrapper.Launch".equals(originalMainClass))
|
||||
// throw new OptiFineInstallTask.UnsupportedOptiFineInstallationException();
|
||||
}
|
||||
|
||||
|
||||
if (detectForgeInstallerType(dependencyManager, version, installer))
|
||||
dependency = new ForgeNewInstallTask(dependencyManager, version, remote.getSelfVersion(), installer);
|
||||
else
|
||||
|
@ -18,15 +18,21 @@
|
||||
package org.jackhuang.hmcl.download.game;
|
||||
|
||||
import org.jackhuang.hmcl.download.AbstractDependencyManager;
|
||||
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||
import org.jackhuang.hmcl.game.GameRepository;
|
||||
import org.jackhuang.hmcl.game.Library;
|
||||
import org.jackhuang.hmcl.game.Version;
|
||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||
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.versioning.GameVersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -81,20 +87,23 @@ public final class GameLibrariesTask extends Task<Void> {
|
||||
File file = gameRepository.getLibraryFile(version, library);
|
||||
Path jar = file.toPath();
|
||||
if (!file.isFile()) return true;
|
||||
|
||||
if (!integrityCheck) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (integrityCheck && !library.getDownload().validateChecksum(jar, true)) return true;
|
||||
if (integrityCheck &&
|
||||
library.getChecksums() != null && !library.getChecksums().isEmpty() &&
|
||||
!LibraryDownloadTask.checksumValid(file, library.getChecksums())) return true;
|
||||
if (integrityCheck) {
|
||||
String ext = FileUtils.getExtension(file);
|
||||
if (ext.equals("jar")) {
|
||||
try {
|
||||
FileDownloadTask.ZIP_INTEGRITY_CHECK_HANDLER.checkIntegrity(jar, jar);
|
||||
} catch (IOException ignored) {
|
||||
// the Jar file is malformed, so re-download it.
|
||||
return true;
|
||||
}
|
||||
if (!library.getDownload().validateChecksum(jar, true)) {
|
||||
return true;
|
||||
}
|
||||
if (library.getChecksums() != null && !library.getChecksums().isEmpty() && !LibraryDownloadTask.checksumValid(file, library.getChecksums())) {
|
||||
return true;
|
||||
}
|
||||
if (FileUtils.getExtension(file).equals("jar")) {
|
||||
try {
|
||||
FileDownloadTask.ZIP_INTEGRITY_CHECK_HANDLER.checkIntegrity(jar, jar);
|
||||
} catch (IOException ignored) {
|
||||
// the Jar file is malformed, so re-download it.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@ -105,16 +114,32 @@ public final class GameLibrariesTask extends Task<Void> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
libraries.stream().filter(Library::appliesToCurrentEnvironment).forEach(library -> {
|
||||
File file = dependencyManager.getGameRepository().getLibraryFile(version, library);
|
||||
if (shouldDownloadLibrary(dependencyManager.getGameRepository(), version, library, integrityCheck)) {
|
||||
if (library.hasDownloadURL() || !"optifine".equals(library.getGroupId()))
|
||||
dependencies.add(new LibraryDownloadTask(dependencyManager, file, library));
|
||||
public void execute() throws IOException {
|
||||
GameRepository gameRepository = dependencyManager.getGameRepository();
|
||||
for (Library library : libraries) {
|
||||
if (!library.appliesToCurrentEnvironment()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
File file = gameRepository.getLibraryFile(version, library);
|
||||
if ("optifine".equals(library.getGroupId()) && file.exists() && GameVersionNumber.asGameVersion(gameRepository.getGameVersion(version)).compareTo("1.20.4") == 0) {
|
||||
String forgeVersion = LibraryAnalyzer.analyze(version, "1.20.4")
|
||||
.getVersion(LibraryAnalyzer.LibraryType.FORGE)
|
||||
.orElse(null);
|
||||
if (forgeVersion != null && LibraryAnalyzer.FORGE_OPTIFINE_BROKEN_RANGE.contains(VersionNumber.asVersion(forgeVersion))) {
|
||||
try (FileSystem fs2 = CompressingUtils.createWritableZipFileSystem(file.toPath())) {
|
||||
Files.deleteIfExists(fs2.getPath("/META-INF/mods.toml"));
|
||||
} catch (IOException e) {
|
||||
throw new IOException("Cannot fix optifine", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shouldDownloadLibrary(gameRepository, version, library, integrityCheck) && library.hasDownloadURL()) {
|
||||
dependencies.add(new LibraryDownloadTask(dependencyManager, file, library));
|
||||
} else {
|
||||
dependencyManager.getCacheRepository().tryCacheLibrary(library, file.toPath());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -125,20 +125,23 @@ public final class OptiFineInstallTask extends Task<Version> {
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
String originalMainClass = version.resolve(dependencyManager.getGameRepository()).getMainClass();
|
||||
if (!LibraryAnalyzer.VANILLA_MAIN.equals(originalMainClass) &&
|
||||
!LibraryAnalyzer.LAUNCH_WRAPPER_MAIN.equals(originalMainClass) &&
|
||||
!LibraryAnalyzer.MOD_LAUNCHER_MAIN.equals(originalMainClass) &&
|
||||
!LibraryAnalyzer.BOOTSTRAP_LAUNCHER_MAIN.equals(originalMainClass))
|
||||
if (!LibraryAnalyzer.FORGE_OPTIFINE_MAIN.contains(originalMainClass))
|
||||
throw new UnsupportedInstallationException(UnsupportedInstallationException.UNSUPPORTED_LAUNCH_WRAPPER);
|
||||
|
||||
List<Library> libraries = new ArrayList<>(4);
|
||||
libraries.add(optiFineLibrary);
|
||||
|
||||
FileUtils.copyFile(dest, gameRepository.getLibraryFile(version, optiFineInstallerLibrary).toPath());
|
||||
Path optiFineInstallerLibraryPath = gameRepository.getLibraryFile(version, optiFineInstallerLibrary).toPath();
|
||||
FileUtils.copyFile(dest, optiFineInstallerLibraryPath);
|
||||
|
||||
try (FileSystem fs2 = CompressingUtils.createWritableZipFileSystem(optiFineInstallerLibraryPath)) {
|
||||
Files.deleteIfExists(fs2.getPath("/META-INF/mods.toml"));
|
||||
}
|
||||
|
||||
// Install launch wrapper modified by OptiFine
|
||||
boolean hasLaunchWrapper = false;
|
||||
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(dest)) {
|
||||
Path optiFineLibraryPath = gameRepository.getLibraryFile(version, optiFineLibrary).toPath();
|
||||
if (Files.exists(fs.getPath("optifine/Patcher.class"))) {
|
||||
String[] command = {
|
||||
JavaVersion.fromCurrentEnvironment().getBinary().toString(),
|
||||
@ -147,13 +150,17 @@ public final class OptiFineInstallTask extends Task<Version> {
|
||||
"optifine.Patcher",
|
||||
gameRepository.getVersionJar(version).getAbsolutePath(),
|
||||
dest.toString(),
|
||||
gameRepository.getLibraryFile(version, optiFineLibrary).toString()
|
||||
optiFineLibraryPath.toString()
|
||||
};
|
||||
int exitCode = SystemUtils.callExternalProcess(command);
|
||||
if (exitCode != 0)
|
||||
throw new IOException("OptiFine patcher failed, command: " + new CommandBuilder().addAll(Arrays.asList(command)));
|
||||
} else {
|
||||
FileUtils.copyFile(dest, gameRepository.getLibraryFile(version, optiFineLibrary).toPath());
|
||||
FileUtils.copyFile(dest, optiFineLibraryPath);
|
||||
}
|
||||
|
||||
try (FileSystem fs2 = CompressingUtils.createWritableZipFileSystem(optiFineLibraryPath)) {
|
||||
Files.deleteIfExists(fs2.getPath("/META-INF/mods.toml"));
|
||||
}
|
||||
|
||||
Path launchWrapper2 = fs.getPath("launchwrapper-2.0.jar");
|
||||
|
@ -295,7 +295,10 @@ public class Version implements Comparable<Version>, Validation {
|
||||
}
|
||||
}
|
||||
|
||||
if (patches != null && !patches.isEmpty()) {
|
||||
if (patches == null) {
|
||||
// This is a version from external launcher.
|
||||
thisVersion = thisVersion.merge(this, true);
|
||||
} else if (!patches.isEmpty()) {
|
||||
// Assume patches themselves do not have patches recursively.
|
||||
List<Version> sortedPatches = patches.stream()
|
||||
.sorted(Comparator.comparing(Version::getPriority))
|
||||
|
Loading…
x
Reference in New Issue
Block a user