Skip to content

Commit

Permalink
Why does MultiMC target me?
Browse files Browse the repository at this point in the history
  • Loading branch information
ZekerZhayard committed Mar 26, 2020
1 parent ee84a6b commit c04ad2e
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 165 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ apply plugin: "idea"

sourceCompatibility = targetCompatibility = 1.8

version = "1.2.0"
version = "1.3.0"
group = "io.github.zekerzhayard"
archivesBaseName = rootProject.name

Expand Down
50 changes: 0 additions & 50 deletions src/main/java/io/github/zekerzhayard/forgewrapper/Main.java

This file was deleted.

82 changes: 50 additions & 32 deletions src/main/java/io/github/zekerzhayard/forgewrapper/Utils.java
Original file line number Diff line number Diff line change
@@ -1,47 +1,65 @@
package io.github.zekerzhayard.forgewrapper;

import java.io.BufferedReader;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import cpw.mods.modlauncher.Launcher;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Locale;

public class Utils {
public static URL[] getURLs(List<String> blackList) {
ClassLoader cl = Utils.class.getClassLoader();
List<URL> urls = new ArrayList<>();
if (cl instanceof URLClassLoader) {
urls.addAll(Stream.of(((URLClassLoader) cl).getURLs()).filter(url -> blackList.stream().noneMatch(str -> url.getFile().endsWith(str))).collect(Collectors.toList()));
} else {
String[] elements = System.getProperty("java.class.path").split(File.pathSeparator);
private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

for (String ele : elements) {
try {
if (blackList.stream().noneMatch(ele::endsWith)) {
urls.add(new File(ele).toURI().toURL());
}
} catch (MalformedURLException e) {
e.printStackTrace();
public static void download(String url, String location) throws Exception {
File localFile = new File(location);
localFile.getParentFile().mkdirs();
if (localFile.isFile()) {
try {
System.out.println("Checking Fingerprints of installer...");
String md5 = new BufferedReader(new InputStreamReader(new URL(url + ".md5").openConnection().getInputStream())).readLine();
String sha1 = new BufferedReader(new InputStreamReader(new URL(url + ".sha1").openConnection().getInputStream())).readLine();
if (!checkMD5(location, md5) || !checkSHA1(location, sha1)) {
System.out.println("Fingerprints do not match!");
localFile.delete();
}
} catch (IOException e) {
e.printStackTrace();
}
}
if (!localFile.isFile()) {
if (localFile.isDirectory()) {
throw new RuntimeException(location + " must be a file!");
}
System.out.println("Downloading forge installer... (" + url + " ---> " + location + ")");
Files.copy(new URL(url).openConnection().getInputStream(), Paths.get(location), StandardCopyOption.REPLACE_EXISTING);
download(url, location);
}
return urls.toArray(new URL[0]);
}

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 boolean checkMD5(String path, String hash) throws IOException, NoSuchAlgorithmException {
String md5 = new String(encodeHex(MessageDigest.getInstance("MD5").digest(Files.readAllBytes(Paths.get(path)))));
System.out.println("MD5: " + hash + " ---> " + md5);
return md5.toLowerCase(Locale.ENGLISH).equals(hash.toLowerCase(Locale.ENGLISH));
}

public static boolean checkSHA1(String path, String hash) throws IOException, NoSuchAlgorithmException {
String sha1 = new String(encodeHex(MessageDigest.getInstance("SHA-1").digest(Files.readAllBytes(Paths.get(path)))));
System.out.println("SHA-1: " + hash + " ---> " + sha1);
return sha1.toLowerCase(Locale.ENGLISH).equals(hash.toLowerCase(Locale.ENGLISH));
}

private static char[] encodeHex(final byte[] data) {
final int l = data.length;
final char[] out = new char[l << 1];
for (int i = 0, j = 0; i < l; i++) {
out[j++] = DIGITS[(0xF0 & data[i]) >>> 4];
out[j++] = DIGITS[0x0F & data[i]];
}
return out;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.github.zekerzhayard.forgewrapper.installer.Download;
import io.github.zekerzhayard.forgewrapper.Utils;

public class Converter {
public static void convert(Path installerPath, Path targetDir, String cursepack) throws Exception {
Expand Down Expand Up @@ -58,27 +58,23 @@ public static void convert(Path installerPath, Path targetDir, String cursepack)
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);

// Extract all curse pack entries to <instance>/.minecraft folder.
Path minecraftPath = instancePath.resolve(".minecraft");
if (cursepack != null) {
ZipFile zip = new ZipFile(cursepack);
Enumeration<? extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
Path targetFolder = forgeWrapperPath.getParent().resolve(entry.getName());
Path targetFolder = minecraftPath.resolve(entry.getName());
Files.createDirectories(targetFolder.getParent());
Files.copy(zip.getInputStream(entry), targetFolder, StandardCopyOption.REPLACE_EXISTING);
}
}
}

public static List<String> getAdditionalArgs(Path installerPath) {
JsonObject installer = getJsonFromZip(installerPath, "version.json");
return getAdditionalArgs(installer);
// 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);
}

public static List<String> getAdditionalArgs(JsonObject installer) {
Expand Down Expand Up @@ -119,7 +115,7 @@ private static Path getForgeInstallerFromCursePack(String cursepack) throws Exce
String packName = getElement(manifest, "name").getAsString();
String packVersion = getElement(manifest, "version").getAsString();
Path installer = Paths.get(System.getProperty("java.io.tmpdir", "."), String.format("%s-%s-installer.jar", packName, packVersion));
Download.download(String.format("https://files.minecraftforge.net/maven/net/minecraftforge/forge/%s-%s/forge-%s-%s-installer.jar", mcVersion, forgeVersion, mcVersion, forgeVersion), installer.toString());
Utils.download(String.format("https://files.minecraftforge.net/maven/net/minecraftforge/forge/%s-%s/forge-%s-%s-installer.jar", mcVersion, forgeVersion, mcVersion, forgeVersion), installer.toString());
return installer;
}

Expand All @@ -146,6 +142,9 @@ private static JsonObject convertPatchesJson(JsonObject installer, String mcVers
JsonObject patches = new JsonParser().parse(new InputStreamReader(Converter.class.getResourceAsStream("/patches/net.minecraftforge.json"))).getAsJsonObject();
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 lib : libraries) {
String name = getElement(lib.getAsJsonObject(), "name").getAsString();
if (name.startsWith("io.github.zekerzhayard:ForgeWrapper:")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import java.nio.file.Paths;
import java.util.HashMap;

import io.github.zekerzhayard.forgewrapper.installer.Download;
import io.github.zekerzhayard.forgewrapper.Utils;

public class Main {
public static void main(String[] args) {
Expand All @@ -18,7 +18,7 @@ public static void main(String[] args) {
installer = Paths.get(argsMap.get("--installer"));
} else {
installer = Paths.get(System.getProperty("java.io.tmpdir", "."), "gson-2.8.6.jar");
Download.download("https://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.6/gson-2.8.6.jar", installer.toString());
Utils.download("https://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.6/gson-2.8.6.jar", installer.toString());
}
if (argsMap.containsKey("--instance")) {
instance = Paths.get(argsMap.get("--instance"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package io.github.zekerzhayard.forgewrapper.installer;

import java.io.File;
import java.net.URISyntaxException;
import java.util.function.Predicate;

import io.github.zekerzhayard.forgewrapper.Utils;
import cpw.mods.modlauncher.Launcher;
import net.minecraftforge.installer.actions.ActionCanceledException;
import net.minecraftforge.installer.actions.ClientInstall;
import net.minecraftforge.installer.actions.ProgressCallback;
Expand All @@ -16,7 +17,15 @@ public ClientInstall4MultiMC(Install profile, ProgressCallback monitor) {

@Override
public boolean run(File target, Predicate<String> optionals) {
File librariesDir = Utils.getLibrariesDir();
File librariesDir;
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
librariesDir = laucnher.getParentFile().getParentFile().getParentFile().getParentFile().getParentFile();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
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.
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.github.zekerzhayard.forgewrapper.installer;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
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<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 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);

URLClassLoader ucl = URLClassLoader.newInstance(new URL[] {
Main.class.getProtectionDomain().getCodeSource().getLocation(),
Launcher.class.getProtectionDomain().getCodeSource().getLocation(),
new File(installerFileStr).toURI().toURL()
}, null);

Class<?> installer = ucl.loadClass("io.github.zekerzhayard.forgewrapper.installer.Installer");
if (!(boolean) installer.getMethod("install").invoke(null)) {
return;
}

Launcher.main(args);
}
}
9 changes: 9 additions & 0 deletions src/main/java/why/does/multimc/target/Me.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package why.does.multimc.target;

import io.github.zekerzhayard.forgewrapper.installer.Main;

public class Me {
public static void main(String[] args) throws Exception {
Main.main(args);
}
}
3 changes: 2 additions & 1 deletion src/main/resources/patches/net.minecraftforge.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"formatVersion": 1,
"mainClass": "io.github.zekerzhayard.forgewrapper.Main",
"mainClass": "why.does.multimc.target.Me",
"minecraftArguments": "",
"name": "Forge",
"requires": [
{
Expand Down

0 comments on commit c04ad2e

Please sign in to comment.