弃用 commons-lang (#2061)
* Remove ArrayUtils * Remove MutableObject * VersionRange * Replace Range with VersionRange * fix checkstyle * Update * update * update * fix checkstyle * fix checkstyle * update
This commit is contained in:
@@ -17,50 +17,51 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.game;
|
||||
|
||||
import org.apache.commons.lang3.Range;
|
||||
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.platform.Architecture;
|
||||
import org.jackhuang.hmcl.util.platform.JavaVersion;
|
||||
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionRange;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LAUNCH_WRAPPER_MAIN;
|
||||
import static org.jackhuang.hmcl.util.versioning.VersionRange.*;
|
||||
|
||||
public enum JavaVersionConstraint {
|
||||
// Minecraft>=1.13 requires Java 8
|
||||
VANILLA_JAVA_8(JavaVersionConstraint.RULE_MANDATORY, versionRange("1.13", JavaVersionConstraint.MAX), versionRange("1.8", JavaVersionConstraint.MAX)),
|
||||
VANILLA_JAVA_8(JavaVersionConstraint.RULE_MANDATORY, atLeast("1.13"), atLeast("1.8")),
|
||||
// Minecraft 1.17 requires Java 16
|
||||
VANILLA_JAVA_16(JavaVersionConstraint.RULE_MANDATORY, versionRange("1.17", JavaVersionConstraint.MAX), versionRange("16", JavaVersionConstraint.MAX)),
|
||||
VANILLA_JAVA_16(JavaVersionConstraint.RULE_MANDATORY, atLeast("1.17"), atLeast("16")),
|
||||
// Minecraft>=1.18 requires Java 17
|
||||
VANILLA_JAVA_17(JavaVersionConstraint.RULE_MANDATORY, versionRange("1.18", JavaVersionConstraint.MAX), versionRange("17", JavaVersionConstraint.MAX)),
|
||||
VANILLA_JAVA_17(JavaVersionConstraint.RULE_MANDATORY, atLeast("1.18"), atLeast("17")),
|
||||
// Minecraft<=1.7.2+Forge requires Java<=7, But LegacyModFixer may fix that problem. So only suggest user using Java 7.
|
||||
MODDED_JAVA_7(JavaVersionConstraint.RULE_SUGGESTED, versionRange(JavaVersionConstraint.MIN, "1.7.2"), versionRange(JavaVersionConstraint.MIN, "1.7.999")) {
|
||||
MODDED_JAVA_7(JavaVersionConstraint.RULE_SUGGESTED, atMost("1.7.2"), atMost("1.7.999")) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
return version != null && analyzer != null && analyzer.has(LibraryAnalyzer.LibraryType.FORGE);
|
||||
}
|
||||
},
|
||||
MODDED_JAVA_8(JavaVersionConstraint.RULE_SUGGESTED, versionRange("1.7.10", "1.16.999"), versionRange("1.8", "1.8.999")) {
|
||||
MODDED_JAVA_8(JavaVersionConstraint.RULE_SUGGESTED, between("1.7.10", "1.16.999"), between("1.8", "1.8.999")) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
return analyzer != null && analyzer.has(LibraryAnalyzer.LibraryType.FORGE);
|
||||
}
|
||||
},
|
||||
MODDED_JAVA_16(JavaVersionConstraint.RULE_SUGGESTED, versionRange("1.17", "1.17.999"), versionRange("16", "16.999")) {
|
||||
MODDED_JAVA_16(JavaVersionConstraint.RULE_SUGGESTED, between("1.17", "1.17.999"), between("16", "16.999")) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
return analyzer != null && analyzer.has(LibraryAnalyzer.LibraryType.FORGE);
|
||||
}
|
||||
},
|
||||
MODDED_JAVA_17(JavaVersionConstraint.RULE_SUGGESTED, versionRange("1.18", JavaVersionConstraint.MAX), versionRange("17", "17.999")) {
|
||||
MODDED_JAVA_17(JavaVersionConstraint.RULE_SUGGESTED, atLeast("1.18"), between("17", "17.999")) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
@@ -68,7 +69,7 @@ public enum JavaVersionConstraint {
|
||||
}
|
||||
},
|
||||
// LaunchWrapper<=1.12 will crash because LaunchWrapper assumes the system class loader is an instance of URLClassLoader (Java 8)
|
||||
LAUNCH_WRAPPER(JavaVersionConstraint.RULE_MANDATORY, versionRange("0", "1.12.999"), versionRange("0", "1.8.999")) {
|
||||
LAUNCH_WRAPPER(JavaVersionConstraint.RULE_MANDATORY, atMost("1.12.999"), atMost("1.8.999")) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
@@ -80,9 +81,9 @@ public enum JavaVersionConstraint {
|
||||
}
|
||||
},
|
||||
// Minecraft>=1.13 may crash when generating world on Java [1.8,1.8.0_51)
|
||||
VANILLA_JAVA_8_51(JavaVersionConstraint.RULE_SUGGESTED, versionRange("1.13", JavaVersionConstraint.MAX), versionRange("1.8.0_51", JavaVersionConstraint.MAX)),
|
||||
VANILLA_JAVA_8_51(JavaVersionConstraint.RULE_SUGGESTED, atLeast("1.13"), atLeast("1.8.0_51")),
|
||||
// Minecraft with suggested java version recorded in game json is restrictedly constrained.
|
||||
GAME_JSON(JavaVersionConstraint.RULE_MANDATORY, versionRange(JavaVersionConstraint.MIN, JavaVersionConstraint.MAX), versionRange(JavaVersionConstraint.MIN, JavaVersionConstraint.MAX)) {
|
||||
GAME_JSON(JavaVersionConstraint.RULE_MANDATORY, VersionRange.all(), VersionRange.all()) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
@@ -92,19 +93,19 @@ public enum JavaVersionConstraint {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Range<VersionNumber> getJavaVersionRange(Version version) {
|
||||
public VersionRange getJavaVersionRange(Version version) {
|
||||
String javaVersion;
|
||||
if (Objects.requireNonNull(version.getJavaVersion()).getMajorVersion() >= 9) {
|
||||
javaVersion = "" + version.getJavaVersion().getMajorVersion();
|
||||
} else {
|
||||
javaVersion = "1." + version.getJavaVersion().getMajorVersion();
|
||||
}
|
||||
return JavaVersionConstraint.versionRange(javaVersion, JavaVersionConstraint.MAX);
|
||||
return atLeast(javaVersion);
|
||||
}
|
||||
},
|
||||
// On Linux, JDK 9+ cannot launch Minecraft<=1.12.2, since JDK 9+ does not accept loading native library built in different arch.
|
||||
// For example, JDK 9+ 64-bit cannot load 32-bit lwjgl native library.
|
||||
VANILLA_LINUX_JAVA_8(JavaVersionConstraint.RULE_MANDATORY, versionRange("0", "1.12.999"), versionRange(JavaVersionConstraint.MIN, "1.8.999")) {
|
||||
VANILLA_LINUX_JAVA_8(JavaVersionConstraint.RULE_MANDATORY, atMost("1.12.999"), atMost("1.8.999")) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
@@ -119,7 +120,7 @@ public enum JavaVersionConstraint {
|
||||
}
|
||||
},
|
||||
// Minecraft currently does not provide official support for architectures other than x86 and x86-64.
|
||||
VANILLA_X86(JavaVersionConstraint.RULE_SUGGESTED, versionRange(JavaVersionConstraint.MIN, JavaVersionConstraint.MAX), versionRange(JavaVersionConstraint.MIN, JavaVersionConstraint.MAX)) {
|
||||
VANILLA_X86(JavaVersionConstraint.RULE_SUGGESTED, VersionRange.all(), VersionRange.all()) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
@@ -138,7 +139,7 @@ public enum JavaVersionConstraint {
|
||||
}
|
||||
},
|
||||
// Minecraft 1.16+Forge with crash because JDK-8273826
|
||||
MODLAUNCHER_8(JavaVersionConstraint.RULE_SUGGESTED, versionRange("1.16.3", "1.17.1"), versionRange(JavaVersionConstraint.MIN, JavaVersionConstraint.MAX)) {
|
||||
MODLAUNCHER_8(JavaVersionConstraint.RULE_SUGGESTED, between("1.16.3", "1.17.1"), VersionRange.all()) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
@@ -158,7 +159,7 @@ public enum JavaVersionConstraint {
|
||||
case "1.16.5":
|
||||
return forgePatchVersion.compareTo(VersionNumber.asVersion("36.2.23")) <= 0;
|
||||
case "1.17.1":
|
||||
return versionRange("37.0.60", "37.0.75").contains(forgePatchVersion);
|
||||
return between("37.0.60", "37.0.75").contains(forgePatchVersion);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -184,10 +185,10 @@ public enum JavaVersionConstraint {
|
||||
};;
|
||||
|
||||
private final int type;
|
||||
private final Range<VersionNumber> gameVersionRange;
|
||||
private final Range<VersionNumber> javaVersionRange;
|
||||
private final VersionRange gameVersionRange;
|
||||
private final VersionRange javaVersionRange;
|
||||
|
||||
JavaVersionConstraint(int type, Range<VersionNumber> gameVersionRange, Range<VersionNumber> javaVersionRange) {
|
||||
JavaVersionConstraint(int type, VersionRange gameVersionRange, VersionRange javaVersionRange) {
|
||||
this.type = type;
|
||||
this.gameVersionRange = gameVersionRange;
|
||||
this.javaVersionRange = javaVersionRange;
|
||||
@@ -197,11 +198,11 @@ public enum JavaVersionConstraint {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Range<VersionNumber> getGameVersionRange() {
|
||||
public VersionRange getGameVersionRange() {
|
||||
return gameVersionRange;
|
||||
}
|
||||
|
||||
public Range<VersionNumber> getJavaVersionRange(Version version) {
|
||||
public VersionRange getJavaVersionRange(Version version) {
|
||||
return javaVersionRange;
|
||||
}
|
||||
|
||||
@@ -224,12 +225,12 @@ public enum JavaVersionConstraint {
|
||||
public static final List<JavaVersionConstraint> ALL = Lang.immutableListOf(values());
|
||||
|
||||
public static VersionRanges findSuitableJavaVersionRange(VersionNumber gameVersion, Version version) {
|
||||
Range<VersionNumber> mandatoryJavaRange = versionRange(MIN, MAX);
|
||||
Range<VersionNumber> suggestedJavaRange = versionRange(MIN, MAX);
|
||||
VersionRange mandatoryJavaRange = VersionRange.all();
|
||||
VersionRange suggestedJavaRange = VersionRange.all();
|
||||
LibraryAnalyzer analyzer = version != null ? LibraryAnalyzer.analyze(version) : null;
|
||||
for (JavaVersionConstraint java : ALL) {
|
||||
if (java.appliesToVersion(gameVersion, version, null, analyzer)) {
|
||||
Range<VersionNumber> javaVersionRange = java.getJavaVersionRange(version);
|
||||
VersionRange javaVersionRange = java.getJavaVersionRange(version);
|
||||
if (java.type == RULE_MANDATORY) {
|
||||
mandatoryJavaRange = mandatoryJavaRange.intersectionWith(javaVersionRange);
|
||||
suggestedJavaRange = suggestedJavaRange.intersectionWith(javaVersionRange);
|
||||
@@ -297,31 +298,20 @@ public enum JavaVersionConstraint {
|
||||
public static final int RULE_MANDATORY = 1;
|
||||
public static final int RULE_SUGGESTED = 2;
|
||||
|
||||
public static final String MIN = "0";
|
||||
public static final String MAX = "10000";
|
||||
public static final class VersionRanges {
|
||||
private final VersionRange mandatory;
|
||||
private final VersionRange suggested;
|
||||
|
||||
private static Range<VersionNumber> versionRange(String fromInclusive, String toExclusive) {
|
||||
return Range.between(VersionNumber.asVersion(fromInclusive), VersionNumber.asVersion(toExclusive));
|
||||
}
|
||||
|
||||
static Range<VersionNumber> versionIs(String version) {
|
||||
return Range.is(VersionNumber.asVersion(version));
|
||||
}
|
||||
|
||||
public static class VersionRanges {
|
||||
private final Range<VersionNumber> mandatory;
|
||||
private final Range<VersionNumber> suggested;
|
||||
|
||||
public VersionRanges(Range<VersionNumber> mandatory, Range<VersionNumber> suggested) {
|
||||
public VersionRanges(VersionRange mandatory, VersionRange suggested) {
|
||||
this.mandatory = mandatory;
|
||||
this.suggested = suggested;
|
||||
}
|
||||
|
||||
public Range<VersionNumber> getMandatory() {
|
||||
public VersionRange getMandatory() {
|
||||
return mandatory;
|
||||
}
|
||||
|
||||
public Range<VersionNumber> getSuggested() {
|
||||
public VersionRange getSuggested() {
|
||||
return suggested;
|
||||
}
|
||||
}
|
||||
|
||||
28
HMCLCore/src/main/java/org/jackhuang/hmcl/util/Holder.java
Normal file
28
HMCLCore/src/main/java/org/jackhuang/hmcl/util/Holder.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package org.jackhuang.hmcl.util;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class Holder<T> {
|
||||
public T value;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
|
||||
if (!(obj instanceof Holder))
|
||||
return false;
|
||||
|
||||
return Objects.equals(this.value, ((Holder<?>) obj).value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Holder[" + value + "]";
|
||||
}
|
||||
}
|
||||
@@ -347,6 +347,14 @@ public class VersionNumber implements Comparable<VersionNumber> {
|
||||
return canonical;
|
||||
}
|
||||
|
||||
public VersionNumber min(VersionNumber that) {
|
||||
return this.compareTo(that) <= 0 ? this : that;
|
||||
}
|
||||
|
||||
public VersionNumber max(VersionNumber that) {
|
||||
return this.compareTo(that) >= 0 ? this : that;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof VersionNumber && canonical.equals(((VersionNumber) o).canonical);
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
package org.jackhuang.hmcl.util.versioning;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class VersionRange {
|
||||
private static final VersionRange EMPTY = new VersionRange(null, null);
|
||||
private static final VersionRange ALL = new VersionRange(null, null);
|
||||
|
||||
public static VersionRange empty() {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
public static VersionRange all() {
|
||||
return ALL;
|
||||
}
|
||||
|
||||
public static VersionRange between(String minimum, String maximum) {
|
||||
return between(VersionNumber.asVersion(minimum), VersionNumber.asVersion(maximum));
|
||||
}
|
||||
|
||||
public static VersionRange between(VersionNumber minimum, VersionNumber maximum) {
|
||||
assert minimum.compareTo(maximum) <= 0;
|
||||
return new VersionRange(minimum, maximum);
|
||||
}
|
||||
|
||||
public static VersionRange atLeast(String minimum) {
|
||||
return atLeast(VersionNumber.asVersion(minimum));
|
||||
}
|
||||
|
||||
public static VersionRange atLeast(VersionNumber minimum) {
|
||||
assert minimum != null;
|
||||
return new VersionRange(minimum, null);
|
||||
}
|
||||
|
||||
public static VersionRange atMost(String maximum) {
|
||||
return atMost(VersionNumber.asVersion(maximum));
|
||||
}
|
||||
|
||||
public static VersionRange atMost(VersionNumber maximum) {
|
||||
assert maximum != null;
|
||||
return new VersionRange(null, maximum);
|
||||
}
|
||||
|
||||
private final VersionNumber minimum;
|
||||
private final VersionNumber maximum;
|
||||
|
||||
private VersionRange(VersionNumber minimum, VersionNumber maximum) {
|
||||
this.minimum = minimum;
|
||||
this.maximum = maximum;
|
||||
}
|
||||
|
||||
public VersionNumber getMinimum() {
|
||||
return minimum;
|
||||
}
|
||||
|
||||
public VersionNumber getMaximum() {
|
||||
return maximum;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this == EMPTY;
|
||||
}
|
||||
|
||||
public boolean isAll() {
|
||||
return !isEmpty() && minimum == null && maximum == null;
|
||||
}
|
||||
|
||||
public boolean contains(String versionNumber) {
|
||||
return contains(VersionNumber.asVersion(versionNumber));
|
||||
}
|
||||
|
||||
public boolean contains(VersionNumber versionNumber) {
|
||||
if (isEmpty()) return false;
|
||||
if (isAll()) return true;
|
||||
|
||||
return (minimum == null || minimum.compareTo(versionNumber) <= 0) && (maximum == null || maximum.compareTo(versionNumber) >= 0);
|
||||
}
|
||||
|
||||
public boolean isOverlappedBy(final VersionRange that) {
|
||||
if (this.isEmpty() || that.isEmpty())
|
||||
return false;
|
||||
|
||||
if (this.isAll() || that.isAll())
|
||||
return true;
|
||||
|
||||
if (this.minimum == null)
|
||||
return that.minimum == null || that.minimum.compareTo(this.maximum) <= 0;
|
||||
|
||||
if (this.maximum == null)
|
||||
return that.maximum == null || that.maximum.compareTo(this.minimum) >= 0;
|
||||
|
||||
return that.contains(minimum) || that.contains(maximum) || (that.minimum != null && contains(that.minimum));
|
||||
}
|
||||
|
||||
public VersionRange intersectionWith(VersionRange that) {
|
||||
if (this.isAll())
|
||||
return that;
|
||||
if (that.isAll())
|
||||
return this;
|
||||
|
||||
if (!isOverlappedBy(that))
|
||||
return EMPTY;
|
||||
|
||||
VersionNumber newMinimum;
|
||||
if (this.minimum == null)
|
||||
newMinimum = that.minimum;
|
||||
else if (that.minimum == null)
|
||||
newMinimum = this.minimum;
|
||||
else
|
||||
newMinimum = this.minimum.max(that.minimum);
|
||||
|
||||
VersionNumber newMaximum;
|
||||
if (this.maximum == null)
|
||||
newMaximum = that.maximum;
|
||||
else if (that.maximum == null)
|
||||
newMaximum = this.maximum;
|
||||
else
|
||||
newMaximum = this.maximum.min(that.maximum);
|
||||
|
||||
return new VersionRange(newMinimum, newMaximum);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (isEmpty())
|
||||
return 1121763849; // Magic Number
|
||||
if (isAll())
|
||||
return -475303149; // Magic Number
|
||||
|
||||
return Objects.hash(minimum) ^ Objects.hash(maximum);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!(obj instanceof VersionRange))
|
||||
return false;
|
||||
|
||||
VersionRange that = (VersionRange) obj;
|
||||
|
||||
return this.isEmpty() == that.isEmpty() && this.isAll() == that.isAll()
|
||||
&& Objects.equals(this.minimum, that.minimum)
|
||||
&& Objects.equals(this.maximum, that.maximum);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (isEmpty())
|
||||
return "EMPTY";
|
||||
|
||||
if (isAll())
|
||||
return "ALL";
|
||||
|
||||
if (minimum == null)
|
||||
return "At most " + maximum;
|
||||
|
||||
if (maximum == null)
|
||||
return "At least " + minimum;
|
||||
|
||||
return "[" + minimum + ".." + maximum + "]";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user