diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/LibrariesUniqueTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/LibrariesUniqueTask.java index 03b1c0831..e6565ab75 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/LibrariesUniqueTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/LibrariesUniqueTask.java @@ -17,10 +17,12 @@ */ package org.jackhuang.hmcl.download.game; +import org.jackhuang.hmcl.game.CompatibilityRule; import org.jackhuang.hmcl.game.Library; import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.task.TaskResult; import org.jackhuang.hmcl.util.Constants; +import org.jackhuang.hmcl.util.Platform; import org.jackhuang.hmcl.util.SimpleMultimap; import org.jackhuang.hmcl.util.VersionNumber; @@ -44,7 +46,6 @@ public class LibrariesUniqueTask extends TaskResult { public void execute() { List libraries = new ArrayList<>(version.getLibraries()); - Map versionMap = new HashMap<>(); SimpleMultimap multimap = new SimpleMultimap(HashMap::new, LinkedList::new); for (Library library : libraries) { @@ -52,32 +53,36 @@ public class LibrariesUniqueTask extends TaskResult { VersionNumber number = VersionNumber.asVersion(library.getVersion()); String serialized = Constants.GSON.toJson(library); - if (versionMap.containsKey(id)) { - VersionNumber otherNumber = versionMap.get(id); - if (number.compareTo(otherNumber) > 0) { - multimap.removeKey(id); - versionMap.put(id, number); - multimap.put(id, library); - } else if (number.compareTo(otherNumber) == 0) { // same library id. - boolean flag = false; - // prevent from duplicated libraries - for (Library otherLibrary : multimap.get(id)) - if (library.equals(otherLibrary)) { - String otherSerialized = Constants.GSON.toJson(otherLibrary); - // A trick, the library that has more information is better, which can be - // considered whose serialized JSON text will be longer. - if (serialized.length() <= otherSerialized.length()) { - flag = true; - break; - } else { - multimap.removeValue(id, otherLibrary); + if (multimap.containsKey(id)) { + boolean hasEqualRule = false; + for (Library otherLibrary : multimap.get(id)) { + VersionNumber otherNumber = VersionNumber.asVersion(otherLibrary.getVersion()); + if (CompatibilityRule.equals(library.getRules(), otherLibrary.getRules())) { // rules equal, ignore older version. + hasEqualRule = true; + if (number.compareTo(otherNumber) > 0) { // if this library is newer + multimap.removeValue(otherLibrary); + multimap.put(id, library); + break; + } else if (number.compareTo(otherNumber) == 0) { // same library id. + // prevent from duplicated libraries + if (library.equals(otherLibrary)) { + String otherSerialized = Constants.GSON.toJson(otherLibrary); + // A trick, the library that has more information is better, which can be + // considered whose serialized JSON text will be longer. + if (serialized.length() > otherSerialized.length()) { + multimap.removeValue(id, otherLibrary); + multimap.put(id, library); + break; + } } } - if (!flag) - multimap.put(id, library); + } + } + + if (!hasEqualRule) { + multimap.put(id, library); } } else { - versionMap.put(id, number); multimap.put(id, library); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/CompatibilityRule.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/CompatibilityRule.java index f3e4b1e82..b5afb3977 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/CompatibilityRule.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/CompatibilityRule.java @@ -76,6 +76,25 @@ public final class CompatibilityRule { return action == Action.ALLOW; } + public static boolean equals(Collection rules1, Collection rules2) { + return Objects.hashCode(rules1) == Objects.hashCode(rules2); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CompatibilityRule that = (CompatibilityRule) o; + return action == that.action && + Objects.equals(os, that.os) && + Objects.equals(features, that.features); + } + + @Override + public int hashCode() { + return Objects.hash(action, os, features); + } + public enum Action { ALLOW, DISALLOW diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/Library.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/Library.java index 75e1b72ea..df2de91d4 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/Library.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/Library.java @@ -137,6 +137,10 @@ public class Library implements Comparable { return checksums; } + public List getRules() { + return rules; + } + public boolean is(String groupId, String artifactId) { return this.groupId.equals(groupId) && this.artifactId.equals(artifactId); }