From c04ad2e036fd965bc9114d2bc8dcbfffa1174eb7 Mon Sep 17 00:00:00 2001 From: ZekerZhayard Date: Thu, 26 Mar 2020 15:12:30 +0800 Subject: [PATCH] Why does MultiMC target me? --- build.gradle | 2 +- .../zekerzhayard/forgewrapper/Main.java | 50 ----------- .../zekerzhayard/forgewrapper/Utils.java | 82 +++++++++++-------- .../forgewrapper/converter/Converter.java | 23 +++--- .../forgewrapper/converter/Main.java | 4 +- .../installer/ClientInstall4MultiMC.java | 13 ++- .../forgewrapper/installer/Download.java | 65 --------------- .../forgewrapper/installer/Main.java | 34 ++++++++ src/main/java/why/does/multimc/target/Me.java | 9 ++ .../resources/patches/net.minecraftforge.json | 3 +- 10 files changed, 120 insertions(+), 165 deletions(-) delete mode 100644 src/main/java/io/github/zekerzhayard/forgewrapper/Main.java delete mode 100644 src/main/java/io/github/zekerzhayard/forgewrapper/installer/Download.java create mode 100644 src/main/java/io/github/zekerzhayard/forgewrapper/installer/Main.java create mode 100644 src/main/java/why/does/multimc/target/Me.java diff --git a/build.gradle b/build.gradle index 13e5703..d5b5bc0 100644 --- a/build.gradle +++ b/build.gradle @@ -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 diff --git a/src/main/java/io/github/zekerzhayard/forgewrapper/Main.java b/src/main/java/io/github/zekerzhayard/forgewrapper/Main.java deleted file mode 100644 index 146c970..0000000 --- a/src/main/java/io/github/zekerzhayard/forgewrapper/Main.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.github.zekerzhayard.forgewrapper; - -import java.io.File; -import java.net.URL; -import java.net.URLClassLoader; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import cpw.mods.modlauncher.Launcher; -import io.github.zekerzhayard.forgewrapper.converter.Converter; -import io.github.zekerzhayard.forgewrapper.installer.Download; - -public class Main { - public static void main(String[] args) throws Exception { - URL[] urls = Utils.getURLs(new ArrayList<>()); - Pattern pattern = Pattern.compile("forge-(?[0-9.]+)-(?[0-9.]+)\\.jar"); - String version = ""; - String installerFileStr = ""; - for (URL url : urls) { - Matcher matcher = pattern.matcher(url.getFile()); - if (matcher.find() && url.getFile().endsWith(matcher.group(0))) { - version = matcher.group("mcVersion") + "-" + matcher.group("forgeVersion"); - String installerUrl = String.format("https://files.minecraftforge.net/maven/net/minecraftforge/forge/%s/forge-%s-installer.jar", version, version); - installerFileStr = String.format("./.forgewrapper/forge-%s-installer.jar", version); - Download.download(installerUrl, installerFileStr); - break; - } - } - - 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; - } - List argsList = Stream.of(args).collect(Collectors.toList()); - argsList.addAll(Converter.getAdditionalArgs(Paths.get(installerFileStr))); - - Launcher.main(argsList.toArray(new String[0])); - } -} diff --git a/src/main/java/io/github/zekerzhayard/forgewrapper/Utils.java b/src/main/java/io/github/zekerzhayard/forgewrapper/Utils.java index 3d3921d..f309d69 100644 --- a/src/main/java/io/github/zekerzhayard/forgewrapper/Utils.java +++ b/src/main/java/io/github/zekerzhayard/forgewrapper/Utils.java @@ -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 blackList) { - ClassLoader cl = Utils.class.getClassLoader(); - List 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 - // / /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; } } 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 0fe1262..060ef77 100644 --- a/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Converter.java +++ b/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Converter.java @@ -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 { @@ -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 /.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 /.minecraft folder. + Path minecraftPath = instancePath.resolve(".minecraft"); if (cursepack != null) { ZipFile zip = new ZipFile(cursepack); Enumeration 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 getAdditionalArgs(Path installerPath) { - JsonObject installer = getJsonFromZip(installerPath, "version.json"); - return getAdditionalArgs(installer); + // 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); } public static List getAdditionalArgs(JsonObject installer) { @@ -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; } @@ -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:")) { 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 31f84be..0b4d736 100644 --- a/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Main.java +++ b/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Main.java @@ -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) { @@ -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")); 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 d104a18..ff61563 100644 --- a/src/main/java/io/github/zekerzhayard/forgewrapper/installer/ClientInstall4MultiMC.java +++ b/src/main/java/io/github/zekerzhayard/forgewrapper/installer/ClientInstall4MultiMC.java @@ -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; @@ -16,7 +17,15 @@ public ClientInstall4MultiMC(Install profile, ProgressCallback monitor) { @Override public boolean run(File target, Predicate 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 + // / /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. diff --git a/src/main/java/io/github/zekerzhayard/forgewrapper/installer/Download.java b/src/main/java/io/github/zekerzhayard/forgewrapper/installer/Download.java deleted file mode 100644 index c89687f..0000000 --- a/src/main/java/io/github/zekerzhayard/forgewrapper/installer/Download.java +++ /dev/null @@ -1,65 +0,0 @@ -package io.github.zekerzhayard.forgewrapper.installer; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; -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 Download { - private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - - 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); - } - } - - 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; - } -} diff --git a/src/main/java/io/github/zekerzhayard/forgewrapper/installer/Main.java b/src/main/java/io/github/zekerzhayard/forgewrapper/installer/Main.java new file mode 100644 index 0000000..1e8c365 --- /dev/null +++ b/src/main/java/io/github/zekerzhayard/forgewrapper/installer/Main.java @@ -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 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); + } +} diff --git a/src/main/java/why/does/multimc/target/Me.java b/src/main/java/why/does/multimc/target/Me.java new file mode 100644 index 0000000..2d82a72 --- /dev/null +++ b/src/main/java/why/does/multimc/target/Me.java @@ -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); + } +} diff --git a/src/main/resources/patches/net.minecraftforge.json b/src/main/resources/patches/net.minecraftforge.json index b037e07..d30c5bb 100644 --- a/src/main/resources/patches/net.minecraftforge.json +++ b/src/main/resources/patches/net.minecraftforge.json @@ -1,6 +1,7 @@ { "formatVersion": 1, - "mainClass": "io.github.zekerzhayard.forgewrapper.Main", + "mainClass": "why.does.multimc.target.Me", + "minecraftArguments": "", "name": "Forge", "requires": [ {