|
25 | 25 | package com.github.juliarn.npclib.bukkit; |
26 | 26 |
|
27 | 27 | import com.github.juliarn.npclib.api.PlatformVersionAccessor; |
28 | | -import io.papermc.lib.PaperLib; |
| 28 | +import io.papermc.paper.ServerBuildInfo; |
| 29 | +import java.util.regex.Matcher; |
| 30 | +import java.util.regex.Pattern; |
| 31 | +import org.bukkit.Bukkit; |
| 32 | +import org.jetbrains.annotations.NotNull; |
29 | 33 |
|
30 | | -public final class BukkitVersionAccessor { |
| 34 | +public final class BukkitVersionAccessor implements PlatformVersionAccessor { |
31 | 35 |
|
32 | | - private BukkitVersionAccessor() { |
33 | | - throw new UnsupportedOperationException(); |
34 | | - } |
| 36 | + /** |
| 37 | + * Regex for any {@code number.number.number} combination, where the last number is optional. |
| 38 | + */ |
| 39 | + private static final Pattern MC_VERSION_PATTERN = Pattern.compile("(\\d+)\\.(\\d+)\\.?(\\d+)?"); |
| 40 | + /** |
| 41 | + * Regex for the bukkit mc version representation. |
| 42 | + */ |
| 43 | + private static final Pattern BUKKIT_VERSION_PATTERN = Pattern.compile("\\(MC: (\\d+)\\.(\\d+)\\.?(\\d+)?"); |
| 44 | + |
| 45 | + /** |
| 46 | + * The version string that couldn't be parsed when no default instance could be constructed. {@code null} in case a |
| 47 | + * default instance was constructed successfully. |
| 48 | + */ |
| 49 | + private static final String FAILED_PARSE_INPUT; |
| 50 | + /** |
| 51 | + * Default instance parsed from a version string. {@code null} in case the version input string couldn't be converted |
| 52 | + * to a SemVer version. In this case the failed parse input field is non-null and holds the parse input that failed. |
| 53 | + */ |
| 54 | + private static final PlatformVersionAccessor DEFAULT_INSTANCE; |
35 | 55 |
|
36 | | - public static PlatformVersionAccessor versionAccessor() { |
37 | | - return PaperLibPlatformVersionAccessor.INSTANCE; |
| 56 | + static { |
| 57 | + Matcher versionMatcher; |
| 58 | + try { |
| 59 | + // try to use the modern approach via Paper ServerBuildInfo |
| 60 | + ServerBuildInfo buildInfo = ServerBuildInfo.buildInfo(); |
| 61 | + versionMatcher = MC_VERSION_PATTERN.matcher(buildInfo.minecraftVersionId()); |
| 62 | + } catch (Throwable throwable) { |
| 63 | + // use the legacy approach via Bukkit.getVersion() |
| 64 | + versionMatcher = BUKKIT_VERSION_PATTERN.matcher(Bukkit.getVersion()); |
| 65 | + } |
| 66 | + |
| 67 | + if (versionMatcher.find()) { |
| 68 | + String major = versionMatcher.group(1); |
| 69 | + String minor = versionMatcher.group(2); |
| 70 | + String patch = versionMatcher.group(3); |
| 71 | + DEFAULT_INSTANCE = new BukkitVersionAccessor( |
| 72 | + Integer.parseInt(major), |
| 73 | + Integer.parseInt(minor), |
| 74 | + patch == null ? 0 : Integer.parseInt(patch)); |
| 75 | + FAILED_PARSE_INPUT = null; |
| 76 | + } else { |
| 77 | + DEFAULT_INSTANCE = null; |
| 78 | + FAILED_PARSE_INPUT = versionMatcher.replaceAll(""); // this returns the full text when there is no match |
| 79 | + } |
38 | 80 | } |
39 | 81 |
|
40 | | - private static final class PaperLibPlatformVersionAccessor implements PlatformVersionAccessor { |
| 82 | + private final int major; |
| 83 | + private final int minor; |
| 84 | + private final int patch; |
41 | 85 |
|
42 | | - private static final PaperLibPlatformVersionAccessor INSTANCE = new PaperLibPlatformVersionAccessor(); |
| 86 | + public BukkitVersionAccessor(int major, int minor, int patch) { |
| 87 | + this.major = major; |
| 88 | + this.minor = minor; |
| 89 | + this.patch = patch; |
| 90 | + } |
43 | 91 |
|
44 | | - @Override |
45 | | - public int major() { |
46 | | - return 1; |
47 | | - } |
| 92 | + public static boolean hasDefaultAccessor() { |
| 93 | + return DEFAULT_INSTANCE != null; |
| 94 | + } |
48 | 95 |
|
49 | | - @Override |
50 | | - public int minor() { |
51 | | - return PaperLib.getMinecraftVersion(); |
| 96 | + public static @NotNull PlatformVersionAccessor versionAccessor() { |
| 97 | + if (DEFAULT_INSTANCE != null) { |
| 98 | + return DEFAULT_INSTANCE; |
52 | 99 | } |
53 | 100 |
|
54 | | - @Override |
55 | | - public int patch() { |
56 | | - return PaperLib.getMinecraftPatchVersion(); |
| 101 | + throw new IllegalStateException("Version is not available as '" + FAILED_PARSE_INPUT + "' couldn't be parsed"); |
| 102 | + } |
| 103 | + |
| 104 | + @Override |
| 105 | + public int major() { |
| 106 | + return this.major; |
| 107 | + } |
| 108 | + |
| 109 | + @Override |
| 110 | + public int minor() { |
| 111 | + return this.minor; |
| 112 | + } |
| 113 | + |
| 114 | + @Override |
| 115 | + public int patch() { |
| 116 | + return this.patch; |
| 117 | + } |
| 118 | + |
| 119 | + @Override |
| 120 | + public boolean atLeast(int major, int minor, int patch) { |
| 121 | + if (this.major != major) { |
| 122 | + return this.major > major; |
57 | 123 | } |
58 | 124 |
|
59 | | - @Override |
60 | | - public boolean atLeast(int major, int minor, int patch) { |
61 | | - return PaperLib.isVersion(minor, patch); |
| 125 | + if (this.minor != minor) { |
| 126 | + return this.minor > minor; |
62 | 127 | } |
| 128 | + |
| 129 | + return this.patch >= patch; |
63 | 130 | } |
64 | 131 | } |
0 commit comments