Fix VersionMatcher not parsing version string correctly

This commit is contained in:
天クマ 2026-05-23 21:49:38 -03:00
commit 425599ff62
5 changed files with 78 additions and 54 deletions

View file

@ -19,10 +19,13 @@ public class Main extends JavaPlugin {
versionedServiceFactory = new DefaultVersionedServiceFactory(versionMatcher);
ServiceLoader<VersionedServiceRegistrar> registrars = ServiceLoader.load(VersionedServiceRegistrar.class);
ServiceLoader<VersionedServiceRegistrar> registrars = ServiceLoader.load(VersionedServiceRegistrar.class, getClassLoader());
int count = 0;
for (VersionedServiceRegistrar registrar : registrars) {
registrar.register(versionedServiceFactory);
count++;
}
getLogger().info("Registered " + count + " version-specific registrars.");
getLogger().info("tenkumaLib has been enabled!");
}

View file

@ -23,12 +23,19 @@ public class DefaultVersionedServiceFactory implements VersionedServiceFactory {
@SuppressWarnings("unchecked")
public <T> T getService(Class<T> serviceType) {
String serverVersion = versionMatcher.getServerVersion();
String versionSuffix = versionMatcher.getClassSuffix(serverVersion);
java.util.List<String> versionSuffixes = versionMatcher.getClassSuffixes(serverVersion);
Map<String, Supplier<?>> versionSuppliers = serviceRegistrations.get(serviceType);
if (versionSuppliers == null || !versionSuppliers.containsKey(versionSuffix)) {
throw new IllegalStateException("No service registered for type " + serviceType.getName() + " and version " + versionSuffix + ". Current server version: " + serverVersion);
if (versionSuppliers == null) {
throw new IllegalStateException("No service registered for type " + serviceType.getName());
}
return (T) versionSuppliers.get(versionSuffix).get();
for (String suffix : versionSuffixes) {
if (versionSuppliers.containsKey(suffix)) {
return (T) versionSuppliers.get(suffix).get();
}
}
throw new IllegalStateException("No service registered for type " + serviceType.getName() + " and versions " + versionSuffixes + ". Current server version: " + serverVersion);
}
}

View file

@ -5,7 +5,7 @@ import org.bukkit.Bukkit;
import java.util.Comparator;
import java.util.List;
import java.util.ArrayList;
import java.util.Optional;
import java.util.Collections;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
@ -15,9 +15,9 @@ public class VersionMatcher {
private record Entry(String pattern, String classSuffix, int minMajor, int minMinor, int maxMajor, int maxMinor) {}
public String getClassSuffix(String serverVersion) {
public List<String> getClassSuffixes(String serverVersion) {
if (serverVersion == null) {
return null;
return Collections.emptyList();
}
List<Entry> entries = populateEntries();
@ -30,22 +30,24 @@ public class VersionMatcher {
for (Entry entry : entries) {
Pattern p = Pattern.compile(entry.pattern());
if (p.matcher(serverVersion).matches()) {
if (serverMajor >= entry.minMajor() && serverMinor >= entry.minMinor() &&
serverMajor <= entry.maxMajor() && serverMinor <= entry.maxMinor()) {
applicableEntries.add(entry);
if (serverMajor > entry.minMajor() || (serverMajor == entry.minMajor() && serverMinor >= entry.minMinor())) {
if (serverMajor < entry.maxMajor() || (serverMajor == entry.maxMajor() && serverMinor <= entry.maxMinor())) {
applicableEntries.add(entry);
}
}
}
}
applicableEntries.sort(Comparator
.comparing(Entry::maxMajor).reversed()
.thenComparing(Entry::maxMinor).reversed()
.thenComparing(Entry::minMajor).reversed()
.thenComparing(Entry::minMinor).reversed());
applicableEntries.sort((a, b) -> {
if (a.minMajor() != b.minMajor()) {
return Integer.compare(b.minMajor(), a.minMajor());
}
return Integer.compare(b.minMinor(), a.minMinor());
});
Optional<Entry> bestMatch = applicableEntries.stream().findFirst();
return bestMatch.map(Entry::classSuffix).orElse(null);
return applicableEntries.stream()
.map(Entry::classSuffix)
.toList();
}
public String getServerVersion() {
@ -70,12 +72,12 @@ public class VersionMatcher {
private List<Entry> populateEntries() {
return List.of(
new Entry("^1\\.7\\.3$", "b1_7_3", 1, 7, 1, 7),
// r1_1 covers versions from 1.1.x up to 1.16.4
new Entry("^1\\.(1[0-5]|[1-9])(\\.\\d+)*$", "r1_1", 1, 1, 1, 16),
// r1_16_5 covers versions from 1.16.5 up to 1.20.x
new Entry("^1\\.(16\\.[5-9]|1[7-9]|20)(\\.\\d+)*$", "r1_16_5", 1, 16, 1, 20),
// r1_21 covers 1.21.x and above
new Entry("^1\\.21(\\.\\d+)*$", "r1_21", 1, 21, Integer.MAX_VALUE, Integer.MAX_VALUE)
// r1_1 covers versions 1.1 and above
new Entry("^1\\.\\d+(\\.\\d+)*$", "r1_1", 1, 1, Integer.MAX_VALUE, Integer.MAX_VALUE),
// r1_16_5 covers versions 1.16.5 and above
new Entry("^1\\.(16\\.[5-9]|1[7-9]|[2-9]\\d)(\\.\\d+)*$", "r1_16_5", 1, 16, Integer.MAX_VALUE, Integer.MAX_VALUE),
// r1_21 covers 1.21 and above
new Entry("^1\\.([2-9]\\d)(\\.\\d+)*$", "r1_21", 1, 21, Integer.MAX_VALUE, Integer.MAX_VALUE)
);
}