mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 03:31:15 +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;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
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.command.Command;
|
||||
import pro.gravit.utils.Downloader;
|
||||
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.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public final class DownloadAssetCommand extends Command {
|
||||
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) {
|
||||
super(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArgsDescription() {
|
||||
return "[version] [dir]";
|
||||
return "[version] [dir] (mojang/mirror)";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,20 +46,89 @@ public void invoke(String... args) throws Exception {
|
|||
verifyArgs(args, 2);
|
||||
//Version version = Version.byName(args[0]);
|
||||
String versionName = args[0];
|
||||
String type = args.length > 2 ? args[2] : "mojang";
|
||||
String dirName = IOHelper.verifyFileName(args[1]);
|
||||
Path assetDir = server.updatesDir.resolve(dirName);
|
||||
|
||||
// Create asset dir
|
||||
if(Files.notExists(assetDir)) {
|
||||
logger.info("Creating asset dir: '{}'", dirName);
|
||||
Files.createDirectory(assetDir);
|
||||
}
|
||||
|
||||
if(type.equals("mojang")) {
|
||||
HttpRequester requester = new HttpRequester();
|
||||
logger.info("Fetch versions from {}", MINECRAFT_VERSIONS_URL);
|
||||
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
|
||||
server.syncUpdatesDir(Collections.singleton(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"))) {
|
||||
options.add(new MakeProfileOptionLaunchWrapper());
|
||||
}
|
||||
if(globalAssets) {
|
||||
options.add(new MakeProfileOptionGlobalAssets());
|
||||
}
|
||||
return options.toArray(new MakeProfileOption[0]);
|
||||
}
|
||||
|
||||
|
|
|
@ -115,7 +115,9 @@ public static void main(String[] args) throws Throwable {
|
|||
|
||||
// Verify 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());
|
||||
// Start client with WatchService monitoring
|
||||
RequestService service;
|
||||
|
|
|
@ -153,7 +153,10 @@ public void start(boolean pipeOutput) throws IOException, InterruptedException {
|
|||
if (params.profile.getClassLoaderConfig() == ClientProfile.ClassLoaderConfig.AGENT) {
|
||||
processArgs.add("-javaagent:".concat(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toAbsolutePath().toString()));
|
||||
} 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) {
|
||||
processArgs.add(JVMHelper.jvmProperty(LogHelper.DEV_PROPERTY, String.valueOf(LogHelper.isDevEnabled())));
|
||||
|
|
Loading…
Reference in a new issue