From 9eda84efefecc99416c3f3abfd118ff69c497769 Mon Sep 17 00:00:00 2001 From: JRoy <10731363+JRoy@users.noreply.github.com> Date: Sun, 22 Mar 2026 18:47:21 -0700 Subject: [PATCH 1/5] Support new MC version scheme --- .../essentials/utils/VersionUtil.java | 55 +++++++++++++------ .../com/earth2me/essentials/UtilTest.java | 50 +++++++++++++++++ 2 files changed, 88 insertions(+), 17 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/utils/VersionUtil.java b/Essentials/src/main/java/com/earth2me/essentials/utils/VersionUtil.java index 0caf7ea6659..efac5444fa4 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/utils/VersionUtil.java +++ b/Essentials/src/main/java/com/earth2me/essentials/utils/VersionUtil.java @@ -46,8 +46,9 @@ public final class VersionUtil { public static final BukkitVersion v1_21_5_R01 = BukkitVersion.fromString("1.21.5-R0.1-SNAPSHOT"); public static final BukkitVersion v1_21_8_R01 = BukkitVersion.fromString("1.21.8-R0.1-SNAPSHOT"); public static final BukkitVersion v1_21_11_R01 = BukkitVersion.fromString("1.21.11-R0.1-SNAPSHOT"); + public static final BukkitVersion v26_1_R01 = BukkitVersion.fromString("26.1-R0.1-SNAPSHOT"); - private static final Set supportedVersions = ImmutableSet.of(v1_8_8_R01, v1_9_4_R01, v1_10_2_R01, v1_11_2_R01, v1_12_2_R01, v1_13_2_R01, v1_14_4_R01, v1_15_2_R01, v1_16_5_R01, v1_17_1_R01, v1_18_2_R01, v1_19_4_R01, v1_20_6_R01, v1_21_11_R01); + private static final Set supportedVersions = ImmutableSet.of(v1_8_8_R01, v1_9_4_R01, v1_10_2_R01, v1_11_2_R01, v1_12_2_R01, v1_13_2_R01, v1_14_4_R01, v1_15_2_R01, v1_16_5_R01, v1_17_1_R01, v1_18_2_R01, v1_19_4_R01, v1_20_6_R01, v1_21_11_R01, v26_1_R01); public static final boolean PRE_FLATTENING = VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01); @@ -189,11 +190,12 @@ public static String getSupportStatusClass() { } public static final class BukkitVersion implements Comparable { - private static final Pattern VERSION_PATTERN = Pattern.compile("^(\\d+)\\.(\\d+)\\.?([0-9]*)?(?:-pre(\\d))?(?:-rc(\\d+))?(?:-?R?([\\d.]+))?(?:-SNAPSHOT)?"); + private static final Pattern VERSION_PATTERN = Pattern.compile("^(\\d+)\\.(\\d+)\\.?([0-9]*)?(?:-snapshot-(\\d+))?(?:-pre-?(\\d+))?(?:-rc-?(\\d+))?(?:-?R?([\\d.]+))?(?:-SNAPSHOT)?"); private static final Pattern SNAPSHOT_PATTERN = Pattern.compile("^(\\d{2})w(\\d{2})([a-z])(?:-?R?([\\d.]+))?(?:-SNAPSHOT)?"); private final int major; private final int minor; + private final int snapshotRelease; private final int preRelease; private final int releaseCandidate; private final int patch; @@ -204,11 +206,12 @@ public static final class BukkitVersion implements Comparable { private final int snapshotWeek; private final char snapshotLetter; - private BukkitVersion(final int major, final int minor, final int patch, final double revision, final int preRelease, final int releaseCandidate) { + private BukkitVersion(final int major, final int minor, final int patch, final double revision, final int snapshotRelease, final int preRelease, final int releaseCandidate) { this.major = major; this.minor = minor; this.patch = patch; this.revision = revision; + this.snapshotRelease = snapshotRelease; this.preRelease = preRelease; this.releaseCandidate = releaseCandidate; this.snapshot = false; @@ -217,12 +220,13 @@ private BukkitVersion(final int major, final int minor, final int patch, final d this.snapshotLetter = '\0'; } - private BukkitVersion(final int major, final int minor, final int patch, final double revision, final int preRelease, final int releaseCandidate, + private BukkitVersion(final int major, final int minor, final int patch, final double revision, final int snapshotRelease, final int preRelease, final int releaseCandidate, final boolean snapshot, final int snapshotYear, final int snapshotWeek, final char snapshotLetter) { this.major = major; this.minor = minor; this.patch = patch; this.revision = revision; + this.snapshotRelease = snapshotRelease; this.preRelease = preRelease; this.releaseCandidate = releaseCandidate; this.snapshot = snapshot; @@ -237,7 +241,7 @@ public static BukkitVersion fromString(final String string) { // Try standard release format first Matcher matcher = VERSION_PATTERN.matcher(string); if (matcher.matches()) { - return from(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(6), matcher.group(4), matcher.group(5)); + return from(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(7), matcher.group(4), matcher.group(5), matcher.group(6)); } // Try snapshot format (e.g., 25w32a-R0.1-SNAPSHOT) @@ -259,24 +263,26 @@ public static BukkitVersion fromString(final String string) { } matcher = VERSION_PATTERN.matcher(v1_16_1_R01.toString()); Preconditions.checkArgument(matcher.matches(), string + " is not in valid version format. e.g. 1.8.8-R0.1"); - return from(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(6), matcher.group(4), matcher.group(5)); + return from(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(7), matcher.group(4), matcher.group(5), matcher.group(6)); } - private static BukkitVersion from(final String major, final String minor, String patch, String revision, String preRelease, String releaseCandidate) { + private static BukkitVersion from(final String major, final String minor, String patch, String revision, String snapshotRelease, String preRelease, String releaseCandidate) { if (patch == null || patch.isEmpty()) patch = "0"; if (revision == null || revision.isEmpty()) revision = "0"; + if (snapshotRelease == null || snapshotRelease.isEmpty()) snapshotRelease = "-1"; if (preRelease == null || preRelease.isEmpty()) preRelease = "-1"; if (releaseCandidate == null || releaseCandidate.isEmpty()) releaseCandidate = "-1"; return new BukkitVersion(Integer.parseInt(major), Integer.parseInt(minor), Integer.parseInt(patch), Double.parseDouble(revision), + Integer.parseInt(snapshotRelease), Integer.parseInt(preRelease), Integer.parseInt(releaseCandidate)); } private static BukkitVersion fromSnapshot(final int year, final int week, final char letter, final double revision) { - return new BukkitVersion(-1, -1, -1, revision, -1, -1, true, year, week, letter); + return new BukkitVersion(-1, -1, -1, revision, -1, -1, -1, true, year, week, letter); } public boolean isHigherThan(final BukkitVersion o) { @@ -319,6 +325,10 @@ public int getReleaseCandidate() { return releaseCandidate; } + public int getSnapshotRelease() { + return snapshotRelease; + } + public boolean isSnapshot() { return snapshot; } @@ -343,7 +353,9 @@ public boolean equals(final Object o) { minor == that.minor && patch == that.patch && revision == that.revision && - preRelease == that.preRelease; + snapshotRelease == that.snapshotRelease && + preRelease == that.preRelease && + releaseCandidate == that.releaseCandidate; } @Override @@ -351,7 +363,7 @@ public int hashCode() { if (snapshot) { return Objects.hashCode("snapshot", snapshotYear, snapshotWeek, snapshotLetter, revision); } - return Objects.hashCode(major, minor, patch, revision, preRelease, releaseCandidate); + return Objects.hashCode(major, minor, patch, revision, snapshotRelease, preRelease, releaseCandidate); } @Override @@ -363,6 +375,9 @@ public String toString() { if (patch != 0) { sb.append(".").append(patch); } + if (snapshotRelease != -1) { + sb.append("-snapshot-").append(snapshotRelease); + } if (preRelease != -1) { sb.append("-pre").append(preRelease); } @@ -407,17 +422,23 @@ public int compareTo(final BukkitVersion o) { } else if (patch > o.patch) { return 1; } else { // equal patch - if (preRelease < o.preRelease) { + if (snapshotRelease < o.snapshotRelease) { return -1; - } else if (preRelease > o.preRelease) { + } else if (snapshotRelease > o.snapshotRelease) { return 1; - } else { // equal prerelease - if (releaseCandidate < o.releaseCandidate) { + } else { // equal snapshot release + if (preRelease < o.preRelease) { return -1; - } else if (releaseCandidate > o.releaseCandidate) { + } else if (preRelease > o.preRelease) { return 1; - } else { // equal release candidate - return Double.compare(revision, o.revision); + } else { // equal prerelease + if (releaseCandidate < o.releaseCandidate) { + return -1; + } else if (releaseCandidate > o.releaseCandidate) { + return 1; + } else { // equal release candidate + return Double.compare(revision, o.revision); + } } } } diff --git a/Essentials/src/test/java/com/earth2me/essentials/UtilTest.java b/Essentials/src/test/java/com/earth2me/essentials/UtilTest.java index 62c64500380..116d548a39b 100644 --- a/Essentials/src/test/java/com/earth2me/essentials/UtilTest.java +++ b/Essentials/src/test/java/com/earth2me/essentials/UtilTest.java @@ -249,5 +249,55 @@ public void testVer() { assertEquals(v.getRevision(), 0.1); assertEquals(v.getPrerelease(), -1); assertEquals(v.getReleaseCandidate(), 3); + // New versioning format (26.x) + v = VersionUtil.BukkitVersion.fromString("26.1-R0.1-SNAPSHOT"); + assertEquals(v.getMajor(), 26); + assertEquals(v.getMinor(), 1); + assertEquals(v.getPatch(), 0); + assertEquals(v.getRevision(), 0.1); + assertEquals(v.getSnapshotRelease(), -1); + assertEquals(v.getPrerelease(), -1); + assertEquals(v.getReleaseCandidate(), -1); + v = VersionUtil.BukkitVersion.fromString("26.1.1-R0.1-SNAPSHOT"); + assertEquals(v.getMajor(), 26); + assertEquals(v.getMinor(), 1); + assertEquals(v.getPatch(), 1); + assertEquals(v.getRevision(), 0.1); + assertEquals(v.getSnapshotRelease(), -1); + assertEquals(v.getPrerelease(), -1); + assertEquals(v.getReleaseCandidate(), -1); + v = VersionUtil.BukkitVersion.fromString("26.1-snapshot-11-R0.1-SNAPSHOT"); + assertEquals(v.getMajor(), 26); + assertEquals(v.getMinor(), 1); + assertEquals(v.getPatch(), 0); + assertEquals(v.getRevision(), 0.1); + assertEquals(v.getSnapshotRelease(), 11); + assertEquals(v.getPrerelease(), -1); + assertEquals(v.getReleaseCandidate(), -1); + v = VersionUtil.BukkitVersion.fromString("26.1-pre-3-R0.1-SNAPSHOT"); + assertEquals(v.getMajor(), 26); + assertEquals(v.getMinor(), 1); + assertEquals(v.getPatch(), 0); + assertEquals(v.getRevision(), 0.1); + assertEquals(v.getSnapshotRelease(), -1); + assertEquals(v.getPrerelease(), 3); + assertEquals(v.getReleaseCandidate(), -1); + v = VersionUtil.BukkitVersion.fromString("26.1-rc-2-R0.1-SNAPSHOT"); + assertEquals(v.getMajor(), 26); + assertEquals(v.getMinor(), 1); + assertEquals(v.getPatch(), 0); + assertEquals(v.getRevision(), 0.1); + assertEquals(v.getSnapshotRelease(), -1); + assertEquals(v.getPrerelease(), -1); + assertEquals(v.getReleaseCandidate(), 2); + // Verify old format backward compat + v = VersionUtil.BukkitVersion.fromString("1.21.5-R0.1-SNAPSHOT"); + assertEquals(v.getMajor(), 1); + assertEquals(v.getMinor(), 21); + assertEquals(v.getPatch(), 5); + assertEquals(v.getRevision(), 0.1); + assertEquals(v.getSnapshotRelease(), -1); + assertEquals(v.getPrerelease(), -1); + assertEquals(v.getReleaseCandidate(), -1); } } From 0038e9758c2c90a8cb895cb061ceaa55c4c394b9 Mon Sep 17 00:00:00 2001 From: JRoy <10731363+JRoy@users.noreply.github.com> Date: Sun, 22 Mar 2026 19:23:13 -0700 Subject: [PATCH 2/5] Minecraft 26.1 Items --- Essentials/src/main/resources/items.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Essentials/src/main/resources/items.json b/Essentials/src/main/resources/items.json index c6a31fd7597..cf725a74331 100644 --- a/Essentials/src/main/resources/items.json +++ b/Essentials/src/main/resources/items.json @@ -8620,6 +8620,12 @@ "gshirt": "golden_chestplate", "gtunic": "golden_chestplate", "minecraft:golden_chestplate": "golden_chestplate", + "golden_dandelion": { + "name": "golden_dandelion", + "material": "GOLDEN_DANDELION" + }, + "goldendandelion": "golden_dandelion", + "minecraft:golden_dandelion": "golden_dandelion", "golden_helmet": { "material": "GOLDEN_HELMET" }, @@ -50980,4 +50986,4 @@ "zpmanmonsterspawner": "zombified_piglin_spawner", "zpmanmspawner": "zombified_piglin_spawner", "zpmanspawner": "zombified_piglin_spawner" -} \ No newline at end of file +} From 09b62d415b3a64e137de8d990c15ca8086b218b0 Mon Sep 17 00:00:00 2001 From: JRoy <10731363+JRoy@users.noreply.github.com> Date: Sun, 22 Mar 2026 19:26:13 -0700 Subject: [PATCH 3/5] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1266ffbf005..37aff5f1822 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ however, have some new requirements: * **EssentialsX requires CraftBukkit, Spigot or Paper to run.** Other server software may work, but these are not tested by the team and we may not be able to help with any issues that occur. * **EssentialsX currently supports Minecraft versions 1.8.8, 1.9.4, 1.10.2, 1.11.2, 1.12.2, 1.13.2, 1.14.4, 1.15.2, - 1.16.5, 1.17.1, 1.18.2, 1.19.4, 1.20.6, and 1.21.11.** + 1.16.5, 1.17.1, 1.18.2, 1.19.4, 1.20.6, 1.21.11, and 26.1.** * **EssentialsX currently requires Java 8 or higher.** We recommend using the latest Java version supported by your server software. * **EssentialsX requires [Vault](http://dev.bukkit.org/bukkit-plugins/vault/) to enable using chat prefix/suffixes and From c7ffece2f096bd17053997c8b85a6afedebb5bd0 Mon Sep 17 00:00:00 2001 From: JRoy <10731363+JRoy@users.noreply.github.com> Date: Mon, 23 Mar 2026 09:29:10 -0700 Subject: [PATCH 4/5] test --- .../com/earth2me/essentials/UtilTest.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Essentials/src/test/java/com/earth2me/essentials/UtilTest.java b/Essentials/src/test/java/com/earth2me/essentials/UtilTest.java index 116d548a39b..336b02df5aa 100644 --- a/Essentials/src/test/java/com/earth2me/essentials/UtilTest.java +++ b/Essentials/src/test/java/com/earth2me/essentials/UtilTest.java @@ -290,14 +290,16 @@ public void testVer() { assertEquals(v.getSnapshotRelease(), -1); assertEquals(v.getPrerelease(), -1); assertEquals(v.getReleaseCandidate(), 2); - // Verify old format backward compat - v = VersionUtil.BukkitVersion.fromString("1.21.5-R0.1-SNAPSHOT"); - assertEquals(v.getMajor(), 1); - assertEquals(v.getMinor(), 21); - assertEquals(v.getPatch(), 5); - assertEquals(v.getRevision(), 0.1); - assertEquals(v.getSnapshotRelease(), -1); - assertEquals(v.getPrerelease(), -1); - assertEquals(v.getReleaseCandidate(), -1); + // Old format versions are always lower than new format versions + assertTrue(VersionUtil.BukkitVersion.fromString("1.21.11-R0.1-SNAPSHOT") + .isLowerThan(VersionUtil.BukkitVersion.fromString("26.1-R0.1-SNAPSHOT"))); + assertTrue(VersionUtil.BukkitVersion.fromString("26.1-R0.1-SNAPSHOT") + .isHigherThan(VersionUtil.BukkitVersion.fromString("1.21.11-R0.1-SNAPSHOT"))); + assertTrue(VersionUtil.BukkitVersion.fromString("1.21.11-R0.1-SNAPSHOT") + .isLowerThan(VersionUtil.BukkitVersion.fromString("26.1-snapshot-1-R0.1-SNAPSHOT"))); + assertTrue(VersionUtil.BukkitVersion.fromString("1.21.11-R0.1-SNAPSHOT") + .isLowerThan(VersionUtil.BukkitVersion.fromString("26.1-pre-1-R0.1-SNAPSHOT"))); + assertTrue(VersionUtil.BukkitVersion.fromString("1.21.11-R0.1-SNAPSHOT") + .isLowerThan(VersionUtil.BukkitVersion.fromString("26.1-rc-1-R0.1-SNAPSHOT"))); } } From e50bfc451a858eb9974c6735107392be74443b1d Mon Sep 17 00:00:00 2001 From: JRoy <10731363+JRoy@users.noreply.github.com> Date: Mon, 23 Mar 2026 09:30:50 -0700 Subject: [PATCH 5/5] rename --- .../main/java/com/earth2me/essentials/utils/VersionUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/utils/VersionUtil.java b/Essentials/src/main/java/com/earth2me/essentials/utils/VersionUtil.java index efac5444fa4..47be345e824 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/utils/VersionUtil.java +++ b/Essentials/src/main/java/com/earth2me/essentials/utils/VersionUtil.java @@ -191,7 +191,7 @@ public static String getSupportStatusClass() { public static final class BukkitVersion implements Comparable { private static final Pattern VERSION_PATTERN = Pattern.compile("^(\\d+)\\.(\\d+)\\.?([0-9]*)?(?:-snapshot-(\\d+))?(?:-pre-?(\\d+))?(?:-rc-?(\\d+))?(?:-?R?([\\d.]+))?(?:-SNAPSHOT)?"); - private static final Pattern SNAPSHOT_PATTERN = Pattern.compile("^(\\d{2})w(\\d{2})([a-z])(?:-?R?([\\d.]+))?(?:-SNAPSHOT)?"); + private static final Pattern LEGACY_SNAPSHOT_PATTERN = Pattern.compile("^(\\d{2})w(\\d{2})([a-z])(?:-?R?([\\d.]+))?(?:-SNAPSHOT)?"); private final int major; private final int minor; @@ -245,7 +245,7 @@ public static BukkitVersion fromString(final String string) { } // Try snapshot format (e.g., 25w32a-R0.1-SNAPSHOT) - final Matcher snapshotMatcher = SNAPSHOT_PATTERN.matcher(string); + final Matcher snapshotMatcher = LEGACY_SNAPSHOT_PATTERN.matcher(string); if (snapshotMatcher.matches()) { final int year = Integer.parseInt(snapshotMatcher.group(1)); final int week = Integer.parseInt(snapshotMatcher.group(2));