Add converter to convert vanilla version json to MultiMC instance json.
This commit is contained in:
parent
c45356218a
commit
1b50883f6d
13 changed files with 261 additions and 204 deletions
15
README.md
Normal file
15
README.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# ForgeWrapper
|
||||||
|
|
||||||
|
Allow MultiMC to launch Minecraft 1.13+ with Forge.
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
|
||||||
|
1. Download Forge installer for Minecraft 1.13+ at [https://files.minecraftforge.net/].
|
||||||
|
2. Download ForgeWrapper jar file at the [release](https://github.com/ZekerZhayard/ForgeWrapper/releases) page.
|
||||||
|
3. Run the below command in terminal:
|
||||||
|
```
|
||||||
|
java -jar <ForgeWrapper.jar> [--installer] <forge-installer.jar> [--instance <instance-path>]
|
||||||
|
```
|
||||||
|
*Notice: If you don't specify a MultiMC instance path, ForgeWrapper will create the instance folder in current working space.*
|
||||||
|
4. If the instance folder which just created is not in `MultiMC/instances` folder, you just need to move to the `MultiMC/instances` folder.
|
||||||
|
5. Run MultiMC, and you will see a new instance named `forge-<mcVersion>-<forgeVersion>`.
|
19
build.gradle
19
build.gradle
|
@ -4,7 +4,7 @@ apply plugin: "idea"
|
||||||
|
|
||||||
sourceCompatibility = targetCompatibility = 1.8
|
sourceCompatibility = targetCompatibility = 1.8
|
||||||
|
|
||||||
version = "1.0.0"
|
version = "1.1.0"
|
||||||
group = "io.github.zekerzhayard"
|
group = "io.github.zekerzhayard"
|
||||||
archivesBaseName = rootProject.name
|
archivesBaseName = rootProject.name
|
||||||
|
|
||||||
|
@ -19,12 +19,23 @@ repositories {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile "commons-codec:commons-codec:1.10"
|
compile "commons-codec:commons-codec:1.10"
|
||||||
compile "cpw.mods:modlauncher:5.0.0-milestone.4"
|
compile "cpw.mods:modlauncher:4.1.0"
|
||||||
compile "net.minecraftforge:forge:1.15.1-30.0.16:installer"
|
compile "net.minecraftforge:forge:1.14.4-28.2.0:installer"
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
manifest.attributes(
|
manifest.attributes(
|
||||||
"Main-Class": "io.github.zekerzhayard.forgewrapper.Main"
|
"Main-Class": "io.github.zekerzhayard.forgewrapper.converter.Main"
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
processResources {
|
||||||
|
inputs.property "version", project.version
|
||||||
|
from(sourceSets.main.resources.srcDirs) {
|
||||||
|
include "patches/net.minecraftforge.json"
|
||||||
|
expand "version": project.version
|
||||||
|
}
|
||||||
|
from(sourceSets.main.resources.srcDirs) {
|
||||||
|
exclude "patches/net.minecraftforge.json"
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
"components": [
|
|
||||||
{
|
|
||||||
"cachedName": "LWJGL 3",
|
|
||||||
"cachedVersion": "3.2.2",
|
|
||||||
"cachedVolatile": true,
|
|
||||||
"dependencyOnly": true,
|
|
||||||
"uid": "org.lwjgl3",
|
|
||||||
"version": "3.2.2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cachedName": "Minecraft",
|
|
||||||
"cachedRequires": [
|
|
||||||
{
|
|
||||||
"equals": "3.2.2",
|
|
||||||
"suggests": "3.2.2",
|
|
||||||
"uid": "org.lwjgl3"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cachedVersion": "1.14.4",
|
|
||||||
"important": true,
|
|
||||||
"uid": "net.minecraft",
|
|
||||||
"version": "1.14.4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cachedName": "MinecraftForge",
|
|
||||||
"cachedRequires": [
|
|
||||||
{
|
|
||||||
"equals": "1.14.4",
|
|
||||||
"uid": "net.minecraft"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cachedVersion": "1.14.4-28.1.109",
|
|
||||||
"uid": "net.minecraftforge"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"formatVersion": 1
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
{
|
|
||||||
"formatVersion": 1,
|
|
||||||
"libraries": [
|
|
||||||
{
|
|
||||||
"name": "com.github.ZekerZhayard:ForgeWrapper:-SNAPSHOT",
|
|
||||||
"url": "https://jitpack.io/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "net.minecraftforge:forge:1.14.4-28.1.109:launcher",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "org.ow2.asm:asm:6.2",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "org.ow2.asm:asm-commons:6.2",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "org.ow2.asm:asm-tree:6.2",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "cpw.mods:modlauncher:4.1.0",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "cpw.mods:grossjava9hacks:1.1.0",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "net.minecraftforge:accesstransformers:1.0.1-milestone.0.1+94458e7:shadowed",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "net.minecraftforge:eventbus:1.0.0:service",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "net.minecraftforge:forgespi:1.5.0",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "net.minecraftforge:coremods:1.0.0",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "net.minecraftforge:unsafe:0.2.0",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.electronwill.night-config:core:3.6.0",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.electronwill.night-config:toml:3.6.0",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "org.jline:jline:3.12.1",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "org.apache.maven:maven-artifact:3.6.0",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "net.jodah:typetools:0.6.0",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "java3d:vecmath:1.5.2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "org.apache.logging.log4j:log4j-api:2.11.2",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "org.apache.logging.log4j:log4j-core:2.11.2",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "net.minecrell:terminalconsoleappender:1.2.0",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "net.sf.jopt-simple:jopt-simple:5.0.4",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "cpw.mods.forge:cursepacklocator:1.2.0",
|
|
||||||
"url": "https://files.minecraftforge.net/maven/"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"mainClass": "io.github.zekerzhayard.forgewrapper.Main",
|
|
||||||
"name": "MinecraftForge",
|
|
||||||
"requires": [
|
|
||||||
{
|
|
||||||
"equals": "1.14.4",
|
|
||||||
"uid": "net.minecraft"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"type": "release",
|
|
||||||
"uid": "net.minecraftforge",
|
|
||||||
"version": "1.14.4-28.1.109"
|
|
||||||
}
|
|
|
@ -16,7 +16,7 @@ import io.github.zekerzhayard.forgewrapper.installer.Download;
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
URL[] urls = Utils.getURLs(new ArrayList<>());
|
URL[] urls = Utils.getURLs(new ArrayList<>());
|
||||||
Pattern pattern = Pattern.compile("forge\\-(?<mcVersion>[0-9\\.]+)\\-(?<forgeVersion>[0-9\\.]+)\\-launcher\\.jar");
|
Pattern pattern = Pattern.compile("forge-(?<mcVersion>[0-9.]+)-(?<forgeVersion>[0-9.]+)\\.jar");
|
||||||
String version = "";
|
String version = "";
|
||||||
for (URL url : urls) {
|
for (URL url : urls) {
|
||||||
Matcher matcher = pattern.matcher(url.getFile());
|
Matcher matcher = pattern.matcher(url.getFile());
|
||||||
|
@ -30,6 +30,7 @@ public class Main {
|
||||||
|
|
||||||
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(),
|
||||||
new File(String.format("./.forgewrapper/forge-%s-installer.jar", version)).toURI().toURL()
|
new File(String.format("./.forgewrapper/forge-%s-installer.jar", version)).toURI().toURL()
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import cpw.mods.modlauncher.Launcher;
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
public static URL[] getURLs(List<String> blackList) {
|
public static URL[] getURLs(List<String> blackList) {
|
||||||
ClassLoader cl = Utils.class.getClassLoader();
|
ClassLoader cl = Utils.class.getClassLoader();
|
||||||
|
@ -32,10 +34,14 @@ public class Utils {
|
||||||
return urls.toArray(new URL[0]);
|
return urls.toArray(new URL[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File getLibrariesDir() throws URISyntaxException {
|
public static File getLibrariesDir() {
|
||||||
File wrapper = new File(Utils.class.getProtectionDomain().getCodeSource().getLocation().toURI());
|
try {
|
||||||
// see https://github.com/MinecraftForge/MinecraftForge/blob/863ab2ca184cf2e2dfa134d07bfc20d6a9a6a4e8/src/main/java/net/minecraftforge/fml/relauncher/libraries/LibraryManager.java#L151
|
File laucnher = new File(Launcher.class.getProtectionDomain().getCodeSource().getLocation().toURI());
|
||||||
// /<version> /ForgeWrapper /ZekerZhayard /github /com /libraries
|
// see https://github.com/MinecraftForge/MinecraftForge/blob/863ab2ca184cf2e2dfa134d07bfc20d6a9a6a4e8/src/main/java/net/minecraftforge/fml/relauncher/libraries/LibraryManager.java#L151
|
||||||
return wrapper.getParentFile().getParentFile().getParentFile().getParentFile().getParentFile().getParentFile();
|
// /<version> /modlauncher /mods /cpw /libraries
|
||||||
|
return laucnher.getParentFile().getParentFile().getParentFile().getParentFile().getParentFile();
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
package io.github.zekerzhayard.forgewrapper.converter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonNull;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
|
||||||
|
public class Converter {
|
||||||
|
public static void convert(Path installerPath, Path targetDir) throws Exception {
|
||||||
|
JsonObject installer = getInstallerJson(installerPath);
|
||||||
|
|
||||||
|
ArrayList<String> arguments = new ArrayList<>();
|
||||||
|
|
||||||
|
getElement(installer.getAsJsonObject("arguments"), "game").getAsJsonArray().iterator().forEachRemaining(je -> arguments.add(je.getAsString()));
|
||||||
|
String mcVersion = arguments.get(arguments.indexOf("--fml.mcVersion") + 1);
|
||||||
|
String forgeVersion = arguments.get(arguments.indexOf("--fml.forgeVersion") + 1);
|
||||||
|
String forgeFullVersion = "forge-" + mcVersion + "-" + forgeVersion;
|
||||||
|
StringBuilder wrapperVersion = new StringBuilder();
|
||||||
|
|
||||||
|
JsonObject pack = convertPackJson(mcVersion);
|
||||||
|
JsonObject patches = convertPatchesJson(installer, mcVersion, forgeVersion, wrapperVersion);
|
||||||
|
|
||||||
|
Files.createDirectories(targetDir);
|
||||||
|
|
||||||
|
// Copy mmc-pack.json and instance.cfg to <instance> folder.
|
||||||
|
Path instancePath = targetDir.resolve(forgeFullVersion);
|
||||||
|
Files.createDirectories(instancePath);
|
||||||
|
Files.copy(new ByteArrayInputStream(pack.toString().getBytes(StandardCharsets.UTF_8)), instancePath.resolve("mmc-pack.json"), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
Files.copy(new ByteArrayInputStream(("InstanceType=OneSix\nname=" + forgeFullVersion).getBytes(StandardCharsets.UTF_8)), instancePath.resolve("instance.cfg"), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|
||||||
|
// Copy ForgeWrapper to <instance>/libraries folder.
|
||||||
|
Path librariesPath = instancePath.resolve("libraries");
|
||||||
|
Files.createDirectories(librariesPath);
|
||||||
|
Files.copy(Paths.get(Converter.class.getProtectionDomain().getCodeSource().getLocation().toURI()), librariesPath.resolve(wrapperVersion.toString()), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|
||||||
|
// Copy net.minecraftforge.json to <instance>/patches folder.
|
||||||
|
Path patchesPath = instancePath.resolve("patches");
|
||||||
|
Files.createDirectories(patchesPath);
|
||||||
|
Files.copy(new ByteArrayInputStream(patches.toString().getBytes(StandardCharsets.UTF_8)), patchesPath.resolve("net.minecraftforge.json"), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|
||||||
|
// Copy forge installer to <instance>/.minecraft/.forgewrapper folder.
|
||||||
|
Path forgeWrapperPath = instancePath.resolve(".minecraft").resolve(".forgewrapper");
|
||||||
|
Files.createDirectories(forgeWrapperPath);
|
||||||
|
Files.copy(installerPath, forgeWrapperPath.resolve(forgeFullVersion + "-installer.jar"), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JsonObject getInstallerJson(Path installerPath) {
|
||||||
|
try {
|
||||||
|
ZipFile zf = new ZipFile(installerPath.toFile());
|
||||||
|
ZipEntry versionFile = zf.getEntry("version.json");
|
||||||
|
if (versionFile == null) {
|
||||||
|
throw new RuntimeException("The forge installer is invalid!");
|
||||||
|
}
|
||||||
|
InputStreamReader isr = new InputStreamReader(zf.getInputStream(versionFile), StandardCharsets.UTF_8);
|
||||||
|
return new JsonParser().parse(isr).getAsJsonObject();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert mmc-pack.json:
|
||||||
|
// - Replace Minecraft version
|
||||||
|
private static JsonObject convertPackJson(String mcVersion) {
|
||||||
|
JsonObject pack = new JsonParser().parse(new InputStreamReader(Converter.class.getResourceAsStream("/mmc-pack.json"))).getAsJsonObject();
|
||||||
|
|
||||||
|
for (JsonElement component : getElement(pack, "components").getAsJsonArray()) {
|
||||||
|
JsonObject componentObject = component.getAsJsonObject();
|
||||||
|
JsonElement version = getElement(componentObject, "version");
|
||||||
|
if (!version.isJsonNull() && getElement(componentObject, "uid").getAsString().equals("net.minecraft")) {
|
||||||
|
componentObject.addProperty("version", mcVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pack;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert patches/net.minecraftforge.json:
|
||||||
|
// - Add libraries
|
||||||
|
// - Add forge-launcher url
|
||||||
|
// - Replace Minecraft & Forge versions
|
||||||
|
private static JsonObject convertPatchesJson(JsonObject installer, String mcVersion, String forgeVersion, StringBuilder wrapperVersion) {
|
||||||
|
JsonObject patches = new JsonParser().parse(new InputStreamReader(Converter.class.getResourceAsStream("/patches/net.minecraftforge.json"))).getAsJsonObject();
|
||||||
|
JsonArray libraries = getElement(patches, "libraries").getAsJsonArray();
|
||||||
|
|
||||||
|
for (JsonElement lib : libraries) {
|
||||||
|
String name = getElement(lib.getAsJsonObject(), "name").getAsString();
|
||||||
|
if (name.startsWith("io.github.zekerzhayard:ForgeWrapper:")) {
|
||||||
|
wrapperVersion.append(getElement(lib.getAsJsonObject(), "MMC-filename").getAsString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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.startsWith("net/minecraftforge/forge/")) {
|
||||||
|
artifact.getAsJsonObject().addProperty("url", "https://files.minecraftforge.net/maven/" + path.replace(".jar", "-launcher.jar"));
|
||||||
|
}
|
||||||
|
libraries.add(lib);
|
||||||
|
}
|
||||||
|
|
||||||
|
patches.addProperty("version", forgeVersion);
|
||||||
|
for (JsonElement require : getElement(patches, "requires").getAsJsonArray()) {
|
||||||
|
JsonObject requireObject = require.getAsJsonObject();
|
||||||
|
if (getElement(requireObject, "uid").getAsString().equals("net.minecraft")) {
|
||||||
|
requireObject.addProperty("equals", mcVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return patches;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JsonElement getElement(JsonObject object, String property) {
|
||||||
|
Optional<Map.Entry<String, JsonElement>> first = object.entrySet().stream().filter(e -> e.getKey().equals(property)).findFirst();
|
||||||
|
if (first.isPresent()) {
|
||||||
|
return first.get().getValue();
|
||||||
|
}
|
||||||
|
return JsonNull.INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package io.github.zekerzhayard.forgewrapper.converter;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
ArrayList<String> argsList = new ArrayList<>(Arrays.asList(args));
|
||||||
|
Path installer, instance;
|
||||||
|
try {
|
||||||
|
installer = Paths.get(argsList.get(argsList.indexOf("--installer") + 1));
|
||||||
|
instance = Paths.get(".");
|
||||||
|
if (argsList.contains("--instance")) {
|
||||||
|
instance = Paths.get(argsList.get(argsList.indexOf("--instance") + 1));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Invalid arguments! Use: java -jar <ForgeWrapper.jar> [--installer] <forge-installer.jar> [--instance <instance-path>]");
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
URLClassLoader ucl = URLClassLoader.newInstance(new URL[] {
|
||||||
|
Converter.class.getProtectionDomain().getCodeSource().getLocation(),
|
||||||
|
installer.toUri().toURL()
|
||||||
|
}, null);
|
||||||
|
ucl.loadClass("io.github.zekerzhayard.forgewrapper.converter.Converter").getMethod("convert", Path.class, Path.class).invoke(null, installer, instance);
|
||||||
|
System.out.println("Successfully install Forge for MultiMC!");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Failed to install Forge!");
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package io.github.zekerzhayard.forgewrapper.installer;
|
package io.github.zekerzhayard.forgewrapper.installer;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import io.github.zekerzhayard.forgewrapper.Utils;
|
import io.github.zekerzhayard.forgewrapper.Utils;
|
||||||
|
@ -16,20 +15,19 @@ public class ClientInstall4MultiMC extends ClientInstall {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean run(File target, Predicate<String> optionals) throws ActionCanceledException {
|
public boolean run(File target, Predicate<String> optionals) {
|
||||||
try {
|
File librariesDir = Utils.getLibrariesDir();
|
||||||
File librariesDir = Utils.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()));
|
|
||||||
|
|
||||||
if (!this.downloadLibraries(librariesDir, optionals)) {
|
boolean downloadLibraries = true; // Force true when without an internet connection.
|
||||||
return false;
|
try {
|
||||||
}
|
downloadLibraries = this.downloadLibraries(librariesDir, optionals);
|
||||||
if (!this.processors.process(librariesDir, clientTarget)) {
|
} catch (ActionCanceledException e) {
|
||||||
return false;
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} catch (URISyntaxException e) {
|
if (!downloadLibraries) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return this.processors.process(librariesDir, clientTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,13 @@ public class Download {
|
||||||
localFile.getParentFile().mkdirs();
|
localFile.getParentFile().mkdirs();
|
||||||
if (localFile.isFile()) {
|
if (localFile.isFile()) {
|
||||||
try {
|
try {
|
||||||
|
System.out.println("Checking Fingerprints of installer...");
|
||||||
Files.copy(new URL(url + ".md5").openConnection().getInputStream(), Paths.get(location + ".md5"), StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(new URL(url + ".md5").openConnection().getInputStream(), Paths.get(location + ".md5"), StandardCopyOption.REPLACE_EXISTING);
|
||||||
Files.copy(new URL(url + ".sha1").openConnection().getInputStream(), Paths.get(location + ".sha1"), StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(new URL(url + ".sha1").openConnection().getInputStream(), Paths.get(location + ".sha1"), StandardCopyOption.REPLACE_EXISTING);
|
||||||
String md5 = new String(Files.readAllBytes(Paths.get(location + ".md5")));
|
String md5 = new String(Files.readAllBytes(Paths.get(location + ".md5")));
|
||||||
String sha1 = new String(Files.readAllBytes(Paths.get(location + ".sha1")));
|
String sha1 = new String(Files.readAllBytes(Paths.get(location + ".sha1")));
|
||||||
if (!checkMD5(location, md5) || !checkSHA1(location, sha1)) {
|
if (!checkMD5(location, md5) || !checkSHA1(location, sha1)) {
|
||||||
|
System.out.println("Fingerprints do not match!");
|
||||||
localFile.delete();
|
localFile.delete();
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -31,6 +33,7 @@ public class Download {
|
||||||
if (localFile.isDirectory()) {
|
if (localFile.isDirectory()) {
|
||||||
throw new RuntimeException(location + " must be a file!");
|
throw new RuntimeException(location + " must be a file!");
|
||||||
}
|
}
|
||||||
|
System.out.println("Downloading forge installer...");
|
||||||
Files.copy(new URL(url).openConnection().getInputStream(), Paths.get(location), StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(new URL(url).openConnection().getInputStream(), Paths.get(location), StandardCopyOption.REPLACE_EXISTING);
|
||||||
download(url, location);
|
download(url, location);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
package io.github.zekerzhayard.forgewrapper.installer;
|
package io.github.zekerzhayard.forgewrapper.installer;
|
||||||
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import net.minecraftforge.installer.actions.ActionCanceledException;
|
|
||||||
import net.minecraftforge.installer.actions.ProgressCallback;
|
import net.minecraftforge.installer.actions.ProgressCallback;
|
||||||
import net.minecraftforge.installer.json.Install;
|
import net.minecraftforge.installer.json.Install;
|
||||||
import net.minecraftforge.installer.json.Util;
|
import net.minecraftforge.installer.json.Util;
|
||||||
|
@ -12,7 +7,7 @@ import net.minecraftforge.installer.json.Util;
|
||||||
public class Installer {
|
public class Installer {
|
||||||
private static Install install;
|
private static Install install;
|
||||||
|
|
||||||
public static boolean install() throws ActionCanceledException {
|
public static boolean install() {
|
||||||
ProgressCallback monitor = ProgressCallback.withOutputs(System.out);
|
ProgressCallback monitor = ProgressCallback.withOutputs(System.out);
|
||||||
install = Util.loadInstallProfile();
|
install = Util.loadInstallProfile();
|
||||||
if (System.getProperty("java.net.preferIPv4Stack") == null) {
|
if (System.getProperty("java.net.preferIPv4Stack") == null) {
|
||||||
|
@ -37,34 +32,4 @@ public class Installer {
|
||||||
public static String getMcpVersion() {
|
public static String getMcpVersion() {
|
||||||
return install.getData(true).get("MCP_VERSION").replace("'", "");
|
return install.getData(true).get("MCP_VERSION").replace("'", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hookStdOut(ProgressCallback monitor) {
|
|
||||||
final Pattern endingWhitespace = Pattern.compile("\\r?\\n$");
|
|
||||||
final OutputStream monitorStream = new OutputStream() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(byte[] buf, int off, int len) {
|
|
||||||
byte[] toWrite = new byte[len];
|
|
||||||
System.arraycopy(buf, off, toWrite, 0, len);
|
|
||||||
write(toWrite);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(byte[] b) {
|
|
||||||
String toWrite = new String(b);
|
|
||||||
toWrite = endingWhitespace.matcher(toWrite).replaceAll("");
|
|
||||||
if (!toWrite.isEmpty()) {
|
|
||||||
monitor.message(toWrite);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(int b) {
|
|
||||||
write(new byte[] {(byte) b});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
System.setOut(new PrintStream(monitorStream));
|
|
||||||
System.setErr(new PrintStream(monitorStream));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
13
src/main/resources/mmc-pack.json
Normal file
13
src/main/resources/mmc-pack.json
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"formatVersion": 1,
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"important": true,
|
||||||
|
"uid": "net.minecraft",
|
||||||
|
"version": "{VERSION}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": "net.minecraftforge"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
21
src/main/resources/patches/net.minecraftforge.json
Normal file
21
src/main/resources/patches/net.minecraftforge.json
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"formatVersion": 1,
|
||||||
|
"mainClass": "io.github.zekerzhayard.forgewrapper.Main",
|
||||||
|
"name": "Forge",
|
||||||
|
"requires": [
|
||||||
|
{
|
||||||
|
"equals": "{VERSION}",
|
||||||
|
"uid": "net.minecraft"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "release",
|
||||||
|
"uid": "net.minecraftforge",
|
||||||
|
"version": "{FORGE_VERSION}",
|
||||||
|
"libraries": [
|
||||||
|
{
|
||||||
|
"name": "io.github.zekerzhayard:ForgeWrapper:${version}",
|
||||||
|
"MMC-hint": "local",
|
||||||
|
"MMC-filename": "ForgeWrapper-${version}.jar"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in a new issue