Making versions whose library being removed pure patched

This commit is contained in:
huanghongxun 2019-08-20 00:53:36 +08:00
parent a26061c388
commit 7aee7e33d0
13 changed files with 187 additions and 166 deletions

View File

@ -146,8 +146,7 @@ public class DefaultDependencyManager extends AbstractDependencyManager {
// So resolving this game version to preserve all information in this version.json is necessary.
Version version = repository.getResolvedPreservingPatchesVersion(versionId);
return Task.supplyAsync(() -> MaintainTask.maintain(repository, LibraryAnalyzer.analyze(version)
.removeLibrary(libraryId).build()));
return Task.supplyAsync(() -> LibraryAnalyzer.analyze(version).removeLibrary(libraryId).build());
}
/**

View File

@ -17,6 +17,7 @@
*/
package org.jackhuang.hmcl.download;
import org.jackhuang.hmcl.game.Artifact;
import org.jackhuang.hmcl.game.CompatibilityRule;
import org.jackhuang.hmcl.game.GameRepository;
import org.jackhuang.hmcl.game.Library;
@ -37,10 +38,11 @@ import java.util.stream.Collectors;
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.*;
public class MaintainTask extends Task<Version> {
private final GameRepository repository;
private final Version version;
public MaintainTask(Version version) {
public MaintainTask(GameRepository repository, Version version) {
this.repository = repository;
this.version = version;
if (version.getInheritsFrom() != null)
@ -49,7 +51,7 @@ public class MaintainTask extends Task<Version> {
@Override
public void execute() {
setResult(maintain(null, version));
setResult(maintain(repository, version));
}
public static Version maintain(GameRepository repository, Version version) {
@ -115,7 +117,7 @@ public class MaintainTask extends Task<Version> {
for (int i = 0; i < version.getLibraries().size(); ++i) {
Library library = libraries.get(i);
if (library.is("optifine", "OptiFine")) {
Library newLibrary = new Library("optifine", "OptiFine", library.getVersion(), "installer", null, null);
Library newLibrary = new Library(new Artifact("optifine", "OptiFine", library.getVersion(), "installer"));
if (repository.getLibraryFile(version, newLibrary).exists()) {
libraries.set(i, null);
// OptiFine should be loaded after Forge in classpath.

View File

@ -21,6 +21,7 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.jackhuang.hmcl.download.DefaultDependencyManager;
import org.jackhuang.hmcl.game.Arguments;
import org.jackhuang.hmcl.game.Artifact;
import org.jackhuang.hmcl.game.Library;
import org.jackhuang.hmcl.game.Version;
import org.jackhuang.hmcl.task.GetTask;
@ -65,7 +66,7 @@ public final class FabricInstallTask extends Task<Version> {
@Override
public void preExecute() {
if (!Objects.equals("net.minecraft.client.main.Main", version.getMainClass()))
if (!Objects.equals("net.minecraft.client.main.Main", version.resolve(dependencyManager.getGameRepository()).getMainClass()))
throw new UnsupportedFabricInstallationException();
}
@ -121,8 +122,8 @@ public final class FabricInstallTask extends Task<Version> {
}
}
libraries.add(new Library("net.fabricmc", "intermediary", gameVersion, null, "https://maven.fabricmc.net/", null));
libraries.add(new Library("net.fabricmc", "fabric-loader", loaderVersion, null, "https://maven.fabricmc.net/", null));
libraries.add(new Library(new Artifact("net.fabricmc", "intermediary", gameVersion), "https://maven.fabricmc.net/", null));
libraries.add(new Library(new Artifact("net.fabricmc", "fabric-loader", loaderVersion), "https://maven.fabricmc.net/", null));
return new Version("net.fabricmc", loaderVersion, 30000, arguments, mainClass, libraries);
}

View File

@ -88,7 +88,7 @@ public class ForgeNewInstallTask extends Task<Version> {
else if (StringUtils.isSurrounded(literal, "'", "'"))
return StringUtils.removeSurrounding(literal, "'");
else if (StringUtils.isSurrounded(literal, "[", "]"))
return gameRepository.getArtifactFile(version, new Artifact(StringUtils.removeSurrounding(literal, "[", "]"))).toString();
return gameRepository.getArtifactFile(version, Artifact.fromDescriptor(StringUtils.removeSurrounding(literal, "[", "]"))).toString();
else
return plainConverter.apply(literal);
}

View File

@ -74,7 +74,7 @@ public class ForgeOldInstallTask extends Task<Version> {
ForgeInstallProfile installProfile = JsonUtils.fromNonNullJson(json, ForgeInstallProfile.class);
// unpack the universal jar in the installer file.
Library forgeLibrary = Library.fromName(installProfile.getInstall().getPath().toString());
Library forgeLibrary = new Library(installProfile.getInstall().getPath());
File forgeFile = dependencyManager.getGameRepository().getLibraryFile(version, forgeLibrary);
if (!FileUtils.makeFile(forgeFile))
throw new IOException("Cannot make directory " + forgeFile.getParent());

View File

@ -20,6 +20,7 @@ package org.jackhuang.hmcl.download.liteloader;
import org.jackhuang.hmcl.download.DefaultDependencyManager;
import org.jackhuang.hmcl.download.LibraryAnalyzer;
import org.jackhuang.hmcl.game.Arguments;
import org.jackhuang.hmcl.game.Artifact;
import org.jackhuang.hmcl.game.LibrariesDownloadInfo;
import org.jackhuang.hmcl.game.Library;
import org.jackhuang.hmcl.game.LibraryDownloadInfo;
@ -64,7 +65,7 @@ public final class LiteLoaderInstallTask extends Task<Version> {
@Override
public void execute() {
Library library = new Library(
"com.mumfrey", "liteloader", remote.getSelfVersion(), null,
new Artifact("com.mumfrey", "liteloader", remote.getSelfVersion()),
"http://dl.liteloader.com/versions/",
new LibrariesDownloadInfo(new LibraryDownloadInfo(null, remote.getUrl()))
);

View File

@ -21,6 +21,7 @@ import org.jackhuang.hmcl.download.DefaultDependencyManager;
import org.jackhuang.hmcl.download.LibraryAnalyzer;
import org.jackhuang.hmcl.download.VersionMismatchException;
import org.jackhuang.hmcl.game.Arguments;
import org.jackhuang.hmcl.game.Artifact;
import org.jackhuang.hmcl.game.DefaultGameRepository;
import org.jackhuang.hmcl.game.GameVersion;
import org.jackhuang.hmcl.game.LibrariesDownloadInfo;
@ -84,10 +85,10 @@ public final class OptiFineInstallTask extends Task<Version> {
String mavenVersion = remote.getGameVersion() + "_" + remote.getSelfVersion();
optiFineLibrary = new Library("optifine", "OptiFine", mavenVersion);
optiFineLibrary = new Library(new Artifact("optifine", "OptiFine", mavenVersion));
optiFineInstallerLibrary = new Library(
"optifine", "OptiFine", mavenVersion, "installer", null,
new Artifact("optifine", "OptiFine", mavenVersion, "installer"), null,
new LibrariesDownloadInfo(new LibraryDownloadInfo(
"optifine/OptiFine/" + mavenVersion + "/OptiFine-" + mavenVersion + "-installer.jar",
remote.getUrl()))
@ -158,7 +159,7 @@ public final class OptiFineInstallTask extends Task<Version> {
String launchWrapperVersion = FileUtils.readText(launchWrapperVersionText).trim();
Path launchWrapperJar = fs.getPath("launchwrapper-of-" + launchWrapperVersion + ".jar");
Library launchWrapper = new Library("optifine", "launchwrapper-of", launchWrapperVersion);
Library launchWrapper = new Library(new Artifact("optifine", "launchwrapper-of", launchWrapperVersion));
if (Files.exists(launchWrapperJar)) {
File launchWrapperFile = gameRepository.getLibraryFile(version, launchWrapper);
@ -172,7 +173,7 @@ public final class OptiFineInstallTask extends Task<Version> {
}
if (!hasLaunchWrapper) {
libraries.add(new Library("net.minecraft", "launchwrapper", "1.12"));
libraries.add(new Library(new Artifact("net.minecraft", "launchwrapper", "1.12")));
}
setResult(new Version(

View File

@ -17,7 +17,14 @@
*/
package org.jackhuang.hmcl.game;
import com.google.gson.*;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.annotations.JsonAdapter;
import org.jackhuang.hmcl.util.Immutable;
@ -38,9 +45,34 @@ public final class Artifact {
private final String fileName;
private final String path;
public Artifact(String descriptor) {
this.descriptor = descriptor;
public Artifact(String group, String name, String version) {
this(group, name, version, null);
}
public Artifact(String group, String name, String version, String classifier) {
this(group, name, version, classifier, null);
}
public Artifact(String group, String name, String version, String classifier, String extension) {
this.group = group;
this.name = name;
this.version = version;
this.classifier = classifier;
this.extension = extension == null ? "jar" : extension;
String fileName = this.name + "-" + this.version;
if (classifier != null) fileName += "-" + this.classifier;
this.fileName = fileName + "." + this.extension;
this.path = String.format("%s/%s/%s/%s", this.group.replace(".", "/"), this.name, this.version, this.fileName);
// group:name:version:classifier@extension
String descriptor = String.format("%s:%s:%s", group, name, version);
if (classifier != null) descriptor += ":" + classifier;
if (!"jar".equals(this.extension)) descriptor += "@" + this.extension;
this.descriptor = descriptor;
}
public static Artifact fromDescriptor(String descriptor) {
String[] arr = descriptor.split(":", 4);
if (arr.length != 3 && arr.length != 4)
throw new IllegalArgumentException("Artifact name is malformed");
@ -55,16 +87,7 @@ public final class Artifact {
throw new IllegalArgumentException("Artifact name is malformed");
}
this.group = arr[0].replace("\\", "/");
this.name = arr[1];
this.version = arr[2];
this.classifier = arr.length >= 4 ? arr[3] : null;
this.extension = ext == null ? "jar" : ext;
String fileName = this.name + "-" + this.version;
if (classifier != null) fileName += "-" + this.classifier;
this.fileName = fileName + "." + this.extension;
this.path = String.format("%s/%s/%s/%s", this.group.replace(".", "/"), this.name, this.version, this.fileName);
return new Artifact(arr[0].replace("\\", "/"), arr[1], arr[2], arr.length >= 4 ? arr[3] : null, ext);
}
public String getGroup() {
@ -83,6 +106,10 @@ public final class Artifact {
return classifier;
}
public Artifact setClassifier(String classifier) {
return new Artifact(group, name, version, classifier, extension);
}
public String getExtension() {
return extension;
}
@ -91,6 +118,8 @@ public final class Artifact {
return fileName;
}
public String getPath() { return path; }
public Path getPath(Path root) {
return root.resolve(path);
}
@ -108,7 +137,7 @@ public final class Artifact {
@Override
public Artifact deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return json.isJsonPrimitive() ? new Artifact(json.getAsJsonPrimitive().getAsString()) : null;
return json.isJsonPrimitive() ? fromDescriptor(json.getAsJsonPrimitive().getAsString()) : null;
}
}
}

View File

@ -32,15 +32,15 @@ public class ClassicVersion extends Version {
super(true, "Classic", null, null, "${auth_player_name} ${auth_session} --workDir ${game_directory}",
null, "net.minecraft.client.Minecraft", null, null, null, null,
Arrays.asList(new ClassicLibrary("lwjgl"), new ClassicLibrary("jinput"), new ClassicLibrary("lwjgl_util")),
null, null, null, ReleaseType.UNKNOWN, new Date(), new Date(), 0, false, null);
null, null, null, ReleaseType.UNKNOWN, new Date(), new Date(), 0, false, false, null);
}
private static class ClassicLibrary extends Library {
public ClassicLibrary(String name) {
super("", "", "", null, null,
super(new Artifact("", "", ""), null,
new LibrariesDownloadInfo(new LibraryDownloadInfo("bin/" + name + ".jar"), null),
null, null, null, null);
null, null, null, null, null, null);
}
}

View File

@ -17,15 +17,16 @@
*/
package org.jackhuang.hmcl.game;
import com.google.gson.*;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.reflect.TypeToken;
import com.google.gson.JsonParseException;
import com.google.gson.annotations.SerializedName;
import org.jackhuang.hmcl.util.Constants;
import org.jackhuang.hmcl.util.Immutable;
import org.jackhuang.hmcl.util.ToStringBuilder;
import org.jackhuang.hmcl.util.gson.TolerableValidationException;
import org.jackhuang.hmcl.util.gson.Validation;
import org.jackhuang.hmcl.util.platform.OperatingSystem;
import org.jackhuang.hmcl.util.platform.Platform;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -36,83 +37,68 @@ import java.util.Optional;
*
* @author huangyuhui
*/
@JsonAdapter(Library.Serializer.class)
public class Library implements Comparable<Library> {
@Immutable
public class Library implements Comparable<Library>, Validation {
private final String groupId;
private final String artifactId;
private final String version;
private final String classifier;
@SerializedName("name")
private final Artifact artifact;
private final String url;
private final LibrariesDownloadInfo downloads;
private transient final LibraryDownloadInfo download;
private final ExtractRules extract;
private final Map<OperatingSystem, String> natives;
private final List<CompatibilityRule> rules;
private final List<String> checksums;
private transient final String path;
@SerializedName(value = "hint", alternate = {"MMC-hint"})
private final String hint;
public Library(String groupId, String artifactId, String version) {
this(groupId, artifactId, version, null, null, null);
@SerializedName(value = "filename", alternate = {"MMC-filename"})
private final String fileName;
public Library(Artifact artifact) {
this(artifact, null, null);
}
public Library(String groupId, String artifactId, String version, String classifier, String url, LibrariesDownloadInfo downloads) {
this(groupId, artifactId, version, classifier, url, downloads, null, null, null, null);
public Library(Artifact artifact, String url, LibrariesDownloadInfo downloads) {
this(artifact, url, downloads, null, null, null, null, null, null);
}
public Library(String groupId, String artifactId, String version, String classifier, String url, LibrariesDownloadInfo downloads, List<String> checksums, ExtractRules extract, Map<OperatingSystem, String> natives, List<CompatibilityRule> rules) {
this.groupId = groupId;
this.artifactId = artifactId;
this.version = version;
if (classifier == null)
if (natives != null && natives.containsKey(OperatingSystem.CURRENT_OS))
this.classifier = natives.get(OperatingSystem.CURRENT_OS).replace("${arch}", Platform.PLATFORM.getBit());
else
this.classifier = null;
else
this.classifier = classifier;
public Library(Artifact artifact, String url, LibrariesDownloadInfo downloads, List<String> checksums, ExtractRules extract, Map<OperatingSystem, String> natives, List<CompatibilityRule> rules, String hint, String filename) {
this.artifact = artifact;
this.url = url;
this.downloads = downloads;
this.extract = extract;
this.natives = natives;
this.rules = rules;
this.checksums = checksums;
LibraryDownloadInfo temp = null;
if (downloads != null)
if (isNative())
temp = downloads.getClassifiers().get(this.classifier);
else
temp = downloads.getArtifact();
if (temp != null && temp.getPath() != null)
path = temp.getPath();
else
path = String.format("%s/%s/%s/%s-%s", groupId.replace(".", "/"), artifactId, version, artifactId, version)
+ (this.classifier == null ? "" : "-" + this.classifier) + ".jar";
download = new LibraryDownloadInfo(path,
Optional.ofNullable(temp).map(LibraryDownloadInfo::getUrl).orElse(Optional.ofNullable(url).orElse(Constants.DEFAULT_LIBRARY_URL) + path),
temp != null ? temp.getSha1() : null,
temp != null ? temp.getSize() : 0
);
this.hint = hint;
this.fileName = filename;
}
public String getGroupId() {
return groupId;
return artifact.getGroup();
}
public String getArtifactId() {
return artifactId;
return artifact.getName();
}
public String getName() {
return groupId + ":" + artifactId + ":" + version;
return artifact.toString();
}
public String getVersion() {
return version;
return artifact.getVersion();
}
public String getClassifier() {
if (artifact.getClassifier() == null)
if (natives != null && natives.containsKey(OperatingSystem.CURRENT_OS))
return natives.get(OperatingSystem.CURRENT_OS).replace("${arch}", Platform.PLATFORM.getBit());
else
return null;
else
return artifact.getClassifier();
}
public ExtractRules getExtract() {
@ -127,12 +113,33 @@ public class Library implements Comparable<Library> {
return natives != null && appliesToCurrentEnvironment();
}
protected LibraryDownloadInfo getRawDownloadInfo() {
if (downloads != null) {
if (isNative())
return downloads.getClassifiers().get(getClassifier());
else
return downloads.getArtifact();
} else {
return null;
}
}
public String getPath() {
return path;
LibraryDownloadInfo temp = getRawDownloadInfo();
if (temp != null && temp.getPath() != null)
return temp.getPath();
else
return artifact.setClassifier(getClassifier()).getPath();
}
public LibraryDownloadInfo getDownload() {
return download;
LibraryDownloadInfo temp = getRawDownloadInfo();
String path = getPath();
return new LibraryDownloadInfo(path,
Optional.ofNullable(temp).map(LibraryDownloadInfo::getUrl).orElse(Optional.ofNullable(url).orElse(Constants.DEFAULT_LIBRARY_URL) + path),
temp != null ? temp.getSha1() : null,
temp != null ? temp.getSize() : 0
);
}
public List<String> getChecksums() {
@ -143,8 +150,24 @@ public class Library implements Comparable<Library> {
return rules;
}
/**
* Hint for how to locate the library file.
* @return null for default, "local" for location in version/&lt;version&gt;/libraries/filename
*/
public String getHint() {
return hint;
}
/**
* Available when hint is "local"
* @return the filename of the local library in version/&lt;version&gt;/libraries/$filename
*/
public String getFileName() {
return fileName;
}
public boolean is(String groupId, String artifactId) {
return this.groupId.equals(groupId) && this.artifactId.equals(artifactId);
return getGroupId().equals(groupId) && getArtifactId().equals(artifactId);
}
@Override
@ -175,58 +198,12 @@ public class Library implements Comparable<Library> {
}
public Library setClassifier(String classifier) {
return new Library(groupId, artifactId, version, classifier, url, downloads, checksums, extract, natives, rules);
return new Library(artifact.setClassifier(classifier), url, downloads, checksums, extract, natives, rules, hint, fileName);
}
public static Library fromName(String name) {
return fromName(name, null, null, null, null, null, null);
}
public static Library fromName(String name, String url, LibrariesDownloadInfo downloads, List<String> checksums, ExtractRules extract, Map<OperatingSystem, String> natives, List<CompatibilityRule> rules) {
String[] arr = name.split(":", 4);
if (arr.length != 3 && arr.length != 4)
throw new IllegalArgumentException("Library name is malformed. Correct example: group:artifact:version(:classifier).");
return new Library(arr[0].replace("\\", "/"), arr[1], arr[2], arr.length >= 4 ? arr[3] : null, url, downloads, checksums, extract, natives, rules);
}
public static class Serializer implements JsonDeserializer<Library>, JsonSerializer<Library> {
@Override
public Library deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
if (json == null || json == JsonNull.INSTANCE)
return null;
JsonObject jsonObject = json.getAsJsonObject();
if (!jsonObject.has("name"))
throw new JsonParseException("Library name not found.");
return fromName(
jsonObject.get("name").getAsString(),
jsonObject.has("url") ? jsonObject.get("url").getAsString() : null,
context.deserialize(jsonObject.get("downloads"), LibrariesDownloadInfo.class),
context.deserialize(jsonObject.get("checksums"), new TypeToken<List<String>>() {
}.getType()),
context.deserialize(jsonObject.get("extract"), ExtractRules.class),
context.deserialize(jsonObject.get("natives"), new TypeToken<Map<OperatingSystem, String>>() {
}.getType()),
context.deserialize(jsonObject.get("rules"), new TypeToken<List<CompatibilityRule>>() {
}.getType()));
}
@Override
public JsonElement serialize(Library src, Type type, JsonSerializationContext context) {
if (src == null)
return JsonNull.INSTANCE;
JsonObject obj = new JsonObject();
obj.addProperty("name", src.getName());
obj.addProperty("url", src.url);
obj.add("downloads", context.serialize(src.downloads));
obj.add("checksums", context.serialize(src.getChecksums()));
obj.add("extract", context.serialize(src.extract));
obj.add("natives", context.serialize(src.natives, new TypeToken<Map<OperatingSystem, String>>() {
}.getType()));
obj.add("rules", context.serialize(src.rules, new TypeToken<List<CompatibilityRule>>() {
}.getType()));
return obj;
}
@Override
public void validate() throws JsonParseException, TolerableValidationException {
if (artifact == null)
throw new JsonParseException("Library.name cannot be null");
}
}

View File

@ -66,13 +66,14 @@ public class Version implements Comparable<Version>, Validation {
private final Date time;
private final Date releaseTime;
private final Integer minimumLauncherVersion;
private final Boolean root;
private final Boolean hidden;
private final List<Version> patches;
private transient final boolean resolved;
public Version(String id) {
this(false, id, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, false, null);
this(false, id, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, false, true, null);
}
/**
@ -85,10 +86,10 @@ public class Version implements Comparable<Version>, Validation {
* @param libraries additional libraries
*/
public Version(String id, String version, int priority, Arguments arguments, String mainClass, List<Library> libraries) {
this(false, id, version, priority, null, arguments, mainClass, null, null, null, null, libraries, null, null, null, null, null, null, null, null, null);
this(false, id, version, priority, null, arguments, mainClass, null, null, null, null, libraries, null, null, null, null, null, null, null, null, null, null);
}
public Version(boolean resolved, String id, String version, Integer priority, String minecraftArguments, Arguments arguments, String mainClass, String inheritsFrom, String jar, AssetIndexInfo assetIndex, String assets, List<Library> libraries, List<CompatibilityRule> compatibilityRules, Map<DownloadType, DownloadInfo> downloads, Map<DownloadType, LoggingInfo> logging, ReleaseType type, Date time, Date releaseTime, Integer minimumLauncherVersion, Boolean hidden, List<Version> patches) {
public Version(boolean resolved, String id, String version, Integer priority, String minecraftArguments, Arguments arguments, String mainClass, String inheritsFrom, String jar, AssetIndexInfo assetIndex, String assets, List<Library> libraries, List<CompatibilityRule> compatibilityRules, Map<DownloadType, DownloadInfo> downloads, Map<DownloadType, LoggingInfo> logging, ReleaseType type, Date time, Date releaseTime, Integer minimumLauncherVersion, Boolean hidden, Boolean root, List<Version> patches) {
this.resolved = resolved;
this.id = id;
this.version = version;
@ -109,6 +110,7 @@ public class Version implements Comparable<Version>, Validation {
this.releaseTime = releaseTime == null ? null : (Date) releaseTime.clone();
this.minimumLauncherVersion = minimumLauncherVersion;
this.hidden = hidden;
this.root = root;
this.patches = Lang.copyList(patches);
}
@ -170,6 +172,8 @@ public class Version implements Comparable<Version>, Validation {
return hidden == null ? false : hidden;
}
public boolean isRoot() { return root == null ? false : root; }
public boolean isResolved() {
return resolved;
}
@ -219,7 +223,7 @@ public class Version implements Comparable<Version>, Validation {
return resolve(provider, new HashSet<>()).setResolved();
}
protected Version merge(Version parent) {
protected Version merge(Version parent, boolean isPatch) {
return new Version(
true,
id,
@ -241,7 +245,8 @@ public class Version implements Comparable<Version>, Validation {
releaseTime,
Lang.merge(minimumLauncherVersion, parent.minimumLauncherVersion, Math::max),
hidden,
Lang.merge(Lang.merge(parent.patches, Collections.singleton(this.clearPatches().setHidden(true).setId("resolved." + getId()))), patches));
false,
isPatch ? parent.patches : Lang.merge(Lang.merge(parent.patches, Collections.singleton(toPatch())), patches));
}
protected Version resolve(VersionProvider provider, Set<String> resolvedSoFar) throws VersionNotFoundException {
@ -256,7 +261,7 @@ public class Version implements Comparable<Version>, Validation {
thisVersion = this.jar == null ? this.setJar(id) : this;
} else {
// It is supposed to auto install an version in getVersion.
thisVersion = merge(provider.getVersion(inheritsFrom).resolve(provider, resolvedSoFar));
thisVersion = merge(provider.getVersion(inheritsFrom).resolve(provider, resolvedSoFar), false);
}
}
@ -266,13 +271,17 @@ public class Version implements Comparable<Version>, Validation {
.sorted(Comparator.comparing(Version::getPriority))
.collect(Collectors.toList());
for (Version patch : sortedPatches) {
thisVersion = patch.setJar(null).merge(thisVersion);
thisVersion = patch.setJar(null).merge(thisVersion, true);
}
}
return thisVersion.setId(id);
}
private Version toPatch() {
return this.clearPatches().setHidden(true).setId("resolved." + getId());
}
/**
* Resolve the version preserving all dependencies and patches.
*/
@ -281,19 +290,19 @@ public class Version implements Comparable<Version>, Validation {
}
protected Version mergePreservingPatches(Version parent) {
return parent.addPatch(this.clearPatches().setHidden(true).setId("resolved." + getId())).addPatches(patches);
return parent.addPatch(toPatch()).addPatches(patches);
}
protected Version resolvePreservingPatches(VersionProvider provider, Set<String> resolvedSoFar) throws VersionNotFoundException {
Version thisVersion;
Version thisVersion = isRoot() ? this : new Version(id).addPatch(toPatch()).addPatches(getPatches());
if (inheritsFrom == null) {
thisVersion = this;
// keep thisVersion
} else {
// To maximize the compatibility.
if (!resolvedSoFar.add(id)) {
Logging.LOG.log(Level.WARNING, "Found circular dependency versions: " + resolvedSoFar);
thisVersion = this;
// keep thisVersion
} else {
// It is supposed to auto install an version in getVersion.
thisVersion = mergePreservingPatches(provider.getVersion(inheritsFrom).resolvePreservingPatches(provider, resolvedSoFar));
@ -304,55 +313,55 @@ public class Version implements Comparable<Version>, Validation {
}
private Version setResolved() {
return new Version(true, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, patches);
return new Version(true, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root, patches);
}
private Version setHidden(Boolean hidden) {
return new Version(true, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, patches);
return new Version(true, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root, patches);
}
public Version setId(String id) {
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, patches);
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root, patches);
}
public Version setVersion(String version) {
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, patches);
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root, patches);
}
public Version setPriority(Integer priority) {
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, patches);
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root, patches);
}
public Version setMinecraftArguments(String minecraftArguments) {
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, patches);
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root, patches);
}
public Version setArguments(Arguments arguments) {
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, patches);
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root, patches);
}
public Version setMainClass(String mainClass) {
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, patches);
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root, patches);
}
public Version setInheritsFrom(String inheritsFrom) {
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, patches);
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root, patches);
}
public Version setJar(String jar) {
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, patches);
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root, patches);
}
public Version setLibraries(List<Library> libraries) {
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, patches);
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root, patches);
}
public Version setLogging(Map<DownloadType, LoggingInfo> logging) {
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, patches);
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root, patches);
}
public Version setPatches(List<Version> patches) {
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, patches);
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root, patches);
}
public Version addPatch(Version... additional) {
@ -360,15 +369,15 @@ public class Version implements Comparable<Version>, Validation {
}
public Version addPatches(List<Version> additional) {
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, Lang.merge(patches, additional));
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root, Lang.merge(patches, additional));
}
public Version clearPatches() {
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, null);
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root,null);
}
public Version removePatchById(String patchId) {
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden,
return new Version(resolved, id, version, priority, minecraftArguments, arguments, mainClass, inheritsFrom, jar, assetIndex, assets, libraries, compatibilityRules, downloads, logging, type, time, releaseTime, minimumLauncherVersion, hidden, root,
patches == null ? null : patches.stream().filter(patch -> !patchId.equals(patch.getId())).collect(Collectors.toList()));
}

View File

@ -72,6 +72,8 @@ public class ModpackUpdateTask extends Task<Void> {
repository.removeVersionFromDisk(id);
FileUtils.copyDirectory(backupFolder, repository.getVersionRoot(id).toPath());
repository.refreshVersionsAsync().start();
}
}
}

View File

@ -199,7 +199,7 @@ public final class FileUtils {
Files.walkFileTree(src, new SimpleFileVisitor<Path>(){
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Path destFile = dest.resolve(src.relativize(file));
Path destFile = dest.resolve(src.relativize(file).toString());
Files.copy(file, destFile, StandardCopyOption.REPLACE_EXISTING);
return FileVisitResult.CONTINUE;
@ -207,7 +207,7 @@ public final class FileUtils {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
Path destDir = dest.resolve(src.relativize(dir));
Path destDir = dest.resolve(src.relativize(dir).toString());
Files.createDirectories(destDir);
return FileVisitResult.CONTINUE;