Skip to content

Commit 5d535dc

Browse files
JasonHorklesCopilotJRoy
authored
Support new PaperMC versioning scheme in VersionUtil (#6480)
ThioJoe is waiting! Re #6479 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: JRoy <10731363+JRoy@users.noreply.github.com>
1 parent 8e3b24f commit 5d535dc

File tree

2 files changed

+220
-12
lines changed

2 files changed

+220
-12
lines changed

Essentials/src/main/java/com/earth2me/essentials/utils/VersionUtil.java

Lines changed: 80 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ public static SupportStatus getServerSupportStatus() {
176176
}
177177
}
178178

179-
if (!supportedVersions.contains(getServerBukkitVersion())) {
179+
if (!isSupportedVersion(getServerBukkitVersion())) {
180180
return supportStatus = SupportStatus.OUTDATED;
181181
}
182182

@@ -189,15 +189,39 @@ public static String getSupportStatusClass() {
189189
return supportStatusClass;
190190
}
191191

192+
/**
193+
* Checks if a version is considered supported, either by exact match in the
194+
* supported versions set, or by matching the base version (major.minor.patch)
195+
* of a supported version. This handles both the new PaperMC versioning scheme
196+
* (which omits the Bukkit revision suffix) and development builds that report
197+
* versions like {@code 26.1-rc-3.build.8-alpha}.
198+
*/
199+
private static boolean isSupportedVersion(final BukkitVersion version) {
200+
if (supportedVersions.contains(version)) {
201+
return true;
202+
}
203+
// Check if this version matches a supported base version.
204+
// This covers Paper versions (no -R0.1-SNAPSHOT suffix) and
205+
// dev variants (snapshot/pre-release/RC/Paper builds).
206+
for (final BukkitVersion supported : supportedVersions) {
207+
if (version.equalsBaseVersion(supported)) {
208+
return true;
209+
}
210+
}
211+
return false;
212+
}
213+
192214
public static final class BukkitVersion implements Comparable<BukkitVersion> {
193-
private static final Pattern VERSION_PATTERN = Pattern.compile("^(\\d+)\\.(\\d+)\\.?([0-9]*)?(?:-snapshot-(\\d+))?(?:-pre-?(\\d+))?(?:-rc-?(\\d+))?(?:-?R?([\\d.]+))?(?:-SNAPSHOT)?");
215+
private static final Pattern VERSION_PATTERN = Pattern.compile("^(\\d+)\\.(\\d+)\\.?([0-9]*)?(?:-snapshot-(\\d+))?(?:-pre-?(\\d+))?(?:-rc-?(\\d+))?(?:\\.build\\.(\\d+)(?:-([a-z]+))?)?(?:-?R?([\\d.]+))?(?:-SNAPSHOT)?");
194216
private static final Pattern LEGACY_SNAPSHOT_PATTERN = Pattern.compile("^(\\d{2})w(\\d{2})([a-z])(?:-?R?([\\d.]+))?(?:-SNAPSHOT)?");
195217

196218
private final int major;
197219
private final int minor;
198220
private final int snapshotRelease;
199221
private final int preRelease;
200222
private final int releaseCandidate;
223+
private final int paperBuild;
224+
private final String releaseChannel;
201225
private final int patch;
202226
private final double revision;
203227

@@ -206,21 +230,23 @@ public static final class BukkitVersion implements Comparable<BukkitVersion> {
206230
private final int snapshotWeek;
207231
private final char snapshotLetter;
208232

209-
private BukkitVersion(final int major, final int minor, final int patch, final double revision, final int snapshotRelease, final int preRelease, final int releaseCandidate) {
233+
private BukkitVersion(final int major, final int minor, final int patch, final double revision, final int snapshotRelease, final int preRelease, final int releaseCandidate, final int paperBuild, final String releaseChannel) {
210234
this.major = major;
211235
this.minor = minor;
212236
this.patch = patch;
213237
this.revision = revision;
214238
this.snapshotRelease = snapshotRelease;
215239
this.preRelease = preRelease;
216240
this.releaseCandidate = releaseCandidate;
241+
this.paperBuild = paperBuild;
242+
this.releaseChannel = releaseChannel;
217243
this.snapshot = false;
218244
this.snapshotYear = -1;
219245
this.snapshotWeek = -1;
220246
this.snapshotLetter = '\0';
221247
}
222248

223-
private BukkitVersion(final int major, final int minor, final int patch, final double revision, final int snapshotRelease, final int preRelease, final int releaseCandidate,
249+
private BukkitVersion(final int major, final int minor, final int patch, final double revision, final int snapshotRelease, final int preRelease, final int releaseCandidate, final int paperBuild, final String releaseChannel,
224250
final boolean snapshot, final int snapshotYear, final int snapshotWeek, final char snapshotLetter) {
225251
this.major = major;
226252
this.minor = minor;
@@ -229,6 +255,8 @@ private BukkitVersion(final int major, final int minor, final int patch, final d
229255
this.snapshotRelease = snapshotRelease;
230256
this.preRelease = preRelease;
231257
this.releaseCandidate = releaseCandidate;
258+
this.paperBuild = paperBuild;
259+
this.releaseChannel = releaseChannel;
232260
this.snapshot = snapshot;
233261
this.snapshotYear = snapshotYear;
234262
this.snapshotWeek = snapshotWeek;
@@ -241,7 +269,7 @@ public static BukkitVersion fromString(final String string) {
241269
// Try standard release format first
242270
Matcher matcher = VERSION_PATTERN.matcher(string);
243271
if (matcher.matches()) {
244-
return from(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(7), matcher.group(4), matcher.group(5), matcher.group(6));
272+
return from(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(9), matcher.group(4), matcher.group(5), matcher.group(6), matcher.group(7), matcher.group(8));
245273
}
246274

247275
// Try snapshot format (e.g., 25w32a-R0.1-SNAPSHOT)
@@ -263,26 +291,29 @@ public static BukkitVersion fromString(final String string) {
263291
}
264292
matcher = VERSION_PATTERN.matcher(v1_16_1_R01.toString());
265293
Preconditions.checkArgument(matcher.matches(), string + " is not in valid version format. e.g. 1.8.8-R0.1");
266-
return from(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(7), matcher.group(4), matcher.group(5), matcher.group(6));
294+
return from(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(9), matcher.group(4), matcher.group(5), matcher.group(6), matcher.group(7), matcher.group(8));
267295
}
268296

269-
private static BukkitVersion from(final String major, final String minor, String patch, String revision, String snapshotRelease, String preRelease, String releaseCandidate) {
297+
private static BukkitVersion from(final String major, final String minor, String patch, String revision, String snapshotRelease, String preRelease, String releaseCandidate, String paperBuild, final String releaseChannel) {
270298
if (patch == null || patch.isEmpty()) patch = "0";
271299
if (revision == null || revision.isEmpty()) revision = "0";
272300
if (snapshotRelease == null || snapshotRelease.isEmpty()) snapshotRelease = "-1";
273301
if (preRelease == null || preRelease.isEmpty()) preRelease = "-1";
274302
if (releaseCandidate == null || releaseCandidate.isEmpty()) releaseCandidate = "-1";
303+
if (paperBuild == null || paperBuild.isEmpty()) paperBuild = "-1";
275304
return new BukkitVersion(Integer.parseInt(major),
276305
Integer.parseInt(minor),
277306
Integer.parseInt(patch),
278307
Double.parseDouble(revision),
279308
Integer.parseInt(snapshotRelease),
280309
Integer.parseInt(preRelease),
281-
Integer.parseInt(releaseCandidate));
310+
Integer.parseInt(releaseCandidate),
311+
Integer.parseInt(paperBuild),
312+
releaseChannel);
282313
}
283314

284315
private static BukkitVersion fromSnapshot(final int year, final int week, final char letter, final double revision) {
285-
return new BukkitVersion(-1, -1, -1, revision, -1, -1, -1, true, year, week, letter);
316+
return new BukkitVersion(-1, -1, -1, revision, -1, -1, -1, -1, null, true, year, week, letter);
286317
}
287318

288319
public boolean isHigherThan(final BukkitVersion o) {
@@ -329,10 +360,35 @@ public int getSnapshotRelease() {
329360
return snapshotRelease;
330361
}
331362

363+
public int getPaperBuild() {
364+
return paperBuild;
365+
}
366+
367+
public String getReleaseChannel() {
368+
return releaseChannel;
369+
}
370+
332371
public boolean isSnapshot() {
333372
return snapshot;
334373
}
335374

375+
/**
376+
* Checks if this version has the same base version (major, minor, and patch)
377+
* as the given version, ignoring development specifiers (snapshot release, pre-release,
378+
* release candidate, paper build numbers) and Bukkit metadata (revision).
379+
* Revision is ignored because Paper versions do not include the Bukkit revision
380+
* suffix (e.g. {@code -R0.1-SNAPSHOT}).
381+
* This is used to match development builds against their target release version.
382+
*/
383+
public boolean equalsBaseVersion(final BukkitVersion other) {
384+
if (this.snapshot || other.snapshot) {
385+
return false;
386+
}
387+
return this.major == other.major &&
388+
this.minor == other.minor &&
389+
this.patch == other.patch;
390+
}
391+
336392
@Override
337393
public boolean equals(final Object o) {
338394
if (this == o) {
@@ -379,10 +435,16 @@ public String toString() {
379435
sb.append("-snapshot-").append(snapshotRelease);
380436
}
381437
if (preRelease != -1) {
382-
sb.append("-pre").append(preRelease);
438+
sb.append("-pre-").append(preRelease);
383439
}
384440
if (releaseCandidate != -1) {
385-
sb.append("-rc").append(releaseCandidate);
441+
sb.append("-rc-").append(releaseCandidate);
442+
}
443+
if (paperBuild != -1) {
444+
sb.append(".build.").append(paperBuild);
445+
if (releaseChannel != null) {
446+
sb.append("-").append(releaseChannel);
447+
}
386448
}
387449
return sb.append("-R").append(revision).toString();
388450
}
@@ -437,7 +499,13 @@ public int compareTo(final BukkitVersion o) {
437499
} else if (releaseCandidate > o.releaseCandidate) {
438500
return 1;
439501
} else { // equal release candidate
440-
return Double.compare(revision, o.revision);
502+
if (paperBuild < o.paperBuild) {
503+
return -1;
504+
} else if (paperBuild > o.paperBuild) {
505+
return 1;
506+
} else { // equal paper build
507+
return Double.compare(revision, o.revision);
508+
}
441509
}
442510
}
443511
}

0 commit comments

Comments
 (0)