1
0
mirror of https://github.com/SKCraft/Launcher.git synced 2025-01-05 19:09:03 +01:00

Update launcher/runner component to new models

- Fix game arguments being missing from version manifest due to new format
- Update Runner to use more substitutions & support new argument model
- Move loader/installer libraries to their own section to avoid runtime conflicts
- Implement some basic feature matching for arguments
This commit is contained in:
Henry Le Grys 2020-12-01 23:41:55 +00:00
parent 410031a86f
commit 86247c98a9
20 changed files with 330 additions and 108 deletions

View File

@ -11,6 +11,7 @@ import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
@ -72,6 +73,8 @@ public class TestServerBuilder {
server.setHandler(gzip);
gzip.setHandler(contexts);
server.addBean(new ErrorHandler());
return new TestServer(server);
}

View File

@ -12,8 +12,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.io.ByteStreams;
import com.google.common.io.CharStreams;
@ -25,10 +24,7 @@ import com.skcraft.launcher.model.loader.InstallProfile;
import com.skcraft.launcher.model.loader.LoaderManifest;
import com.skcraft.launcher.model.loader.SidedData;
import com.skcraft.launcher.model.loader.VersionInfo;
import com.skcraft.launcher.model.minecraft.Library;
import com.skcraft.launcher.model.minecraft.ReleaseList;
import com.skcraft.launcher.model.minecraft.Version;
import com.skcraft.launcher.model.minecraft.VersionManifest;
import com.skcraft.launcher.model.minecraft.*;
import com.skcraft.launcher.model.modpack.DownloadableFile;
import com.skcraft.launcher.model.modpack.Manifest;
import com.skcraft.launcher.util.Environment;
@ -75,6 +71,7 @@ public class PackageBuilder {
private File baseDir;
private List<Library> loaderLibraries = Lists.newArrayList();
private List<Library> installerLibraries = Lists.newArrayList();
private List<String> mavenRepos;
private List<URL> jarMavens = Lists.newArrayList();
@ -176,12 +173,9 @@ public class PackageBuilder {
}
// Copy tweak class arguments
List<String> gameArguments = info.getMinecraftArguments().getGameArguments();
List<GameArgument> gameArguments = info.getMinecraftArguments().getGameArguments();
if (gameArguments != null) {
String args = Joiner.on(' ').join(gameArguments);
String existingArgs = Strings.nullToEmpty(version.getMinecraftArguments());
version.setMinecraftArguments(Joiner.on(' ').join(existingArgs, args));
version.getArguments().getGameArguments().addAll(gameArguments);
}
// Add libraries
@ -213,7 +207,7 @@ public class PackageBuilder {
InstallProfile profile = mapper.readValue(data, InstallProfile.class);
// Import the libraries for the installer
loaderLibraries.addAll(profile.getLibraries());
installerLibraries.addAll(profile.getLibraries());
// Extract the data files
List<DownloadableFile> extraFiles = Lists.newArrayList();
@ -243,7 +237,7 @@ public class PackageBuilder {
profile.getData().put("SIDE", SidedData.create("client", "server"));
// Add loader manifest to the map
manifest.getLoaders().put(loaderName, new LoaderManifest(profile.getData(), extraFiles));
manifest.getLoaders().put(loaderName, new LoaderManifest(profile.getLibraries(), profile.getData(), extraFiles));
// Add processors
manifest.getTasks().addAll(profile.toProcessorEntries(loaderName));
@ -266,7 +260,7 @@ public class PackageBuilder {
// TODO: Download libraries for different environments -- As of writing, this is not an issue
Environment env = Environment.getInstance();
for (Library library : loaderLibraries) {
for (Library library : Iterables.concat(loaderLibraries, installerLibraries)) {
Library.Artifact artifact = library.getArtifact(env);
File outputPath = new File(librariesDir, artifact.getPath());

View File

@ -137,6 +137,15 @@ public final class Launcher {
}
}
/**
* Get the launcher title.
*
* @return The launcher title.
*/
public String getTitle() {
return tr("launcher.appTitle");
}
/**
* Get the launcher version.
*

View File

@ -52,7 +52,7 @@ public class ProcessorTask implements InstallTask {
Map<String, String> outputs = processor.resolveOutputs(resolver);
message = "Finding libraries";
Library execFile = versionManifest.findLibrary(processor.getJar());
Library execFile = loaderManifest.findLibrary(processor.getJar());
File jar = launcher.getLibraryFile(execFile);
JarFile jarFile = new JarFile(jar);
@ -68,7 +68,7 @@ public class ProcessorTask implements InstallTask {
int total = processor.getClasspath().size();
for (String libraryName : processor.getClasspath()) {
message = "Adding library " + libraryName;
File libraryFile = launcher.getLibraryFile(versionManifest.findLibrary(libraryName));
File libraryFile = launcher.getLibraryFile(loaderManifest.findLibrary(libraryName));
if (!libraryFile.exists()) {
throw new RuntimeException(String.format("Missing library '%s' for processor '%s'",
libraryName, processor.getJar()));

View File

@ -106,9 +106,6 @@ public class JavaProcessBuilder {
command.add("-XX:MaxPermSize=" + String.valueOf(permGen) + "M");
}
command.add("-cp");
command.add(buildClassPath());
command.add(mainClass);
for (String arg : args) {

View File

@ -15,9 +15,7 @@ import com.skcraft.concurrency.ProgressObservable;
import com.skcraft.launcher.*;
import com.skcraft.launcher.auth.Session;
import com.skcraft.launcher.install.ZipExtract;
import com.skcraft.launcher.model.minecraft.AssetsIndex;
import com.skcraft.launcher.model.minecraft.Library;
import com.skcraft.launcher.model.minecraft.VersionManifest;
import com.skcraft.launcher.model.minecraft.*;
import com.skcraft.launcher.persistence.Persistence;
import com.skcraft.launcher.util.Environment;
import com.skcraft.launcher.util.Platform;
@ -60,6 +58,7 @@ public class Runner implements Callable<Process>, ProgressObservable {
private Configuration config;
private JavaProcessBuilder builder;
private AssetsRoot assetsRoot;
private FeatureList.Mutable featureList;
/**
* Create a new instance launcher.
@ -75,6 +74,7 @@ public class Runner implements Callable<Process>, ProgressObservable {
this.instance = instance;
this.session = session;
this.extractDir = extractDir;
this.featureList = new FeatureList.Mutable();
}
/**
@ -132,12 +132,12 @@ public class Runner implements Callable<Process>, ProgressObservable {
progress = new DefaultProgress(0.9, SharedLocale.tr("runner.collectingArgs"));
addJvmArgs();
addWindowArgs();
addLibraries();
addJvmArgs();
addJarArgs();
addProxyArgs();
addServerArgs();
addWindowArgs();
addPlatformArgs();
addLegacyArgs();
@ -175,11 +175,6 @@ public class Runner implements Callable<Process>, ProgressObservable {
builder.getFlags().add("-Xdock:name=Minecraft");
}
}
// Windows arguments
if (getEnvironment().getPlatform() == Platform.WINDOWS) {
builder.getFlags().add("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump");
}
}
/**
@ -210,8 +205,6 @@ public class Runner implements Callable<Process>, ProgressObservable {
tr("runner.missingLibrary", instance.getTitle(), library.getName()));
}
}
builder.getFlags().add("-Djava.library.path=" + extractDir.getAbsoluteFile());
}
/**
@ -253,14 +246,22 @@ public class Runner implements Callable<Process>, ProgressObservable {
builder.tryJvmPath(new File(rawJvmPath));
}
List<String> flags = builder.getFlags();
String rawJvmArgs = config.getJvmArgs();
if (!Strings.isNullOrEmpty(rawJvmArgs)) {
List<String> flags = builder.getFlags();
for (String arg : JavaProcessBuilder.splitArgs(rawJvmArgs)) {
flags.add(arg);
}
}
List<GameArgument> javaArguments = versionManifest.getArguments().getJvmArguments();
StrSubstitutor substitutor = new StrSubstitutor(getCommandSubstitutions());
for (GameArgument arg : javaArguments) {
if (arg.resolveRules(environment, featureList)) {
flags.add(substitutor.replace(arg.getJoinedValue()));
}
}
}
/**
@ -271,10 +272,12 @@ public class Runner implements Callable<Process>, ProgressObservable {
private void addJarArgs() throws JsonProcessingException {
List<String> args = builder.getArgs();
String[] rawArgs = versionManifest.getMinecraftArguments().split(" +");
List<GameArgument> rawArgs = versionManifest.getArguments().getGameArguments();
StrSubstitutor substitutor = new StrSubstitutor(getCommandSubstitutions());
for (String arg : rawArgs) {
args.add(substitutor.replace(arg));
for (GameArgument arg : rawArgs) {
if (arg.resolveRules(environment, featureList)) {
args.add(substitutor.replace(arg.getJoinedValue()));
}
}
}
@ -329,15 +332,10 @@ public class Runner implements Callable<Process>, ProgressObservable {
* Add window arguments.
*/
private void addWindowArgs() {
List<String> args = builder.getArgs();
int width = config.getWindowWidth();
int height = config.getWidowHeight();
if (width >= 10) {
args.add("--width");
args.add(String.valueOf(width));
args.add("--height");
args.add(String.valueOf(height));
featureList.addFeature("has_custom_resolution", true);
}
}
@ -373,6 +371,14 @@ public class Runner implements Callable<Process>, ProgressObservable {
map.put("assets_root", launcher.getAssets().getDir().getAbsolutePath());
map.put("assets_index_name", versionManifest.getAssetId());
map.put("resolution_width", String.valueOf(config.getWindowWidth()));
map.put("resolution_height", String.valueOf(config.getWidowHeight()));
map.put("launcher_name", launcher.getTitle());
map.put("launcher_version", launcher.getVersion());
map.put("classpath", builder.buildClassPath());
map.put("natives_directory", extractDir.getAbsolutePath());
return map;
}

View File

@ -1,5 +1,6 @@
package com.skcraft.launcher.model.loader;
import com.skcraft.launcher.model.minecraft.Library;
import com.skcraft.launcher.model.modpack.DownloadableFile;
import lombok.AllArgsConstructor;
import lombok.Data;
@ -12,6 +13,17 @@ import java.util.Map;
@AllArgsConstructor
@NoArgsConstructor
public class LoaderManifest {
private List<Library> libraries;
private Map<String, SidedData> sidedData;
private List<DownloadableFile> downloadableFiles;
public Library findLibrary(String name) {
for (Library library : getLibraries()) {
if (library.getName().equals(name)) {
return library;
}
}
return null;
}
}

View File

@ -2,7 +2,6 @@ package com.skcraft.launcher.model.loader;
import com.skcraft.launcher.model.minecraft.Library;
import com.skcraft.launcher.model.minecraft.Side;
import com.skcraft.launcher.model.minecraft.VersionManifest;
import com.skcraft.launcher.model.modpack.DownloadableFile;
import com.skcraft.launcher.model.modpack.Manifest;
import com.skcraft.launcher.util.Environment;
@ -30,8 +29,6 @@ public class LoaderSubResolver {
}
public String transform(String arg) {
VersionManifest version = manifest.getVersionManifest();
while (true) {
char start = arg.charAt(0);
int bound = arg.length() - 1;
@ -44,7 +41,7 @@ public class LoaderSubResolver {
}
} else if (start == '[' && end == ']') {
String libraryName = arg.substring(1, bound);
Library library = version.findLibrary(libraryName);
Library library = loader.findLibrary(libraryName);
if (library != null) {
arg = getPathOf(manifest.getLibrariesLocation(), library.getPath(env));
} else {

View File

@ -0,0 +1,32 @@
package com.skcraft.launcher.model.minecraft;
import com.google.common.collect.Maps;
import lombok.NoArgsConstructor;
import java.util.Map;
/**
* List of enabled features for Minecraft feature rules.
*/
@NoArgsConstructor
public class FeatureList {
protected Map<String, Boolean> features = Maps.newHashMap();
public boolean doesMatch(Map<String, Boolean> features) {
for (Map.Entry<String, Boolean> entry : features.entrySet()) {
if (!entry.getValue().equals(this.features.get(entry.getKey()))) {
return false;
}
}
return true;
}
public static class Mutable extends FeatureList {
public void addFeature(String key, boolean value) {
features.put(key, value);
}
}
public static final FeatureList EMPTY = new FeatureList();
}

View File

@ -0,0 +1,51 @@
package com.skcraft.launcher.model.minecraft;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.skcraft.launcher.model.minecraft.mapper.ArgumentValueDeserializer;
import com.skcraft.launcher.util.Environment;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@NoArgsConstructor
public class GameArgument {
@JsonProperty("value")
@JsonDeserialize(using = ArgumentValueDeserializer.class)
private List<String> values;
private List<Rule> rules;
public GameArgument(List<String> values) {
this.values = values;
}
public GameArgument(String value) {
this.values = Lists.newArrayList(value);
}
@JsonIgnore
public String getJoinedValue() {
return Joiner.on(' ').join(values);
}
public boolean resolveRules(Environment environment, FeatureList featureList) {
if (getRules() == null) return true;
boolean result = false;
for (Rule rule : rules) {
if (rule.matches(environment, featureList)) {
result = rule.isAllowed();
}
}
return result;
}
}

View File

@ -6,12 +6,7 @@
package com.skcraft.launcher.model.minecraft;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.skcraft.launcher.util.Environment;
@ -20,7 +15,6 @@ import lombok.Data;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@ -43,8 +37,8 @@ public class Library {
if (getRules() != null) {
for (Rule rule : getRules()) {
if (rule.matches(environment)) {
allow = rule.getAction() == Action.ALLOW;
if (rule.matches(environment, FeatureList.EMPTY)) {
allow = rule.isAllowed();
}
}
} else {
@ -95,6 +89,10 @@ public class Library {
if (name != null ? !name.equals(library.name) : library.name != null)
return false;
// If libraries have different natives lists, they should be separate.
if (natives != null ? !natives.equals(library.natives) : library.natives != null)
return false;
return true;
}
@ -103,38 +101,6 @@ public class Library {
return name != null ? name.hashCode() : 0;
}
@Data
public static class Rule {
private Action action;
private OS os;
public boolean matches(Environment environment) {
if (getOs() == null) {
return true;
} else {
return getOs().matches(environment);
}
}
}
@Data
public static class OS {
private Platform platform;
private Pattern version;
@JsonProperty("name")
@JsonDeserialize(using = PlatformDeserializer.class)
@JsonSerialize(using = PlatformSerializer.class)
public Platform getPlatform() {
return platform;
}
public boolean matches(Environment environment) {
return (getPlatform() == null || getPlatform().equals(environment.getPlatform())) &&
(getVersion() == null || getVersion().matcher(environment.getPlatformVersion()).matches());
}
}
@Data
public static class Extract {
private List<String> exclude;
@ -155,21 +121,6 @@ public class Library {
private Map<String, Artifact> classifiers;
}
private enum Action {
ALLOW,
DISALLOW;
@JsonCreator
public static Action fromJson(String text) {
return valueOf(text.toUpperCase());
}
@JsonValue
public String toJson() {
return name().toLowerCase();
}
}
public static String mavenNameToPath(String mavenName) {
List<String> split = Splitter.on(':').splitToList(mavenName);
int size = split.size();

View File

@ -2,6 +2,9 @@ package com.skcraft.launcher.model.minecraft;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.skcraft.launcher.model.minecraft.mapper.MinecraftArgumentsDeserializer;
import lombok.Data;
import java.util.List;
@ -10,6 +13,13 @@ import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
public class MinecraftArguments {
@JsonProperty("game")
private List<String> gameArguments;
@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
@JsonDeserialize(contentUsing = MinecraftArgumentsDeserializer.class)
private List<GameArgument> gameArguments;
@JsonProperty("jvm")
@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
@JsonDeserialize(contentUsing = MinecraftArgumentsDeserializer.class)
private List<GameArgument> jvmArguments;
}

View File

@ -0,0 +1,77 @@
package com.skcraft.launcher.model.minecraft;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.skcraft.launcher.model.minecraft.mapper.PlatformDeserializer;
import com.skcraft.launcher.model.minecraft.mapper.PlatformSerializer;
import com.skcraft.launcher.util.Environment;
import com.skcraft.launcher.util.Platform;
import lombok.Data;
import java.util.Map;
import java.util.regex.Pattern;
@Data
public class Rule {
private Action action;
private OS os;
private Map<String, Boolean> features;
private boolean doesOsMatch(Environment environment) {
if (getOs() == null) {
return true;
} else {
return getOs().matches(environment);
}
}
private boolean doFeaturesMatch(FeatureList match) {
if (getFeatures() == null) return true;
return match.doesMatch(features);
}
public boolean matches(Environment environment, FeatureList match) {
return doesOsMatch(environment) && doFeaturesMatch(match);
}
@JsonIgnore
public boolean isAllowed() {
return action == Action.ALLOW;
}
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public static class OS {
private Platform platform;
private Pattern version;
@JsonProperty("name")
@JsonDeserialize(using = PlatformDeserializer.class)
@JsonSerialize(using = PlatformSerializer.class)
public Platform getPlatform() {
return platform;
}
public boolean matches(Environment environment) {
return (getPlatform() == null || getPlatform().equals(environment.getPlatform())) &&
(getVersion() == null || getVersion().matcher(environment.getPlatformVersion()).matches());
}
}
public enum Action {
ALLOW,
DISALLOW;
@JsonCreator
public static Action fromJson(String text) {
return valueOf(text.toUpperCase());
}
@JsonValue
public String toJson() {
return name().toLowerCase();
}
}
}

View File

@ -8,6 +8,7 @@ package com.skcraft.launcher.model.minecraft;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Splitter;
import lombok.Data;
import java.util.Date;
@ -25,8 +26,7 @@ public class VersionManifest {
private String assets;
private AssetIndex assetIndex;
private String type;
private String processArguments;
private String minecraftArguments;
private MinecraftArguments arguments;
private String mainClass;
private int minimumLauncherVersion;
private LinkedHashSet<Library> libraries;
@ -48,6 +48,15 @@ public class VersionManifest {
return null;
}
public void setMinecraftArguments(String minecraftArguments) {
for (String arg : Splitter.on(' ').split(minecraftArguments)) {
this.arguments.getGameArguments().add(new GameArgument(arg));
}
// TODO: Possibly do some cheaty side-effects here to add parameters missing from early game versions.
// Either that or use a proper version adapter.
}
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Artifact {

View File

@ -0,0 +1,35 @@
package com.skcraft.launcher.model.minecraft.mapper;
import com.beust.jcommander.internal.Lists;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.fasterxml.jackson.databind.type.TypeFactory;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class ArgumentValueDeserializer extends StdDeserializer<List<String>> {
protected ArgumentValueDeserializer() {
super(TypeFactory.defaultInstance().constructCollectionType(List.class, String.class));
}
@Override
public List<String> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
if (!jp.hasCurrentToken()) jp.nextToken();
if (jp.getCurrentToken() == JsonToken.START_ARRAY) {
String[] allValues = jp.readValueAs(String[].class);
return Arrays.asList(allValues);
} else if (jp.getCurrentToken() == JsonToken.VALUE_STRING) {
String value = jp.readValueAs(String.class);
return Lists.newArrayList(value);
}
throw new InvalidFormatException("Invalid JSON type for deserializer (not string or array)", null, List.class);
}
}

View File

@ -0,0 +1,31 @@
package com.skcraft.launcher.model.minecraft.mapper;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.skcraft.launcher.model.minecraft.GameArgument;
import java.io.IOException;
public class MinecraftArgumentsDeserializer extends StdDeserializer<GameArgument> {
protected MinecraftArgumentsDeserializer() {
super(GameArgument.class);
}
@Override
public GameArgument deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
if (!jp.hasCurrentToken()) jp.nextToken();
if (jp.getCurrentToken() == JsonToken.START_OBJECT) {
return jp.readValueAs(GameArgument.class);
} else if (jp.getCurrentToken() == JsonToken.VALUE_STRING) {
String argument = jp.getValueAsString();
return new GameArgument(argument);
}
throw new InvalidFormatException("Invalid JSON type for deserializer (not string or object)", null, GameArgument.class);
}
}

View File

@ -4,7 +4,7 @@
* Please see LICENSE.txt for license information.
*/
package com.skcraft.launcher.model.minecraft;
package com.skcraft.launcher.model.minecraft.mapper;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;

View File

@ -4,7 +4,7 @@
* Please see LICENSE.txt for license information.
*/
package com.skcraft.launcher.model.minecraft;
package com.skcraft.launcher.model.minecraft.mapper;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;

View File

@ -7,6 +7,7 @@
package com.skcraft.launcher.update;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.skcraft.launcher.AssetsRoot;
import com.skcraft.launcher.Instance;
import com.skcraft.launcher.Launcher;
@ -14,6 +15,7 @@ import com.skcraft.launcher.LauncherException;
import com.skcraft.launcher.dialog.FeatureSelectionDialog;
import com.skcraft.launcher.dialog.ProgressDialog;
import com.skcraft.launcher.install.*;
import com.skcraft.launcher.model.loader.LoaderManifest;
import com.skcraft.launcher.model.minecraft.Asset;
import com.skcraft.launcher.model.minecraft.AssetsIndex;
import com.skcraft.launcher.model.minecraft.Library;
@ -201,11 +203,17 @@ public abstract class BaseUpdater {
}
protected void installLibraries(@NonNull Installer installer,
@NonNull VersionManifest versionManifest,
@NonNull Manifest manifest,
@NonNull File librariesDir,
@NonNull List<URL> sources) throws InterruptedException {
VersionManifest versionManifest = manifest.getVersionManifest();
for (Library library : versionManifest.getLibraries()) {
Iterable<Library> allLibraries = versionManifest.getLibraries();
for (LoaderManifest loader : manifest.getLoaders().values()) {
allLibraries = Iterables.concat(allLibraries, loader.getLibraries());
}
for (Library library : allLibraries) {
if (library.matches(environment)) {
checkInterrupted();

View File

@ -166,7 +166,7 @@ public class Updater extends BaseUpdater implements Callable<Instance>, Progress
}
progress = new DefaultProgress(-1, SharedLocale.tr("instanceUpdater.collectingLibraries"));
installLibraries(installer, version, launcher.getLibrariesDir(), librarySources);
installLibraries(installer, manifest, launcher.getLibrariesDir(), librarySources);
// Download assets
log.info("Enumerating assets to download...");