diff --git a/.gitignore b/.gitignore index 760c29d96..5e6b85816 100644 --- a/.gitignore +++ b/.gitignore @@ -17,17 +17,20 @@ NVIDIA /build/ /HMCL/build/ /HMCLCore/build/ +/HMCLTransformerDiscoveryService/build/ # idea .idea /out/ /HMCL/out/ /HMCLCore/out/ +/HMCLTransformerDiscoveryService/out/ # eclipse /bin/ /HMCL/bin/ /HMCLCore/bin/ +/HMCLTransformerDiscoveryService/bin/ .classpath .project .settings diff --git a/HMCL/build.gradle b/HMCL/build.gradle index 16d1bdb20..917cf3bfa 100644 --- a/HMCL/build.gradle +++ b/HMCL/build.gradle @@ -1,3 +1,9 @@ +buildscript { + dependencies { + classpath 'org.tukaani:xz:1.8' + } +} + plugins { id 'com.github.johnrengelman.shadow' version '4.0.0' id 'application' @@ -77,7 +83,7 @@ def repack(File file) { jar { manifest { - attributes 'Created-By': 'Copyright(c) 2013-2018 huangyuhui.', + attributes 'Created-By': 'Copyright(c) 2013-2020 huangyuhui.', 'Main-Class': mainClassName, 'Multi-Release': 'true', 'Implementation-Version': version diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java index b6789d7d5..a6181ddbf 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java @@ -20,6 +20,7 @@ package org.jackhuang.hmcl.game; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import javafx.scene.image.Image; +import org.jackhuang.hmcl.download.LibraryAnalyzer; import org.jackhuang.hmcl.mod.Modpack; import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.setting.VersionSetting; @@ -218,9 +219,9 @@ public class HMCLGameRepository extends DefaultGameRepository { if (iconFile.exists()) return new Image("file:" + iconFile.getAbsolutePath()); else if (version.getMainClass() != null && - ("net.minecraft.launchwrapper.Launch".equals(version.getMainClass()) + (LibraryAnalyzer.LAUNCH_WRAPPER_MAIN.equals(version.getMainClass()) || version.getMainClass().startsWith("net.fabricmc") - || "cpw.mods.modlauncher.Launcher".equals(version.getMainClass()))) + || LibraryAnalyzer.MOD_LAUNCHER_MAIN.equals(version.getMainClass()))) return newImage("/assets/img/furnace.png"); else return newImage("/assets/img/grass.png"); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java index fa78440e8..b5706a924 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java @@ -23,6 +23,7 @@ import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.auth.*; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorDownloadException; import org.jackhuang.hmcl.download.DefaultDependencyManager; +import org.jackhuang.hmcl.download.LibraryAnalyzer; import org.jackhuang.hmcl.download.MaintainTask; import org.jackhuang.hmcl.download.game.GameAssetIndexDownloadTask; import org.jackhuang.hmcl.download.game.LibraryDownloadException; @@ -330,7 +331,7 @@ public final class LauncherHelper { // LaunchWrapper 1.12 will crash because of assuming the system class loader is an instance of URLClassLoader. if (!flag && java.getParsedVersion() >= JavaVersion.JAVA_9_AND_LATER - && version.getMainClass().contains("launchwrapper") + && version.getMainClass().equals(LibraryAnalyzer.LAUNCH_WRAPPER_MAIN) && version.getLibraries().stream() .filter(library -> "launchwrapper".equals(library.getArtifactId())) .anyMatch(library -> VersionNumber.asVersion(library.getVersion()).compareTo(VersionNumber.asVersion("1.13")) < 0)) { @@ -421,6 +422,18 @@ public final class LauncherHelper { } } + // OptiFine 1.14.4 is not compatible with Forge 28.2.2 and later versions. + if (!flag) { + boolean hasForge28_2_2 = version.getLibraries().stream().filter(it -> it.is("net.minecraftforge", "forge")) + .anyMatch(it -> + VersionNumber.VERSION_COMPARATOR.compare("1.14.4-28.2.2", it.getVersion()) <= 0); + boolean hasOptiFine = version.getLibraries().stream().anyMatch(it -> it.is("optifine", "OptiFine")); + if (hasForge28_2_2 && hasOptiFine && gameVersion.compareTo(VersionNumber.asVersion("1.14.4")) == 0) { + Controllers.confirm(i18n("launch.advice.forge28_2_2_optifine"), i18n("message.error"), onAccept, null); + flag = true; + } + } + if (!flag) onAccept.run(); } diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index b1358b5d3..706e0ba9e 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -169,6 +169,7 @@ launch.advice.corrected=We have already fixed the JVM selection. If you want to launch.advice.uncorrected=If you are sure that the game can be started normally, you can disable the Java VM check in game settings. launch.advice.different_platform=Your OS is 64-Bit but your Java is 32-Bit. The 64-Bit Java is recommended. launch.advice.forge2760_liteloader=Forge 2760 and higher are not compatible with LiteLoader, please consider upgrading Forge to 2773 or later. Shall we continue launching? +launch.advice.forge28_2_2_optifine=Forge 28.2.2 and later versions are not compatible with OptiFine. Please consider downgrading Forge to 28.2.1 or earlier versions. Shall we continue launching? launch.advice.java8_1_13=Minecraft 1.13 and later can only run on Java 8 or later. launch.advice.java8_51_1_13=Minecraft 1.13 may crash on Java 8 earlier than 1.8.0_51. Please install the latest version of Java 8. launch.advice.java9=You cannot launch Minecraft 1.12 or earlier with Java 9 or later versions of Java. diff --git a/HMCL/src/main/resources/assets/lang/I18N_es.properties b/HMCL/src/main/resources/assets/lang/I18N_es.properties index c29131074..7e6452fe1 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_es.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_es.properties @@ -165,6 +165,7 @@ launch.advice.corrected=Ya hemos corregido la selección de JVM y el juego puede launch.advice.uncorrected=Si está seguro que el juego puede ser lanzado normalmente, puede deshabilitar el Java VM checker en la configuración del juego. launch.advice.different_platform=Su SO es 64-Bit pero su Java es 32-Bit. 64-Bit Java es recomendado. launch.advice.forge2760_liteloader=Forge 2760 y posterior no es compatible con LiteLoader, considere actualizando Forge a 2773 o más. +launch.advice.forge28_2_2_optifine=Forge 28.2.2 and later versions are not compatible with OptiFine. Please consider downgrading Forge to 28.2.1 or earlier versions. Shall we continue launching? launch.advice.java8_1_13=Minecraft 1.13 y posterior sólo pueden correr en Java 8 o luego. launch.advice.java8_51_1_13=Minecraft 1.13 puediera fallar en Java 8 anterior 1.8.0_51. Debe instalar la versión de Java 8 más reciente. launch.advice.java9=No puedes lanzar Minecraft hasta que su versión de juego sea más allá de 1.13 con Java 9 o posterior. diff --git a/HMCL/src/main/resources/assets/lang/I18N_ru.properties b/HMCL/src/main/resources/assets/lang/I18N_ru.properties index de720a3f5..122945d36 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ru.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ru.properties @@ -169,6 +169,7 @@ launch.advice.corrected=Мы уже исправили выбор JVMЕ. Есл launch.advice.uncorrected=Если вы уверены, что игра запускается нормально, то можете отключить проверку Java VM в настройках игры. launch.advice.different_platform=Ваша ОС 64-битная, а ваша Java 32-битная. Рекомендуется использовать 64-битный Java. launch.advice.forge2760_liteloader=Forge 2760 и выше не совместимы с LiteLoader, рассмотрите возможность обновления Forge до 2773 или более поздней версии. +launch.advice.forge28_2_2_optifine=Forge 28.2.2 and later versions are not compatible with OptiFine. Please consider downgrading Forge to 28.2.1 or earlier versions. Shall we continue launching? launch.advice.java8_1_13=Minecraft 1.13 и выше может работать только на Java 8 или более поздней версии. launch.advice.java8_51_1_13=У Minecraft 1.13 может произойти сбой на Java 8 меньше, чем 1.8.0_51. Установите последнюю версию Java 8. launch.advice.java9=Вы не можете запустить Minecraft 1.12 или более ранней версии с Java 9 или более новых версий Java. diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index e2bf3f512..034b1f0a3 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -169,6 +169,7 @@ launch.advice.corrected=我們已經修正了問題。如果您確實希望使 launch.advice.uncorrected=如果您確實希望使用您自訂的 Java 虛擬機,您可以在遊戲設定中關閉 Java 虛擬機相容性檢查。 launch.advice.different_platform=您的系統為 64 位元,但是 Java 是 32 位元,建議您安裝 64 位 Java。 launch.advice.forge2760_liteloader=Forge 2760 與 LiteLoader 不相容。請刪除 LiteLoader 或者變更 Forge 至 2773 或更新的版本。是否繼續啟動? +launch.advice.forge28_2_2_optifine=Forge 28.2.2 或更高版本與 OptiFine 不相容。請變更 Forge 至 28.2.1 或更低版本。是否繼續啟動? launch.advice.java8_1_13=Minecraft 1.13 只支援 Java 8 或更高版本,請使用 Java 8 或最新版本。 launch.advice.java8_51_1_13=低於 1.8.0_51 的 Java 版本可能會導致 Minecraft 1.13 崩潰。建議您到 https://java.com 安裝最新版的 Java 8。 launch.advice.java9=低於 (包含) 1.13 的有安裝 Mod 的 Minecraft 版本不支援 Java 9 或更高版本,請使用 Java 8。 diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index e6b2b639f..f33e891f1 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -169,6 +169,7 @@ launch.advice.corrected=我们已经修复了问题。如果您确实希望使 launch.advice.uncorrected=如果您确实希望使用您自定义的 Java 虚拟机,您可以在游戏设置中关闭 Java 虚拟机兼容性检查。 launch.advice.different_platform=您的系统是 64 位,但是 Java 是 32 位的,建议您安装 64 位 Java。 launch.advice.forge2760_liteloader=Forge 2760 与 LiteLoader 不兼容。请删除 LiteLoader 或者更换 Forge 至 2773 或更新的版本。是否继续启动? +launch.advice.forge28_2_2_optifine=Forge 28.2.2 或更高版本与 OptiFine 不兼容。请更换 Forge 至 28.2.1 或更低版本。是否继续启动? launch.advice.java8_1_13=Minecraft 1.13 只支持 Java 8 或更高版本,请使用 Java 8 或最新版本。 launch.advice.java8_51_1_13=低于 1.8.0_51 的 Java 版本可能会导致 Minecraft 1.13 崩溃。建议您到 https://java.com 安装最新版的 Java 8。 launch.advice.java9=低于 1.13 的有安装 Mod 的 Minecraft 版本不支持 Java 9 或更高版本,请使用 Java 8。 diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/LibraryAnalyzer.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/LibraryAnalyzer.java index 248622673..d7f2ac419 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/LibraryAnalyzer.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/LibraryAnalyzer.java @@ -198,4 +198,8 @@ public final class LibraryAnalyzer implements Iterable { private final GameRepository repository; @@ -60,13 +64,15 @@ public class MaintainTask extends Task { String mainClass = version.resolve(null).getMainClass(); - if (mainClass != null && mainClass.contains("launchwrapper")) { - return maintainOptiFineLibrary(repository, maintainGameWithLaunchWrapper(unique(version), true)); + if (mainClass != null && mainClass.equals(LibraryAnalyzer.LAUNCH_WRAPPER_MAIN)) { + return maintainOptiFineLibrary(repository, maintainGameWithLaunchWrapper(unique(version), true), false); + } else if (mainClass != null && mainClass.equals(LibraryAnalyzer.MOD_LAUNCHER_MAIN)) { + // Forge 1.13 and OptiFine + return maintainOptiFineLibrary(repository, maintainGameWithModLauncher(repository, unique(version)), true); } else { // Vanilla Minecraft does not need maintain - // Forge 1.13 support not implemented, not compatible with OptiFine currently. // Fabric does not need maintain, nothing compatible with fabric now. - return maintainOptiFineLibrary(repository, unique(version)); + return maintainOptiFineLibrary(repository, unique(version), false); } } @@ -116,7 +122,34 @@ public class MaintainTask extends Task { return mainClass == null ? ret : ret.setMainClass(mainClass); } - private static Version maintainOptiFineLibrary(GameRepository repository, Version version) { + private static Version maintainGameWithModLauncher(GameRepository repository, Version version) { + LibraryAnalyzer libraryAnalyzer = LibraryAnalyzer.analyze(version); + VersionLibraryBuilder builder = new VersionLibraryBuilder(version); + + if (!libraryAnalyzer.has(FORGE)) return version; + + if (libraryAnalyzer.has(OPTIFINE)) { + Library hmclTransformerDiscoveryService = new Library(new Artifact("org.jackhuang.hmcl", "transformer-discovery-service", "1.0")); + Optional optiFine = version.getLibraries().stream().filter(library -> library.is("optifine", "OptiFine")).findAny(); + boolean libraryExisting = version.getLibraries().stream().anyMatch(library -> library.is("org.jackhuang.hmcl", "transformer-discovery-service")); + optiFine.ifPresent(library -> { + builder.addJvmArgument("-Dhmcl.transformer.candidates=${libraries_directory}/" + library.getPath()); + if (!libraryExisting) builder.addLibrary(hmclTransformerDiscoveryService); + Path libraryPath = repository.getLibraryFile(version, hmclTransformerDiscoveryService).toPath(); + try { + Files.createDirectories(libraryPath.getParent()); + Files.copy(MaintainTask.class.getResourceAsStream("/assets/game/HMCLTransformerDiscoveryService-1.0.jar"), + libraryPath, StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + Logging.LOG.log(Level.WARNING, "Unable to unpack HMCLTransformerDiscoveryService", e); + } + }); + } + + return builder.build(); + } + + private static Version maintainOptiFineLibrary(GameRepository repository, Version version, boolean remove) { LibraryAnalyzer libraryAnalyzer = LibraryAnalyzer.analyze(version); List libraries = new ArrayList<>(version.getLibraries()); @@ -135,7 +168,7 @@ public class MaintainTask extends Task { // Although we have altered priority of OptiFine higher than Forge, // there still exists a situation that Forge is installed without patch. // Here we manually alter the position of OptiFine library in classpath. - libraries.add(newLibrary); + if (!remove) libraries.add(newLibrary); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeInstallTask.java index a558b65cc..943dd7e83 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeInstallTask.java @@ -19,6 +19,7 @@ package org.jackhuang.hmcl.download.forge; import org.jackhuang.hmcl.download.DefaultDependencyManager; import org.jackhuang.hmcl.download.DependencyManager; +import org.jackhuang.hmcl.download.LibraryAnalyzer; import org.jackhuang.hmcl.download.VersionMismatchException; import org.jackhuang.hmcl.download.optifine.OptiFineInstallTask; import org.jackhuang.hmcl.game.GameVersion; @@ -104,7 +105,7 @@ public final class ForgeInstallTask extends Task { String originalMainClass = version.resolve(dependencyManager.getGameRepository()).getMainClass(); if (VersionNumber.VERSION_COMPARATOR.compare("1.13", remote.getGameVersion()) <= 0) { // Forge 1.13 is not compatible with any other libraries. - if (!"net.minecraft.client.main.Main".equals(originalMainClass) && !"cpw.mods.modlauncher.Launcher".equals(originalMainClass)) + if (!LibraryAnalyzer.VANILLA_MAIN.equals(originalMainClass) && !LibraryAnalyzer.MOD_LAUNCHER_MAIN.equals(originalMainClass) && !LibraryAnalyzer.LAUNCH_WRAPPER_MAIN.equals(originalMainClass)) throw new OptiFineInstallTask.UnsupportedOptiFineInstallationException(); } else { // Forge 1.12 and older versions is compatible with vanilla and launchwrapper. diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderInstallTask.java index 1d5c38b73..5999fc6fd 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderInstallTask.java @@ -69,7 +69,7 @@ public final class LiteLoaderInstallTask extends Task { remote.getSelfVersion(), 60000, new Arguments().addGameArguments("--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker"), - "net.minecraft.launchwrapper.Launch", + LibraryAnalyzer.LAUNCH_WRAPPER_MAIN, Lang.merge(remote.getLibraries(), Collections.singleton(library))) .setLogging(Collections.emptyMap()) // Mods may log in malformed format, causing XML parser to crash. So we suppress using official log4j configuration ); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/optifine/OptiFineInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/optifine/OptiFineInstallTask.java index 8764ed495..97ab70ba5 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/optifine/OptiFineInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/optifine/OptiFineInstallTask.java @@ -121,7 +121,7 @@ public final class OptiFineInstallTask extends Task { @Override public void execute() throws Exception { String originalMainClass = version.resolve(dependencyManager.getGameRepository()).getMainClass(); - if (!"net.minecraft.client.main.Main".equals(originalMainClass) && !"net.minecraft.launchwrapper.Launch".equals(originalMainClass)) + if (!LibraryAnalyzer.VANILLA_MAIN.equals(originalMainClass) && !LibraryAnalyzer.LAUNCH_WRAPPER_MAIN.equals(originalMainClass) && !LibraryAnalyzer.MOD_LAUNCHER_MAIN.equals(originalMainClass)) throw new OptiFineInstallTask.UnsupportedOptiFineInstallationException(); List libraries = new LinkedList<>(); @@ -183,9 +183,9 @@ public final class OptiFineInstallTask extends Task { setResult(new Version( LibraryAnalyzer.LibraryType.OPTIFINE.getPatchId(), remote.getSelfVersion(), - 90000, + 10000, new Arguments().addGameArguments("--tweakClass", "optifine.OptiFineTweaker"), - "net.minecraft.launchwrapper.Launch", + LibraryAnalyzer.LAUNCH_WRAPPER_MAIN, libraries )); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java index 1824a688d..01a0255e0 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java @@ -96,12 +96,17 @@ public class DefaultGameRepository implements GameRepository { return versions.values(); } + @Override + public File getLibrariesDirectory(Version version) { + return new File(getBaseDirectory(), "libraries"); + } + @Override public File getLibraryFile(Version version, Library lib) { if ("local".equals(lib.getHint()) && lib.getFileName() != null) return new File(getVersionRoot(version.getId()), "libraries/" + lib.getFileName()); else - return new File(getBaseDirectory(), "libraries/" + lib.getPath()); + return new File(getLibrariesDirectory(version), lib.getPath()); } public Path getArtifactFile(Version version, Artifact artifact) { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/GameRepository.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/GameRepository.java index f32da6006..cefbde81a 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/GameRepository.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/GameRepository.java @@ -99,6 +99,8 @@ public interface GameRepository extends VersionProvider { */ File getRunDirectory(String id); + File getLibrariesDirectory(Version version); + /** * Get the library file in disk. * This method allows versions and libraries that are not loaded by this game repository. diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/VersionLibraryBuilder.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/VersionLibraryBuilder.java index 275944f3d..272c0aebb 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/VersionLibraryBuilder.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/VersionLibraryBuilder.java @@ -20,8 +20,7 @@ package org.jackhuang.hmcl.game; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.platform.CommandBuilder; -import java.util.ArrayList; -import java.util.List; +import java.util.*; /** * @@ -31,12 +30,17 @@ public final class VersionLibraryBuilder { private final Version version; private final List mcArgs; private final List game; + private final List jvm; + private final List libraries; private final boolean useMcArgs; + private boolean jvmChanged = false; public VersionLibraryBuilder(Version version) { this.version = version; + this.libraries = new ArrayList<>(version.getLibraries()); this.mcArgs = version.getMinecraftArguments().map(StringUtils::tokenize).map(ArrayList::new).orElse(null); this.game = version.getArguments().map(Arguments::getGame).map(ArrayList::new).orElseGet(ArrayList::new); + this.jvm = new ArrayList<>(version.getArguments().map(Arguments::getJvm).orElse(Arguments.DEFAULT_JVM_ARGUMENTS)); this.useMcArgs = mcArgs != null; } @@ -47,7 +51,10 @@ public final class VersionLibraryBuilder { // so we regenerate the minecraftArgument without escaping. ret = ret.setMinecraftArguments(new CommandBuilder().addAllWithoutParsing(mcArgs).toString()); } - return ret.setArguments(ret.getArguments().map(args -> args.withGame(game)).orElse(new Arguments(game, null))); + return ret.setArguments(ret.getArguments() + .map(args -> args.withGame(game)) + .map(args -> jvmChanged ? args.withJvm(jvm) : args).orElse(new Arguments(game, jvmChanged ? jvm : null))) + .setLibraries(libraries); } public void removeTweakClass(String target) { @@ -138,8 +145,18 @@ public final class VersionLibraryBuilder { } } - public void addArgument(String... args) { + public void addGameArgument(String... args) { for (String arg : args) game.add(new StringArgument(arg)); } + + public void addJvmArgument(String... args) { + jvmChanged = true; + for (String arg : args) + jvm.add(new StringArgument(arg)); + } + + public void addLibrary(Library library) { + libraries.add(library); + } } 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 f2d717cd0..148a6fb11 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java @@ -153,6 +153,7 @@ public class DefaultLauncher extends Launcher { configuration.put("${natives_directory}", nativeFolder.getAbsolutePath()); configuration.put("${game_assets}", gameAssets.getAbsolutePath()); configuration.put("${assets_root}", gameAssets.getAbsolutePath()); + configuration.put("${libraries_directory}", repository.getLibrariesDirectory(version).getAbsolutePath()); res.addAll(Arguments.parseArguments(version.getArguments().map(Arguments::getJvm).orElseGet(this::getDefaultJVMArguments), configuration)); if (authInfo.getArguments() != null && authInfo.getArguments().getJvm() != null && !authInfo.getArguments().getJvm().isEmpty()) diff --git a/HMCLCore/src/main/resources/assets/game/HMCLTransformerDiscoveryService-1.0.jar b/HMCLCore/src/main/resources/assets/game/HMCLTransformerDiscoveryService-1.0.jar new file mode 100644 index 000000000..3ea51be50 Binary files /dev/null and b/HMCLCore/src/main/resources/assets/game/HMCLTransformerDiscoveryService-1.0.jar differ diff --git a/HMCLTransformerDiscoveryService/bin/main/META-INF/services/cpw.mods.modlauncher.serviceapi.ITransformerDiscoveryService b/HMCLTransformerDiscoveryService/bin/main/META-INF/services/cpw.mods.modlauncher.serviceapi.ITransformerDiscoveryService new file mode 100644 index 000000000..82fc86968 --- /dev/null +++ b/HMCLTransformerDiscoveryService/bin/main/META-INF/services/cpw.mods.modlauncher.serviceapi.ITransformerDiscoveryService @@ -0,0 +1 @@ +org.jackhuang.hmcl.HMCLTransformerDiscoveryService diff --git a/HMCLTransformerDiscoveryService/build.gradle b/HMCLTransformerDiscoveryService/build.gradle new file mode 100644 index 000000000..82d65da47 --- /dev/null +++ b/HMCLTransformerDiscoveryService/build.gradle @@ -0,0 +1,12 @@ +version '1.0' + +dependencies { + compileOnly project.files("lib/modlauncher-4.1.0.jar") +} + +jar { + manifest { + attributes 'Created-By': 'Copyright(c) 2013-2020 huangyuhui.', + 'Implementation-Version': version + } +} diff --git a/HMCLTransformerDiscoveryService/lib/modlauncher-4.1.0.jar b/HMCLTransformerDiscoveryService/lib/modlauncher-4.1.0.jar new file mode 100644 index 000000000..2dd8cb64e Binary files /dev/null and b/HMCLTransformerDiscoveryService/lib/modlauncher-4.1.0.jar differ diff --git a/HMCLTransformerDiscoveryService/src/main/java/org/jackhuang/hmcl/HMCLTransformerDiscoveryService.java b/HMCLTransformerDiscoveryService/src/main/java/org/jackhuang/hmcl/HMCLTransformerDiscoveryService.java new file mode 100644 index 000000000..64d4b3dbd --- /dev/null +++ b/HMCLTransformerDiscoveryService/src/main/java/org/jackhuang/hmcl/HMCLTransformerDiscoveryService.java @@ -0,0 +1,44 @@ +/* + * Hello Minecraft! Launcher + * Copyright (C) 2020 huangyuhui 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 . + */ +package org.jackhuang.hmcl; + +import cpw.mods.modlauncher.serviceapi.ITransformerDiscoveryService; + +import java.io.File; +import java.nio.file.InvalidPathException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class HMCLTransformerDiscoveryService implements ITransformerDiscoveryService { + private static final String CANDIDATES = System.getProperty("hmcl.transformer.candidates"); + + @Override + public List candidates(Path gameDirectory) { + return Arrays.stream(CANDIDATES.split(File.pathSeparator)) + .flatMap(path -> { + try { + return Stream.of(Paths.get(path)); + } catch (InvalidPathException e) { + return Stream.of(); + } + }).collect(Collectors.toList()); + } +} diff --git a/HMCLTransformerDiscoveryService/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ITransformerDiscoveryService b/HMCLTransformerDiscoveryService/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ITransformerDiscoveryService new file mode 100644 index 000000000..82fc86968 --- /dev/null +++ b/HMCLTransformerDiscoveryService/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ITransformerDiscoveryService @@ -0,0 +1 @@ +org.jackhuang.hmcl.HMCLTransformerDiscoveryService diff --git a/build.gradle b/build.gradle index bc6c1051a..f8443b1ce 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,6 @@ buildscript { maven { url 'https://plugins.gradle.org/m2/' } } dependencies { - classpath 'org.tukaani:xz:1.8' classpath 'gradle.plugin.com.hierynomus.gradle.plugins:license-gradle-plugin:0.15.0' } } diff --git a/settings.gradle b/settings.gradle index d9fd5ba34..32100c8ff 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,5 @@ rootProject.name = 'HMCL3' include 'HMCL' include 'HMCLCore' +include 'HMCLTransformerDiscoveryService'