From 4d481edcb2658e6193c3828ae19072d29bf7df77 Mon Sep 17 00:00:00 2001 From: ch4ika Date: Tue, 25 Aug 2026 10:30:34 +0200 Subject: [PATCH 1/2] Tolerate non-numeric segments in Bukkit.getBukkitVersion() when resolving McVersion Some server forks append build/commit metadata as extra dot-separated segments (e.g. "26.2.build.17406-6bc38be"), which is not numeric and made the McVersion static initializer throw a NumberFormatException, permanently breaking any feature that touches this class (anvil input included) for the lifetime of the classloader. McVersion now reads only the leading run of numeric major[.minor[.patch]] segments and ignores anything after the first non-numeric one. --- .../runtime/thirdparty/McVersion.java | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/inventory-framework-platform-bukkit/src/main/java/me/devnatan/inventoryframework/runtime/thirdparty/McVersion.java b/inventory-framework-platform-bukkit/src/main/java/me/devnatan/inventoryframework/runtime/thirdparty/McVersion.java index 276e1f13..9f00ebb2 100644 --- a/inventory-framework-platform-bukkit/src/main/java/me/devnatan/inventoryframework/runtime/thirdparty/McVersion.java +++ b/inventory-framework-platform-bukkit/src/main/java/me/devnatan/inventoryframework/runtime/thirdparty/McVersion.java @@ -1,33 +1,36 @@ package me.devnatan.inventoryframework.runtime.thirdparty; import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.bukkit.Bukkit; public class McVersion implements Comparable { + private static final Pattern LEADING_VERSION = + Pattern.compile("(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?"); + private static final McVersion CURRENT_VERSION; static { - final int currentMajor = Integer.parseInt(Bukkit.getBukkitVersion().split("\\.")[0]); - final int currentMinor = - Integer.parseInt(Bukkit.getBukkitVersion().split("\\.")[1].split("-")[0]); - boolean hasPatch = countColons(Bukkit.getBukkitVersion()) == 3; - final int currentPatch = hasPatch - ? Integer.parseInt(Bukkit.getBukkitVersion().split("\\.")[2].split("-")[0]) - : 0; - - CURRENT_VERSION = new McVersion(currentMajor, currentMinor, currentPatch); - } - - private static int countColons(final String string) { - int count = 0; - char[] arr = string.toCharArray(); - for (int i = 0; i < string.length(); i++) { - if (arr[i] == '.') { - count++; - } + CURRENT_VERSION = parse(Bukkit.getBukkitVersion()); + } + + /** + * Reads only the leading run of dot-separated numeric segments (major[.minor[.patch]]), + * so a build/commit suffix appended by a non-standard server fork (e.g. "26.2.build.17406-6bc38be") + * is ignored instead of throwing a {@link NumberFormatException} out of a static initializer. + */ + private static McVersion parse(final String version) { + final Matcher matcher = LEADING_VERSION.matcher(version); + if (!matcher.lookingAt()) { + return new McVersion(1, 0, 0); } - return count; + + final int major = Integer.parseInt(matcher.group(1)); + final int minor = matcher.group(2) != null ? Integer.parseInt(matcher.group(2)) : 0; + final int patch = matcher.group(3) != null ? Integer.parseInt(matcher.group(3)) : 0; + return new McVersion(major, minor, patch); } private final int major; From 66d780688a432700f1ed8d89bbb67c72fdd33b76 Mon Sep 17 00:00:00 2001 From: ch4ika Date: Tue, 25 Aug 2026 10:30:42 +0200 Subject: [PATCH 2/2] Run the fallback git-tag lookup in the project directory providers.exec defaults to the Gradle process's working directory, not the project directory, so nextGitTag() ran 'git describe' against whatever repository the build happened to be invoked from. That only worked by coincidence when this project was built standalone from its own root; included as a composite build from another project it ran git against the wrong repository and failed. --- build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle.kts b/build.gradle.kts index 8a049f55..b1b7c42a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,6 +13,7 @@ version = property("version") @Suppress("UnstableApiUsage") fun Project.nextGitTag(): String { val latestTag = providers.exec { + workingDir(project.projectDir) commandLine("git", "describe", "--tags", "--abbrev=0") }.standardOutput.asText.get().trim()