From e1062303df84e8f1afd0f2cb0e5cd02f6ac7863f Mon Sep 17 00:00:00 2001 From: Henry Le Grys Date: Wed, 2 Dec 2020 04:14:29 +0000 Subject: [PATCH] Fix argument passing & add back commandline for legacy versions - Game/jvm arguments are now passed one-at-a-time, never grouped - Added support for legacy version manifests by adding in the missing arguments - Correctly pull arguments from old manifests - Some slightly hacky handling for old library stanzas - Short-circuit if library URL has empty path to prevent accidentally downloading HTML pages as jars - Add launcherShortname prop, passed to --versionType --- .../launcher/builder/PackageBuilder.java | 8 +++- .../loaders/ModernForgeLoaderProcessor.java | 2 +- .../loaders/OldForgeLoaderProcessor.java | 14 ++---- .../com/skcraft/launcher/launch/Runner.java | 46 +++++++++++++++---- .../model/loader/BasicInstallProfile.java | 1 + .../launcher/model/loader/VersionInfo.java | 10 +--- .../launcher/model/minecraft/FeatureList.java | 4 ++ .../model/minecraft/GameArgument.java | 2 +- .../launcher/model/minecraft/Library.java | 19 ++++++++ .../com/skcraft/launcher/launcher.properties | 1 + 10 files changed, 78 insertions(+), 29 deletions(-) diff --git a/launcher-builder/src/main/java/com/skcraft/launcher/builder/PackageBuilder.java b/launcher-builder/src/main/java/com/skcraft/launcher/builder/PackageBuilder.java index 9cbbbd8..b079be5 100644 --- a/launcher-builder/src/main/java/com/skcraft/launcher/builder/PackageBuilder.java +++ b/launcher-builder/src/main/java/com/skcraft/launcher/builder/PackageBuilder.java @@ -233,7 +233,11 @@ public class PackageBuilder { private boolean tryDownloadLibrary(Library library, Library.Artifact artifact, String baseUrl, File outputPath) throws IOException, InterruptedException { URL url = new URL(baseUrl); - File tempFile = File.createTempFile("launcherlib", null); + + if (url.getPath().isEmpty() || url.getPath().equals("/")) { + // empty path, this is probably the first "is this a full URL" try. + return false; + } // Some repositories compress their files List compressors = BuilderUtils.getCompressors(baseUrl); @@ -241,6 +245,8 @@ public class PackageBuilder { url = new URL(url, compressor.transformPathname(artifact.getPath())); } + File tempFile = File.createTempFile("launcherlib", null); + try { log.info("Downloading library " + library.getName() + " from " + url + "..."); HttpRequest.get(url).execute().expectResponseCode(200).saveContent(tempFile); diff --git a/launcher-builder/src/main/java/com/skcraft/launcher/builder/loaders/ModernForgeLoaderProcessor.java b/launcher-builder/src/main/java/com/skcraft/launcher/builder/loaders/ModernForgeLoaderProcessor.java index ab6d658..96f0175 100644 --- a/launcher-builder/src/main/java/com/skcraft/launcher/builder/loaders/ModernForgeLoaderProcessor.java +++ b/launcher-builder/src/main/java/com/skcraft/launcher/builder/loaders/ModernForgeLoaderProcessor.java @@ -52,7 +52,7 @@ public class ModernForgeLoaderProcessor implements ILoaderProcessor { } // Copy tweak class arguments - List gameArguments = info.getMinecraftArguments().getGameArguments(); + List gameArguments = info.getArguments().getGameArguments(); if (gameArguments != null) { version.getArguments().getGameArguments().addAll(gameArguments); } diff --git a/launcher-builder/src/main/java/com/skcraft/launcher/builder/loaders/OldForgeLoaderProcessor.java b/launcher-builder/src/main/java/com/skcraft/launcher/builder/loaders/OldForgeLoaderProcessor.java index b4151c6..8daa555 100644 --- a/launcher-builder/src/main/java/com/skcraft/launcher/builder/loaders/OldForgeLoaderProcessor.java +++ b/launcher-builder/src/main/java/com/skcraft/launcher/builder/loaders/OldForgeLoaderProcessor.java @@ -1,7 +1,6 @@ package com.skcraft.launcher.builder.loaders; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.Lists; import com.google.common.io.ByteStreams; import com.google.common.io.Closer; import com.google.common.io.Files; @@ -12,7 +11,6 @@ import com.skcraft.launcher.model.minecraft.Library; import com.skcraft.launcher.model.minecraft.MinecraftArguments; import com.skcraft.launcher.model.minecraft.VersionManifest; import com.skcraft.launcher.model.modpack.Manifest; -import com.skcraft.launcher.util.Environment; import lombok.extern.java.Log; import java.io.File; @@ -44,7 +42,7 @@ public class OldForgeLoaderProcessor implements ILoaderProcessor { VersionManifest version = manifest.getVersionManifest(); // Copy tweak class arguments - MinecraftArguments args = profile.getVersionInfo().getMinecraftArguments(); + MinecraftArguments args = profile.getVersionInfo().getArguments(); if (args != null) { Iterator iter = args.getGameArguments().iterator(); while (iter.hasNext()) { @@ -54,8 +52,9 @@ public class OldForgeLoaderProcessor implements ILoaderProcessor { ? cur.getValues().get(1) : iter.next().getJoinedValue(); - GameArgument tweakArg = new GameArgument(Lists.newArrayList("--tweakClass", tweakClass)); - manifest.getVersionManifest().getArguments().getGameArguments().add(tweakArg); + List gameArgs = manifest.getVersionManifest().getArguments().getGameArguments(); + gameArgs.add(new GameArgument("--tweakClass")); + gameArgs.add(new GameArgument(tweakClass)); log.info(String.format("Adding tweak class '%s' to arguments", tweakClass)); } @@ -87,11 +86,8 @@ public class OldForgeLoaderProcessor implements ILoaderProcessor { ZipEntry libraryEntry = BuilderUtils.getZipEntry(jarFile, filePath); if (libraryEntry != null) { - Library library = new Library(); - library.setName(libraryPath); - File librariesDir = new File(baseDir, manifest.getLibrariesLocation()); - File extractPath = new File(librariesDir, library.getPath(Environment.getInstance())); + File extractPath = new File(librariesDir, Library.mavenNameToPath(libraryPath)); Files.createParentDirs(extractPath); ByteStreams.copy(closer.register(jarFile.getInputStream(libraryEntry)), diff --git a/launcher/src/main/java/com/skcraft/launcher/launch/Runner.java b/launcher/src/main/java/com/skcraft/launcher/launch/Runner.java index 0b40dd7..c0cd5c5 100644 --- a/launcher/src/main/java/com/skcraft/launcher/launch/Runner.java +++ b/launcher/src/main/java/com/skcraft/launcher/launch/Runner.java @@ -131,6 +131,8 @@ public class Runner implements Callable, ProgressObservable { } progress = new DefaultProgress(0.9, SharedLocale.tr("runner.collectingArgs")); + builder.classPath(getJarPath()); + builder.setMainClass(versionManifest.getMainClass()); addWindowArgs(); addLibraries(); @@ -141,9 +143,6 @@ public class Runner implements Callable, ProgressObservable { addPlatformArgs(); addLegacyArgs(); - builder.classPath(getJarPath()); - builder.setMainClass(versionManifest.getMainClass()); - callLaunchModifier(); ProcessBuilder processBuilder = new ProcessBuilder(builder.buildCommand()); @@ -249,7 +248,6 @@ public class Runner implements Callable, ProgressObservable { List flags = builder.getFlags(); String rawJvmArgs = config.getJvmArgs(); if (!Strings.isNullOrEmpty(rawJvmArgs)) { - for (String arg : JavaProcessBuilder.splitArgs(rawJvmArgs)) { flags.add(arg); } @@ -258,8 +256,10 @@ public class Runner implements Callable, ProgressObservable { List javaArguments = versionManifest.getArguments().getJvmArguments(); StrSubstitutor substitutor = new StrSubstitutor(getCommandSubstitutions()); for (GameArgument arg : javaArguments) { - if (arg.resolveRules(environment, featureList)) { - flags.add(substitutor.replace(arg.getJoinedValue())); + if (arg.shouldApply(environment, featureList)) { + for (String subArg : arg.getValues()) { + flags.add(substitutor.replace(subArg)); + } } } } @@ -275,8 +275,10 @@ public class Runner implements Callable, ProgressObservable { List rawArgs = versionManifest.getArguments().getGameArguments(); StrSubstitutor substitutor = new StrSubstitutor(getCommandSubstitutions()); for (GameArgument arg : rawArgs) { - if (arg.resolveRules(environment, featureList)) { - args.add(substitutor.replace(arg.getJoinedValue())); + if (arg.shouldApply(environment, featureList)) { + for (String subArg : arg.getValues()) { + args.add(substitutor.replace(subArg)); + } } } } @@ -343,7 +345,32 @@ public class Runner implements Callable, ProgressObservable { * Add arguments to make legacy Minecraft work. */ private void addLegacyArgs() { - builder.getFlags().add("-Dminecraft.applet.TargetDirectory=" + instance.getContentDir()); + List flags = builder.getFlags(); + + if (versionManifest.getMinimumLauncherVersion() < 21) { + // Add bits that the legacy manifests don't + flags.add("-Djava.library.path=" + extractDir.getAbsoluteFile()); + flags.add("-cp"); + flags.add(builder.buildClassPath()); + + if (featureList.hasFeature("has_custom_resolution")) { + List args = builder.getArgs(); + args.add("--width"); + args.add(String.valueOf(config.getWindowWidth())); + args.add("--height"); + args.add(String.valueOf(config.getWidowHeight())); + } + + // Add old platform hacks that the new manifests already specify + if (getEnvironment().getPlatform() == Platform.WINDOWS) { + flags.add("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump"); + } + } + + if (versionManifest.getMinimumLauncherVersion() < 18) { + // TODO find out exactly what versions need this hack. + flags.add("-Dminecraft.applet.TargetDirectory=" + instance.getContentDir()); + } } /** @@ -356,6 +383,7 @@ public class Runner implements Callable, ProgressObservable { Map map = new HashMap(); map.put("version_name", versionManifest.getId()); + map.put("version_type", launcher.getProperties().getProperty("launcherShortname")); map.put("auth_access_token", session.getAccessToken()); map.put("auth_session", session.getSessionToken()); diff --git a/launcher/src/main/java/com/skcraft/launcher/model/loader/BasicInstallProfile.java b/launcher/src/main/java/com/skcraft/launcher/model/loader/BasicInstallProfile.java index 1d774a8..b5f5f2f 100644 --- a/launcher/src/main/java/com/skcraft/launcher/model/loader/BasicInstallProfile.java +++ b/launcher/src/main/java/com/skcraft/launcher/model/loader/BasicInstallProfile.java @@ -28,6 +28,7 @@ public class BasicInstallProfile { } @Data + @JsonIgnoreProperties(ignoreUnknown = true) public static class Legacy { private String profileName; } diff --git a/launcher/src/main/java/com/skcraft/launcher/model/loader/VersionInfo.java b/launcher/src/main/java/com/skcraft/launcher/model/loader/VersionInfo.java index a4625ab..55908d5 100644 --- a/launcher/src/main/java/com/skcraft/launcher/model/loader/VersionInfo.java +++ b/launcher/src/main/java/com/skcraft/launcher/model/loader/VersionInfo.java @@ -7,7 +7,6 @@ package com.skcraft.launcher.model.loader; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.Splitter; import com.skcraft.launcher.model.minecraft.GameArgument; import com.skcraft.launcher.model.minecraft.Library; @@ -21,15 +20,10 @@ import java.util.List; @JsonIgnoreProperties(ignoreUnknown = true) public class VersionInfo { private String id; - @JsonProperty("arguments") - private MinecraftArguments minecraftArguments; + private MinecraftArguments arguments; private String mainClass; private List libraries; - public void setMinecraftArguments(MinecraftArguments arguments) { - this.minecraftArguments = arguments; - } - public void setMinecraftArguments(String argumentString) { MinecraftArguments minecraftArguments = new MinecraftArguments(); minecraftArguments.setGameArguments(new ArrayList()); @@ -38,6 +32,6 @@ public class VersionInfo { minecraftArguments.getGameArguments().add(new GameArgument(arg)); } - setMinecraftArguments(minecraftArguments); + setArguments(minecraftArguments); } } diff --git a/launcher/src/main/java/com/skcraft/launcher/model/minecraft/FeatureList.java b/launcher/src/main/java/com/skcraft/launcher/model/minecraft/FeatureList.java index 9e0adbb..a32bcc1 100644 --- a/launcher/src/main/java/com/skcraft/launcher/model/minecraft/FeatureList.java +++ b/launcher/src/main/java/com/skcraft/launcher/model/minecraft/FeatureList.java @@ -22,6 +22,10 @@ public class FeatureList { return true; } + public boolean hasFeature(String key) { + return features.get(key) != null && features.get(key); + } + public static class Mutable extends FeatureList { public void addFeature(String key, boolean value) { features.put(key, value); diff --git a/launcher/src/main/java/com/skcraft/launcher/model/minecraft/GameArgument.java b/launcher/src/main/java/com/skcraft/launcher/model/minecraft/GameArgument.java index 9f52c4b..bc4bfbd 100644 --- a/launcher/src/main/java/com/skcraft/launcher/model/minecraft/GameArgument.java +++ b/launcher/src/main/java/com/skcraft/launcher/model/minecraft/GameArgument.java @@ -35,7 +35,7 @@ public class GameArgument { return Joiner.on(' ').join(values); } - public boolean resolveRules(Environment environment, FeatureList featureList) { + public boolean shouldApply(Environment environment, FeatureList featureList) { if (getRules() == null) return true; boolean result = false; diff --git a/launcher/src/main/java/com/skcraft/launcher/model/minecraft/Library.java b/launcher/src/main/java/com/skcraft/launcher/model/minecraft/Library.java index 9a039f6..a6acd7f 100644 --- a/launcher/src/main/java/com/skcraft/launcher/model/minecraft/Library.java +++ b/launcher/src/main/java/com/skcraft/launcher/model/minecraft/Library.java @@ -121,6 +121,25 @@ public class Library { private Map classifiers; } + // Support for old Forge distributions with legacy library specs. + public void setUrl(String url) { + Artifact virtualArtifact = new Artifact(); + + virtualArtifact.setUrl(url); + virtualArtifact.setPath(mavenNameToPath(name)); + + Downloads downloads = new Downloads(); + downloads.setArtifact(virtualArtifact); + + setDownloads(downloads); + } + + public void setServerreq(boolean value) { + if (value) { + setUrl("https://libraries.minecraft.net/"); // TODO do something better than this + } + } + public static String mavenNameToPath(String mavenName) { List split = Splitter.on(':').splitToList(mavenName); int size = split.size(); diff --git a/launcher/src/main/resources/com/skcraft/launcher/launcher.properties b/launcher/src/main/resources/com/skcraft/launcher/launcher.properties index 29bcf81..67119ca 100644 --- a/launcher/src/main/resources/com/skcraft/launcher/launcher.properties +++ b/launcher/src/main/resources/com/skcraft/launcher/launcher.properties @@ -6,6 +6,7 @@ version=${project.version} agentName=Minecraft +launcherShortname=SKCLauncher offlinePlayerName=Player versionManifestUrl=https://launchermeta.mojang.com/mc/game/version_manifest.json