diff --git a/build.gradle b/build.gradle index 39d82af..d1dfebe 100644 --- a/build.gradle +++ b/build.gradle @@ -5,16 +5,14 @@ apply plugin: "idea" sourceCompatibility = targetCompatibility = 1.8 -version = "1.3.1" +version = "1.4.0" group = "io.github.zekerzhayard" archivesBaseName = rootProject.name repositories { - mavenCentral() - jcenter() maven { name = "forge" - url = "https://files.minecraftforge.net/maven" + url = "https://files.minecraftforge.net/maven/" } } diff --git a/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Converter.java b/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Converter.java index 060ef77..983310a 100644 --- a/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Converter.java +++ b/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Converter.java @@ -10,6 +10,7 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.Enumeration; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -24,12 +25,13 @@ import com.google.gson.JsonParser; import io.github.zekerzhayard.forgewrapper.Utils; public class Converter { - public static void convert(Path installerPath, Path targetDir, String cursepack) throws Exception { + public static void convert(Path installerPath, Path targetDir, Path multimcDir, String cursepack) throws Exception { if (cursepack != null) { installerPath = getForgeInstallerFromCursePack(cursepack); } JsonObject installer = getJsonFromZip(installerPath, "version.json"); + JsonObject installProfile = getJsonFromZip(installerPath, "install_profile.json"); List arguments = getAdditionalArgs(installer); String mcVersion = arguments.get(arguments.indexOf("--fml.mcVersion") + 1); String forgeVersion = arguments.get(arguments.indexOf("--fml.forgeVersion") + 1); @@ -38,7 +40,7 @@ public class Converter { StringBuilder wrapperVersion = new StringBuilder(); JsonObject pack = convertPackJson(mcVersion); - JsonObject patches = convertPatchesJson(installer, mcVersion, forgeVersion, wrapperVersion, cursepack); + JsonObject patches = convertPatchesJson(installer, installProfile, mcVersion, forgeVersion, wrapperVersion, cursepack); Files.createDirectories(targetDir); @@ -71,10 +73,12 @@ public class Converter { } } - // Copy forge installer to /.minecraft/.forgewrapper folder. - Path forgeWrapperPath = minecraftPath.resolve(".forgewrapper"); - Files.createDirectories(forgeWrapperPath); - Files.copy(installerPath, forgeWrapperPath.resolve(forgeFullVersion + "-installer.jar"), StandardCopyOption.REPLACE_EXISTING); + // Copy forge installer to MultiMC/libraries/net/minecraftforge/forge/- folder. + if (multimcDir != null) { + Path targetInstallerPath = multimcDir.resolve("net").resolve("minecraftforge").resolve("forge").resolve(forgeVersion); + Files.createDirectories(targetInstallerPath); + Files.copy(installerPath, targetInstallerPath.resolve(forgeFullVersion + "-installer.jar"), StandardCopyOption.REPLACE_EXISTING); + } } public static List getAdditionalArgs(JsonObject installer) { @@ -138,13 +142,18 @@ public class Converter { // - Add libraries // - Add forge-launcher url // - Replace Minecraft & Forge versions - private static JsonObject convertPatchesJson(JsonObject installer, String mcVersion, String forgeVersion, StringBuilder wrapperVersion, String cursepack) { + private static JsonObject convertPatchesJson(JsonObject installer, JsonObject installProfile, String mcVersion, String forgeVersion, StringBuilder wrapperVersion, String cursepack) { JsonObject patches = new JsonParser().parse(new InputStreamReader(Converter.class.getResourceAsStream("/patches/net.minecraftforge.json"))).getAsJsonObject(); + JsonArray mavenFiles = getElement(patches, "mavenFiles").getAsJsonArray(); JsonArray libraries = getElement(patches, "libraries").getAsJsonArray(); String minecraftArguments = String.join(" ", getElement(patches, "minecraftArguments").getAsString(), "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}", String.join(" ", getAdditionalArgs(installer))).trim(); patches.addProperty("minecraftArguments", minecraftArguments); + for (JsonElement mavenFile : mavenFiles) { + String name = getElement(mavenFile.getAsJsonObject(), "name").getAsString(); + mavenFile.getAsJsonObject().addProperty("name", name.replace("{VERSION}", mcVersion).replace("{FORGE_VERSION}", forgeVersion)); + } for (JsonElement lib : libraries) { String name = getElement(lib.getAsJsonObject(), "name").getAsString(); if (name.startsWith("io.github.zekerzhayard:ForgeWrapper:")) { @@ -157,14 +166,13 @@ public class Converter { cursepacklocator.addProperty("url", "https://files.minecraftforge.net/maven/"); libraries.add(cursepacklocator); } - for (JsonElement lib : getElement(installer ,"libraries").getAsJsonArray()) { - JsonObject artifact = getElement(getElement(lib.getAsJsonObject(), "downloads").getAsJsonObject(), "artifact").getAsJsonObject(); - String path = getElement(artifact, "path").getAsString(); - if (path.equals(String.format("net/minecraftforge/forge/%s-%s/forge-%s-%s.jar", mcVersion, forgeVersion, mcVersion, forgeVersion))) { - artifact.getAsJsonObject().addProperty("url", "https://files.minecraftforge.net/maven/" + path.replace(".jar", "-launcher.jar")); - } - libraries.add(lib); - } + Map additionalUrls = new HashMap<>(); + String path = String.format("net/minecraftforge/forge/%s-%s/forge-%s-%s", mcVersion, forgeVersion, mcVersion, forgeVersion); + additionalUrls.put(path + "-universal.jar", "https://files.minecraftforge.net/maven/" + path + "-universal.jar"); + transformLibraries(getElement(installProfile, "libraries").getAsJsonArray(), mavenFiles, additionalUrls); + additionalUrls.clear(); + additionalUrls.put(path + ".jar", "https://files.minecraftforge.net/maven/" + path + "-launcher.jar"); + transformLibraries(getElement(installer ,"libraries").getAsJsonArray(), libraries, additionalUrls); patches.addProperty("version", forgeVersion); for (JsonElement require : getElement(patches, "requires").getAsJsonArray()) { @@ -183,4 +191,15 @@ public class Converter { } return JsonNull.INSTANCE; } + + private static void transformLibraries(JsonArray source, JsonArray target, Map additionalUrls) { + for (JsonElement lib : source) { + JsonObject artifact = getElement(getElement(lib.getAsJsonObject(), "downloads").getAsJsonObject(), "artifact").getAsJsonObject(); + String path = getElement(artifact, "path").getAsString(); + if (additionalUrls.containsKey(path)) { + artifact.getAsJsonObject().addProperty("url", additionalUrls.get(path)); + } + target.add(lib); + } + } } diff --git a/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Main.java b/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Main.java index 0b4d736..312f9c3 100644 --- a/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Main.java +++ b/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Main.java @@ -10,7 +10,7 @@ import io.github.zekerzhayard.forgewrapper.Utils; public class Main { public static void main(String[] args) { - Path installer = null, instance = Paths.get("."); + Path installer = null, instance = Paths.get("."), multimc = null; String cursepack = null; try { HashMap argsMap = parseArgs(args); @@ -22,6 +22,7 @@ public class Main { } if (argsMap.containsKey("--instance")) { instance = Paths.get(argsMap.get("--instance")); + multimc = instance.getParent(); } if (argsMap.containsKey("--cursepack")) { cursepack = argsMap.get("--cursepack"); @@ -36,7 +37,7 @@ public class Main { Converter.class.getProtectionDomain().getCodeSource().getLocation(), installer.toUri().toURL() }, null); - ucl.loadClass("io.github.zekerzhayard.forgewrapper.converter.Converter").getMethod("convert", Path.class, Path.class, String.class).invoke(null, installer, instance, cursepack); + ucl.loadClass("io.github.zekerzhayard.forgewrapper.converter.Converter").getMethod("convert", Path.class, Path.class, Path.class, String.class).invoke(null, installer, instance, multimc, cursepack); System.out.println("Successfully install Forge for MultiMC!"); } catch (Exception e) { System.out.println("Failed to install Forge!"); diff --git a/src/main/java/io/github/zekerzhayard/forgewrapper/installer/ClientInstall4MultiMC.java b/src/main/java/io/github/zekerzhayard/forgewrapper/installer/ClientInstall4MultiMC.java index dbe8daf..f2db374 100644 --- a/src/main/java/io/github/zekerzhayard/forgewrapper/installer/ClientInstall4MultiMC.java +++ b/src/main/java/io/github/zekerzhayard/forgewrapper/installer/ClientInstall4MultiMC.java @@ -3,7 +3,6 @@ package io.github.zekerzhayard.forgewrapper.installer; import java.io.File; import java.util.function.Predicate; -import net.minecraftforge.installer.actions.ActionCanceledException; import net.minecraftforge.installer.actions.ClientInstall; import net.minecraftforge.installer.actions.ProgressCallback; import net.minecraftforge.installer.json.Install; @@ -17,16 +16,6 @@ public class ClientInstall4MultiMC extends ClientInstall { public boolean run(File target, Predicate optionals) { File librariesDir = Main.getLibrariesDir(); File clientTarget = new File(String.format("%s/com/mojang/minecraft/%s/minecraft-%s-client.jar", librariesDir.getAbsolutePath(), this.profile.getMinecraft(), this.profile.getMinecraft())); - - boolean downloadLibraries = true; // Force true when without an internet connection. - try { - downloadLibraries = this.downloadLibraries(librariesDir, optionals); - } catch (ActionCanceledException e) { - e.printStackTrace(); - } - if (!downloadLibraries) { - return false; - } return this.processors.process(librariesDir, clientTarget); } } diff --git a/src/main/java/io/github/zekerzhayard/forgewrapper/installer/Main.java b/src/main/java/io/github/zekerzhayard/forgewrapper/installer/Main.java index cd70fac..f9d534c 100644 --- a/src/main/java/io/github/zekerzhayard/forgewrapper/installer/Main.java +++ b/src/main/java/io/github/zekerzhayard/forgewrapper/installer/Main.java @@ -11,25 +11,23 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import cpw.mods.modlauncher.Launcher; -import io.github.zekerzhayard.forgewrapper.Utils; public class Main { public static void main(String[] args) throws Exception { List argsList = Stream.of(args).collect(Collectors.toList()); - String version = argsList.get(argsList.indexOf("--fml.mcVersion") + 1) + "-" + argsList.get(argsList.indexOf("--fml.forgeVersion") + 1); - - Path forgeDir = getLibrariesDir().toPath().resolve("net").resolve("minecraftforge").resolve("forge").resolve(version); - Path clientJar = forgeDir.resolve("forge-" + version + "-client.jar"); - Path extraJar = forgeDir.resolve("forge-" + version + "-extra.jar"); - if (Files.exists(clientJar) && Files.exists(extraJar)) { - String installerUrl = String.format("https://files.minecraftforge.net/maven/net/minecraftforge/forge/%s/forge-%s-installer.jar", version, version); - String installerFileStr = String.format("./.forgewrapper/forge-%s-installer.jar", version); - Utils.download(installerUrl, installerFileStr); + String mcVersion = argsList.get(argsList.indexOf("--fml.mcVersion") + 1); + String mcpFullVersion = mcVersion + "-" + argsList.get(argsList.indexOf("--fml.mcpVersion") + 1); + String forgeFullVersion = mcVersion + "-" + argsList.get(argsList.indexOf("--fml.forgeVersion") + 1); + Path librariesDir = getLibrariesDir().toPath(); + Path minecraftDir = librariesDir.resolve("net").resolve("minecraft").resolve("client"); + Path forgeDir = librariesDir.resolve("net").resolve("minecraftforge").resolve("forge").resolve(forgeFullVersion); + if (getAdditionalLibraries(minecraftDir, forgeDir, mcVersion, forgeFullVersion, mcpFullVersion).anyMatch(path -> !Files.exists(path))) { + System.out.println("Some extra libraries are missing! Run installer to spawn them now."); URLClassLoader ucl = URLClassLoader.newInstance(new URL[] { Main.class.getProtectionDomain().getCodeSource().getLocation(), Launcher.class.getProtectionDomain().getCodeSource().getLocation(), - new File(installerFileStr).toURI().toURL() + forgeDir.resolve("forge-" + forgeFullVersion + "-installer.jar").toUri().toURL() }, null); Class installer = ucl.loadClass("io.github.zekerzhayard.forgewrapper.installer.Installer"); @@ -44,11 +42,18 @@ public class Main { public static File getLibrariesDir() { try { File laucnher = new File(Launcher.class.getProtectionDomain().getCodeSource().getLocation().toURI()); - // see https://github.com/MinecraftForge/MinecraftForge/blob/863ab2ca184cf2e2dfa134d07bfc20d6a9a6a4e8/src/main/java/net/minecraftforge/fml/relauncher/libraries/LibraryManager.java#L151 // / /modlauncher /mods /cpw /libraries return laucnher.getParentFile().getParentFile().getParentFile().getParentFile().getParentFile(); } catch (URISyntaxException e) { throw new RuntimeException(e); } } + + public static Stream getAdditionalLibraries(Path minecraftDir, Path forgeDir, String mcVersion, String forgeFullVersion, String mcpFullVersion) { + return Stream.of( + forgeDir.resolve("forge-" + forgeFullVersion + "-client.jar"), + minecraftDir.resolve(mcVersion).resolve("client-" + mcVersion + "-extra.jar"), + minecraftDir.resolve(mcpFullVersion).resolve("client-" + mcpFullVersion + "-srg.jar") + ); + } } diff --git a/src/main/resources/patches/net.minecraftforge.json b/src/main/resources/patches/net.minecraftforge.json index 1add737..d170dd2 100644 --- a/src/main/resources/patches/net.minecraftforge.json +++ b/src/main/resources/patches/net.minecraftforge.json @@ -12,9 +12,15 @@ "type": "release", "uid": "net.minecraftforge", "version": "{FORGE_VERSION}", + "mavenFiles": [ + { + "name": "net.minecraftforge:forge:{VERSION}-{FORGE_VERSION}:installer", + "url": "https://files.minecraftforge.net/maven/" + } + ], "libraries": [ { - "name": "io.github.zekerzhayard:Forge-Wrapper:${version}", + "name": "io.github.zekerzhayard:ForgeWrapper:${version}", "MMC-hint": "local", "MMC-filename": "ForgeWrapper-${version}.jar" }