Skip to content

Commit

Permalink
All libraries can be downloaded by MultiMC now.
Browse files Browse the repository at this point in the history
  • Loading branch information
ZekerZhayard committed Mar 27, 2020
1 parent 812a810 commit fb8888a
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 46 deletions.
6 changes: 2 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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/"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
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;
Expand All @@ -24,12 +25,13 @@
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<String> arguments = getAdditionalArgs(installer);
String mcVersion = arguments.get(arguments.indexOf("--fml.mcVersion") + 1);
String forgeVersion = arguments.get(arguments.indexOf("--fml.forgeVersion") + 1);
Expand All @@ -38,7 +40,7 @@ public static void convert(Path installerPath, Path targetDir, String cursepack)
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);

Expand Down Expand Up @@ -71,10 +73,12 @@ public static void convert(Path installerPath, Path targetDir, String cursepack)
}
}

// Copy forge installer to <instance>/.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/<mcVersion>-<forgeVersion> 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<String> getAdditionalArgs(JsonObject installer) {
Expand Down Expand Up @@ -138,13 +142,18 @@ private static JsonObject convertPackJson(String mcVersion) {
// - 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:")) {
Expand All @@ -157,14 +166,13 @@ private static JsonObject convertPatchesJson(JsonObject installer, String mcVers
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<String, String> 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()) {
Expand All @@ -183,4 +191,15 @@ private static JsonElement getElement(JsonObject object, String property) {
}
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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

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<String, String> argsMap = parseArgs(args);
Expand All @@ -22,6 +22,7 @@ public static void main(String[] args) {
}
if (argsMap.containsKey("--instance")) {
instance = Paths.get(argsMap.get("--instance"));
multimc = instance.getParent();
}
if (argsMap.containsKey("--cursepack")) {
cursepack = argsMap.get("--cursepack");
Expand All @@ -36,7 +37,7 @@ public static void main(String[] args) {
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!");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
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;
Expand All @@ -17,16 +16,6 @@ public ClientInstall4MultiMC(Install profile, ProgressCallback monitor) {
public boolean run(File target, Predicate<String> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,23 @@
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<String> 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");
Expand All @@ -44,11 +42,18 @@ public static void main(String[] args) throws Exception {
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
// /<version> /modlauncher /mods /cpw /libraries
return laucnher.getParentFile().getParentFile().getParentFile().getParentFile().getParentFile();
} catch (URISyntaxException 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")
);
}
}
8 changes: 7 additions & 1 deletion src/main/resources/patches/net.minecraftforge.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
Expand Down

2 comments on commit fb8888a

@robsob91
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Godspeed. Even though I haven't touched MC past 1.12, functionality and targeted function removal shouldnt be happen because of petty reasons.

@ZekerZhayard
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Godspeed. Even though I haven't touched MC past 1.12, functionality and targeted function removal shouldnt be happen because of petty reasons.

Nothing was been removed, just move downloading tasks from here to MultiMC.

Please sign in to comment.