Created
June 26, 2019 11:24
-
-
Save Runemoro/6890bcadae617ed91e8ee79680e9769a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package downloader; | |
import downloader.mlp.LauncherJsonHelper; | |
import downloader.mlp.Version; | |
import downloader.mlp.VersionManifest; | |
import net.fabricmc.stitch.merge.JarMerger; | |
import java.io.*; | |
import java.net.URL; | |
import java.nio.file.Files; | |
import java.nio.file.StandardCopyOption; | |
import java.security.MessageDigest; | |
import java.security.NoSuchAlgorithmException; | |
import java.util.LinkedHashSet; | |
import java.util.Map; | |
import java.util.Scanner; | |
import java.util.Set; | |
public class Downloader { | |
private static final String VERSION_MANIFEST = "https://launchermeta.mojang.com/mc/game/version_manifest.json"; | |
public static void main(String[] args) throws Exception { | |
VersionManifest versionManifest = readJson(new URL(VERSION_MANIFEST), VersionManifest.class); | |
for (Map.Entry<String, String> entry : versionManifest.latest.entrySet()) { | |
System.out.println("Latest '" + entry.getKey() + "' version is '" + entry.getValue() + "'"); | |
} | |
String versionId = ask("Minecraft version", versionManifest.latest.get("snapshot")); | |
URL versionUrl = versionManifest.versions.stream() | |
.filter(version -> version.id.equals(versionId)) | |
.findFirst() | |
.orElseThrow(() -> new IllegalArgumentException("version not found: " + versionId)) | |
.url; | |
Version version = readJson(versionUrl, Version.class); | |
File clientJar = null; | |
File serverJar = null; | |
for (Map.Entry<String, Version.Download> entry : version.downloads.entrySet()) { | |
File file = new File("tmp", version.id + "_" + entry.getKey() + ".jar"); | |
if (entry.getKey().equals("client")) { | |
clientJar = file; | |
} else if (entry.getKey().equals("server")) { | |
serverJar = file; | |
} else { | |
throw new IllegalStateException("unknown jar type " + entry); | |
} | |
System.out.println("Downloading " + entry.getKey()); | |
downloadIfAbsent(entry.getValue().url, file, entry.getValue().sha1); | |
} | |
Set<File> libs = new LinkedHashSet<>(); | |
for (Version.Library library : version.libraries) { | |
Version.Download artifact = library.downloads.artifact; | |
File file = new File("tmp/libs", artifact.path); | |
libs.add(file); | |
System.out.println("Downloading library " + library.name); | |
downloadIfAbsent(artifact.url, file, artifact.sha1); | |
} | |
System.out.println("Creating merged jar"); | |
File mergedJar = new File("tmp", version.id + "_merged.jar"); | |
try (JarMerger merger = new JarMerger(clientJar, serverJar, mergedJar)) { | |
merger.enableSnowmanRemoval(); | |
merger.merge(); | |
} | |
} | |
private static void downloadIfAbsent(URL url, File file, String sha1) throws IOException { | |
if (!file.exists() || !sha1(file).equals(sha1)) { | |
file.getParentFile().mkdirs(); | |
try (InputStream in = url.openStream()) { | |
Files.copy(in, file.toPath(), StandardCopyOption.REPLACE_EXISTING); | |
} | |
} | |
} | |
private static String sha1(File file) throws IOException { | |
try { | |
byte[] hash = MessageDigest.getInstance("SHA1").digest(Files.readAllBytes(file.toPath())); | |
StringBuilder sb = new StringBuilder(); | |
for (byte b : hash) { | |
sb.append(String.format("%02x", b)); | |
} | |
return sb.toString(); | |
} catch (NoSuchAlgorithmException e) { | |
throw new AssertionError(e); | |
} | |
} | |
private static <T> T readJson(URL url, Class<T> classOfT) throws IOException { | |
T t; | |
try (Reader reader = new InputStreamReader(url.openStream())) { | |
t = LauncherJsonHelper.GSON.fromJson(reader, classOfT); | |
} | |
return t; | |
} | |
private static String ask(String message, String fallback) { | |
System.out.print(message + (fallback == null ? "" : " (or blank for " + fallback + ")") + ": "); | |
String result = new Scanner(System.in).nextLine().trim(); | |
return result.isEmpty() ? fallback : result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment