summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZekerZhayard <trees1000@qq.com>2020-03-20 22:08:13 +0800
committerZekerZhayard <trees1000@qq.com>2020-03-20 22:08:13 +0800
commitbd7373a320b90b5eb90a2fd4ca76b8d9d4f8ef28 (patch)
treed82ccfa76c0122dd268326f180c010f050e095c4
parent7114b3e0d59ab162d934a91635d1624abc14f5e2 (diff)
downloadProject-Tick-bd7373a320b90b5eb90a2fd4ca76b8d9d4f8ef28.tar.gz
Project-Tick-bd7373a320b90b5eb90a2fd4ca76b8d9d4f8ef28.zip
Add --cursepack argument for installing curseforge modpack.
-rw-r--r--README.md20
-rw-r--r--build.gradle3
-rw-r--r--gradle/wrapper/gradle-wrapper.properties3
-rw-r--r--src/main/java/cpw/mods/forge/cursepacklocator/Murmur2.java166
-rw-r--r--src/main/java/io/github/zekerzhayard/forgewrapper/converter/Converter.java72
-rw-r--r--src/main/java/io/github/zekerzhayard/forgewrapper/converter/Main.java46
-rw-r--r--src/main/java/io/github/zekerzhayard/forgewrapper/installer/Download.java38
7 files changed, 307 insertions, 41 deletions
diff --git a/README.md b/README.md
index db9aed1db6..5e9d2b5707 100644
--- a/README.md
+++ b/README.md
@@ -4,13 +4,27 @@ 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/].
+### Install Forge Only
+1. Download Forge installer for Minecraft 1.13+ [here](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>]
+ 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>`. \ No newline at end of file
+5. Run MultiMC, and you will see a new instance named `forge-<mcVersion>-<forgeVersion>`.
+
+### Install CurseForge Modpack
+1. Download the modpack zip file.
+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> --cursepack=<curseforge-modpack.zip> [--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 `<modpackName>-<modpackVersion>`.
+*Notice: CurseForge modpack will be installed on first launch by [cursepacklocator](https://github.com/cpw/cursepacklocator), it will take a few minutes.* \ No newline at end of file
diff --git a/build.gradle b/build.gradle
index fa854059d1..13e5703295 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ apply plugin: "idea"
sourceCompatibility = targetCompatibility = 1.8
-version = "1.1.0"
+version = "1.2.0"
group = "io.github.zekerzhayard"
archivesBaseName = rootProject.name
@@ -19,7 +19,6 @@ repositories {
}
dependencies {
- compile "commons-codec:commons-codec:1.10"
compile "cpw.mods:modlauncher:4.1.0"
compile "net.minecraftforge:forge:1.14.4-28.2.0:installer"
}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 290541c738..d193c615fa 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,6 @@
+#Thu Mar 12 20:06:29 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip
diff --git a/src/main/java/cpw/mods/forge/cursepacklocator/Murmur2.java b/src/main/java/cpw/mods/forge/cursepacklocator/Murmur2.java
new file mode 100644
index 0000000000..f754e18b16
--- /dev/null
+++ b/src/main/java/cpw/mods/forge/cursepacklocator/Murmur2.java
@@ -0,0 +1,166 @@
+/**
+ * Copyright 2014 Prasanth Jayachandran
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package cpw.mods.forge.cursepacklocator;
+
+/**
+ * Murmur2 32 and 64 bit variants.
+ * 32-bit Java port of https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash2.cpp#37
+ * 64-bit Java port of https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash2.cpp#96
+ */
+public class Murmur2 {
+ // Constants for 32-bit variant
+ private static final int M_32 = 0x5bd1e995;
+ private static final int R_32 = 24;
+
+ // Constants for 64-bit variant
+ private static final long M_64 = 0xc6a4a7935bd1e995L;
+ private static final int R_64 = 47;
+ private static final int DEFAULT_SEED = 0;
+
+ /**
+ * Murmur2 32-bit variant.
+ *
+ * @param data - input byte array
+ * @return - hashcode
+ */
+ public static int hash32(byte[] data) {
+ return hash32(data, data.length, DEFAULT_SEED);
+ }
+
+ /**
+ * Murmur2 32-bit variant.
+ *
+ * @param data - input byte array
+ * @param length - length of array
+ * @param seed - seed. (default 0)
+ * @return - hashcode
+ */
+ public static int hash32(byte[] data, int length, int seed) {
+ int h = seed ^ length;
+ int len_4 = length >> 2;
+
+ // body
+ for (int i = 0; i < len_4; i++) {
+ int i_4 = i << 2;
+ int k = (data[i_4] & 0xff)
+ | ((data[i_4 + 1] & 0xff) << 8)
+ | ((data[i_4 + 2] & 0xff) << 16)
+ | ((data[i_4 + 3] & 0xff) << 24);
+
+ // mix functions
+ k *= M_32;
+ k ^= k >>> R_32;
+ k *= M_32;
+ h *= M_32;
+ h ^= k;
+ }
+
+ // tail
+ int len_m = len_4 << 2;
+ int left = length - len_m;
+ if (left != 0) {
+ // see https://github.com/cpw/cursepacklocator/pull/3
+ if (left >= 3) {
+ h ^= (int) data[length - (left - 2)] << 16;
+ }
+ if (left >= 2) {
+ h ^= (int) data[length - (left - 1)] << 8;
+ }
+ if (left >= 1) {
+ h ^= (int) data[length - left];
+ }
+
+ h *= M_32;
+ }
+
+ // finalization
+ h ^= h >>> 13;
+ h *= M_32;
+ h ^= h >>> 15;
+
+ return h;
+ }
+
+ /**
+ * Murmur2 64-bit variant.
+ *
+ * @param data - input byte array
+ * @return - hashcode
+ */
+ public static long hash64(final byte[] data) {
+ return hash64(data, data.length, DEFAULT_SEED);
+ }
+
+ /**
+ * Murmur2 64-bit variant.
+ *
+ * @param data - input byte array
+ * @param length - length of array
+ * @param seed - seed. (default 0)
+ * @return - hashcode
+ */
+ public static long hash64(final byte[] data, int length, int seed) {
+ long h = (seed & 0xffffffffl) ^ (length * M_64);
+ int length8 = length >> 3;
+
+ // body
+ for (int i = 0; i < length8; i++) {
+ final int i8 = i << 3;
+ long k = ((long) data[i8] & 0xff)
+ | (((long) data[i8 + 1] & 0xff) << 8)
+ | (((long) data[i8 + 2] & 0xff) << 16)
+ | (((long) data[i8 + 3] & 0xff) << 24)
+ | (((long) data[i8 + 4] & 0xff) << 32)
+ | (((long) data[i8 + 5] & 0xff) << 40)
+ | (((long) data[i8 + 6] & 0xff) << 48)
+ | (((long) data[i8 + 7] & 0xff) << 56);
+
+ // mix functions
+ k *= M_64;
+ k ^= k >>> R_64;
+ k *= M_64;
+ h ^= k;
+ h *= M_64;
+ }
+
+ // tail
+ int tailStart = length8 << 3;
+ switch (length - tailStart) {
+ case 7:
+ h ^= (long) (data[tailStart + 6] & 0xff) << 48;
+ case 6:
+ h ^= (long) (data[tailStart + 5] & 0xff) << 40;
+ case 5:
+ h ^= (long) (data[tailStart + 4] & 0xff) << 32;
+ case 4:
+ h ^= (long) (data[tailStart + 3] & 0xff) << 24;
+ case 3:
+ h ^= (long) (data[tailStart + 2] & 0xff) << 16;
+ case 2:
+ h ^= (long) (data[tailStart + 1] & 0xff) << 8;
+ case 1:
+ h ^= (long) (data[tailStart] & 0xff);
+ h *= M_64;
+ }
+
+ // finalization
+ h ^= h >>> R_64;
+ h *= M_64;
+ h ^= h >>> R_64;
+
+ return h;
+ }
+} \ No newline at end of file
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 f9737eb62e..0fe1262b21 100644
--- a/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Converter.java
+++ b/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Converter.java
@@ -8,8 +8,8 @@ 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.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -21,26 +21,32 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
+import io.github.zekerzhayard.forgewrapper.installer.Download;
public class Converter {
- public static void convert(Path installerPath, Path targetDir) throws Exception {
- JsonObject installer = getInstallerJson(installerPath);
+ public static void convert(Path installerPath, Path targetDir, String cursepack) throws Exception {
+ if (cursepack != null) {
+ installerPath = getForgeInstallerFromCursePack(cursepack);
+ }
+
+ JsonObject installer = getJsonFromZip(installerPath, "version.json");
List<String> arguments = getAdditionalArgs(installer);
String mcVersion = arguments.get(arguments.indexOf("--fml.mcVersion") + 1);
String forgeVersion = arguments.get(arguments.indexOf("--fml.forgeVersion") + 1);
String forgeFullVersion = "forge-" + mcVersion + "-" + forgeVersion;
+ String instanceName = cursepack == null ? forgeFullVersion : installerPath.toFile().getName().replace("-installer.jar", "");
StringBuilder wrapperVersion = new StringBuilder();
JsonObject pack = convertPackJson(mcVersion);
- JsonObject patches = convertPatchesJson(installer, mcVersion, forgeVersion, wrapperVersion);
+ JsonObject patches = convertPatchesJson(installer, mcVersion, forgeVersion, wrapperVersion, cursepack);
Files.createDirectories(targetDir);
// Copy mmc-pack.json and instance.cfg to <instance> folder.
- Path instancePath = targetDir.resolve(forgeFullVersion);
+ Path instancePath = targetDir.resolve(instanceName);
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);
+ Files.copy(new ByteArrayInputStream(("InstanceType=OneSix\nname=" + instanceName).getBytes(StandardCharsets.UTF_8)), instancePath.resolve("instance.cfg"), StandardCopyOption.REPLACE_EXISTING);
// Copy ForgeWrapper to <instance>/libraries folder.
Path librariesPath = instancePath.resolve("libraries");
@@ -56,10 +62,22 @@ public class Converter {
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.
+ 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());
+ Files.createDirectories(targetFolder.getParent());
+ Files.copy(zip.getInputStream(entry), targetFolder, StandardCopyOption.REPLACE_EXISTING);
+ }
+ }
}
public static List<String> getAdditionalArgs(Path installerPath) {
- JsonObject installer = getInstallerJson(installerPath);
+ JsonObject installer = getJsonFromZip(installerPath, "version.json");
return getAdditionalArgs(installer);
}
@@ -69,12 +87,12 @@ public class Converter {
return args;
}
- public static JsonObject getInstallerJson(Path installerPath) {
+ public static JsonObject getJsonFromZip(Path path, String json) {
try {
- ZipFile zf = new ZipFile(installerPath.toFile());
- ZipEntry versionFile = zf.getEntry("version.json");
+ ZipFile zf = new ZipFile(path.toFile());
+ ZipEntry versionFile = zf.getEntry(json);
if (versionFile == null) {
- throw new RuntimeException("The forge installer is invalid!");
+ throw new RuntimeException("The zip file is invalid!");
}
InputStreamReader isr = new InputStreamReader(zf.getInputStream(versionFile), StandardCharsets.UTF_8);
return new JsonParser().parse(isr).getAsJsonObject();
@@ -83,6 +101,28 @@ public class Converter {
}
}
+ private static Path getForgeInstallerFromCursePack(String cursepack) throws Exception {
+ JsonObject manifest = getJsonFromZip(Paths.get(cursepack), "manifest.json");
+ JsonObject minecraft = getElement(manifest, "minecraft").getAsJsonObject();
+ String mcVersion = getElement(minecraft, "version").getAsString();
+ String forgeVersion = null;
+ for (JsonElement element : getElement(minecraft, "modLoaders").getAsJsonArray()) {
+ String id = getElement(element.getAsJsonObject(), "id").getAsString();
+ if (id.startsWith("forge-")) {
+ forgeVersion = id.replace("forge-", "");
+ break;
+ }
+ }
+ if (forgeVersion == null) {
+ throw new RuntimeException("The curse pack is invalid!");
+ }
+ 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());
+ return installer;
+ }
+
// Convert mmc-pack.json:
// - Replace Minecraft version
private static JsonObject convertPackJson(String mcVersion) {
@@ -102,7 +142,7 @@ public class Converter {
// - Add libraries
// - Add forge-launcher url
// - Replace Minecraft & Forge versions
- private static JsonObject convertPatchesJson(JsonObject installer, String mcVersion, String forgeVersion, StringBuilder wrapperVersion) {
+ private static JsonObject convertPatchesJson(JsonObject installer, String mcVersion, String forgeVersion, StringBuilder wrapperVersion, String cursepack) {
JsonObject patches = new JsonParser().parse(new InputStreamReader(Converter.class.getResourceAsStream("/patches/net.minecraftforge.json"))).getAsJsonObject();
JsonArray libraries = getElement(patches, "libraries").getAsJsonArray();
@@ -112,10 +152,16 @@ public class Converter {
wrapperVersion.append(getElement(lib.getAsJsonObject(), "MMC-filename").getAsString());
}
}
+ if (cursepack != null) {
+ JsonObject cursepacklocator = new JsonObject();
+ cursepacklocator.addProperty("name", "cpw.mods.forge:cursepacklocator:1.2.0");
+ 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.startsWith("net/minecraftforge/forge/")) {
+ 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);
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 a9d4c38e64..31f84be635 100644
--- a/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Main.java
+++ b/src/main/java/io/github/zekerzhayard/forgewrapper/converter/Main.java
@@ -4,21 +4,30 @@ 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;
+import java.util.HashMap;
+
+import io.github.zekerzhayard.forgewrapper.installer.Download;
public class Main {
public static void main(String[] args) {
- ArrayList<String> argsList = new ArrayList<>(Arrays.asList(args));
- Path installer, instance;
+ Path installer = null, instance = Paths.get(".");
+ String cursepack = null;
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));
+ HashMap<String, String> argsMap = parseArgs(args);
+ if (argsMap.containsKey("--installer")) {
+ 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());
+ }
+ if (argsMap.containsKey("--instance")) {
+ instance = Paths.get(argsMap.get("--instance"));
+ }
+ if (argsMap.containsKey("--cursepack")) {
+ cursepack = argsMap.get("--cursepack");
}
} catch (Exception e) {
- System.out.println("Invalid arguments! Use: java -jar <ForgeWrapper.jar> [--installer] <forge-installer.jar> [--instance <instance-path>]");
+ System.out.println("Invalid arguments! Use: java -jar <ForgeWrapper.jar> [--installer=<forge-installer.jar> | --cursepack=<curseforge-modpack.zip>] [--instance=<instance-path>]");
throw new RuntimeException(e);
}
@@ -27,11 +36,28 @@ public class Main {
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);
+ ucl.loadClass("io.github.zekerzhayard.forgewrapper.converter.Converter").getMethod("convert", Path.class, Path.class, String.class).invoke(null, installer, instance, cursepack);
System.out.println("Successfully install Forge for MultiMC!");
} catch (Exception e) {
System.out.println("Failed to install Forge!");
throw new RuntimeException(e);
}
}
+
+ /**
+ * @return installer -- The path of forge installer.<br/>
+ * instance -- The instance folder of MultiMC.<br/>
+ * cursepack -- The version of cursepacklocator.<br/>
+ */
+ private static HashMap<String, String> parseArgs(String[] args) {
+ HashMap<String, String> map = new HashMap<>();
+ for (String arg : args) {
+ String[] params = arg.split("=", 2);
+ map.put(params[0], params[1]);
+ }
+ if (!map.containsKey("--installer") && !map.containsKey("--cursepack")) {
+ throw new IllegalArgumentException();
+ }
+ return map;
+ }
}
diff --git a/src/main/java/io/github/zekerzhayard/forgewrapper/installer/Download.java b/src/main/java/io/github/zekerzhayard/forgewrapper/installer/Download.java
index 38846f5843..c89687fd2f 100644
--- a/src/main/java/io/github/zekerzhayard/forgewrapper/installer/Download.java
+++ b/src/main/java/io/github/zekerzhayard/forgewrapper/installer/Download.java
@@ -1,26 +1,28 @@
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;
-import org.apache.commons.codec.digest.DigestUtils;
-
public class Download {
- public static void download(String url, String location) throws IOException {
+ 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...");
- 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);
- String md5 = new String(Files.readAllBytes(Paths.get(location + ".md5")));
- String sha1 = new String(Files.readAllBytes(Paths.get(location + ".sha1")));
+ 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();
@@ -33,19 +35,31 @@ public class Download {
if (localFile.isDirectory()) {
throw new RuntimeException(location + " must be a file!");
}
- System.out.println("Downloading forge installer...");
+ 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 {
- String md5 = DigestUtils.md5Hex(Files.readAllBytes(Paths.get(path)));
+ 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 {
- String sha1 = DigestUtils.sha1Hex(Files.readAllBytes(Paths.get(path)));
+ 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;
+ }
}