mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-09 03:46:18 -04:00
更新游戏版本比较规则 (#2700)
* Create GameVersionNumber * Update GameVersionNumber * Rename DefaultVersionNumber * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update versions.txt * update * update * update
This commit is contained in:
parent
fe608e32f1
commit
95afaa5112
@ -25,7 +25,7 @@ import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.i18n.I18n;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jackhuang.hmcl.util.platform.ManagedProcess;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -84,7 +84,7 @@ public final class HMCLGameLauncher extends DefaultLauncher {
|
||||
1.11 ~ 12:zh_cn 时正常,zh_CN 时虽然显示了中文但语言设置会错误地显示选择英文
|
||||
1.13+ :zh_cn 时正常,zh_CN 时自动切换为英文
|
||||
*/
|
||||
VersionNumber gameVersion = VersionNumber.asVersion(repository.getGameVersion(version).orElse("0.0"));
|
||||
GameVersionNumber gameVersion = GameVersionNumber.asGameVersion(repository.getGameVersion(version));
|
||||
if (gameVersion.compareTo("1.1") < 0) {
|
||||
lang = null;
|
||||
} else if (gameVersion.compareTo("1.11") < 0) {
|
||||
|
@ -45,6 +45,7 @@ import org.jackhuang.hmcl.util.*;
|
||||
import org.jackhuang.hmcl.util.i18n.I18n;
|
||||
import org.jackhuang.hmcl.util.io.ResponseCodeException;
|
||||
import org.jackhuang.hmcl.util.platform.*;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
|
||||
import java.io.File;
|
||||
@ -332,7 +333,7 @@ public final class LauncherHelper {
|
||||
}
|
||||
|
||||
private static Task<JavaVersion> checkGameState(Profile profile, VersionSetting setting, Version version) {
|
||||
VersionNumber gameVersion = VersionNumber.asVersion(profile.getRepository().getGameVersion(version).orElse("Unknown"));
|
||||
GameVersionNumber gameVersion = GameVersionNumber.asGameVersion(profile.getRepository().getGameVersion(version));
|
||||
|
||||
if (setting.isNotCheckJVM()) {
|
||||
return Task.composeAsync(() -> setting.getJavaVersion(gameVersion, version))
|
||||
@ -549,14 +550,14 @@ public final class LauncherHelper {
|
||||
// Forge 2760~2773 will crash game with LiteLoader.
|
||||
boolean hasForge2760 = forgeVersion != null && (forgeVersion.compareTo("1.12.2-14.23.5.2760") >= 0) && (forgeVersion.compareTo("1.12.2-14.23.5.2773") < 0);
|
||||
boolean hasLiteLoader = version.getLibraries().stream().anyMatch(it -> it.is("com.mumfrey", "liteloader"));
|
||||
if (hasForge2760 && hasLiteLoader && gameVersion.compareTo(VersionNumber.asVersion("1.12.2")) == 0) {
|
||||
if (hasForge2760 && hasLiteLoader && gameVersion.compareTo("1.12.2") == 0) {
|
||||
suggestions.add(i18n("launch.advice.forge2760_liteloader"));
|
||||
}
|
||||
|
||||
// OptiFine 1.14.4 is not compatible with Forge 28.2.2 and later versions.
|
||||
boolean hasForge28_2_2 = forgeVersion != null && (forgeVersion.compareTo("1.14.4-28.2.2") >= 0);
|
||||
boolean hasOptiFine = version.getLibraries().stream().anyMatch(it -> it.is("optifine", "OptiFine"));
|
||||
if (hasForge28_2_2 && hasOptiFine && gameVersion.compareTo(VersionNumber.asVersion("1.14.4")) == 0) {
|
||||
if (hasForge28_2_2 && hasOptiFine && gameVersion.compareTo("1.14.4") == 0) {
|
||||
suggestions.add(i18n("launch.advice.forge28_2_2_optifine"));
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ 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.platform.Platform;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
@ -644,11 +644,11 @@ public final class VersionSetting implements Cloneable {
|
||||
launcherVisibilityProperty.set(launcherVisibility);
|
||||
}
|
||||
|
||||
public Task<JavaVersion> getJavaVersion(VersionNumber gameVersion, Version version) {
|
||||
public Task<JavaVersion> getJavaVersion(GameVersionNumber gameVersion, Version version) {
|
||||
return getJavaVersion(gameVersion, version, true);
|
||||
}
|
||||
|
||||
public Task<JavaVersion> getJavaVersion(VersionNumber gameVersion, Version version, boolean checkJava) {
|
||||
public Task<JavaVersion> getJavaVersion(GameVersionNumber gameVersion, Version version, boolean checkJava) {
|
||||
return Task.runAsync(Schedulers.javafx(), () -> {
|
||||
if (StringUtils.isBlank(getJava())) {
|
||||
setJava(StringUtils.isBlank(getJavaDir()) ? "Auto" : "Custom");
|
||||
|
@ -39,7 +39,7 @@ import org.jackhuang.hmcl.setting.Theme;
|
||||
import org.jackhuang.hmcl.setting.VersionIconType;
|
||||
import org.jackhuang.hmcl.ui.construct.RipplerContainer;
|
||||
import org.jackhuang.hmcl.util.i18n.I18n;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@ -204,7 +204,7 @@ public class InstallerItem extends Control {
|
||||
|
||||
if (gameVersion == null) {
|
||||
this.libraries = new InstallerItem[]{game, forge, neoForge, liteLoader, optiFine, fabric, fabricApi, quilt, quiltApi};
|
||||
} else if (VersionNumber.compare(gameVersion, "1.13") < 0) {
|
||||
} else if (GameVersionNumber.compare(gameVersion, "1.13") < 0) {
|
||||
this.libraries = new InstallerItem[]{game, forge, liteLoader, optiFine};
|
||||
} else {
|
||||
this.libraries = new InstallerItem[]{game, forge, neoForge, optiFine, fabric, fabricApi, quilt, quiltApi};
|
||||
|
@ -120,7 +120,7 @@ public class RootPage extends DecoratorAnimatedPage implements DecoratorPage {
|
||||
.sorted(Comparator
|
||||
.comparing((Version version) -> version.getReleaseTime() == null ? new Date(0L)
|
||||
: version.getReleaseTime())
|
||||
.thenComparing(a -> VersionNumber.asVersion(a.getId())))
|
||||
.thenComparing(version -> VersionNumber.asVersion(repository.getGameVersion(version).orElse(version.getId()))))
|
||||
.collect(Collectors.toList());
|
||||
runInFX(() -> {
|
||||
if (profile == Profiles.getSelectedProfile())
|
||||
|
@ -37,7 +37,6 @@ import javafx.scene.control.Skin;
|
||||
import javafx.scene.control.SkinBase;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.*;
|
||||
import org.jackhuang.hmcl.game.GameVersion;
|
||||
import org.jackhuang.hmcl.game.Version;
|
||||
import org.jackhuang.hmcl.mod.RemoteMod;
|
||||
import org.jackhuang.hmcl.mod.RemoteModRepository;
|
||||
@ -57,8 +56,8 @@ import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.i18n.I18n;
|
||||
import org.jackhuang.hmcl.util.javafx.BindingMapping;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@ -163,24 +162,23 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
retrySearch = null;
|
||||
setLoading(true);
|
||||
setFailed(false);
|
||||
File versionJar = StringUtils.isNotBlank(version.get().getVersion())
|
||||
? version.get().getProfile().getRepository().getVersionJar(version.get().getVersion())
|
||||
: null;
|
||||
|
||||
if (executor != null && !executor.isCancelled()) {
|
||||
executor.cancel();
|
||||
}
|
||||
|
||||
executor = Task.supplyAsync(() -> {
|
||||
String gameVersion;
|
||||
if (StringUtils.isBlank(version.get().getVersion())) {
|
||||
gameVersion = userGameVersion;
|
||||
Profile.ProfileVersion version = this.version.get();
|
||||
if (StringUtils.isBlank(version.getVersion())) {
|
||||
return userGameVersion;
|
||||
} else {
|
||||
gameVersion = GameVersion.minecraftVersion(versionJar).orElse("");
|
||||
return StringUtils.isNotBlank(version.getVersion())
|
||||
? version.getProfile().getRepository().getGameVersion(version.getVersion()).orElse("")
|
||||
: "";
|
||||
}
|
||||
return gameVersion;
|
||||
}).thenApplyAsync(gameVersion -> {
|
||||
return repository.search(gameVersion, category, pageOffset, 50, searchFilter, sort, RemoteModRepository.SortOrder.DESC);
|
||||
}).whenComplete(Schedulers.javafx(), (result, exception) -> {
|
||||
}).thenApplyAsync(gameVersion ->
|
||||
repository.search(gameVersion, category, pageOffset, 50, searchFilter, sort, RemoteModRepository.SortOrder.DESC)
|
||||
).whenComplete(Schedulers.javafx(), (result, exception) -> {
|
||||
setLoading(false);
|
||||
if (exception == null) {
|
||||
items.setAll(result.getResults().collect(Collectors.toList()));
|
||||
@ -295,7 +293,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
JFXComboBox<String> gameVersionField = new JFXComboBox<>();
|
||||
gameVersionField.setMaxWidth(Double.MAX_VALUE);
|
||||
gameVersionField.setEditable(true);
|
||||
gameVersionField.getItems().setAll(RemoteModRepository.DEFAULT_GAME_VERSIONS);
|
||||
gameVersionField.getItems().setAll(GameVersionNumber.getDefaultGameVersions());
|
||||
Label lblGameVersion = new Label(i18n("world.game_version"));
|
||||
searchPane.addRow(rowIndex++, new Label(i18n("mods.name")), nameField, lblGameVersion, gameVersionField);
|
||||
|
||||
|
@ -51,7 +51,7 @@ import org.jackhuang.hmcl.util.*;
|
||||
import org.jackhuang.hmcl.util.i18n.I18n;
|
||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
||||
import org.jackhuang.hmcl.util.javafx.BindingMapping;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
@ -309,7 +309,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
}
|
||||
|
||||
for (String gameVersion : control.versions.keys().stream()
|
||||
.sorted(Collections.reverseOrder(VersionNumber::compare))
|
||||
.sorted(Collections.reverseOrder(GameVersionNumber::compare))
|
||||
.collect(Collectors.toList())) {
|
||||
ComponentList sublist = new ComponentList(() ->
|
||||
control.versions.get(gameVersion).stream()
|
||||
|
@ -46,7 +46,7 @@ import org.jackhuang.hmcl.util.javafx.SafeStringConverter;
|
||||
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.GameVersionNumber;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
@ -611,10 +611,10 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
||||
|
||||
Task.composeAsync(Schedulers.javafx(), () -> {
|
||||
if (versionId == null) {
|
||||
return versionSetting.getJavaVersion(VersionNumber.asVersion("Unknown"), null);
|
||||
return versionSetting.getJavaVersion(GameVersionNumber.unknown(), null);
|
||||
} else {
|
||||
return versionSetting.getJavaVersion(
|
||||
VersionNumber.asVersion(GameVersion.minecraftVersion(profile.getRepository().getVersionJar(versionId)).orElse("Unknown")),
|
||||
GameVersionNumber.asGameVersion(profile.getRepository().getGameVersion(versionId)),
|
||||
profile.getRepository().getVersion(versionId));
|
||||
}
|
||||
}).thenAcceptAsync(Schedulers.javafx(), javaVersion -> javaSublist.setSubtitle(Optional.ofNullable(javaVersion)
|
||||
|
@ -29,7 +29,7 @@ import org.jackhuang.hmcl.game.World;
|
||||
import org.jackhuang.hmcl.ui.Controllers;
|
||||
import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.ui.wizard.SinglePageWizardProvider;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.Instant;
|
||||
@ -94,8 +94,7 @@ public class WorldListItem extends Control {
|
||||
|
||||
public void manageDatapacks() {
|
||||
if (world.getGameVersion() == null || // old game will not write game version to level.dat
|
||||
(VersionNumber.isIntVersionNumber(world.getGameVersion()) // we don't parse snapshot version
|
||||
&& VersionNumber.asVersion(world.getGameVersion()).compareTo(VersionNumber.asVersion("1.13")) < 0)) {
|
||||
GameVersionNumber.compare(world.getGameVersion(), "1.13") < 0) {
|
||||
Controllers.dialog(i18n("world.datapack.1_13"));
|
||||
return;
|
||||
}
|
||||
|
@ -32,13 +32,12 @@ import static org.jackhuang.hmcl.util.Lang.mapOf;
|
||||
import static org.jackhuang.hmcl.util.Lang.thread;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
import static org.jackhuang.hmcl.util.versioning.VersionNumber.asVersion;
|
||||
|
||||
public final class UpdateChecker {
|
||||
private UpdateChecker() {}
|
||||
|
||||
private static ObjectProperty<RemoteVersion> latestVersion = new SimpleObjectProperty<>();
|
||||
private static BooleanBinding outdated = Bindings.createBooleanBinding(
|
||||
private static final ObjectProperty<RemoteVersion> latestVersion = new SimpleObjectProperty<>();
|
||||
private static final BooleanBinding outdated = Bindings.createBooleanBinding(
|
||||
() -> {
|
||||
RemoteVersion latest = latestVersion.get();
|
||||
if (latest == null || isDevelopmentVersion(Metadata.VERSION)) {
|
||||
@ -46,11 +45,11 @@ public final class UpdateChecker {
|
||||
} else {
|
||||
// We can update from development version to stable version,
|
||||
// which can be downgrading.
|
||||
return asVersion(latest.getVersion()).compareTo(asVersion(Metadata.VERSION)) != 0;
|
||||
return !latest.getVersion().equals(Metadata.VERSION);
|
||||
}
|
||||
},
|
||||
latestVersion);
|
||||
private static ReadOnlyBooleanWrapper checkingUpdate = new ReadOnlyBooleanWrapper(false);
|
||||
private static final ReadOnlyBooleanWrapper checkingUpdate = new ReadOnlyBooleanWrapper(false);
|
||||
|
||||
public static void init() {
|
||||
requestCheckUpdate(UpdateChannel.getChannel());
|
||||
|
@ -8,7 +8,7 @@ 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.platform.Platform;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
@ -45,7 +45,7 @@ public final class NativePatcher {
|
||||
|
||||
public static Version patchNative(Version version, String gameVersion, JavaVersion javaVersion, VersionSetting settings) {
|
||||
if (settings.getNativesDirType() == NativesDirectoryType.CUSTOM) {
|
||||
if (gameVersion != null && VersionNumber.compare(gameVersion, "1.19") < 0)
|
||||
if (gameVersion != null && GameVersionNumber.compare(gameVersion, "1.19") < 0)
|
||||
return version;
|
||||
|
||||
ArrayList<Library> newLibraries = new ArrayList<>();
|
||||
@ -66,7 +66,7 @@ public final class NativePatcher {
|
||||
final boolean useNativeOpenAL = settings.isUseNativeOpenAL();
|
||||
|
||||
if (OperatingSystem.CURRENT_OS.isLinuxOrBSD() && (useNativeGLFW || useNativeOpenAL)
|
||||
&& VersionNumber.compare(gameVersion, "1.19") >= 0) {
|
||||
&& GameVersionNumber.compare(gameVersion, "1.19") >= 0) {
|
||||
|
||||
version = version.setLibraries(version.getLibraries().stream()
|
||||
.filter(library -> {
|
||||
@ -88,7 +88,7 @@ public final class NativePatcher {
|
||||
|
||||
OperatingSystem os = javaVersion.getPlatform().getOperatingSystem();
|
||||
Architecture arch = javaVersion.getArchitecture();
|
||||
VersionNumber gameVersionNumber = gameVersion != null ? VersionNumber.asVersion(gameVersion) : null;
|
||||
GameVersionNumber gameVersionNumber = gameVersion != null ? GameVersionNumber.asGameVersion(gameVersion) : null;
|
||||
|
||||
if (settings.isNotPatchNatives())
|
||||
return version;
|
||||
|
@ -24,7 +24,7 @@ import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.CompressingUtils;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystem;
|
||||
@ -100,7 +100,7 @@ public final class ForgeInstallTask extends Task<Version> {
|
||||
@Override
|
||||
public void execute() throws IOException, VersionMismatchException, UnsupportedInstallationException {
|
||||
String originalMainClass = version.resolve(dependencyManager.getGameRepository()).getMainClass();
|
||||
if (VersionNumber.compare("1.13", remote.getGameVersion()) <= 0) {
|
||||
if (GameVersionNumber.compare("1.13", remote.getGameVersion()) <= 0) {
|
||||
// Forge 1.13 is not compatible with fabric.
|
||||
if (!LibraryAnalyzer.VANILLA_MAIN.equals(originalMainClass)
|
||||
&& !LibraryAnalyzer.MOD_LAUNCHER_MAIN.equals(originalMainClass)
|
||||
|
@ -22,7 +22,7 @@ import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||
import org.jackhuang.hmcl.game.Version;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.io.CompressingUtils;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -65,7 +65,7 @@ public final class GameVerificationFixTask extends Task<Void> {
|
||||
File jar = dependencyManager.getGameRepository().getVersionJar(version);
|
||||
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(version);
|
||||
|
||||
if (jar.exists() && VersionNumber.compare(gameVersion, "1.6") < 0 && analyzer.has(LibraryAnalyzer.LibraryType.FORGE)) {
|
||||
if (jar.exists() && GameVersionNumber.compare(gameVersion, "1.6") < 0 && analyzer.has(LibraryAnalyzer.LibraryType.FORGE)) {
|
||||
try (FileSystem fs = CompressingUtils.createWritableZipFileSystem(jar.toPath(), StandardCharsets.UTF_8)) {
|
||||
Files.deleteIfExists(fs.getPath("META-INF/MOJANG_C.DSA"));
|
||||
Files.deleteIfExists(fs.getPath("META-INF/MOJANG_C.SF"));
|
||||
|
@ -190,7 +190,7 @@ public final class OptiFineInstallTask extends Task<Version> {
|
||||
|
||||
if (LibraryAnalyzer.BOOTSTRAP_LAUNCHER_MAIN.equals(originalMainClass)) {
|
||||
// OptiFine H1 Pre2+ is compatible with Forge 1.17
|
||||
if (buildofVer.compareTo(VersionNumber.asVersion("20210924-190833")) < 0) {
|
||||
if (buildofVer.compareTo("20210924-190833") < 0) {
|
||||
throw new UnsupportedInstallationException(UnsupportedInstallationException.FORGE_1_17_OPTIFINE_H1_PRE2);
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
/**
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class GameVersion {
|
||||
final class GameVersion {
|
||||
private GameVersion() {
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ 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.GameVersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionRange;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -30,48 +31,47 @@ 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, atLeast("1.13"), atLeast("1.8")),
|
||||
VANILLA_JAVA_8(JavaVersionConstraint.RULE_MANDATORY, GameVersionNumber.atLeast("1.13"), VersionNumber.atLeast("1.8")),
|
||||
// Minecraft 1.17 requires Java 16
|
||||
VANILLA_JAVA_16(JavaVersionConstraint.RULE_MANDATORY, atLeast("1.17"), atLeast("16")),
|
||||
VANILLA_JAVA_16(JavaVersionConstraint.RULE_MANDATORY, GameVersionNumber.atLeast("1.17"), VersionNumber.atLeast("16")),
|
||||
// Minecraft>=1.18 requires Java 17
|
||||
VANILLA_JAVA_17(JavaVersionConstraint.RULE_MANDATORY, atLeast("1.18"), atLeast("17")),
|
||||
VANILLA_JAVA_17(JavaVersionConstraint.RULE_MANDATORY, GameVersionNumber.atLeast("1.18"), VersionNumber.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, atMost("1.7.2"), atMost("1.7.999")) {
|
||||
MODDED_JAVA_7(JavaVersionConstraint.RULE_SUGGESTED, GameVersionNumber.atMost("1.7.2"), VersionNumber.atMost("1.7.999")) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
protected boolean appliesToVersionImpl(GameVersionNumber 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, between("1.7.10", "1.16.999"), between("1.8", "1.8.999")) {
|
||||
MODDED_JAVA_8(JavaVersionConstraint.RULE_SUGGESTED, GameVersionNumber.between("1.7.10", "1.16.999"), VersionNumber.between("1.8", "1.8.999")) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
return analyzer != null && analyzer.has(LibraryAnalyzer.LibraryType.FORGE);
|
||||
}
|
||||
},
|
||||
MODDED_JAVA_16(JavaVersionConstraint.RULE_SUGGESTED, between("1.17", "1.17.999"), between("16", "16.999")) {
|
||||
MODDED_JAVA_16(JavaVersionConstraint.RULE_SUGGESTED, GameVersionNumber.between("1.17", "1.17.999"), VersionNumber.between("16", "16.999")) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
return analyzer != null && analyzer.has(LibraryAnalyzer.LibraryType.FORGE);
|
||||
}
|
||||
},
|
||||
MODDED_JAVA_17(JavaVersionConstraint.RULE_SUGGESTED, atLeast("1.18"), between("17", "17.999")) {
|
||||
MODDED_JAVA_17(JavaVersionConstraint.RULE_SUGGESTED, GameVersionNumber.atLeast("1.18"), VersionNumber.between("17", "17.999")) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
return analyzer != null && analyzer.has(LibraryAnalyzer.LibraryType.FORGE);
|
||||
}
|
||||
},
|
||||
// LaunchWrapper<=1.12 will crash because LaunchWrapper assumes the system class loader is an instance of URLClassLoader (Java 8)
|
||||
LAUNCH_WRAPPER(JavaVersionConstraint.RULE_MANDATORY, atMost("1.12.999"), atMost("1.8.999")) {
|
||||
LAUNCH_WRAPPER(JavaVersionConstraint.RULE_MANDATORY, GameVersionNumber.atMost("1.12.999"), VersionNumber.atMost("1.8.999")) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
if (version == null) return false;
|
||||
return LAUNCH_WRAPPER_MAIN.equals(version.getMainClass()) &&
|
||||
@ -81,15 +81,15 @@ 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, atLeast("1.13"), atLeast("1.8.0_51")),
|
||||
VANILLA_JAVA_8_51(JavaVersionConstraint.RULE_SUGGESTED, GameVersionNumber.atLeast("1.13"), VersionNumber.atLeast("1.8.0_51")),
|
||||
// Minecraft with suggested java version recorded in game json is restrictedly constrained.
|
||||
GAME_JSON(JavaVersionConstraint.RULE_MANDATORY, VersionRange.all(), VersionRange.all()) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
if (version == null) return false;
|
||||
// We only checks for 1.7.10 and above, since 1.7.2 with Forge can only run on Java 7, but it is recorded Java 8 in game json, which is not correct.
|
||||
return gameVersionNumber.compareTo(VersionNumber.asVersion("1.7.10")) >= 0 && version.getJavaVersion() != null;
|
||||
return gameVersionNumber.compareTo("1.7.10") >= 0 && version.getJavaVersion() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -100,14 +100,14 @@ public enum JavaVersionConstraint {
|
||||
} else {
|
||||
javaVersion = "1." + version.getJavaVersion().getMajorVersion();
|
||||
}
|
||||
return atLeast(javaVersion);
|
||||
return VersionNumber.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, atMost("1.12.999"), atMost("1.8.999")) {
|
||||
VANILLA_LINUX_JAVA_8(JavaVersionConstraint.RULE_MANDATORY, GameVersionNumber.atMost("1.12.999"), VersionNumber.atMost("1.8.999")) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
return OperatingSystem.CURRENT_OS == OperatingSystem.LINUX
|
||||
&& Architecture.SYSTEM_ARCH == Architecture.X86_64
|
||||
@ -115,33 +115,33 @@ public enum JavaVersionConstraint {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkJava(VersionNumber gameVersionNumber, Version version, JavaVersion javaVersion) {
|
||||
public boolean checkJava(GameVersionNumber gameVersionNumber, Version version, JavaVersion javaVersion) {
|
||||
return javaVersion.getArchitecture() != Architecture.X86_64 || super.checkJava(gameVersionNumber, version, javaVersion);
|
||||
}
|
||||
},
|
||||
// Minecraft currently does not provide official support for architectures other than x86 and x86-64.
|
||||
VANILLA_X86(JavaVersionConstraint.RULE_SUGGESTED, VersionRange.all(), VersionRange.all()) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
if (javaVersion == null || javaVersion.getArchitecture() != Architecture.ARM64)
|
||||
return false;
|
||||
|
||||
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS || OperatingSystem.CURRENT_OS == OperatingSystem.OSX)
|
||||
return gameVersionNumber.compareTo(VersionNumber.asVersion("1.6")) < 0;
|
||||
return gameVersionNumber.compareTo("1.6") < 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkJava(VersionNumber gameVersionNumber, Version version, JavaVersion javaVersion) {
|
||||
public boolean checkJava(GameVersionNumber gameVersionNumber, Version version, JavaVersion javaVersion) {
|
||||
return javaVersion.getArchitecture().isX86();
|
||||
}
|
||||
},
|
||||
// Minecraft 1.16+Forge with crash because JDK-8273826
|
||||
MODLAUNCHER_8(JavaVersionConstraint.RULE_SUGGESTED, between("1.16.3", "1.17.1"), VersionRange.all()) {
|
||||
MODLAUNCHER_8(JavaVersionConstraint.RULE_SUGGESTED, GameVersionNumber.between("1.16.3", "1.17.1"), VersionRange.all()) {
|
||||
@Override
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
if (version == null || javaVersion == null || analyzer == null) return false;
|
||||
VersionNumber forgePatchVersion = analyzer.getVersion(LibraryAnalyzer.LibraryType.FORGE)
|
||||
@ -158,14 +158,14 @@ public enum JavaVersionConstraint {
|
||||
case "1.16.5":
|
||||
return forgePatchVersion.compareTo(VersionNumber.asVersion("36.2.23")) <= 0;
|
||||
case "1.17.1":
|
||||
return between("37.0.60", "37.0.75").contains(forgePatchVersion);
|
||||
return VersionNumber.between("37.0.60", "37.0.75").contains(forgePatchVersion);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkJava(VersionNumber gameVersionNumber, Version version, JavaVersion javaVersion) {
|
||||
public boolean checkJava(GameVersionNumber gameVersionNumber, Version version, JavaVersion javaVersion) {
|
||||
int parsedJavaVersion = javaVersion.getParsedVersion();
|
||||
if (parsedJavaVersion > 17) {
|
||||
return false;
|
||||
@ -181,13 +181,13 @@ public enum JavaVersionConstraint {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};;
|
||||
};
|
||||
|
||||
private final int type;
|
||||
private final VersionRange gameVersionRange;
|
||||
private final VersionRange javaVersionRange;
|
||||
private final VersionRange<GameVersionNumber> gameVersionRange;
|
||||
private final VersionRange<VersionNumber> javaVersionRange;
|
||||
|
||||
JavaVersionConstraint(int type, VersionRange gameVersionRange, VersionRange javaVersionRange) {
|
||||
JavaVersionConstraint(int type, VersionRange<GameVersionNumber> gameVersionRange, VersionRange<VersionNumber> javaVersionRange) {
|
||||
this.type = type;
|
||||
this.gameVersionRange = gameVersionRange;
|
||||
this.javaVersionRange = javaVersionRange;
|
||||
@ -197,39 +197,39 @@ public enum JavaVersionConstraint {
|
||||
return type;
|
||||
}
|
||||
|
||||
public VersionRange getGameVersionRange() {
|
||||
public VersionRange<GameVersionNumber> getGameVersionRange() {
|
||||
return gameVersionRange;
|
||||
}
|
||||
|
||||
public VersionRange getJavaVersionRange(Version version) {
|
||||
public VersionRange<VersionNumber> getJavaVersionRange(Version version) {
|
||||
return javaVersionRange;
|
||||
}
|
||||
|
||||
public final boolean appliesToVersion(@Nullable VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
public final boolean appliesToVersion(@Nullable GameVersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, LibraryAnalyzer analyzer) {
|
||||
return gameVersionRange.contains(gameVersionNumber)
|
||||
&& appliesToVersionImpl(gameVersionNumber, version, javaVersion, analyzer);
|
||||
}
|
||||
|
||||
protected boolean appliesToVersionImpl(VersionNumber gameVersionNumber, @Nullable Version version,
|
||||
protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nullable Version version,
|
||||
@Nullable JavaVersion javaVersion, @Nullable LibraryAnalyzer analyzer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
public boolean checkJava(VersionNumber gameVersionNumber, Version version, JavaVersion javaVersion) {
|
||||
public boolean checkJava(GameVersionNumber gameVersionNumber, Version version, JavaVersion javaVersion) {
|
||||
return getJavaVersionRange(version).contains(javaVersion.getVersionNumber());
|
||||
}
|
||||
|
||||
public static final List<JavaVersionConstraint> ALL = Lang.immutableListOf(values());
|
||||
|
||||
public static VersionRanges findSuitableJavaVersionRange(VersionNumber gameVersion, Version version) {
|
||||
VersionRange mandatoryJavaRange = VersionRange.all();
|
||||
VersionRange suggestedJavaRange = VersionRange.all();
|
||||
public static VersionRanges findSuitableJavaVersionRange(GameVersionNumber gameVersion, Version version) {
|
||||
VersionRange<VersionNumber> mandatoryJavaRange = VersionRange.all();
|
||||
VersionRange<VersionNumber> suggestedJavaRange = VersionRange.all();
|
||||
LibraryAnalyzer analyzer = version != null ? LibraryAnalyzer.analyze(version) : null;
|
||||
for (JavaVersionConstraint java : ALL) {
|
||||
if (java.appliesToVersion(gameVersion, version, null, analyzer)) {
|
||||
VersionRange javaVersionRange = java.getJavaVersionRange(version);
|
||||
VersionRange<VersionNumber> javaVersionRange = java.getJavaVersionRange(version);
|
||||
if (java.type == RULE_MANDATORY) {
|
||||
mandatoryJavaRange = mandatoryJavaRange.intersectionWith(javaVersionRange);
|
||||
suggestedJavaRange = suggestedJavaRange.intersectionWith(javaVersionRange);
|
||||
@ -242,12 +242,12 @@ public enum JavaVersionConstraint {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static JavaVersion findSuitableJavaVersion(VersionNumber gameVersion, Version version) throws InterruptedException {
|
||||
public static JavaVersion findSuitableJavaVersion(GameVersionNumber gameVersion, Version version) throws InterruptedException {
|
||||
VersionRanges range = findSuitableJavaVersionRange(gameVersion, version);
|
||||
|
||||
boolean forceX86 = Architecture.SYSTEM_ARCH == Architecture.ARM64
|
||||
&& (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS || OperatingSystem.CURRENT_OS == OperatingSystem.OSX)
|
||||
&& gameVersion.compareTo(VersionNumber.asVersion("1.6")) < 0;
|
||||
&& gameVersion.compareTo("1.6") < 0;
|
||||
|
||||
JavaVersion mandatory = null;
|
||||
JavaVersion suggested = null;
|
||||
@ -298,19 +298,19 @@ public enum JavaVersionConstraint {
|
||||
public static final int RULE_SUGGESTED = 2;
|
||||
|
||||
public static final class VersionRanges {
|
||||
private final VersionRange mandatory;
|
||||
private final VersionRange suggested;
|
||||
private final VersionRange<VersionNumber> mandatory;
|
||||
private final VersionRange<VersionNumber> suggested;
|
||||
|
||||
public VersionRanges(VersionRange mandatory, VersionRange suggested) {
|
||||
public VersionRanges(VersionRange<VersionNumber> mandatory, VersionRange<VersionNumber> suggested) {
|
||||
this.mandatory = mandatory;
|
||||
this.suggested = suggested;
|
||||
}
|
||||
|
||||
public VersionRange getMandatory() {
|
||||
public VersionRange<VersionNumber> getMandatory() {
|
||||
return mandatory;
|
||||
}
|
||||
|
||||
public VersionRange getSuggested() {
|
||||
public VersionRange<VersionNumber> getSuggested() {
|
||||
return suggested;
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ import org.jackhuang.hmcl.util.io.IOUtils;
|
||||
import org.jackhuang.hmcl.util.io.Unzipper;
|
||||
import org.jackhuang.hmcl.util.platform.Bits;
|
||||
import org.jackhuang.hmcl.util.platform.*;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.InetSocketAddress;
|
||||
@ -230,7 +230,7 @@ public class DefaultLauncher extends Launcher {
|
||||
Path tempNativeFolder = null;
|
||||
if ((OperatingSystem.CURRENT_OS == OperatingSystem.LINUX || OperatingSystem.CURRENT_OS == OperatingSystem.OSX)
|
||||
&& !StringUtils.isASCII(nativeFolderPath)
|
||||
&& gameVersion.isPresent() && VersionNumber.compare(gameVersion.get(), "1.19") < 0) {
|
||||
&& gameVersion.isPresent() && GameVersionNumber.compare(gameVersion.get(), "1.19") < 0) {
|
||||
tempNativeFolder = Paths.get("/", "tmp", "hmcl-natives-" + UUID.randomUUID());
|
||||
nativeFolderPath = tempNativeFolder + File.pathSeparator + nativeFolderPath;
|
||||
}
|
||||
@ -259,7 +259,7 @@ public class DefaultLauncher extends Launcher {
|
||||
|
||||
if (StringUtils.isNotBlank(options.getServerIp())) {
|
||||
String[] args = options.getServerIp().split(":");
|
||||
if (VersionNumber.compare(gameVersion.orElse("0.0"), "1.20") < 0) {
|
||||
if (GameVersionNumber.asGameVersion(gameVersion).compareTo("1.20") < 0) {
|
||||
res.add("--server");
|
||||
res.add(args[0]);
|
||||
res.add("--port");
|
||||
@ -357,7 +357,7 @@ public class DefaultLauncher extends Launcher {
|
||||
}
|
||||
|
||||
private boolean isUsingLog4j() {
|
||||
return VersionNumber.compare(repository.getGameVersion(version).orElse("1.7"), "1.7") >= 0;
|
||||
return GameVersionNumber.compare(repository.getGameVersion(version).orElse("1.7"), "1.7") >= 0;
|
||||
}
|
||||
|
||||
public File getLog4jConfigurationFile() {
|
||||
@ -367,7 +367,7 @@ public class DefaultLauncher extends Launcher {
|
||||
public void extractLog4jConfigurationFile() throws IOException {
|
||||
File targetFile = getLog4jConfigurationFile();
|
||||
InputStream source;
|
||||
if (VersionNumber.compare(repository.getGameVersion(version).orElse("0.0"), "1.12") < 0) {
|
||||
if (GameVersionNumber.asGameVersion(repository.getGameVersion(version)).compareTo("1.12") < 0) {
|
||||
source = DefaultLauncher.class.getResourceAsStream("/assets/game/log4j2-1.7.xml");
|
||||
} else {
|
||||
source = DefaultLauncher.class.getResourceAsStream("/assets/game/log4j2-1.12.xml");
|
||||
|
@ -119,28 +119,4 @@ public interface RemoteModRepository {
|
||||
return subcategories;
|
||||
}
|
||||
}
|
||||
|
||||
String[] DEFAULT_GAME_VERSIONS = new String[]{
|
||||
"1.20.4", "1.20.3", "1.20.2", "1.20.1", "1.20",
|
||||
"1.19.4", "1.19.3", "1.19.2", "1.19.1", "1.19",
|
||||
"1.18.2", "1.18.1", "1.18",
|
||||
"1.17.1", "1.17",
|
||||
"1.16.5", "1.16.4", "1.16.3", "1.16.2", "1.16.1", "1.16",
|
||||
"1.15.2", "1.15.1", "1.15",
|
||||
"1.14.4", "1.14.3", "1.14.2", "1.14.1", "1.14",
|
||||
"1.13.2", "1.13.1", "1.13",
|
||||
"1.12.2", "1.12.1", "1.12",
|
||||
"1.11.2", "1.11.1", "1.11",
|
||||
"1.10.2", "1.10.1", "1.10",
|
||||
"1.9.4", "1.9.3", "1.9.2", "1.9.1", "1.9",
|
||||
"1.8.9", "1.8.8", "1.8.7", "1.8.6", "1.8.5", "1.8.4", "1.8.3", "1.8.2", "1.8.1", "1.8",
|
||||
"1.7.10", "1.7.9", "1.7.8", "1.7.7", "1.7.6", "1.7.5", "1.7.4", "1.7.3", "1.7.2",
|
||||
"1.6.4", "1.6.2", "1.6.1",
|
||||
"1.5.2", "1.5.1",
|
||||
"1.4.7", "1.4.6", "1.4.5", "1.4.4", "1.4.2",
|
||||
"1.3.2", "1.3.1",
|
||||
"1.2.5", "1.2.4", "1.2.3", "1.2.2", "1.2.1",
|
||||
"1.1",
|
||||
"1.0"
|
||||
};
|
||||
}
|
||||
|
@ -0,0 +1,616 @@
|
||||
package org.jackhuang.hmcl.util.versioning;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public abstract class GameVersionNumber implements Comparable<GameVersionNumber> {
|
||||
|
||||
public static String[] getDefaultGameVersions() {
|
||||
return Versions.DEFAULT_GAME_VERSIONS;
|
||||
}
|
||||
|
||||
public static GameVersionNumber asGameVersion(String version) {
|
||||
try {
|
||||
if (!version.isEmpty()) {
|
||||
char ch = version.charAt(0);
|
||||
switch (ch) {
|
||||
case 'r':
|
||||
return Old.parsePreClassic(version);
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
return Old.parseAlphaBetaClassic(version);
|
||||
case 'i':
|
||||
return Old.parseInfdev(version);
|
||||
}
|
||||
|
||||
if (version.equals("0.0")) {
|
||||
return Release.ZERO;
|
||||
}
|
||||
|
||||
if (version.startsWith("1.")) {
|
||||
return Release.parse(version);
|
||||
}
|
||||
|
||||
if (version.length() == 6 && version.charAt(2) == 'w') {
|
||||
return Snapshot.parse(version);
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException ignore) {
|
||||
}
|
||||
|
||||
Special special = Versions.SPECIALS.get(version);
|
||||
if (special == null) {
|
||||
special = new Special(version);
|
||||
}
|
||||
return special;
|
||||
}
|
||||
|
||||
public static GameVersionNumber asGameVersion(Optional<String> version) {
|
||||
return version.isPresent() ? asGameVersion(version.get()) : unknown();
|
||||
}
|
||||
|
||||
public static GameVersionNumber unknown() {
|
||||
return Release.ZERO;
|
||||
}
|
||||
|
||||
public static int compare(String version1, String version2) {
|
||||
return asGameVersion(version1).compareTo(asGameVersion(version2));
|
||||
}
|
||||
|
||||
public static VersionRange<GameVersionNumber> between(String minimum, String maximum) {
|
||||
return VersionRange.between(asGameVersion(minimum), asGameVersion(maximum));
|
||||
}
|
||||
|
||||
public static VersionRange<GameVersionNumber> atLeast(String minimum) {
|
||||
return VersionRange.atLeast(asGameVersion(minimum));
|
||||
}
|
||||
|
||||
public static VersionRange<GameVersionNumber> atMost(String maximum) {
|
||||
return VersionRange.atMost(asGameVersion(maximum));
|
||||
}
|
||||
|
||||
final String value;
|
||||
|
||||
GameVersionNumber(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
enum Type {
|
||||
PRE_CLASSIC, CLASSIC, INFDEV, ALPHA, BETA, NEW
|
||||
}
|
||||
|
||||
abstract Type getType();
|
||||
|
||||
abstract int compareToImpl(@NotNull GameVersionNumber other);
|
||||
|
||||
public int compareTo(@NotNull String other) {
|
||||
return this.compareTo(asGameVersion(other));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull GameVersionNumber other) {
|
||||
if (this.getType() != other.getType()) {
|
||||
return Integer.compare(this.getType().ordinal(), other.getType().ordinal());
|
||||
}
|
||||
|
||||
return compareToImpl(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
|
||||
static final class Old extends GameVersionNumber {
|
||||
|
||||
private static final Pattern PATTERN = Pattern.compile("[abc](?<major>[0-9]+)\\.(?<minor>[0-9]+)(\\.(?<patch>[0-9]+))?([^0-9]*(?<additional>[0-9]+).*)?");
|
||||
|
||||
static Old parsePreClassic(String value) {
|
||||
int version;
|
||||
try {
|
||||
version = Integer.parseInt(value.substring("rd-".length()));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
return new Old(value, Type.PRE_CLASSIC, version, 0, 0, 0);
|
||||
}
|
||||
|
||||
static Old parseAlphaBetaClassic(String value) {
|
||||
Matcher matcher = PATTERN.matcher(value);
|
||||
if (!matcher.matches()) {
|
||||
throw new IllegalArgumentException(value);
|
||||
}
|
||||
|
||||
Type type;
|
||||
switch (value.charAt(0)) {
|
||||
case 'a':
|
||||
type = Type.ALPHA;
|
||||
break;
|
||||
case 'b':
|
||||
type = Type.BETA;
|
||||
break;
|
||||
case 'c':
|
||||
type = Type.CLASSIC;
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError(value);
|
||||
}
|
||||
|
||||
int major = Integer.parseInt(matcher.group("major"));
|
||||
int minor = Integer.parseInt(matcher.group("minor"));
|
||||
|
||||
String patchString = matcher.group("patch");
|
||||
int patch = patchString != null ? Integer.parseInt(patchString) : 0;
|
||||
|
||||
String additionalString = matcher.group("additional");
|
||||
int additional = additionalString != null ? Integer.parseInt(additionalString) : 0;
|
||||
|
||||
return new Old(value, type, major, minor, patch, additional);
|
||||
}
|
||||
|
||||
static Old parseInfdev(String value) {
|
||||
String version = value.substring("inf-".length());
|
||||
int major;
|
||||
int patch;
|
||||
|
||||
try {
|
||||
major = Integer.parseInt(version);
|
||||
patch = 0;
|
||||
} catch (NumberFormatException e) {
|
||||
int idx = version.indexOf('-');
|
||||
if (idx >= 0) {
|
||||
try {
|
||||
major = Integer.parseInt(version.substring(0, idx));
|
||||
patch = Integer.parseInt(version.substring(idx + 1));
|
||||
} catch (NumberFormatException ignore) {
|
||||
throw new IllegalArgumentException(value);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException(value);
|
||||
}
|
||||
}
|
||||
|
||||
return new Old(value, Type.INFDEV, major, 0, patch, 0);
|
||||
}
|
||||
|
||||
|
||||
final Type type;
|
||||
final int major;
|
||||
final int minor;
|
||||
final int patch;
|
||||
final int additional;
|
||||
|
||||
private Old(String value, Type type, int major, int minor, int patch, int additional) {
|
||||
super(value);
|
||||
this.type = type;
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.patch = patch;
|
||||
this.additional = additional;
|
||||
}
|
||||
|
||||
@Override
|
||||
Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
int compareToImpl(@NotNull GameVersionNumber other) {
|
||||
Old that = (Old) other;
|
||||
int c = Integer.compare(this.major, that.major);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
|
||||
c = Integer.compare(this.minor, that.minor);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
|
||||
c = Integer.compare(this.patch, that.patch);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
|
||||
return Integer.compare(this.additional, that.additional);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Old other = (Old) o;
|
||||
return major == other.major && minor == other.minor && patch == other.patch && additional == other.additional && type == other.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(type, major, minor, patch, additional);
|
||||
}
|
||||
}
|
||||
|
||||
static final class Release extends GameVersionNumber {
|
||||
|
||||
private static final Pattern PATTERN = Pattern.compile("1\\.(?<minor>[0-9]+)(\\.(?<patch>[0-9]+))?((?<eaType>(-[a-zA-Z]+| Pre-Release ))(?<eaVersion>[0-9]+))?");
|
||||
|
||||
static final int TYPE_GA = Integer.MAX_VALUE;
|
||||
|
||||
static final int TYPE_UNKNOWN = 0;
|
||||
static final int TYPE_EXP = 1;
|
||||
static final int TYPE_PRE = 2;
|
||||
static final int TYPE_RC = 3;
|
||||
|
||||
static final Release ZERO = new Release("0.0", 0, 0, 0, TYPE_GA, 0);
|
||||
|
||||
static Release parse(String value) {
|
||||
Matcher matcher = PATTERN.matcher(value);
|
||||
if (!matcher.matches()) {
|
||||
throw new IllegalArgumentException(value);
|
||||
}
|
||||
|
||||
int minor = Integer.parseInt(matcher.group("minor"));
|
||||
|
||||
String patchString = matcher.group("patch");
|
||||
int patch = patchString != null ? Integer.parseInt(patchString) : 0;
|
||||
|
||||
String eaTypeString = matcher.group("eaType");
|
||||
int eaType;
|
||||
if (eaTypeString == null) {
|
||||
eaType = TYPE_GA;
|
||||
} else if ("-pre".equals(eaTypeString) || " Pre-Release ".equals(eaTypeString)) {
|
||||
eaType = TYPE_PRE;
|
||||
} else if ("-rc".equals(eaTypeString)) {
|
||||
eaType = TYPE_RC;
|
||||
} else if ("-exp".equals(eaTypeString)) {
|
||||
eaType = TYPE_EXP;
|
||||
} else {
|
||||
eaType = TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
String eaVersionString = matcher.group("eaVersion");
|
||||
int eaVersion = eaVersionString == null ? 0 : Integer.parseInt(eaVersionString);
|
||||
|
||||
return new Release(value, 1, minor, patch, eaType, eaVersion);
|
||||
}
|
||||
|
||||
private final int major;
|
||||
private final int minor;
|
||||
private final int patch;
|
||||
|
||||
private final int eaType;
|
||||
private final int eaVersion;
|
||||
|
||||
Release(String value, int major, int minor, int patch, int eaType, int eaVersion) {
|
||||
super(value);
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.patch = patch;
|
||||
this.eaType = eaType;
|
||||
this.eaVersion = eaVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
Type getType() {
|
||||
return Type.NEW;
|
||||
}
|
||||
|
||||
int compareToRelease(Release other) {
|
||||
int c = Integer.compare(this.major, other.major);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
|
||||
c = Integer.compare(this.minor, other.minor);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
|
||||
c = Integer.compare(this.patch, other.patch);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
|
||||
c = Integer.compare(this.eaType, other.eaType);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
|
||||
return Integer.compare(this.eaVersion, other.eaVersion);
|
||||
}
|
||||
|
||||
int compareToSnapshot(Snapshot other) {
|
||||
int idx = Arrays.binarySearch(Versions.SNAPSHOT_INTS, other.intValue);
|
||||
if (idx >= 0) {
|
||||
return this.compareToRelease(Versions.SNAPSHOT_PREV[idx]) <= 0 ? -1 : 1;
|
||||
}
|
||||
|
||||
idx = -(idx + 1);
|
||||
if (idx == Versions.SNAPSHOT_INTS.length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return this.compareToRelease(Versions.SNAPSHOT_PREV[idx]) <= 0 ? -1 : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
int compareToImpl(@NotNull GameVersionNumber other) {
|
||||
if (other instanceof Release) {
|
||||
return compareToRelease((Release) other);
|
||||
}
|
||||
|
||||
if (other instanceof Snapshot) {
|
||||
return compareToSnapshot((Snapshot) other);
|
||||
}
|
||||
|
||||
if (other instanceof Special) {
|
||||
return -((Special) other).compareToReleaseOrSnapshot(this);
|
||||
}
|
||||
|
||||
throw new AssertionError(other.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(major, minor, patch, eaType, eaVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Release other = (Release) o;
|
||||
return major == other.major && minor == other.minor && patch == other.patch && eaType == other.eaType && eaVersion == other.eaVersion;
|
||||
}
|
||||
}
|
||||
|
||||
static final class Snapshot extends GameVersionNumber {
|
||||
static Snapshot parse(String value) {
|
||||
if (value.length() != 6 || value.charAt(2) != 'w') {
|
||||
throw new IllegalArgumentException(value);
|
||||
}
|
||||
|
||||
int year;
|
||||
int week;
|
||||
try {
|
||||
year = Integer.parseInt(value.substring(0, 2));
|
||||
week = Integer.parseInt(value.substring(3, 5));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException(value);
|
||||
}
|
||||
|
||||
char suffix = value.charAt(5);
|
||||
if ((suffix < 'a' || suffix > 'z') && suffix != '~') {
|
||||
throw new IllegalArgumentException(value);
|
||||
}
|
||||
|
||||
return new Snapshot(value, year, week, suffix);
|
||||
}
|
||||
|
||||
static int toInt(int year, int week, char suffix) {
|
||||
return (year << 16) | (week << 8) | suffix;
|
||||
}
|
||||
|
||||
final int intValue;
|
||||
|
||||
Snapshot(String value, int year, int week, char suffix) {
|
||||
super(value);
|
||||
this.intValue = toInt(year, week, suffix);
|
||||
}
|
||||
|
||||
@Override
|
||||
Type getType() {
|
||||
return Type.NEW;
|
||||
}
|
||||
|
||||
@Override
|
||||
int compareToImpl(@NotNull GameVersionNumber other) {
|
||||
if (other instanceof Release) {
|
||||
return -((Release) other).compareToSnapshot(this);
|
||||
}
|
||||
|
||||
if (other instanceof Snapshot) {
|
||||
return Integer.compare(this.intValue, ((Snapshot) other).intValue);
|
||||
}
|
||||
|
||||
if (other instanceof Special) {
|
||||
return -((Special) other).compareToReleaseOrSnapshot(this);
|
||||
}
|
||||
|
||||
throw new AssertionError(other.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Snapshot other = (Snapshot) o;
|
||||
return this.intValue == other.intValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return intValue;
|
||||
}
|
||||
}
|
||||
|
||||
static final class Special extends GameVersionNumber {
|
||||
private VersionNumber versionNumber;
|
||||
|
||||
private GameVersionNumber prev;
|
||||
|
||||
Special(String value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
Type getType() {
|
||||
return Type.NEW;
|
||||
}
|
||||
|
||||
boolean isUnknown() {
|
||||
return prev == null;
|
||||
}
|
||||
|
||||
VersionNumber asVersionNumber() {
|
||||
if (versionNumber != null) {
|
||||
return versionNumber;
|
||||
}
|
||||
|
||||
return versionNumber = VersionNumber.asVersion(value);
|
||||
}
|
||||
|
||||
GameVersionNumber getPrevNormalVersion() {
|
||||
GameVersionNumber v = prev;
|
||||
while (v instanceof Special) {
|
||||
v = ((Special) v).prev;
|
||||
}
|
||||
|
||||
if (v == null) {
|
||||
throw new AssertionError("version: " + value);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
int compareToReleaseOrSnapshot(GameVersionNumber other) {
|
||||
if (isUnknown()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (getPrevNormalVersion().compareTo(other) >= 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int compareToSpecial(Special other) {
|
||||
if (this.isUnknown()) {
|
||||
return other.isUnknown() ? this.asVersionNumber().compareTo(other.asVersionNumber()) : 1;
|
||||
}
|
||||
|
||||
if (other.isUnknown()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (this.value.equals(other.value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int c = this.getPrevNormalVersion().compareTo(other.getPrevNormalVersion());
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
|
||||
GameVersionNumber v = prev;
|
||||
while (v instanceof Special) {
|
||||
if (v == other) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
v = ((Special) v).prev;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
int compareToImpl(@NotNull GameVersionNumber o) {
|
||||
if (o instanceof Release) {
|
||||
return compareToReleaseOrSnapshot(o);
|
||||
}
|
||||
|
||||
if (o instanceof Snapshot) {
|
||||
return compareToReleaseOrSnapshot(o);
|
||||
}
|
||||
|
||||
if (o instanceof Special) {
|
||||
return compareToSpecial((Special) o);
|
||||
}
|
||||
|
||||
throw new AssertionError(o.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return value.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Special other = (Special) o;
|
||||
return Objects.equals(this.value, other.value);
|
||||
}
|
||||
}
|
||||
|
||||
static final class Versions {
|
||||
static final HashMap<String, Special> SPECIALS = new HashMap<>();
|
||||
static final String[] DEFAULT_GAME_VERSIONS;
|
||||
|
||||
static final int[] SNAPSHOT_INTS;
|
||||
static final Release[] SNAPSHOT_PREV;
|
||||
|
||||
static {
|
||||
ArrayDeque<String> defaultGameVersions = new ArrayDeque<>(64);
|
||||
|
||||
List<Snapshot> snapshots = new ArrayList<>(1024);
|
||||
List<Release> snapshotPrev = new ArrayList<>(1024);
|
||||
|
||||
// Convert it to dynamic resource after the website is repaired?
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(GameVersionNumber.class.getResourceAsStream("/assets/game/versions.txt"), StandardCharsets.US_ASCII))) {
|
||||
Release currentRelease = null;
|
||||
GameVersionNumber prev = null;
|
||||
|
||||
for (String line; (line = reader.readLine()) != null; ) {
|
||||
if (line.isEmpty())
|
||||
continue;
|
||||
|
||||
GameVersionNumber version = GameVersionNumber.asGameVersion(line);
|
||||
|
||||
if (currentRelease == null)
|
||||
currentRelease = (Release) version;
|
||||
|
||||
if (version instanceof Snapshot) {
|
||||
Snapshot snapshot = (Snapshot) version;
|
||||
snapshots.add(snapshot);
|
||||
snapshotPrev.add(currentRelease);
|
||||
} else if (version instanceof Release) {
|
||||
currentRelease = (Release) version;
|
||||
|
||||
if (currentRelease.eaType == Release.TYPE_GA) {
|
||||
defaultGameVersions.addFirst(currentRelease.value);
|
||||
}
|
||||
} else if (version instanceof Special) {
|
||||
Special special = (Special) version;
|
||||
special.prev = prev;
|
||||
SPECIALS.put(special.value, special);
|
||||
} else
|
||||
throw new AssertionError("version: " + version);
|
||||
|
||||
prev = version;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
DEFAULT_GAME_VERSIONS = defaultGameVersions.toArray(new String[0]);
|
||||
|
||||
SNAPSHOT_INTS = new int[snapshots.size()];
|
||||
for (int i = 0; i < snapshots.size(); i++) {
|
||||
SNAPSHOT_INTS[i] = snapshots.get(i).intValue;
|
||||
}
|
||||
|
||||
SNAPSHOT_PREV = snapshotPrev.toArray(new Release[SNAPSHOT_INTS.length]);
|
||||
}
|
||||
}
|
||||
}
|
@ -83,6 +83,18 @@ public final class VersionNumber implements Comparable<VersionNumber> {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static VersionRange<VersionNumber> between(String minimum, String maximum) {
|
||||
return VersionRange.between(asVersion(minimum), asVersion(maximum));
|
||||
}
|
||||
|
||||
public static VersionRange<VersionNumber> atLeast(String minimum) {
|
||||
return VersionRange.atLeast(asVersion(minimum));
|
||||
}
|
||||
|
||||
public static VersionRange<VersionNumber> atMost(String maximum) {
|
||||
return VersionRange.atMost(asVersion(maximum));
|
||||
}
|
||||
|
||||
private interface Item {
|
||||
int LONG_ITEM = 0;
|
||||
int BIGINTEGER_ITEM = 1;
|
||||
@ -475,14 +487,6 @@ public final 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);
|
||||
|
@ -2,58 +2,50 @@ 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);
|
||||
/**
|
||||
* @author Glavo
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public final class VersionRange<T extends Comparable<T>> {
|
||||
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 <T extends Comparable<T>> VersionRange<T> empty() {
|
||||
return (VersionRange<T>) EMPTY;
|
||||
}
|
||||
|
||||
public static VersionRange all() {
|
||||
return ALL;
|
||||
public static <T extends Comparable<T>> VersionRange<T> all() {
|
||||
return (VersionRange<T>) 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) {
|
||||
public static <T extends Comparable<T>> VersionRange<T> between(T minimum, T maximum) {
|
||||
assert minimum.compareTo(maximum) <= 0;
|
||||
return new VersionRange(minimum, maximum);
|
||||
return new VersionRange<>(minimum, maximum);
|
||||
}
|
||||
|
||||
public static VersionRange atLeast(String minimum) {
|
||||
return atLeast(VersionNumber.asVersion(minimum));
|
||||
}
|
||||
|
||||
public static VersionRange atLeast(VersionNumber minimum) {
|
||||
public static <T extends Comparable<T>> VersionRange<T> atLeast(T minimum) {
|
||||
assert minimum != null;
|
||||
return new VersionRange(minimum, null);
|
||||
return new VersionRange<>(minimum, null);
|
||||
}
|
||||
|
||||
public static VersionRange atMost(String maximum) {
|
||||
return atMost(VersionNumber.asVersion(maximum));
|
||||
}
|
||||
|
||||
public static VersionRange atMost(VersionNumber maximum) {
|
||||
public static <T extends Comparable<T>> VersionRange<T> atMost(T maximum) {
|
||||
assert maximum != null;
|
||||
return new VersionRange(null, maximum);
|
||||
return new VersionRange<>(null, maximum);
|
||||
}
|
||||
|
||||
private final VersionNumber minimum;
|
||||
private final VersionNumber maximum;
|
||||
private final T minimum;
|
||||
private final T maximum;
|
||||
|
||||
private VersionRange(VersionNumber minimum, VersionNumber maximum) {
|
||||
private VersionRange(T minimum, T maximum) {
|
||||
this.minimum = minimum;
|
||||
this.maximum = maximum;
|
||||
}
|
||||
|
||||
public VersionNumber getMinimum() {
|
||||
public T getMinimum() {
|
||||
return minimum;
|
||||
}
|
||||
|
||||
public VersionNumber getMaximum() {
|
||||
public T getMaximum() {
|
||||
return maximum;
|
||||
}
|
||||
|
||||
@ -65,12 +57,7 @@ public final class VersionRange {
|
||||
return !isEmpty() && minimum == null && maximum == null;
|
||||
}
|
||||
|
||||
public boolean contains(String versionNumber) {
|
||||
if (versionNumber == null) return false;
|
||||
return contains(VersionNumber.asVersion(versionNumber));
|
||||
}
|
||||
|
||||
public boolean contains(VersionNumber versionNumber) {
|
||||
public boolean contains(T versionNumber) {
|
||||
if (versionNumber == null) return false;
|
||||
if (isEmpty()) return false;
|
||||
if (isAll()) return true;
|
||||
@ -78,7 +65,7 @@ public final class VersionRange {
|
||||
return (minimum == null || minimum.compareTo(versionNumber) <= 0) && (maximum == null || maximum.compareTo(versionNumber) >= 0);
|
||||
}
|
||||
|
||||
public boolean isOverlappedBy(final VersionRange that) {
|
||||
public boolean isOverlappedBy(final VersionRange<T> that) {
|
||||
if (this.isEmpty() || that.isEmpty())
|
||||
return false;
|
||||
|
||||
@ -94,32 +81,32 @@ public final class VersionRange {
|
||||
return that.contains(minimum) || that.contains(maximum) || (that.minimum != null && contains(that.minimum));
|
||||
}
|
||||
|
||||
public VersionRange intersectionWith(VersionRange that) {
|
||||
public VersionRange<T> intersectionWith(VersionRange<T> that) {
|
||||
if (this.isAll())
|
||||
return that;
|
||||
if (that.isAll())
|
||||
return this;
|
||||
|
||||
if (!isOverlappedBy(that))
|
||||
return EMPTY;
|
||||
return empty();
|
||||
|
||||
VersionNumber newMinimum;
|
||||
T newMinimum;
|
||||
if (this.minimum == null)
|
||||
newMinimum = that.minimum;
|
||||
else if (that.minimum == null)
|
||||
newMinimum = this.minimum;
|
||||
else
|
||||
newMinimum = this.minimum.max(that.minimum);
|
||||
newMinimum = this.minimum.compareTo(that.minimum) >= 0 ? this.minimum : that.minimum;
|
||||
|
||||
VersionNumber newMaximum;
|
||||
T newMaximum;
|
||||
if (this.maximum == null)
|
||||
newMaximum = that.maximum;
|
||||
else if (that.maximum == null)
|
||||
newMaximum = this.maximum;
|
||||
else
|
||||
newMaximum = this.maximum.min(that.maximum);
|
||||
newMaximum = this.maximum.compareTo(that.maximum) <= 0 ? this.maximum : that.maximum;
|
||||
|
||||
return new VersionRange(newMinimum, newMaximum);
|
||||
return new VersionRange<>(newMinimum, newMaximum);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -139,7 +126,7 @@ public final class VersionRange {
|
||||
if (!(obj instanceof VersionRange))
|
||||
return false;
|
||||
|
||||
VersionRange that = (VersionRange) obj;
|
||||
VersionRange<T> that = (VersionRange<T>) obj;
|
||||
|
||||
return this.isEmpty() == that.isEmpty() && this.isAll() == that.isAll()
|
||||
&& Objects.equals(this.minimum, that.minimum)
|
||||
|
738
HMCLCore/src/main/resources/assets/game/versions.txt
Normal file
738
HMCLCore/src/main/resources/assets/game/versions.txt
Normal file
@ -0,0 +1,738 @@
|
||||
1.0
|
||||
11w47a
|
||||
11w48a
|
||||
11w49a
|
||||
11w50a
|
||||
12w01a
|
||||
1.1
|
||||
12w03a
|
||||
12w04a
|
||||
12w05a
|
||||
12w05b
|
||||
12w06a
|
||||
12w07a
|
||||
12w07b
|
||||
12w08a
|
||||
1.2
|
||||
1.2.1
|
||||
1.2.2
|
||||
1.2.3
|
||||
1.2.4
|
||||
1.2.5
|
||||
12w15a
|
||||
12w16a
|
||||
12w17a
|
||||
12w18a
|
||||
12w19a
|
||||
12w21a
|
||||
12w21b
|
||||
12w22a
|
||||
12w23a
|
||||
12w23b
|
||||
12w24a
|
||||
12w25a
|
||||
12w26a
|
||||
12w27a
|
||||
12w30a
|
||||
12w30b
|
||||
12w30c
|
||||
12w30d
|
||||
12w30e
|
||||
1.3
|
||||
1.3.1
|
||||
1.3.2
|
||||
12w32a
|
||||
12w34a
|
||||
12w34b
|
||||
12w36a
|
||||
12w37a
|
||||
12w38a
|
||||
12w38b
|
||||
12w39a
|
||||
12w39b
|
||||
12w40a
|
||||
12w40b
|
||||
12w41a
|
||||
12w41b
|
||||
12w42a
|
||||
12w42b
|
||||
1.4
|
||||
1.4.1
|
||||
1.4.2
|
||||
1.4.3
|
||||
1.4.4
|
||||
12w49a
|
||||
12w50a
|
||||
12w50b
|
||||
1.4.5
|
||||
1.4.6
|
||||
1.4.7
|
||||
13w01a
|
||||
13w01b
|
||||
13w02a
|
||||
13w02b
|
||||
13w03a
|
||||
13w04a
|
||||
13w05a
|
||||
13w05b
|
||||
13w06a
|
||||
13w07a
|
||||
13w09a
|
||||
13w09b
|
||||
13w09c
|
||||
13w10a
|
||||
13w10b
|
||||
1.5
|
||||
13w11a
|
||||
13w12~
|
||||
1.5.1
|
||||
2.0
|
||||
1.5.2
|
||||
13w16a
|
||||
13w16b
|
||||
13w17a
|
||||
13w18a
|
||||
13w18b
|
||||
13w18c
|
||||
13w19a
|
||||
13w21a
|
||||
13w21b
|
||||
13w22a
|
||||
13w23a
|
||||
13w23b
|
||||
13w24a
|
||||
13w24b
|
||||
13w25a
|
||||
13w25b
|
||||
13w25c
|
||||
13w26a
|
||||
1.6
|
||||
1.6.1
|
||||
1.6.2
|
||||
1.6.3
|
||||
1.6.4
|
||||
13w36a
|
||||
13w36b
|
||||
13w37a
|
||||
13w37b
|
||||
13w38a
|
||||
13w38b
|
||||
13w38c
|
||||
13w39a
|
||||
13w39b
|
||||
13w41a
|
||||
13w41b
|
||||
13w42a
|
||||
13w42b
|
||||
13w43a
|
||||
1.7
|
||||
1.7.1
|
||||
1.7.2
|
||||
13w47a
|
||||
13w47b
|
||||
13w47c
|
||||
13w47d
|
||||
13w47e
|
||||
13w48a
|
||||
13w48b
|
||||
13w49a
|
||||
1.7.3
|
||||
1.7.4
|
||||
1.7.5
|
||||
1.7.6-pre1
|
||||
1.7.6-pre2
|
||||
1.7.6
|
||||
1.7.7
|
||||
1.7.8
|
||||
1.7.9
|
||||
1.7.10-pre1
|
||||
1.7.10-pre2
|
||||
1.7.10-pre3
|
||||
1.7.10-pre4
|
||||
1.7.10
|
||||
14w02a
|
||||
14w02b
|
||||
14w02c
|
||||
14w03a
|
||||
14w03b
|
||||
14w04a
|
||||
14w04b
|
||||
14w05a
|
||||
14w05b
|
||||
14w06a
|
||||
14w06b
|
||||
14w07a
|
||||
14w08a
|
||||
14w10a
|
||||
14w10b
|
||||
14w10c
|
||||
14w11a
|
||||
14w11b
|
||||
14w17a
|
||||
14w18a
|
||||
14w18b
|
||||
14w19a
|
||||
14w20a
|
||||
14w20b
|
||||
14w21a
|
||||
14w21b
|
||||
14w25a
|
||||
14w25b
|
||||
14w26a
|
||||
14w26b
|
||||
14w26c
|
||||
14w27a
|
||||
14w27b
|
||||
14w28a
|
||||
14w28b
|
||||
14w29a
|
||||
14w29b
|
||||
14w30a
|
||||
14w30b
|
||||
14w30c
|
||||
14w31a
|
||||
14w32a
|
||||
14w32b
|
||||
14w32c
|
||||
14w32d
|
||||
14w33a
|
||||
14w33b
|
||||
14w33c
|
||||
14w34a
|
||||
14w34b
|
||||
14w34c
|
||||
14w34d
|
||||
1.8-pre1
|
||||
1.8-pre2
|
||||
1.8-pre3
|
||||
1.8
|
||||
1.8.1-pre1
|
||||
1.8.1-pre2
|
||||
1.8.1-pre3
|
||||
1.8.1-pre4
|
||||
1.8.1-pre5
|
||||
1.8.1
|
||||
1.8.2-pre1
|
||||
1.8.2-pre2
|
||||
1.8.2-pre3
|
||||
1.8.2-pre4
|
||||
1.8.2-pre5
|
||||
1.8.2-pre6
|
||||
1.8.2-pre7
|
||||
1.8.2
|
||||
1.8.3
|
||||
15w14a
|
||||
1.8.4
|
||||
1.8.5
|
||||
1.8.6
|
||||
1.8.7
|
||||
1.8.8
|
||||
1.8.9
|
||||
15w31a
|
||||
15w31b
|
||||
15w31c
|
||||
15w32a
|
||||
15w32b
|
||||
15w32c
|
||||
15w33a
|
||||
15w33b
|
||||
15w33c
|
||||
15w34a
|
||||
15w34b
|
||||
15w34c
|
||||
15w34d
|
||||
15w35a
|
||||
15w35b
|
||||
15w35c
|
||||
15w35d
|
||||
15w35e
|
||||
15w36a
|
||||
15w36b
|
||||
15w36c
|
||||
15w36d
|
||||
15w37a
|
||||
15w38a
|
||||
15w38b
|
||||
15w39a
|
||||
15w39b
|
||||
15w39c
|
||||
15w40a
|
||||
15w40b
|
||||
15w41a
|
||||
15w41b
|
||||
15w42a
|
||||
15w43a
|
||||
15w43b
|
||||
15w43c
|
||||
15w44a
|
||||
15w44b
|
||||
15w45a
|
||||
15w46a
|
||||
15w47a
|
||||
15w47b
|
||||
15w47c
|
||||
15w49a
|
||||
15w49b
|
||||
15w50a
|
||||
15w51a
|
||||
15w51b
|
||||
16w02a
|
||||
16w03a
|
||||
16w04a
|
||||
16w05a
|
||||
16w05b
|
||||
16w06a
|
||||
16w07a
|
||||
16w07b
|
||||
1.9-pre1
|
||||
1.9-pre2
|
||||
1.9-pre3
|
||||
1.9-pre4
|
||||
1.9
|
||||
1.9.1-pre1
|
||||
1.9.1-pre2
|
||||
1.9.1-pre3
|
||||
1.9.1
|
||||
1.9.2
|
||||
1.RV-Pre1
|
||||
16w14a
|
||||
16w15a
|
||||
16w15b
|
||||
1.9.3-pre1
|
||||
1.9.3-pre2
|
||||
1.9.3-pre3
|
||||
1.9.3
|
||||
1.9.4
|
||||
16w20a
|
||||
16w21a
|
||||
16w21b
|
||||
1.10-pre1
|
||||
1.10-pre2
|
||||
1.10
|
||||
1.10.1
|
||||
1.10.2
|
||||
16w32a
|
||||
16w32b
|
||||
16w33a
|
||||
16w35a
|
||||
16w36a
|
||||
16w38a
|
||||
16w39a
|
||||
16w39b
|
||||
16w39c
|
||||
16w40a
|
||||
16w41a
|
||||
16w42a
|
||||
16w43a
|
||||
16w44a
|
||||
1.11-pre1
|
||||
1.11
|
||||
16w50a
|
||||
1.11.1
|
||||
1.11.2
|
||||
17w06a
|
||||
17w13a
|
||||
17w13b
|
||||
17w14a
|
||||
17w15a
|
||||
17w16a
|
||||
17w16b
|
||||
17w17a
|
||||
17w17b
|
||||
17w18a
|
||||
17w18b
|
||||
1.12-pre1
|
||||
1.12-pre2
|
||||
1.12-pre3
|
||||
1.12-pre4
|
||||
1.12-pre5
|
||||
1.12-pre6
|
||||
1.12-pre7
|
||||
1.12
|
||||
17w31a
|
||||
1.12.1-pre1
|
||||
1.12.1
|
||||
1.12.2-pre1
|
||||
1.12.2-pre2
|
||||
1.12.2
|
||||
17w43a
|
||||
17w43b
|
||||
17w45a
|
||||
17w45b
|
||||
17w46a
|
||||
17w47a
|
||||
17w47b
|
||||
17w48a
|
||||
17w49a
|
||||
17w49b
|
||||
17w50a
|
||||
18w01a
|
||||
18w02a
|
||||
18w03a
|
||||
18w03b
|
||||
18w05a
|
||||
18w06a
|
||||
18w07a
|
||||
18w07b
|
||||
18w07c
|
||||
18w08a
|
||||
18w08b
|
||||
18w09a
|
||||
18w10a
|
||||
18w10b
|
||||
18w10c
|
||||
18w10d
|
||||
18w11a
|
||||
18w14a
|
||||
18w14b
|
||||
18w15a
|
||||
18w16a
|
||||
18w19a
|
||||
18w19b
|
||||
18w20a
|
||||
18w20b
|
||||
18w20c
|
||||
18w21a
|
||||
18w21b
|
||||
18w22a
|
||||
18w22b
|
||||
18w22c
|
||||
1.13-pre1
|
||||
1.13-pre2
|
||||
1.13-pre3
|
||||
1.13-pre4
|
||||
1.13-pre5
|
||||
1.13-pre6
|
||||
1.13-pre7
|
||||
1.13-pre8
|
||||
1.13-pre9
|
||||
1.13-pre10
|
||||
1.13
|
||||
18w30a
|
||||
18w30b
|
||||
18w31a
|
||||
18w32a
|
||||
18w33a
|
||||
1.13.1-pre1
|
||||
1.13.1-pre2
|
||||
1.13.1
|
||||
1.13.2-pre1
|
||||
1.13.2-pre2
|
||||
1.13.2
|
||||
18w43a
|
||||
18w43b
|
||||
18w43c
|
||||
18w44a
|
||||
18w45a
|
||||
18w46a
|
||||
18w47a
|
||||
18w47b
|
||||
18w48a
|
||||
18w48b
|
||||
18w49a
|
||||
18w50a
|
||||
19w02a
|
||||
19w03a
|
||||
19w03b
|
||||
19w03c
|
||||
19w04a
|
||||
19w04b
|
||||
19w05a
|
||||
19w06a
|
||||
19w07a
|
||||
19w08a
|
||||
19w08b
|
||||
19w09a
|
||||
19w11a
|
||||
19w11b
|
||||
19w12a
|
||||
19w12b
|
||||
19w13a
|
||||
19w13b
|
||||
3D Shareware v1.34
|
||||
19w14a
|
||||
19w14b
|
||||
1.14 Pre-Release 1
|
||||
1.14 Pre-Release 2
|
||||
1.14 Pre-Release 3
|
||||
1.14 Pre-Release 4
|
||||
1.14 Pre-Release 5
|
||||
1.14
|
||||
1.14.1 Pre-Release 1
|
||||
1.14.1 Pre-Release 2
|
||||
1.14.1
|
||||
1.14.2 Pre-Release 1
|
||||
1.14.2 Pre-Release 2
|
||||
1.14.2 Pre-Release 3
|
||||
1.14.2 Pre-Release 4
|
||||
1.14.2
|
||||
1.14.3-pre1
|
||||
1.14.3-pre2
|
||||
1.14.3-pre3
|
||||
1.14.3-pre4
|
||||
1.14.3
|
||||
1.14.4-pre1
|
||||
1.14.4-pre2
|
||||
1.14.4-pre3
|
||||
1.14.4-pre4
|
||||
1.14.4-pre5
|
||||
1.14.4-pre6
|
||||
1.14.4-pre7
|
||||
1.14.4
|
||||
19w34a
|
||||
19w35a
|
||||
19w36a
|
||||
19w37a
|
||||
19w38a
|
||||
19w38b
|
||||
19w39a
|
||||
19w40a
|
||||
19w41a
|
||||
19w42a
|
||||
19w44a
|
||||
19w45a
|
||||
19w45b
|
||||
19w46a
|
||||
19w46b
|
||||
1.15-pre1
|
||||
1.15-pre2
|
||||
1.15-pre3
|
||||
1.15-pre4
|
||||
1.15-pre5
|
||||
1.15-pre6
|
||||
1.15-pre7
|
||||
1.15
|
||||
1.15.1-pre1
|
||||
1.15.1
|
||||
1.15.2-pre1
|
||||
1.15.2-pre2
|
||||
1.15.2
|
||||
20w06a
|
||||
20w07a
|
||||
20w08a
|
||||
20w09a
|
||||
20w10a
|
||||
20w11a
|
||||
20w12a
|
||||
20w13a
|
||||
20w13b
|
||||
20w14infinite
|
||||
20w14a
|
||||
20w15a
|
||||
20w16a
|
||||
20w17a
|
||||
20w18a
|
||||
20w19a
|
||||
20w20a
|
||||
20w20b
|
||||
20w21a
|
||||
20w22a
|
||||
1.16-pre1
|
||||
1.16-pre2
|
||||
1.16-pre3
|
||||
1.16-pre4
|
||||
1.16-pre5
|
||||
1.16-pre6
|
||||
1.16-pre7
|
||||
1.16-pre8
|
||||
1.16-rc1
|
||||
1.16
|
||||
1.16.1
|
||||
20w27a
|
||||
20w28a
|
||||
20w29a
|
||||
20w30a
|
||||
1.16.2-pre1
|
||||
1.16.2-pre2
|
||||
1.16.2-pre3
|
||||
1.16.2-rc1
|
||||
1.16.2-rc2
|
||||
1.16.2
|
||||
1.16.3-rc1
|
||||
1.16.3
|
||||
1.16.4-pre1
|
||||
1.16.4-pre2
|
||||
1.16.4-rc1
|
||||
1.16.4
|
||||
1.16.5-rc1
|
||||
1.16.5
|
||||
20w45a
|
||||
20w46a
|
||||
20w48a
|
||||
20w49a
|
||||
20w51a
|
||||
21w03a
|
||||
21w05a
|
||||
21w05b
|
||||
21w06a
|
||||
21w07a
|
||||
21w08a
|
||||
21w08b
|
||||
21w10a
|
||||
21w11a
|
||||
21w13a
|
||||
21w14a
|
||||
21w15a
|
||||
21w16a
|
||||
21w17a
|
||||
21w18a
|
||||
21w19a
|
||||
21w20a
|
||||
1.17-pre1
|
||||
1.17-pre2
|
||||
1.17-pre3
|
||||
1.17-pre4
|
||||
1.17-pre5
|
||||
1.17-rc1
|
||||
1.17-rc2
|
||||
1.17
|
||||
1.17.1-pre1
|
||||
1.17.1-pre2
|
||||
1.17.1-pre3
|
||||
1.17.1-rc1
|
||||
1.17.1-rc2
|
||||
1.17.1
|
||||
21w37a
|
||||
21w38a
|
||||
21w39a
|
||||
21w40a
|
||||
21w41a
|
||||
21w42a
|
||||
21w43a
|
||||
21w44a
|
||||
1.18-pre1
|
||||
1.18-pre2
|
||||
1.18-pre3
|
||||
1.18-pre4
|
||||
1.18-pre5
|
||||
1.18-pre6
|
||||
1.18-pre7
|
||||
1.18-pre8
|
||||
1.18-rc1
|
||||
1.18-rc2
|
||||
1.18-rc3
|
||||
1.18-rc4
|
||||
1.18
|
||||
1.18.1-pre1
|
||||
1.18.1-rc1
|
||||
1.18.1-rc2
|
||||
1.18.1-rc3
|
||||
1.18.1
|
||||
22w03a
|
||||
22w05a
|
||||
22w06a
|
||||
22w07a
|
||||
1.18.2-pre1
|
||||
1.18.2-pre2
|
||||
1.18.2-pre3
|
||||
1.18.2-rc1
|
||||
1.18.2
|
||||
22w13oneblockatatime
|
||||
22w11a
|
||||
22w12a
|
||||
22w13a
|
||||
22w14a
|
||||
22w15a
|
||||
22w16a
|
||||
22w16b
|
||||
22w17a
|
||||
22w18a
|
||||
22w19a
|
||||
1.19-pre1
|
||||
1.19-pre2
|
||||
1.19-pre3
|
||||
1.19-pre4
|
||||
1.19-pre5
|
||||
1.19-rc1
|
||||
1.19-rc2
|
||||
1.19
|
||||
22w24a
|
||||
1.19.1-pre1
|
||||
1.19.1-pre2
|
||||
1.19.1-pre3
|
||||
1.19.1-pre4
|
||||
1.19.1-pre5
|
||||
1.19.1-pre6
|
||||
1.19.1-rc1
|
||||
1.19.1-rc2
|
||||
1.19.1-rc3
|
||||
1.19.1
|
||||
1.19.2-rc1
|
||||
1.19.2-rc2
|
||||
1.19.2
|
||||
22w42a
|
||||
22w43a
|
||||
22w44a
|
||||
22w45a
|
||||
22w46a
|
||||
1.19.3-pre1
|
||||
1.19.3-pre2
|
||||
1.19.3-pre3
|
||||
1.19.3-rc1
|
||||
1.19.3-rc2
|
||||
1.19.3-rc3
|
||||
1.19.3
|
||||
23w03a
|
||||
23w04a
|
||||
23w05a
|
||||
23w06a
|
||||
23w07a
|
||||
1.19.4-pre1
|
||||
1.19.4-pre2
|
||||
1.19.4-pre3
|
||||
1.19.4-pre4
|
||||
1.19.4-rc1
|
||||
1.19.4-rc2
|
||||
1.19.4-rc3
|
||||
1.19.4
|
||||
23w12a
|
||||
23w13a
|
||||
23w13a_or_b
|
||||
23w14a
|
||||
23w16a
|
||||
23w17a
|
||||
23w18a
|
||||
1.20-pre1
|
||||
1.20-pre2
|
||||
1.20-pre3
|
||||
1.20-pre4
|
||||
1.20-pre5
|
||||
1.20-pre6
|
||||
1.20-pre7
|
||||
1.20-rc1
|
||||
1.20
|
||||
1.20.1-rc1
|
||||
1.20.1
|
||||
23w31a
|
||||
23w32a
|
||||
23w33a
|
||||
23w35a
|
||||
1.20.2-pre1
|
||||
1.20.2-pre2
|
||||
1.20.2-pre3
|
||||
1.20.2-pre4
|
||||
1.20.2-rc1
|
||||
1.20.2-rc2
|
||||
1.20.2
|
||||
23w40a
|
||||
23w41a
|
||||
23w42a
|
||||
23w43a
|
||||
23w43b
|
||||
23w44a
|
||||
23w45a
|
||||
23w46a
|
||||
1.20.3-pre1
|
||||
1.20.3-pre2
|
||||
1.20.3-pre3
|
||||
1.20.3-pre4
|
||||
1.20.3-rc1
|
||||
1.20.3
|
||||
1.20.4-rc1
|
||||
1.20.4
|
||||
23w51a
|
||||
23w51b
|
||||
24w03a
|
||||
24w03b
|
||||
24w04a
|
||||
24w05a
|
@ -17,8 +17,8 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.game;
|
||||
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
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.*;
|
||||
@ -28,10 +28,10 @@ public class JavaVersionConstraintTest {
|
||||
@Test
|
||||
public void vanillaJava16() {
|
||||
JavaVersionConstraint.VersionRanges range = JavaVersionConstraint.findSuitableJavaVersionRange(
|
||||
VersionNumber.asVersion("1.17"),
|
||||
GameVersionNumber.asGameVersion("1.17"),
|
||||
null
|
||||
);
|
||||
|
||||
assertEquals(VersionRange.atLeast("16"), range.getMandatory());
|
||||
assertEquals(VersionNumber.atLeast("16"), range.getMandatory());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,218 @@
|
||||
package org.jackhuang.hmcl.util.versioning;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* @author Glavo
|
||||
*/
|
||||
public class GameVersionNumberTest {
|
||||
|
||||
@Test
|
||||
public void testSortVersions() throws IOException {
|
||||
List<String> versions = new ArrayList<>();
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(GameVersionNumber.class.getResourceAsStream("/assets/game/versions.txt"), StandardCharsets.UTF_8))) {
|
||||
for (String line; (line = reader.readLine()) != null && !line.isEmpty(); ) {
|
||||
versions.add(line);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> copied = new ArrayList<>(versions);
|
||||
Collections.shuffle(copied, new Random(0));
|
||||
copied.sort(Comparator.comparing(GameVersionNumber::asGameVersion));
|
||||
|
||||
assertIterableEquals(versions, copied);
|
||||
}
|
||||
|
||||
private static String errorMessage(String version1, String version2) {
|
||||
return String.format("version1=%s, version2=%s", version1, version2);
|
||||
}
|
||||
|
||||
private static void assertGameVersionEquals(String version) {
|
||||
assertGameVersionEquals(version, version);
|
||||
}
|
||||
|
||||
private static void assertGameVersionEquals(String version1, String version2) {
|
||||
assertEquals(0, GameVersionNumber.asGameVersion(version1).compareTo(version2), errorMessage(version1, version2));
|
||||
}
|
||||
|
||||
private static void assertLessThan(String version1, String version2) {
|
||||
assertTrue(GameVersionNumber.asGameVersion(version1).compareTo(version2) < 0, errorMessage(version1, version2));
|
||||
}
|
||||
|
||||
private static void assertOrder(String... versions) {
|
||||
for (int i = 0; i < versions.length - 1; i++) {
|
||||
GameVersionNumber version1 = GameVersionNumber.asGameVersion(versions[i]);
|
||||
|
||||
//noinspection EqualsWithItself
|
||||
assertEquals(0, version1.compareTo(version1), "version=" + versions[i]);
|
||||
|
||||
for (int j = i + 1; j < versions.length; j++) {
|
||||
GameVersionNumber version2 = GameVersionNumber.asGameVersion(versions[j]);
|
||||
|
||||
assertEquals(-1, version1.compareTo(version2), String.format("version1=%s, version2=%s", versions[i], versions[j]));
|
||||
assertEquals(1, version2.compareTo(version1), String.format("version1=%s, version2=%s", versions[i], versions[j]));
|
||||
}
|
||||
}
|
||||
|
||||
assertGameVersionEquals(versions[versions.length - 1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseOld() {
|
||||
{
|
||||
GameVersionNumber version = GameVersionNumber.asGameVersion("b1.0");
|
||||
assertInstanceOf(GameVersionNumber.Old.class, version);
|
||||
GameVersionNumber.Old old = (GameVersionNumber.Old) version;
|
||||
assertEquals(GameVersionNumber.Type.BETA, old.type);
|
||||
assertEquals(1, old.major);
|
||||
assertEquals(0, old.minor);
|
||||
assertEquals(0, old.patch);
|
||||
assertEquals(0, old.additional);
|
||||
}
|
||||
|
||||
{
|
||||
GameVersionNumber version = GameVersionNumber.asGameVersion("b1.0_01");
|
||||
assertInstanceOf(GameVersionNumber.Old.class, version);
|
||||
GameVersionNumber.Old old = (GameVersionNumber.Old) version;
|
||||
assertEquals(GameVersionNumber.Type.BETA, old.type);
|
||||
assertEquals(1, old.major);
|
||||
assertEquals(0, old.minor);
|
||||
assertEquals(0, old.patch);
|
||||
assertEquals(1, old.additional);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareRelease() {
|
||||
assertGameVersionEquals("0.0");
|
||||
assertGameVersionEquals("1.100");
|
||||
assertGameVersionEquals("1.100.1");
|
||||
assertGameVersionEquals("1.100.1-pre1");
|
||||
assertGameVersionEquals("1.100.1-pre1", "1.100.1 Pre-Release 1");
|
||||
|
||||
assertOrder(
|
||||
"0.0",
|
||||
"1.0",
|
||||
"1.99",
|
||||
"1.99.1-unknown1",
|
||||
"1.99.1-pre1",
|
||||
"1.99.1 Pre-Release 2",
|
||||
"1.99.1-rc1",
|
||||
"1.99.1",
|
||||
"1.100",
|
||||
"1.100.1"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareSnapshot() {
|
||||
assertOrder(
|
||||
"90w01a",
|
||||
"90w01b",
|
||||
"90w01e",
|
||||
"90w01~",
|
||||
"90w02a"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareMix() {
|
||||
assertOrder(
|
||||
"rd-132211",
|
||||
"rd-161348",
|
||||
"rd-20090515",
|
||||
"c0.0.11a",
|
||||
"c0.0.13a",
|
||||
"c0.0.13a_03",
|
||||
"c0.30_01c",
|
||||
"inf-20100330-1",
|
||||
"inf-20100330-2",
|
||||
"inf-20100618",
|
||||
"a1.0.4",
|
||||
"a1.0.17_02",
|
||||
"a1.0.17_04",
|
||||
"a1.1.0",
|
||||
"b1.0",
|
||||
"b1.0_01",
|
||||
"b1.1_02",
|
||||
"b1.2",
|
||||
"b1.8.1",
|
||||
"0.0",
|
||||
"1.0",
|
||||
"11w47a",
|
||||
"1.1",
|
||||
"1.5.1",
|
||||
"2.0",
|
||||
"1.5.2",
|
||||
"1.9.2",
|
||||
"1.RV-Pre1",
|
||||
"16w14a",
|
||||
"1.9.3-pre1",
|
||||
"1.13.2",
|
||||
"19w13b",
|
||||
"3D Shareware v1.34",
|
||||
"19w14a",
|
||||
"1.14 Pre-Release 1",
|
||||
"1.14",
|
||||
"1.15.2",
|
||||
"20w06a",
|
||||
"20w14infinite",
|
||||
"20w22a",
|
||||
"1.16-pre1",
|
||||
"1.16",
|
||||
"1.18.2",
|
||||
"22w13oneblockatatime",
|
||||
"22w11a",
|
||||
"1.19-pre1",
|
||||
"1.19.4",
|
||||
"23w13a",
|
||||
"23w13a_or_b",
|
||||
"23w14a",
|
||||
"1.20",
|
||||
|
||||
"Unknown",
|
||||
"100.0"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareUnknown() {
|
||||
assertOrder(
|
||||
"23w35a",
|
||||
"1.20.2-pre1",
|
||||
"1.20.2-rc1",
|
||||
"1.20.2",
|
||||
"23w35b", // fictional version number
|
||||
"23w40a"
|
||||
);
|
||||
|
||||
assertOrder(
|
||||
"1.20.4",
|
||||
"24w04a",
|
||||
"1.100" // fictional version number
|
||||
);
|
||||
|
||||
assertOrder(
|
||||
"1.19.4",
|
||||
"23w18a", // fictional version number
|
||||
"1.19.5",
|
||||
"1.20"
|
||||
);
|
||||
|
||||
assertOrder(
|
||||
"1.0",
|
||||
"10w47a", // fictional version number
|
||||
"11w47a",
|
||||
"1.1"
|
||||
);
|
||||
}
|
||||
}
|
@ -9,43 +9,46 @@ 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"));
|
||||
VersionRange<VersionNumber> empty = VersionRange.empty();
|
||||
VersionRange<VersionNumber> all = all();
|
||||
|
||||
assertTrue(between("10", "10").contains("10"));
|
||||
assertFalse(between("10", "10").contains("5"));
|
||||
assertFalse(between("10", "10").contains("15"));
|
||||
assertTrue(VersionNumber.between("10", "20").contains(VersionNumber.asVersion("10")));
|
||||
assertTrue(VersionNumber.between("10", "20").contains(VersionNumber.asVersion("15")));
|
||||
assertTrue(VersionNumber.between("10", "20").contains(VersionNumber.asVersion("20")));
|
||||
assertFalse(VersionNumber.between("10", "20").contains(VersionNumber.asVersion("5")));
|
||||
assertFalse(VersionNumber.between("10", "20").contains(VersionNumber.asVersion("25")));
|
||||
|
||||
assertTrue(atLeast("10").contains("10"));
|
||||
assertTrue(atLeast("10").contains("20"));
|
||||
assertFalse(atLeast("10").contains("5"));
|
||||
assertTrue(VersionNumber.between("10", "10").contains(VersionNumber.asVersion("10")));
|
||||
assertFalse(VersionNumber.between("10", "10").contains(VersionNumber.asVersion("5")));
|
||||
assertFalse(VersionNumber.between("10", "10").contains(VersionNumber.asVersion("15")));
|
||||
|
||||
assertTrue(atMost("10").contains("10"));
|
||||
assertTrue(atMost("10").contains("5"));
|
||||
assertFalse(atMost("10").contains("20"));
|
||||
assertTrue(VersionNumber.atLeast("10").contains(VersionNumber.asVersion("10")));
|
||||
assertTrue(VersionNumber.atLeast("10").contains(VersionNumber.asVersion("20")));
|
||||
assertFalse(VersionNumber.atLeast("10").contains(VersionNumber.asVersion("5")));
|
||||
|
||||
assertFalse(empty().contains("0"));
|
||||
assertFalse(empty().contains("10"));
|
||||
assertTrue(VersionNumber.atMost("10").contains(VersionNumber.asVersion("10")));
|
||||
assertTrue(VersionNumber.atMost("10").contains(VersionNumber.asVersion("5")));
|
||||
assertFalse(VersionNumber.atMost("10").contains(VersionNumber.asVersion("20")));
|
||||
|
||||
assertTrue(all().contains("0"));
|
||||
assertTrue(all().contains("10"));
|
||||
assertFalse(empty.contains(VersionNumber.asVersion("0")));
|
||||
assertFalse(empty.contains(VersionNumber.asVersion("10")));
|
||||
|
||||
assertFalse(all().contains((String) null));
|
||||
assertFalse(empty().contains((String) null));
|
||||
assertFalse(between("0", "10").contains((String) null));
|
||||
assertFalse(atLeast("10").contains((String) null));
|
||||
assertFalse(atMost("10").contains((String) null));
|
||||
assertFalse(all().contains((VersionNumber) null));
|
||||
assertFalse(empty().contains((VersionNumber) null));
|
||||
assertFalse(between("0", "10").contains((VersionNumber) null));
|
||||
assertFalse(atLeast("10").contains((VersionNumber) null));
|
||||
assertFalse(atMost("10").contains((VersionNumber) null));
|
||||
assertTrue(all.contains(VersionNumber.asVersion("0")));
|
||||
assertTrue(all.contains(VersionNumber.asVersion("10")));
|
||||
|
||||
assertFalse(all.contains(null));
|
||||
assertFalse(empty.contains( null));
|
||||
assertFalse(VersionNumber.between("0", "10").contains(null));
|
||||
assertFalse(VersionNumber.atLeast("10").contains(null));
|
||||
assertFalse(VersionNumber.atMost("10").contains(null));
|
||||
assertFalse(all.contains(null));
|
||||
assertFalse(empty.contains(null));
|
||||
assertFalse(VersionNumber.between("0", "10").contains(null));
|
||||
assertFalse(VersionNumber.atLeast("10").contains(null));
|
||||
assertFalse(VersionNumber.atMost("10").contains(null));
|
||||
}
|
||||
|
||||
private static void assertIsOverlappedBy(boolean value, VersionRange range1, VersionRange range2) {
|
||||
private static void assertIsOverlappedBy(boolean value, VersionRange<VersionNumber> range1, VersionRange<VersionNumber> range2) {
|
||||
assertEquals(value, range1.isOverlappedBy(range2));
|
||||
assertEquals(value, range2.isOverlappedBy(range1));
|
||||
}
|
||||
@ -56,38 +59,38 @@ public class VersionRangeTest {
|
||||
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(true, all(), VersionNumber.between("10", "20"));
|
||||
assertIsOverlappedBy(true, all(), VersionNumber.atLeast("10"));
|
||||
assertIsOverlappedBy(true, all(), VersionNumber.atMost("10"));
|
||||
|
||||
assertIsOverlappedBy(false, empty(), between("10", "20"));
|
||||
assertIsOverlappedBy(false, empty(), atLeast("10"));
|
||||
assertIsOverlappedBy(false, empty(), atMost("10"));
|
||||
assertIsOverlappedBy(false, empty(), VersionNumber.between("10", "20"));
|
||||
assertIsOverlappedBy(false, empty(), VersionNumber.atLeast("10"));
|
||||
assertIsOverlappedBy(false, empty(), VersionNumber.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, VersionNumber.between("10", "20"), VersionNumber.between("10", "20"));
|
||||
assertIsOverlappedBy(true, VersionNumber.between("10", "20"), VersionNumber.between("5", "20"));
|
||||
assertIsOverlappedBy(true, VersionNumber.between("10", "20"), VersionNumber.between("5", "15"));
|
||||
assertIsOverlappedBy(true, VersionNumber.between("10", "20"), VersionNumber.between("5", "10"));
|
||||
assertIsOverlappedBy(false, VersionNumber.between("10", "20"), VersionNumber.between("5", "5"));
|
||||
assertIsOverlappedBy(true, VersionNumber.between("10", "20"), VersionNumber.between("10", "30"));
|
||||
assertIsOverlappedBy(true, VersionNumber.between("10", "20"), VersionNumber.between("15", "30"));
|
||||
assertIsOverlappedBy(true, VersionNumber.between("10", "20"), VersionNumber.between("20", "30"));
|
||||
assertIsOverlappedBy(false, VersionNumber.between("10", "20"), VersionNumber.between("21", "30"));
|
||||
assertIsOverlappedBy(true, VersionNumber.between("10", "20"), VersionNumber.atLeast("5"));
|
||||
assertIsOverlappedBy(true, VersionNumber.between("10", "20"), VersionNumber.atLeast("10"));
|
||||
assertIsOverlappedBy(true, VersionNumber.between("10", "20"), VersionNumber.atLeast("15"));
|
||||
assertIsOverlappedBy(true, VersionNumber.between("10", "20"), VersionNumber.atLeast("20"));
|
||||
assertIsOverlappedBy(false, VersionNumber.between("10", "20"), VersionNumber.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"));
|
||||
assertIsOverlappedBy(true, VersionNumber.atLeast("10"), VersionNumber.atLeast("10"));
|
||||
assertIsOverlappedBy(true, VersionNumber.atLeast("10"), VersionNumber.atLeast("20"));
|
||||
assertIsOverlappedBy(true, VersionNumber.atLeast("10"), VersionNumber.atLeast("5"));
|
||||
assertIsOverlappedBy(true, VersionNumber.atLeast("10"), VersionNumber.atMost("10"));
|
||||
assertIsOverlappedBy(true, VersionNumber.atLeast("10"), VersionNumber.atMost("20"));
|
||||
assertIsOverlappedBy(false, VersionNumber.atLeast("10"), VersionNumber.atMost("5"));
|
||||
}
|
||||
|
||||
private static void assertIntersectionWith(VersionRange range1, VersionRange range2, VersionRange result) {
|
||||
private static void assertIntersectionWith(VersionRange<VersionNumber> range1, VersionRange<VersionNumber> range2, VersionRange<VersionNumber> result) {
|
||||
assertEquals(result, range1.intersectionWith(range2));
|
||||
assertEquals(result, range2.intersectionWith(range1));
|
||||
}
|
||||
@ -96,35 +99,35 @@ public class VersionRangeTest {
|
||||
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(all(), VersionNumber.between("10", "20"), VersionNumber.between("10", "20"));
|
||||
assertIntersectionWith(all(), VersionNumber.atLeast("10"), VersionNumber.atLeast("10"));
|
||||
assertIntersectionWith(all(), VersionNumber.atMost("10"), VersionNumber.atMost("10"));
|
||||
|
||||
assertIntersectionWith(empty(), empty(), empty());
|
||||
assertIntersectionWith(empty(), between("10", "20"), empty());
|
||||
assertIntersectionWith(empty(), atLeast("10"), empty());
|
||||
assertIntersectionWith(empty(), atMost("10"), empty());
|
||||
assertIntersectionWith(empty(), VersionNumber.between("10", "20"), empty());
|
||||
assertIntersectionWith(empty(), VersionNumber.atLeast("10"), empty());
|
||||
assertIntersectionWith(empty(), VersionNumber.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(VersionNumber.between("10", "20"), VersionNumber.between("10", "20"), VersionNumber.between("10", "20"));
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.between("5", "20"), VersionNumber.between("10", "20"));
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.between("10", "25"), VersionNumber.between("10", "20"));
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.between("5", "25"), VersionNumber.between("10", "20"));
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.between("15", "20"), VersionNumber.between("15", "20"));
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.between("10", "15"), VersionNumber.between("10", "15"));
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.between("14", "16"), VersionNumber.between("14", "16"));
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.atLeast("5"), VersionNumber.between("10", "20"));
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.atLeast("10"), VersionNumber.between("10", "20"));
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.atLeast("15"), VersionNumber.between("15", "20"));
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.atLeast("20"), VersionNumber.between("20", "20"));
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.atLeast("25"), empty());
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.atMost("25"), VersionNumber.between("10", "20"));
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.atMost("20"), VersionNumber.between("10", "20"));
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.atMost("15"), VersionNumber.between("10", "15"));
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.atMost("10"), VersionNumber.between("10", "10"));
|
||||
assertIntersectionWith(VersionNumber.between("10", "20"), VersionNumber.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());
|
||||
assertIntersectionWith(VersionNumber.atLeast("10"), VersionNumber.atMost("10"), VersionNumber.between("10", "10"));
|
||||
assertIntersectionWith(VersionNumber.atLeast("10"), VersionNumber.atMost("20"), VersionNumber.between("10", "20"));
|
||||
assertIntersectionWith(VersionNumber.atLeast("10"), VersionNumber.atMost("5"), empty());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user