弃用 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:
@@ -4,8 +4,6 @@ import javafx.scene.shape.Mesh;
|
||||
import javafx.scene.shape.MeshView;
|
||||
import javafx.scene.shape.TriangleMesh;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
public class SkinCube extends MeshView {
|
||||
|
||||
public static class Model extends TriangleMesh {
|
||||
@@ -77,13 +75,23 @@ public class SkinCube extends MeshView {
|
||||
};
|
||||
|
||||
int[] copy = faces.clone();
|
||||
ArrayUtils.reverse(copy);
|
||||
|
||||
for (int i = 0, mid = copy.length >> 1, j = copy.length - 1; i < mid; i++, j--) {
|
||||
int tmp = copy[i];
|
||||
copy[i] = copy[j];
|
||||
copy[j] = tmp;
|
||||
}
|
||||
|
||||
for (int i = 0; i < copy.length; i += 2) {
|
||||
int tmp = copy[i];
|
||||
copy[i] = copy[i + 1];
|
||||
copy[i + 1] = tmp;
|
||||
}
|
||||
return ArrayUtils.addAll(faces, copy);
|
||||
|
||||
int[] result = new int[faces.length + copy.length];
|
||||
System.arraycopy(faces, 0, result, 0, faces.length);
|
||||
System.arraycopy(copy, 0, result, faces.length, copy.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,9 +46,9 @@ import javafx.scene.text.TextFlow;
|
||||
import javafx.util.Callback;
|
||||
import javafx.util.Duration;
|
||||
import javafx.util.StringConverter;
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.ui.construct.JFXHyperlink;
|
||||
import org.jackhuang.hmcl.util.Holder;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.ResourceNotFoundError;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
@@ -721,16 +721,16 @@ public final class FXUtils {
|
||||
}
|
||||
|
||||
public static <T> Callback<ListView<T>, ListCell<T>> jfxListCellFactory(Function<T, Node> graphicBuilder) {
|
||||
MutableObject<Object> lastCell = new MutableObject<>();
|
||||
Holder<Object> lastCell = new Holder<>();
|
||||
return view -> new JFXListCell<T>() {
|
||||
@Override
|
||||
public void updateItem(T item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
// https://mail.openjdk.org/pipermail/openjfx-dev/2022-July/034764.html
|
||||
if (this == lastCell.getValue() && !isVisible())
|
||||
if (this == lastCell.value && !isVisible())
|
||||
return;
|
||||
lastCell.setValue(this);
|
||||
lastCell.value = this;
|
||||
|
||||
if (!empty) {
|
||||
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
|
||||
|
||||
@@ -35,9 +35,9 @@ import javafx.scene.control.Label;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.stage.Stage;
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
import org.jackhuang.hmcl.game.LauncherHelper;
|
||||
import org.jackhuang.hmcl.setting.Theme;
|
||||
import org.jackhuang.hmcl.util.Holder;
|
||||
import org.jackhuang.hmcl.util.CircularArrayList;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.Log4jLevel;
|
||||
@@ -294,7 +294,7 @@ public final class LogWindow extends Stage {
|
||||
|
||||
listView.setStyle("-fx-font-family: " + Lang.requireNonNullElse(config().getFontFamily(), FXUtils.DEFAULT_MONOSPACE_FONT)
|
||||
+ "; -fx-font-size: " + config().getFontSize() + "px;");
|
||||
MutableObject<Object> lastCell = new MutableObject<>();
|
||||
Holder<Object> lastCell = new Holder<>();
|
||||
listView.setCellFactory(x -> new ListCell<Log>() {
|
||||
{
|
||||
getStyleClass().add("log-window-list-cell");
|
||||
@@ -313,9 +313,9 @@ public final class LogWindow extends Stage {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
// https://mail.openjdk.org/pipermail/openjfx-dev/2022-July/034764.html
|
||||
if (this == lastCell.getValue() && !isVisible())
|
||||
if (this == lastCell.value && !isVisible())
|
||||
return;
|
||||
lastCell.setValue(this);
|
||||
lastCell.value = this;
|
||||
|
||||
pseudoClassStateChanged(EMPTY, empty);
|
||||
pseudoClassStateChanged(FATAL, !empty && item.level == Log4jLevel.FATAL);
|
||||
|
||||
@@ -22,17 +22,17 @@ import javafx.css.PseudoClass;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.util.Holder;
|
||||
|
||||
public abstract class MDListCell<T> extends ListCell<T> {
|
||||
private final PseudoClass SELECTED = PseudoClass.getPseudoClass("selected");
|
||||
|
||||
private final StackPane container = new StackPane();
|
||||
private final StackPane root = new StackPane();
|
||||
private final MutableObject<Object> lastCell;
|
||||
private final Holder<Object> lastCell;
|
||||
|
||||
public MDListCell(JFXListView<T> listView, MutableObject<Object> lastCell) {
|
||||
public MDListCell(JFXListView<T> listView, Holder<Object> lastCell) {
|
||||
this.lastCell = lastCell;
|
||||
|
||||
setText(null);
|
||||
@@ -57,9 +57,9 @@ public abstract class MDListCell<T> extends ListCell<T> {
|
||||
|
||||
// https://mail.openjdk.org/pipermail/openjfx-dev/2022-July/034764.html
|
||||
if (lastCell != null) {
|
||||
if (this == lastCell.getValue() && !isVisible())
|
||||
if (this == lastCell.value && !isVisible())
|
||||
return;
|
||||
lastCell.setValue(this);
|
||||
lastCell.value = this;
|
||||
}
|
||||
|
||||
updateControl(item, empty);
|
||||
|
||||
@@ -28,7 +28,6 @@ import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.*;
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||
import org.jackhuang.hmcl.download.VersionList;
|
||||
@@ -53,6 +52,7 @@ import org.jackhuang.hmcl.ui.wizard.Navigation;
|
||||
import org.jackhuang.hmcl.ui.wizard.Refreshable;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardPage;
|
||||
import org.jackhuang.hmcl.util.HMCLService;
|
||||
import org.jackhuang.hmcl.util.Holder;
|
||||
import org.jackhuang.hmcl.util.i18n.Locales;
|
||||
|
||||
import java.util.EnumMap;
|
||||
@@ -179,7 +179,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
|
||||
|
||||
btnRefresh.setGraphic(wrap(SVG.refresh(Theme.blackFillBinding(), -1, -1)));
|
||||
|
||||
MutableObject<RemoteVersionListCell> lastCell = new MutableObject<>();
|
||||
Holder<RemoteVersionListCell> lastCell = new Holder<>();
|
||||
EnumMap<VersionIconType, Image> icons = new EnumMap<>(VersionIconType.class);
|
||||
list.setCellFactory(listView -> new RemoteVersionListCell(lastCell, icons));
|
||||
|
||||
@@ -273,10 +273,10 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
|
||||
final RipplerContainer ripplerContainer = new RipplerContainer(content);
|
||||
final StackPane pane = new StackPane();
|
||||
|
||||
private final MutableObject<RemoteVersionListCell> lastCell;
|
||||
private final Holder<RemoteVersionListCell> lastCell;
|
||||
private final EnumMap<VersionIconType, Image> icons;
|
||||
|
||||
RemoteVersionListCell(MutableObject<RemoteVersionListCell> lastCell, EnumMap<VersionIconType, Image> icons) {
|
||||
RemoteVersionListCell(Holder<RemoteVersionListCell> lastCell, EnumMap<VersionIconType, Image> icons) {
|
||||
this.lastCell = lastCell;
|
||||
this.icons = icons;
|
||||
|
||||
@@ -294,9 +294,9 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
|
||||
super.updateItem(remoteVersion, empty);
|
||||
|
||||
// https://mail.openjdk.org/pipermail/openjfx-dev/2022-July/034764.html
|
||||
if (this == lastCell.getValue() && !isVisible())
|
||||
if (this == lastCell.value && !isVisible())
|
||||
return;
|
||||
lastCell.setValue(this);
|
||||
lastCell.value = this;
|
||||
|
||||
if (empty) {
|
||||
setGraphic(null);
|
||||
|
||||
@@ -27,10 +27,10 @@ import javafx.scene.Cursor;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.scene.text.TextAlignment;
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.util.Holder;
|
||||
import org.jackhuang.hmcl.util.io.HttpRequest;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@@ -85,16 +85,16 @@ public class SponsorPage extends StackPane {
|
||||
StackPane pane = new StackPane();
|
||||
pane.getStyleClass().add("card");
|
||||
listView = new JFXListView<>();
|
||||
MutableObject<Object> lastCell = new MutableObject<>();
|
||||
Holder<Object> lastCell = new Holder<>();
|
||||
listView.setCellFactory((listView) -> new JFXListCell<Sponsor>() {
|
||||
@Override
|
||||
public void updateItem(Sponsor item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
// https://mail.openjdk.org/pipermail/openjfx-dev/2022-July/034764.html
|
||||
if (this == lastCell.getValue() && !isVisible())
|
||||
if (this == lastCell.value && !isVisible())
|
||||
return;
|
||||
lastCell.setValue(this);
|
||||
lastCell.value = this;
|
||||
|
||||
if (!empty) {
|
||||
setText(item.getName());
|
||||
|
||||
@@ -32,7 +32,6 @@ import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
import org.jackhuang.hmcl.mod.LocalModFile;
|
||||
import org.jackhuang.hmcl.mod.ModManager;
|
||||
import org.jackhuang.hmcl.setting.Theme;
|
||||
@@ -44,6 +43,7 @@ import org.jackhuang.hmcl.ui.SVG;
|
||||
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
||||
import org.jackhuang.hmcl.ui.animation.TransitionPane;
|
||||
import org.jackhuang.hmcl.ui.construct.*;
|
||||
import org.jackhuang.hmcl.util.Holder;
|
||||
import org.jackhuang.hmcl.util.Lazy;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.i18n.I18n;
|
||||
@@ -164,7 +164,7 @@ class ModListPageSkin extends SkinBase<ModListPage> {
|
||||
center.getStyleClass().add("large-spinner-pane");
|
||||
center.loadingProperty().bind(skinnable.loadingProperty());
|
||||
|
||||
MutableObject<Object> lastCell = new MutableObject<>();
|
||||
Holder<Object> lastCell = new Holder<>();
|
||||
listView.setCellFactory(x -> new ModInfoListCell(listView, lastCell));
|
||||
listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
|
||||
Bindings.bindContent(listView.getItems(), skinnable.getItems());
|
||||
@@ -371,7 +371,7 @@ class ModListPageSkin extends SkinBase<ModListPage> {
|
||||
JFXButton revealButton = new JFXButton();
|
||||
BooleanProperty booleanProperty;
|
||||
|
||||
ModInfoListCell(JFXListView<ModInfoObject> listView, MutableObject<Object> lastCell) {
|
||||
ModInfoListCell(JFXListView<ModInfoObject> listView, Holder<Object> lastCell) {
|
||||
super(listView, lastCell);
|
||||
|
||||
HBox container = new HBox(8);
|
||||
|
||||
@@ -15,6 +15,5 @@ dependencies {
|
||||
api("com.nqzero:permit-reflect:0.3")
|
||||
api("org.nanohttpd:nanohttpd:2.3.1")
|
||||
api("org.apache.commons:commons-compress:1.21")
|
||||
api("org.apache.commons:commons-lang3:3.12.0")
|
||||
compileOnlyApi("org.jetbrains:annotations:16.0.3")
|
||||
}
|
||||
|
||||
@@ -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 + "]";
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,8 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.game;
|
||||
|
||||
import org.apache.commons.lang3.Range;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionRange;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
@@ -32,8 +32,6 @@ public class JavaVersionConstraintTest {
|
||||
null
|
||||
);
|
||||
|
||||
assertEquals(
|
||||
Range.between(VersionNumber.asVersion("16"), VersionNumber.asVersion(JavaVersionConstraint.MAX)),
|
||||
range.getMandatory());
|
||||
assertEquals(VersionRange.atLeast("16"), range.getMandatory());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util;
|
||||
package org.jackhuang.hmcl.util.versioning;
|
||||
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -0,0 +1,119 @@
|
||||
package org.jackhuang.hmcl.util.versioning;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.jackhuang.hmcl.util.versioning.VersionRange.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class VersionRangeTest {
|
||||
|
||||
@Test
|
||||
public void testContains() {
|
||||
assertTrue(between("10", "20").contains("10"));
|
||||
assertTrue(between("10", "20").contains("15"));
|
||||
assertTrue(between("10", "20").contains("20"));
|
||||
assertFalse(between("10", "20").contains("5"));
|
||||
assertFalse(between("10", "20").contains("25"));
|
||||
|
||||
assertTrue(between("10", "10").contains("10"));
|
||||
assertFalse(between("10", "10").contains("5"));
|
||||
assertFalse(between("10", "10").contains("15"));
|
||||
|
||||
assertTrue(atLeast("10").contains("10"));
|
||||
assertTrue(atLeast("10").contains("20"));
|
||||
assertFalse(atLeast("10").contains("5"));
|
||||
|
||||
assertTrue(atMost("10").contains("10"));
|
||||
assertTrue(atMost("10").contains("5"));
|
||||
assertFalse(atMost("10").contains("20"));
|
||||
|
||||
assertFalse(empty().contains("0"));
|
||||
assertFalse(empty().contains("10"));
|
||||
|
||||
assertTrue(all().contains("0"));
|
||||
assertTrue(all().contains("10"));
|
||||
}
|
||||
|
||||
private static void assertIsOverlappedBy(boolean value, VersionRange range1, VersionRange range2) {
|
||||
assertEquals(value, range1.isOverlappedBy(range2));
|
||||
assertEquals(value, range2.isOverlappedBy(range1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsOverlappedBy() {
|
||||
assertIsOverlappedBy(true, all(), all());
|
||||
assertIsOverlappedBy(false, all(), empty());
|
||||
assertIsOverlappedBy(false, empty(), empty());
|
||||
|
||||
assertIsOverlappedBy(true, all(), between("10", "20"));
|
||||
assertIsOverlappedBy(true, all(), atLeast("10"));
|
||||
assertIsOverlappedBy(true, all(), atMost("10"));
|
||||
|
||||
assertIsOverlappedBy(false, empty(), between("10", "20"));
|
||||
assertIsOverlappedBy(false, empty(), atLeast("10"));
|
||||
assertIsOverlappedBy(false, empty(), atMost("10"));
|
||||
|
||||
assertIsOverlappedBy(true, between("10", "20"), between("10", "20"));
|
||||
assertIsOverlappedBy(true, between("10", "20"), between("5", "20"));
|
||||
assertIsOverlappedBy(true, between("10", "20"), between("5", "15"));
|
||||
assertIsOverlappedBy(true, between("10", "20"), between("5", "10"));
|
||||
assertIsOverlappedBy(false, between("10", "20"), between("5", "5"));
|
||||
assertIsOverlappedBy(true, between("10", "20"), between("10", "30"));
|
||||
assertIsOverlappedBy(true, between("10", "20"), between("15", "30"));
|
||||
assertIsOverlappedBy(true, between("10", "20"), between("20", "30"));
|
||||
assertIsOverlappedBy(false, between("10", "20"), between("21", "30"));
|
||||
assertIsOverlappedBy(true, between("10", "20"), atLeast("5"));
|
||||
assertIsOverlappedBy(true, between("10", "20"), atLeast("10"));
|
||||
assertIsOverlappedBy(true, between("10", "20"), atLeast("15"));
|
||||
assertIsOverlappedBy(true, between("10", "20"), atLeast("20"));
|
||||
assertIsOverlappedBy(false, between("10", "20"), atLeast("25"));
|
||||
|
||||
assertIsOverlappedBy(true, atLeast("10"), atLeast("10"));
|
||||
assertIsOverlappedBy(true, atLeast("10"), atLeast("20"));
|
||||
assertIsOverlappedBy(true, atLeast("10"), atLeast("5"));
|
||||
assertIsOverlappedBy(true, atLeast("10"), atMost("10"));
|
||||
assertIsOverlappedBy(true, atLeast("10"), atMost("20"));
|
||||
assertIsOverlappedBy(false, atLeast("10"), atMost("5"));
|
||||
}
|
||||
|
||||
private static void assertIntersectionWith(VersionRange range1, VersionRange range2, VersionRange result) {
|
||||
assertEquals(result, range1.intersectionWith(range2));
|
||||
assertEquals(result, range2.intersectionWith(range1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntersectionWith() {
|
||||
assertIntersectionWith(all(), all(), all());
|
||||
assertIntersectionWith(all(), empty(), empty());
|
||||
assertIntersectionWith(all(), between("10", "20"), between("10", "20"));
|
||||
assertIntersectionWith(all(), atLeast("10"), atLeast("10"));
|
||||
assertIntersectionWith(all(), atMost("10"), atMost("10"));
|
||||
|
||||
assertIntersectionWith(empty(), empty(), empty());
|
||||
assertIntersectionWith(empty(), between("10", "20"), empty());
|
||||
assertIntersectionWith(empty(), atLeast("10"), empty());
|
||||
assertIntersectionWith(empty(), atMost("10"), empty());
|
||||
|
||||
assertIntersectionWith(between("10", "20"), between("10", "20"), between("10", "20"));
|
||||
assertIntersectionWith(between("10", "20"), between("5", "20"), between("10", "20"));
|
||||
assertIntersectionWith(between("10", "20"), between("10", "25"), between("10", "20"));
|
||||
assertIntersectionWith(between("10", "20"), between("5", "25"), between("10", "20"));
|
||||
assertIntersectionWith(between("10", "20"), between("15", "20"), between("15", "20"));
|
||||
assertIntersectionWith(between("10", "20"), between("10", "15"), between("10", "15"));
|
||||
assertIntersectionWith(between("10", "20"), between("14", "16"), between("14", "16"));
|
||||
assertIntersectionWith(between("10", "20"), atLeast("5"), between("10", "20"));
|
||||
assertIntersectionWith(between("10", "20"), atLeast("10"), between("10", "20"));
|
||||
assertIntersectionWith(between("10", "20"), atLeast("15"), between("15", "20"));
|
||||
assertIntersectionWith(between("10", "20"), atLeast("20"), between("20", "20"));
|
||||
assertIntersectionWith(between("10", "20"), atLeast("25"), empty());
|
||||
assertIntersectionWith(between("10", "20"), atMost("25"), between("10", "20"));
|
||||
assertIntersectionWith(between("10", "20"), atMost("20"), between("10", "20"));
|
||||
assertIntersectionWith(between("10", "20"), atMost("15"), between("10", "15"));
|
||||
assertIntersectionWith(between("10", "20"), atMost("10"), between("10", "10"));
|
||||
assertIntersectionWith(between("10", "20"), atMost("5"), empty());
|
||||
|
||||
assertIntersectionWith(atLeast("10"), atMost("10"), between("10", "10"));
|
||||
assertIntersectionWith(atLeast("10"), atMost("20"), between("10", "20"));
|
||||
assertIntersectionWith(atLeast("10"), atMost("5"), empty());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user