mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 11:39:11 +03:00
[FEATURE] Download assets from mojang
This commit is contained in:
parent
bbb962c624
commit
81b80a7938
4 changed files with 100 additions and 9 deletions
|
@ -1,25 +1,39 @@
|
||||||
package pro.gravit.launchserver.command.hash;
|
package pro.gravit.launchserver.command.hash;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import pro.gravit.launcher.AsyncDownloader;
|
||||||
|
import pro.gravit.launcher.Launcher;
|
||||||
|
import pro.gravit.launchserver.HttpRequester;
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.command.Command;
|
import pro.gravit.launchserver.command.Command;
|
||||||
|
import pro.gravit.utils.Downloader;
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
|
import proguard.OutputWriter;
|
||||||
|
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.Writer;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public final class DownloadAssetCommand extends Command {
|
public final class DownloadAssetCommand extends Command {
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
private transient final Logger logger = LogManager.getLogger();
|
||||||
|
|
||||||
|
private static final String MINECRAFT_VERSIONS_URL = "https://launchermeta.mojang.com/mc/game/version_manifest.json";
|
||||||
|
|
||||||
|
private static final String RESOURCES_DOWNLOAD_URL = "https://resources.download.minecraft.net/";
|
||||||
|
|
||||||
public DownloadAssetCommand(LaunchServer server) {
|
public DownloadAssetCommand(LaunchServer server) {
|
||||||
super(server);
|
super(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getArgsDescription() {
|
public String getArgsDescription() {
|
||||||
return "[version] [dir]";
|
return "[version] [dir] (mojang/mirror)";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -32,20 +46,89 @@ public void invoke(String... args) throws Exception {
|
||||||
verifyArgs(args, 2);
|
verifyArgs(args, 2);
|
||||||
//Version version = Version.byName(args[0]);
|
//Version version = Version.byName(args[0]);
|
||||||
String versionName = args[0];
|
String versionName = args[0];
|
||||||
|
String type = args.length > 2 ? args[2] : "mojang";
|
||||||
String dirName = IOHelper.verifyFileName(args[1]);
|
String dirName = IOHelper.verifyFileName(args[1]);
|
||||||
Path assetDir = server.updatesDir.resolve(dirName);
|
Path assetDir = server.updatesDir.resolve(dirName);
|
||||||
|
|
||||||
// Create asset dir
|
// Create asset dir
|
||||||
logger.info("Creating asset dir: '{}'", dirName);
|
if(Files.notExists(assetDir)) {
|
||||||
Files.createDirectory(assetDir);
|
logger.info("Creating asset dir: '{}'", dirName);
|
||||||
|
Files.createDirectory(assetDir);
|
||||||
|
}
|
||||||
|
|
||||||
// Download required asset
|
if(type.equals("mojang")) {
|
||||||
logger.info("Downloading asset, it may take some time");
|
HttpRequester requester = new HttpRequester();
|
||||||
//HttpDownloader.downloadZip(server.mirrorManager.getDefaultMirror().getAssetsURL(version.name), assetDir);
|
logger.info("Fetch versions from {}", MINECRAFT_VERSIONS_URL);
|
||||||
server.mirrorManager.downloadZip(assetDir, "assets/%s.zip", versionName);
|
var versions = requester.send(requester.get(MINECRAFT_VERSIONS_URL, null), MinecraftVersions.class).getOrThrow();
|
||||||
|
String profileUrl = null;
|
||||||
|
for(var e : versions.versions) {
|
||||||
|
if(e.id.equals(versionName)) {
|
||||||
|
profileUrl = e.url;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(profileUrl == null) {
|
||||||
|
logger.error("Version {} not found", versionName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.info("Fetch profile {} from {}", versionName, profileUrl);
|
||||||
|
var profileInfo = requester.send(requester.get(profileUrl, null), MiniVersion.class).getOrThrow();
|
||||||
|
String assetsIndexUrl = profileInfo.assetIndex.url;
|
||||||
|
String assetIndex = profileInfo.assetIndex.id;
|
||||||
|
Path indexPath = assetDir.resolve("indexes").resolve(assetIndex+".json");
|
||||||
|
logger.info("Fetch asset index {} from {}", assetIndex, assetsIndexUrl);
|
||||||
|
JsonObject assets = requester.send(requester.get(assetsIndexUrl, null), JsonObject.class).getOrThrow();
|
||||||
|
JsonObject objects = assets.get("objects").getAsJsonObject();
|
||||||
|
try(Writer writer = IOHelper.newWriter(indexPath)) {
|
||||||
|
logger.info("Save {}", indexPath);
|
||||||
|
Launcher.gsonManager.configGson.toJson(assets, writer);
|
||||||
|
}
|
||||||
|
List<AsyncDownloader.SizedFile> toDownload = new ArrayList<>(128);
|
||||||
|
for(var e : objects.entrySet()) {
|
||||||
|
var value = e.getValue().getAsJsonObject();
|
||||||
|
var hash = value.get("hash").getAsString();
|
||||||
|
hash = hash.substring(0, 2) + "/" + hash;
|
||||||
|
var size = value.get("size").getAsLong();
|
||||||
|
var path = "objects/" + hash;
|
||||||
|
var target = assetDir.resolve(path);
|
||||||
|
if(Files.exists(target)) {
|
||||||
|
long fileSize = Files.size(target);
|
||||||
|
if(fileSize != size) {
|
||||||
|
logger.warn("File {} corrupted. Size {}, expected {}", target, size, fileSize);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toDownload.add(new AsyncDownloader.SizedFile(hash, path, size));
|
||||||
|
}
|
||||||
|
logger.info("Download {} files", toDownload.size());
|
||||||
|
Downloader downloader = downloadWithProgressBar(dirName, toDownload, RESOURCES_DOWNLOAD_URL, assetDir);
|
||||||
|
downloader.getFuture().get();
|
||||||
|
} else {
|
||||||
|
// Download required asset
|
||||||
|
logger.info("Downloading asset, it may take some time");
|
||||||
|
//HttpDownloader.downloadZip(server.mirrorManager.getDefaultMirror().getAssetsURL(version.name), assetDir);
|
||||||
|
server.mirrorManager.downloadZip(assetDir, "assets/%s.zip", versionName);
|
||||||
|
}
|
||||||
|
|
||||||
// Finished
|
// Finished
|
||||||
server.syncUpdatesDir(Collections.singleton(dirName));
|
server.syncUpdatesDir(Collections.singleton(dirName));
|
||||||
logger.info("Asset successfully downloaded: '{}'", dirName);
|
logger.info("Asset successfully downloaded: '{}'", dirName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record MiniVersionInfo(String id, String url) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public record MinecraftVersions(List<MiniVersionInfo> versions) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public record MinecraftAssetIndexInfo(String id, String url) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public record MiniVersion(MinecraftAssetIndexInfo assetIndex) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,6 +236,9 @@ public static MakeProfileOption[] getMakeProfileOptionsFromDir(Path dir, ClientP
|
||||||
if (Files.exists(dir.resolve("libraries/forge/launchwrapper-1.12-launcherfixed.jar.jar")) || Files.exists(dir.resolve("libraries/net/minecraft/launchwrapper"))) {
|
if (Files.exists(dir.resolve("libraries/forge/launchwrapper-1.12-launcherfixed.jar.jar")) || Files.exists(dir.resolve("libraries/net/minecraft/launchwrapper"))) {
|
||||||
options.add(new MakeProfileOptionLaunchWrapper());
|
options.add(new MakeProfileOptionLaunchWrapper());
|
||||||
}
|
}
|
||||||
|
if(globalAssets) {
|
||||||
|
options.add(new MakeProfileOptionGlobalAssets());
|
||||||
|
}
|
||||||
return options.toArray(new MakeProfileOption[0]);
|
return options.toArray(new MakeProfileOption[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,9 @@ public static void main(String[] args) throws Throwable {
|
||||||
|
|
||||||
// Verify ClientLauncher sign and classpath
|
// Verify ClientLauncher sign and classpath
|
||||||
LogHelper.debug("Verifying ClientLauncher sign and classpath");
|
LogHelper.debug("Verifying ClientLauncher sign and classpath");
|
||||||
List<Path> classpath = resolveClassPath(clientDir, params.actions, params.profile).collect(Collectors.toList());
|
List<Path> classpath = resolveClassPath(clientDir, params.actions, params.profile)
|
||||||
|
.filter(x -> !profile.getModulePath().contains(clientDir.relativize(x).toString()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
List<URL> classpathURLs = classpath.stream().map(IOHelper::toURL).collect(Collectors.toList());
|
List<URL> classpathURLs = classpath.stream().map(IOHelper::toURL).collect(Collectors.toList());
|
||||||
// Start client with WatchService monitoring
|
// Start client with WatchService monitoring
|
||||||
RequestService service;
|
RequestService service;
|
||||||
|
|
|
@ -153,7 +153,10 @@ public void start(boolean pipeOutput) throws IOException, InterruptedException {
|
||||||
if (params.profile.getClassLoaderConfig() == ClientProfile.ClassLoaderConfig.AGENT) {
|
if (params.profile.getClassLoaderConfig() == ClientProfile.ClassLoaderConfig.AGENT) {
|
||||||
processArgs.add("-javaagent:".concat(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toAbsolutePath().toString()));
|
processArgs.add("-javaagent:".concat(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toAbsolutePath().toString()));
|
||||||
} else if (params.profile.getClassLoaderConfig() == ClientProfile.ClassLoaderConfig.SYSTEM_ARGS) {
|
} else if (params.profile.getClassLoaderConfig() == ClientProfile.ClassLoaderConfig.SYSTEM_ARGS) {
|
||||||
systemClassPath.addAll(ClientLauncherEntryPoint.resolveClassPath(workDir, params.actions, params.profile).map(Path::toString).collect(Collectors.toList()));
|
systemClassPath.addAll(ClientLauncherEntryPoint.resolveClassPath(workDir, params.actions, params.profile)
|
||||||
|
.filter(x -> !params.profile.getModulePath().contains(workDir.relativize(x).toString()))
|
||||||
|
.map(Path::toString)
|
||||||
|
.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
if(Launcher.getConfig().environment != LauncherConfig.LauncherEnvironment.PROD) {
|
if(Launcher.getConfig().environment != LauncherConfig.LauncherEnvironment.PROD) {
|
||||||
processArgs.add(JVMHelper.jvmProperty(LogHelper.DEV_PROPERTY, String.valueOf(LogHelper.isDevEnabled())));
|
processArgs.add(JVMHelper.jvmProperty(LogHelper.DEV_PROPERTY, String.valueOf(LogHelper.isDevEnabled())));
|
||||||
|
|
Loading…
Reference in a new issue