All libraries can be downloaded by MultiMC now.

This commit is contained in:
ZekerZhayard 2020-03-27 14:11:43 +08:00
parent 812a810acc
commit fb8888aed9
6 changed files with 63 additions and 45 deletions

View file

@ -5,16 +5,14 @@ apply plugin: "idea"
sourceCompatibility = targetCompatibility = 1.8 sourceCompatibility = targetCompatibility = 1.8
version = "1.3.1" version = "1.4.0"
group = "io.github.zekerzhayard" group = "io.github.zekerzhayard"
archivesBaseName = rootProject.name archivesBaseName = rootProject.name
repositories { repositories {
mavenCentral()
jcenter()
maven { maven {
name = "forge" name = "forge"
url = "https://files.minecraftforge.net/maven" url = "https://files.minecraftforge.net/maven/"
} }
} }

View file

@ -10,6 +10,7 @@ import java.nio.file.Paths;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -24,12 +25,13 @@ import com.google.gson.JsonParser;
import io.github.zekerzhayard.forgewrapper.Utils; import io.github.zekerzhayard.forgewrapper.Utils;
public class Converter { 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) { if (cursepack != null) {
installerPath = getForgeInstallerFromCursePack(cursepack); installerPath = getForgeInstallerFromCursePack(cursepack);
} }
JsonObject installer = getJsonFromZip(installerPath, "version.json"); JsonObject installer = getJsonFromZip(installerPath, "version.json");
JsonObject installProfile = getJsonFromZip(installerPath, "install_profile.json");
List<String> arguments = getAdditionalArgs(installer); List<String> arguments = getAdditionalArgs(installer);
String mcVersion = arguments.get(arguments.indexOf("--fml.mcVersion") + 1); String mcVersion = arguments.get(arguments.indexOf("--fml.mcVersion") + 1);
String forgeVersion = arguments.get(arguments.indexOf("--fml.forgeVersion") + 1); String forgeVersion = arguments.get(arguments.indexOf("--fml.forgeVersion") + 1);
@ -38,7 +40,7 @@ public class Converter {
StringBuilder wrapperVersion = new StringBuilder(); StringBuilder wrapperVersion = new StringBuilder();
JsonObject pack = convertPackJson(mcVersion); JsonObject pack = convertPackJson(mcVersion);
JsonObject patches = convertPatchesJson(installer, mcVersion, forgeVersion, wrapperVersion, cursepack); JsonObject patches = convertPatchesJson(installer, installProfile, mcVersion, forgeVersion, wrapperVersion, cursepack);
Files.createDirectories(targetDir); Files.createDirectories(targetDir);
@ -71,10 +73,12 @@ public class Converter {
} }
} }
// Copy forge installer to <instance>/.minecraft/.forgewrapper folder. // Copy forge installer to MultiMC/libraries/net/minecraftforge/forge/<mcVersion>-<forgeVersion> folder.
Path forgeWrapperPath = minecraftPath.resolve(".forgewrapper"); if (multimcDir != null) {
Files.createDirectories(forgeWrapperPath); Path targetInstallerPath = multimcDir.resolve("net").resolve("minecraftforge").resolve("forge").resolve(forgeVersion);
Files.copy(installerPath, forgeWrapperPath.resolve(forgeFullVersion + "-installer.jar"), StandardCopyOption.REPLACE_EXISTING); Files.createDirectories(targetInstallerPath);
Files.copy(installerPath, targetInstallerPath.resolve(forgeFullVersion + "-installer.jar"), StandardCopyOption.REPLACE_EXISTING);
}
} }
public static List<String> getAdditionalArgs(JsonObject installer) { public static List<String> getAdditionalArgs(JsonObject installer) {
@ -138,13 +142,18 @@ public class Converter {
// - Add libraries // - Add libraries
// - Add forge-launcher url // - Add forge-launcher url
// - Replace Minecraft & Forge versions // - 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(); 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(); 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(); 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); 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) { for (JsonElement lib : libraries) {
String name = getElement(lib.getAsJsonObject(), "name").getAsString(); String name = getElement(lib.getAsJsonObject(), "name").getAsString();
if (name.startsWith("io.github.zekerzhayard:ForgeWrapper:")) { if (name.startsWith("io.github.zekerzhayard:ForgeWrapper:")) {
@ -157,14 +166,13 @@ public class Converter {
cursepacklocator.addProperty("url", "https://files.minecraftforge.net/maven/"); cursepacklocator.addProperty("url", "https://files.minecraftforge.net/maven/");
libraries.add(cursepacklocator); libraries.add(cursepacklocator);
} }
for (JsonElement lib : getElement(installer ,"libraries").getAsJsonArray()) { Map<String, String> additionalUrls = new HashMap<>();
JsonObject artifact = getElement(getElement(lib.getAsJsonObject(), "downloads").getAsJsonObject(), "artifact").getAsJsonObject(); String path = String.format("net/minecraftforge/forge/%s-%s/forge-%s-%s", mcVersion, forgeVersion, mcVersion, forgeVersion);
String path = getElement(artifact, "path").getAsString(); additionalUrls.put(path + "-universal.jar", "https://files.minecraftforge.net/maven/" + path + "-universal.jar");
if (path.equals(String.format("net/minecraftforge/forge/%s-%s/forge-%s-%s.jar", mcVersion, forgeVersion, mcVersion, forgeVersion))) { transformLibraries(getElement(installProfile, "libraries").getAsJsonArray(), mavenFiles, additionalUrls);
artifact.getAsJsonObject().addProperty("url", "https://files.minecraftforge.net/maven/" + path.replace(".jar", "-launcher.jar")); additionalUrls.clear();
} additionalUrls.put(path + ".jar", "https://files.minecraftforge.net/maven/" + path + "-launcher.jar");
libraries.add(lib); transformLibraries(getElement(installer ,"libraries").getAsJsonArray(), libraries, additionalUrls);
}
patches.addProperty("version", forgeVersion); patches.addProperty("version", forgeVersion);
for (JsonElement require : getElement(patches, "requires").getAsJsonArray()) { for (JsonElement require : getElement(patches, "requires").getAsJsonArray()) {
@ -183,4 +191,15 @@ public class Converter {
} }
return JsonNull.INSTANCE; return JsonNull.INSTANCE;
} }
private static void transformLibraries(JsonArray source, JsonArray target, Map<String, String> 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);
}
}
} }

View file

@ -10,7 +10,7 @@ import io.github.zekerzhayard.forgewrapper.Utils;
public class Main { public class Main {
public static void main(String[] args) { public static void main(String[] args) {
Path installer = null, instance = Paths.get("."); Path installer = null, instance = Paths.get("."), multimc = null;
String cursepack = null; String cursepack = null;
try { try {
HashMap<String, String> argsMap = parseArgs(args); HashMap<String, String> argsMap = parseArgs(args);
@ -22,6 +22,7 @@ public class Main {
} }
if (argsMap.containsKey("--instance")) { if (argsMap.containsKey("--instance")) {
instance = Paths.get(argsMap.get("--instance")); instance = Paths.get(argsMap.get("--instance"));
multimc = instance.getParent();
} }
if (argsMap.containsKey("--cursepack")) { if (argsMap.containsKey("--cursepack")) {
cursepack = argsMap.get("--cursepack"); cursepack = argsMap.get("--cursepack");
@ -36,7 +37,7 @@ public class Main {
Converter.class.getProtectionDomain().getCodeSource().getLocation(), Converter.class.getProtectionDomain().getCodeSource().getLocation(),
installer.toUri().toURL() installer.toUri().toURL()
}, null); }, 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!"); System.out.println("Successfully install Forge for MultiMC!");
} catch (Exception e) { } catch (Exception e) {
System.out.println("Failed to install Forge!"); System.out.println("Failed to install Forge!");

View file

@ -3,7 +3,6 @@ package io.github.zekerzhayard.forgewrapper.installer;
import java.io.File; import java.io.File;
import java.util.function.Predicate; import java.util.function.Predicate;
import net.minecraftforge.installer.actions.ActionCanceledException;
import net.minecraftforge.installer.actions.ClientInstall; import net.minecraftforge.installer.actions.ClientInstall;
import net.minecraftforge.installer.actions.ProgressCallback; import net.minecraftforge.installer.actions.ProgressCallback;
import net.minecraftforge.installer.json.Install; import net.minecraftforge.installer.json.Install;
@ -17,16 +16,6 @@ public class ClientInstall4MultiMC extends ClientInstall {
public boolean run(File target, Predicate<String> optionals) { public boolean run(File target, Predicate<String> optionals) {
File librariesDir = Main.getLibrariesDir(); 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())); 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); return this.processors.process(librariesDir, clientTarget);
} }
} }

View file

@ -11,25 +11,23 @@ import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import cpw.mods.modlauncher.Launcher; import cpw.mods.modlauncher.Launcher;
import io.github.zekerzhayard.forgewrapper.Utils;
public class Main { public class Main {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
List<String> argsList = Stream.of(args).collect(Collectors.toList()); List<String> argsList = Stream.of(args).collect(Collectors.toList());
String version = argsList.get(argsList.indexOf("--fml.mcVersion") + 1) + "-" + argsList.get(argsList.indexOf("--fml.forgeVersion") + 1); String mcVersion = argsList.get(argsList.indexOf("--fml.mcVersion") + 1);
String mcpFullVersion = mcVersion + "-" + argsList.get(argsList.indexOf("--fml.mcpVersion") + 1);
Path forgeDir = getLibrariesDir().toPath().resolve("net").resolve("minecraftforge").resolve("forge").resolve(version); String forgeFullVersion = mcVersion + "-" + argsList.get(argsList.indexOf("--fml.forgeVersion") + 1);
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);
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[] { URLClassLoader ucl = URLClassLoader.newInstance(new URL[] {
Main.class.getProtectionDomain().getCodeSource().getLocation(), Main.class.getProtectionDomain().getCodeSource().getLocation(),
Launcher.class.getProtectionDomain().getCodeSource().getLocation(), Launcher.class.getProtectionDomain().getCodeSource().getLocation(),
new File(installerFileStr).toURI().toURL() forgeDir.resolve("forge-" + forgeFullVersion + "-installer.jar").toUri().toURL()
}, null); }, null);
Class<?> installer = ucl.loadClass("io.github.zekerzhayard.forgewrapper.installer.Installer"); Class<?> installer = ucl.loadClass("io.github.zekerzhayard.forgewrapper.installer.Installer");
@ -44,11 +42,18 @@ public class Main {
public static File getLibrariesDir() { public static File getLibrariesDir() {
try { try {
File laucnher = new File(Launcher.class.getProtectionDomain().getCodeSource().getLocation().toURI()); 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
// /<version> /modlauncher /mods /cpw /libraries // /<version> /modlauncher /mods /cpw /libraries
return laucnher.getParentFile().getParentFile().getParentFile().getParentFile().getParentFile(); return laucnher.getParentFile().getParentFile().getParentFile().getParentFile().getParentFile();
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
public static Stream<Path> 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")
);
}
} }

View file

@ -12,9 +12,15 @@
"type": "release", "type": "release",
"uid": "net.minecraftforge", "uid": "net.minecraftforge",
"version": "{FORGE_VERSION}", "version": "{FORGE_VERSION}",
"mavenFiles": [
{
"name": "net.minecraftforge:forge:{VERSION}-{FORGE_VERSION}:installer",
"url": "https://files.minecraftforge.net/maven/"
}
],
"libraries": [ "libraries": [
{ {
"name": "io.github.zekerzhayard:Forge-Wrapper:${version}", "name": "io.github.zekerzhayard:ForgeWrapper:${version}",
"MMC-hint": "local", "MMC-hint": "local",
"MMC-filename": "ForgeWrapper-${version}.jar" "MMC-filename": "ForgeWrapper-${version}.jar"
} }