diff --git a/README.md b/README.md index e8068a36..731eb6c3 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ HuskSync supports the following [compatible versions](https://william278.net/doc | Minecraft | Latest HuskSync | Java Version | Platforms | Support Status | |:---------------:|:---------------:|:------------:|:--------------|:------------------------------| -| 1.21.7 | _latest_ | 21 | Paper | ✅ **Active Release** | +| 1.21.7/8 | _latest_ | 21 | Paper | ✅ **Active Release** | | 1.21.6 | 3.8.5 | 21 | Paper | 🗃️ Archived (July 2025) | | 1.21.5 | _latest_ | 21 | Paper | ✅ **January 2026** (Non-LTS) | | 1.21.4 | _latest_ | 21 | Paper, Fabric | ✅ **November 2025** (Non-LTS) | diff --git a/bukkit/1.20.1/gradle.properties b/bukkit/1.20.1/gradle.properties index 07bb19bc..635fd197 100644 --- a/bukkit/1.20.1/gradle.properties +++ b/bukkit/1.20.1/gradle.properties @@ -1,3 +1,4 @@ +minecraft_version_range='1.20.1' minecraft_version_numeric=12001 minecraft_api_version=1.20 paper_api_version=1.20.1-R0.1-SNAPSHOT \ No newline at end of file diff --git a/bukkit/1.21.1/gradle.properties b/bukkit/1.21.1/gradle.properties index fefcb568..fbca64c6 100644 --- a/bukkit/1.21.1/gradle.properties +++ b/bukkit/1.21.1/gradle.properties @@ -1,3 +1,4 @@ +minecraft_version_range='1.21.1' minecraft_version_numeric=12101 minecraft_api_version=1.21 paper_api_version=1.21.1-R0.1-SNAPSHOT \ No newline at end of file diff --git a/bukkit/1.21.4/gradle.properties b/bukkit/1.21.4/gradle.properties index 6d26d274..071a42ab 100644 --- a/bukkit/1.21.4/gradle.properties +++ b/bukkit/1.21.4/gradle.properties @@ -1,3 +1,4 @@ +minecraft_version_range='1.21.4' minecraft_version_numeric=12104 minecraft_api_version=1.21 paper_api_version=1.21.4-R0.1-SNAPSHOT \ No newline at end of file diff --git a/bukkit/1.21.5/gradle.properties b/bukkit/1.21.5/gradle.properties index 5c7ad61b..13cb4ab0 100644 --- a/bukkit/1.21.5/gradle.properties +++ b/bukkit/1.21.5/gradle.properties @@ -1,3 +1,4 @@ +minecraft_version_range='1.21.5' minecraft_version_numeric=12105 minecraft_api_version=1.21 paper_api_version=1.21.5-R0.1-SNAPSHOT \ No newline at end of file diff --git a/bukkit/1.21.7/gradle.properties b/bukkit/1.21.7/gradle.properties index 214c00c6..4c009502 100644 --- a/bukkit/1.21.7/gradle.properties +++ b/bukkit/1.21.7/gradle.properties @@ -1,3 +1,4 @@ -minecraft_version_numeric=12107 +minecraft_version_range='>=1.21.7 <=1.21.8' +minecraft_version_numeric=12108 minecraft_api_version=1.21 -paper_api_version=1.21.7-R0.1-SNAPSHOT \ No newline at end of file +paper_api_version=1.21.8-R0.1-SNAPSHOT \ No newline at end of file diff --git a/bukkit/build.gradle b/bukkit/build.gradle index e1d3044f..f500cbbc 100644 --- a/bukkit/build.gradle +++ b/bukkit/build.gradle @@ -42,6 +42,7 @@ processResources { version: version, paper_api_version: paper_api_version, minecraft_version: project.name, + minecraft_version_range: minecraft_version_range, minecraft_api_version: minecraft_api_version ]) } diff --git a/bukkit/src/main/resources/compatibility.yml b/bukkit/src/main/resources/compatibility.yml index 84a64025..16dd9832 100644 --- a/bukkit/src/main/resources/compatibility.yml +++ b/bukkit/src/main/resources/compatibility.yml @@ -1,2 +1,2 @@ # File used for checking Minecraft server compatibility with this version of HuskSync -minecraft_version: '${minecraft_version}' \ No newline at end of file +minecraft_version_range: '${minecraft_version_range}' \ No newline at end of file diff --git a/common/src/main/java/net/william278/husksync/config/Settings.java b/common/src/main/java/net/william278/husksync/config/Settings.java index 8033c9dd..9ca3a45c 100644 --- a/common/src/main/java/net/william278/husksync/config/Settings.java +++ b/common/src/main/java/net/william278/husksync/config/Settings.java @@ -327,7 +327,7 @@ public class Settings { private Map eventPriorities = EventListener.ListenerType.getDefaults(); @Comment("Enable check-in petitions for data syncing (don't change this unless you know what you're doing)") - private boolean checkinPetitions = true; + private boolean checkinPetitions = false; public boolean doAutoPin(@NotNull DataSnapshot.SaveCause cause) { return autoPinnedSaveCauses.contains(cause.name()); diff --git a/common/src/main/java/net/william278/husksync/util/CompatibilityChecker.java b/common/src/main/java/net/william278/husksync/util/CompatibilityChecker.java index 15e937a2..8a8c2501 100644 --- a/common/src/main/java/net/william278/husksync/util/CompatibilityChecker.java +++ b/common/src/main/java/net/william278/husksync/util/CompatibilityChecker.java @@ -22,12 +22,13 @@ package net.william278.husksync.util; import de.exlll.configlib.Configuration; import de.exlll.configlib.YamlConfigurationProperties; import de.exlll.configlib.YamlConfigurationStore; +import lombok.AllArgsConstructor; import net.william278.desertwell.util.Version; import net.william278.husksync.HuskSync; import org.jetbrains.annotations.NotNull; import java.io.InputStream; -import java.util.Objects; +import java.util.function.BiFunction; import java.util.logging.Level; import static net.william278.husksync.config.ConfigProvider.YAML_CONFIGURATION_PROPERTIES; @@ -38,23 +39,22 @@ public interface CompatibilityChecker { default void checkCompatibility() throws HuskSync.FailedToLoadException { final YamlConfigurationProperties p = YAML_CONFIGURATION_PROPERTIES.build(); - final Version compatible; + final CompatibilityConfig compat; // Load compatibility file try (InputStream input = getResource(COMPATIBILITY_FILE)) { - final CompatibilityConfig compat = new YamlConfigurationStore<>(CompatibilityConfig.class, p).read(input); - compatible = Objects.requireNonNull(compat.getCompatibleWith()); + compat = new YamlConfigurationStore<>(CompatibilityConfig.class, p).read(input); } catch (Throwable e) { getPlugin().log(Level.WARNING, "Failed to load compatibility config, skipping check.", e); return; } // Check compatibility - if (compatible.compareTo(getPlugin().getMinecraftVersion()) != 0) { + if (!compat.isCompatibleWith(getPlugin().getMinecraftVersion())) { throw new HuskSync.FailedToLoadException(""" Incompatible Minecraft version. This version of HuskSync is designed for Minecraft %s. Please download the correct version of HuskSync for your server's Minecraft version (%s).""" - .formatted(compatible.toString(), getPlugin().getMinecraftVersion().toString())); + .formatted(compat.minecraftVersionRange(), getPlugin().getMinecraftVersion().toString())); } } @@ -64,11 +64,38 @@ public interface CompatibilityChecker { HuskSync getPlugin(); @Configuration - record CompatibilityConfig(@NotNull String minecraftVersion) { + record CompatibilityConfig(@NotNull String minecraftVersionRange) { - @NotNull - public Version getCompatibleWith() { - return Version.fromString(minecraftVersion); + @AllArgsConstructor + enum ExpressionType { + GTE(">=", (v, s) -> v.compareTo(Version.fromString(s.substring(2))) >= 0), + LTE("<=", (v, s) -> v.compareTo(Version.fromString(s.substring(2))) <= 0), + GT(">", (v, s) -> v.compareTo(Version.fromString(s.substring(1))) > 0), + LT("<", (v, s) -> v.compareTo(Version.fromString(s.substring(1))) < 0), + NOT("!", (v, s) -> v.compareTo(Version.fromString(s.substring(1))) != 0), + E("=", (v, s) -> v.compareTo(Version.fromString(s.substring(1))) == 0); + + private final String match; + private final BiFunction function; + + private static boolean check(@NotNull String versionRange, @NotNull Version mcVer) { + boolean passes = true; + versions: + for (String exp : versionRange.split(" ")) { + for (ExpressionType type : values()) { + if (exp.trim().startsWith(type.match)) { + passes = passes && type.function.apply(mcVer, exp.trim()); + continue versions; + } + } + passes = passes && mcVer.compareTo(Version.fromString(exp.trim())) == 0; + } + return passes; + } + } + + public boolean isCompatibleWith(@NotNull Version version) { + return ExpressionType.check(minecraftVersionRange, version); } } diff --git a/common/src/test/java/net/william278/husksync/util/CompatibilityCheckerTests.java b/common/src/test/java/net/william278/husksync/util/CompatibilityCheckerTests.java new file mode 100644 index 00000000..e6ccdaa1 --- /dev/null +++ b/common/src/test/java/net/william278/husksync/util/CompatibilityCheckerTests.java @@ -0,0 +1,59 @@ +/* + * This file is part of HuskSync, licensed under the Apache License 2.0. + * + * Copyright (c) William278 + * Copyright (c) contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.william278.husksync.util; + +import net.william278.desertwell.util.Version; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +@DisplayName("Compatibility Checker Tests") +public class CompatibilityCheckerTests { + + @ParameterizedTest(name = "Ver: {0}, Range: {1}") + @DisplayName("Test Compatibility Checker") + @CsvSource({ + "1.20.1, 1.21.1, false", + "1.21.1, 1.20.1, false", + "1.7.2, 1.21.5, false", + "1.19.4, 1.21.1, false", + "1.21.3, 1.21.3, true", + "1.20.1, 1.20.1, true", + "1.21.7, 1.21.7, true", + "1.21.8, >=1.21.7, true", + "1.21.8, >1.21.7, true", + "1.0, <1.21.7, true", + "1.17.1, !1.17.1, false", + "1.21.7, '>=1.21.7 <=1.21.8', true", + "1.21.8, '>=1.21.7 <=1.21.8', true", + "1.21.5, '>=1.21.7 <=1.21.8', false", + }) + public void testCompatibilityChecker(@NotNull String mcVer, @NotNull String range, boolean exp) { + final Version version = Version.fromString(mcVer); + Assertions.assertNotNull(version, "Version should not be null"); + + final CompatibilityChecker.CompatibilityConfig config = new CompatibilityChecker.CompatibilityConfig(range); + Assertions.assertEquals(exp, config.isCompatibleWith(version), "Checker should return " + exp); + } + + +} diff --git a/docs/Compatibility.md b/docs/Compatibility.md index 53c262ca..d3aeafea 100644 --- a/docs/Compatibility.md +++ b/docs/Compatibility.md @@ -2,7 +2,7 @@ HuskSync supports the following versions of Minecraft. Since v3.7, you must down | Minecraft | Latest HuskSync | Java Version | Platforms | Support Status | |:---------------:|:---------------:|:------------:|:--------------|:------------------------------| -| 1.21.7 | _latest_ | 21 | Paper | ✅ **Active Release** | +| 1.21.7/8 | _latest_ | 21 | Paper | ✅ **Active Release** | | 1.21.6 | 3.8.5 | 21 | Paper | 🗃️ Archived (July 2025) | | 1.21.5 | _latest_ | 21 | Paper | ✅ **January 2026** (Non-LTS) | | 1.21.4 | _latest_ | 21 | Paper, Fabric | ✅ **November 2025** (Non-LTS) | diff --git a/fabric/1.20.1/gradle.properties b/fabric/1.20.1/gradle.properties index 687ccd05..c71ff8f9 100644 --- a/fabric/1.20.1/gradle.properties +++ b/fabric/1.20.1/gradle.properties @@ -1,5 +1,7 @@ essential.defaults.loom.mappings=net.fabricmc:yarn:1.20.1+build.10:v2 +minecraft_version_range='1.20.1' + fabric_loader_version=0.15.11 fabric_api_version=0.92.2+1.20.1 fabric_permissions_api_version=0.2-SNAPSHOT diff --git a/fabric/1.21.1/gradle.properties b/fabric/1.21.1/gradle.properties index 308449cf..f9b7955c 100644 --- a/fabric/1.21.1/gradle.properties +++ b/fabric/1.21.1/gradle.properties @@ -1,5 +1,7 @@ essential.defaults.loom.mappings=net.fabricmc:yarn:1.21.1+build.3:v2 +minecraft_version_range='1.21.1' + fabric_loader_version=0.16.10 fabric_api_version=0.107.0+1.21.1 fabric_permissions_api_version=0.3.1 diff --git a/fabric/1.21.4/gradle.properties b/fabric/1.21.4/gradle.properties index da4e4bf5..981f8b68 100644 --- a/fabric/1.21.4/gradle.properties +++ b/fabric/1.21.4/gradle.properties @@ -1,5 +1,7 @@ essential.defaults.loom.mappings=net.fabricmc:yarn:1.21.4+build.4:v2 +minecraft_version_range='1.21.4' + fabric_loader_version=0.16.10 fabric_api_version=0.116.1+1.21.4 fabric_permissions_api_version=0.3.3 diff --git a/fabric/1.21.5/gradle.properties b/fabric/1.21.5/gradle.properties index d2acb0f9..77fd17c9 100644 --- a/fabric/1.21.5/gradle.properties +++ b/fabric/1.21.5/gradle.properties @@ -1,5 +1,7 @@ essential.defaults.loom.mappings=net.fabricmc:yarn:1.21.5+build.1:v2 +minecraft_version_range='1.21.5' + fabric_loader_version=0.16.14 fabric_api_version=0.122.0+1.21.5 fabric_permissions_api_version=0.3.3 diff --git a/fabric/1.21.7/gradle.properties b/fabric/1.21.7/gradle.properties index ca57daa1..c11cd248 100644 --- a/fabric/1.21.7/gradle.properties +++ b/fabric/1.21.7/gradle.properties @@ -1,5 +1,7 @@ essential.defaults.loom.mappings=net.fabricmc:yarn:1.21.7+build.2:v2 +minecraft_version_range='>=1.21.7 <=1.21.8' + fabric_loader_version=0.16.14 fabric_api_version=0.128.1+1.21.7 fabric_permissions_api_version=0.4.1 diff --git a/fabric/build.gradle b/fabric/build.gradle index b97d729f..a5b6be5e 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -49,7 +49,8 @@ processResources { expand([ version: version, fabric_loader_version: fabric_loader_version, - fabric_minecraft_version: project.name + fabric_minecraft_version: project.name, + minecraft_version_range: minecraft_version_range ]) } } diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index d1e09d38..1985fd75 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -40,7 +40,7 @@ }, "depends": { "fabricloader": ">=${fabric_loader_version}", - "minecraft": "${fabric_minecraft_version}", + "minecraft": "${minecraft_version_range}", "fabric-api": "*" }, "suggests": { diff --git a/gradle.properties b/gradle.properties index 9daad570..a5f5f830 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org.gradle.daemon=true javaVersion=21 # Plugin metadata -plugin_version=3.8.6 +plugin_version=3.8.7 plugin_archive=husksync plugin_description=A modern, cross-server player data synchronization system