Skip to content

Commit dab50e8

Browse files
committed
feat(compat): Add Bukkit version compatibility check
1 parent ec9cece commit dab50e8

4 files changed

Lines changed: 159 additions & 0 deletions

File tree

core/src/main/kotlin/ECInventoryPlugin.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ package ru.endlesscode.inventory
2121

2222
import org.bukkit.command.CommandSender
2323
import org.bukkit.plugin.java.JavaPlugin
24+
import ru.endlesscode.inventory.internal.compat.BukkitVersion
2425
import ru.endlesscode.inventory.internal.di.DI
2526
import ru.endlesscode.inventory.internal.di.DataModule
2627
import ru.endlesscode.inventory.internal.hook.PlaceholderApiPlaceholders
@@ -69,6 +70,7 @@ public class ECInventoryPlugin : JavaPlugin() {
6970

7071
private fun loadParts(): Boolean {
7172
if (!checkPluginIsEnabled()) return false
73+
if (!BukkitVersion.checkCompatibility()) return false
7274

7375
return makeSure {
7476
initHooks()
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* This file is part of ECInventory
3+
* <https://github.com/EndlessCodeGroup/ECInventory>.
4+
* Copyright (c) 2022 EndlessCode Group and contributors
5+
*
6+
* ECInventory is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Affero General Public License as
8+
* published by the Free Software Foundation, either version 3 of the
9+
* License, or (at your option) any later version.
10+
*
11+
* ECInventory is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Affero General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Affero General Public License
17+
* along with ECInventory. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
package ru.endlesscode.inventory.internal.compat
21+
22+
import org.bukkit.Bukkit
23+
import ru.endlesscode.inventory.internal.util.Log
24+
25+
internal object BukkitVersion {
26+
27+
private const val VERSION_1_16_5 = 1_16_05
28+
private const val VERSION_1_19 = 1_19_00
29+
30+
private val versionRegex = Regex("(?<version>\\d\\.\\d{1,2}(\\.\\d)?)-.*")
31+
private val version by lazy { initVersionCode() }
32+
33+
fun checkCompatibility(): Boolean {
34+
return when {
35+
version < VERSION_1_16_5 -> {
36+
Log.e(
37+
"Minimal required Bukkit version is 1.16.5 because ECInventory uses libraries",
38+
"loading feature. Current version is $version.",
39+
)
40+
false
41+
}
42+
43+
version >= VERSION_1_19 -> {
44+
Log.w(
45+
"ECInventory is not tested with Bukkit $version,",
46+
"please report any problems you find.",
47+
)
48+
true
49+
}
50+
51+
else -> true
52+
}
53+
}
54+
55+
private fun initVersionCode(): Version {
56+
val result = checkNotNull(versionRegex.matchEntire(Bukkit.getBukkitVersion()))
57+
val versionString = checkNotNull(result.groups["version"]?.value)
58+
return Version.parseVersion(versionString)
59+
}
60+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* This file is part of ECInventory
3+
* <https://github.com/EndlessCodeGroup/ECInventory>.
4+
* Copyright (c) 2022 EndlessCode Group and contributors
5+
*
6+
* ECInventory is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Affero General Public License as
8+
* published by the Free Software Foundation, either version 3 of the
9+
* License, or (at your option) any later version.
10+
*
11+
* ECInventory is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Affero General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Affero General Public License
17+
* along with ECInventory. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
package ru.endlesscode.inventory.internal.compat
21+
22+
/**
23+
* Constructs Version object from the given data according to semantic versioning.
24+
*
25+
* @param major Major version.
26+
* @param minor Minor version.
27+
* @param patch Patch version.
28+
* @param qualifier Qualifier, or empty string if qualifier not exists.
29+
* @throws IllegalArgumentException when passed negative version codes.
30+
*/
31+
internal data class Version(
32+
val major: Int,
33+
val minor: Int,
34+
val patch: Int,
35+
val qualifier: String = "",
36+
) : Comparable<Version> {
37+
38+
/**
39+
* Returns version code in format xxyyzz, where x - major version, y - minor and z - patch.
40+
* Example:
41+
* 1.12.2 -> 11202
42+
* 21.0.12 -> 210012
43+
* 1.9 -> 10900
44+
* 2.2.1 -> 20201
45+
* Major, minor and patch versions shouldn't be higher than 99.
46+
*/
47+
val versionCode: Int
48+
get() = major * 10000 + minor * 100 + patch
49+
50+
init {
51+
require(major >= 0 && minor >= 0 && patch >= 0) { "Version can't include negative numbers" }
52+
}
53+
54+
operator fun compareTo(other: Int): Int = versionCode.compareTo(other)
55+
operator fun compareTo(other: String): Int = this.compareTo(parseVersion(other))
56+
57+
override operator fun compareTo(other: Version): Int = COMPARATOR.compare(this, other)
58+
59+
override fun toString(): String {
60+
val qualifier = if (qualifier.isEmpty()) "" else "-$qualifier"
61+
return "$major.$minor.$patch$qualifier"
62+
}
63+
64+
companion object {
65+
66+
private val COMPARATOR = compareBy<Version> { it.major }
67+
.thenBy { it.minor }
68+
.thenBy { it.patch }
69+
70+
/**
71+
* Parses version from the given string.
72+
*
73+
* @param version String representation of version.
74+
* @return The constructed version.
75+
* @throws IllegalArgumentException If passed string with wrong format.
76+
*/
77+
fun parseVersion(version: String): Version {
78+
var parts = version.split("-", limit = 2)
79+
val qualifier = if (parts.size > 1) parts[1] else ""
80+
81+
parts = parts[0].split("\\.", limit = 3)
82+
return try {
83+
val patch = if (parts.size > 2) parts[2].toInt() else 0
84+
val minor = if (parts.size > 1) parts[1].toInt() else 0
85+
val major = parts[0].toInt()
86+
Version(major, minor, patch, qualifier)
87+
} catch (e: NumberFormatException) {
88+
throw IllegalArgumentException("Can not parse version string: $version", e)
89+
}
90+
}
91+
}
92+
}

core/src/main/kotlin/internal/util/Log.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ internal object Log {
4141
messages.forEach { logger?.warning(it) }
4242
}
4343

44+
/** Writes error message to log. */
45+
fun e(vararg messages: String) {
46+
messages.forEach { logger?.severe(it) }
47+
}
48+
4449
/** Writes error message to log. */
4550
fun e(message: String, throwable: Throwable) {
4651
logger?.log(Level.SEVERE, message, throwable)

0 commit comments

Comments
 (0)