diff --git a/build.gradle.kts b/build.gradle.kts index 5d70d1e..ac81dcb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } group = "cn.hamster3.mc.plugin" -version = "1.3.5" +version = "1.4.0" description = "叁只仓鼠的 Minecraft 插件开发通用工具包" subprojects { diff --git a/core-bukkit/build.gradle.kts b/core-bukkit/build.gradle.kts index 557a5e1..52441a0 100644 --- a/core-bukkit/build.gradle.kts +++ b/core-bukkit/build.gradle.kts @@ -1,6 +1,9 @@ @file:Suppress("VulnerableLibrariesLocal") evaluationDependsOn(":core-common") +evaluationDependsOn(":core-relocate-lettuce") + +val shade = configurations.create("shade") dependencies { api(project(":core-common")) { isTransitive = false } @@ -10,26 +13,31 @@ dependencies { compileOnly("org.black_ixx:playerpoints:3.2.6") { isTransitive = false } compileOnly("me.clip:placeholderapi:2.11.5") { isTransitive = false } + // https://www.spigotmc.org/resources/nbt-api.7939/ + implementation("de.tr7zw:item-nbt-api:2.15.1") + api("net.kyori:adventure-platform-bukkit:4.3.2") { exclude(group = "org.jetbrains") exclude(group = "com.google.code.gson") + exclude(group = "io.netty") } api("net.kyori:adventure-text-minimessage:4.15.0") { exclude(module = "adventure-api") exclude(group = "org.jetbrains") + exclude(group = "io.netty") } - // https://mvnrepository.com/artifact/redis.clients/jedis + + implementation("com.zaxxer:HikariCP:4.0.3") { exclude(group = "org.slf4j") } api("redis.clients:jedis:5.1.4") { exclude(group = "com.google.code.gson") exclude(group = "org.slf4j") } - - // https://www.spigotmc.org/resources/nbt-api.7939/ - implementation("de.tr7zw:item-nbt-api:2.13.2") - // https://mvnrepository.com/artifact/com.zaxxer/HikariCP - implementation("com.zaxxer:HikariCP:4.0.3") { exclude(group = "org.slf4j") } + compileOnlyApi("io.lettuce:lettuce-core:6.7.1.RELEASE") { + exclude(group = "org.slf4j") + exclude(group = "io.netty") + } + shade(project(":core-relocate-lettuce")) } - tasks { processResources { filesMatching("plugin.yml") { @@ -40,6 +48,13 @@ tasks { archiveBaseName = "HamsterCore-Bukkit" } shadowJar { + dependsOn(":core-relocate-lettuce:shadowJar") + val task = project(":core-relocate-lettuce").tasks.shadowJar.get() + from(task.outputs.files.map { + if (it.isDirectory) it else zipTree( + it + ) + }) destinationDirectory = rootProject.layout.buildDirectory relocate("de.tr7zw.changeme.nbtapi", "cn.hamster3.mc.plugin.core.lib.de.tr7zw.nbtapi") relocate("de.tr7zw.annotations", "cn.hamster3.mc.plugin.core.lib.de.tr7zw.nbtapi.annotations") diff --git a/core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/HamsterCorePlugin.java b/core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/HamsterCorePlugin.java index b7e8e3e..b4bfebd 100644 --- a/core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/HamsterCorePlugin.java +++ b/core-bukkit/src/main/java/cn/hamster3/mc/plugin/core/bukkit/HamsterCorePlugin.java @@ -132,6 +132,7 @@ public class HamsterCorePlugin extends JavaPlugin { long start = System.currentTimeMillis(); if (CoreAPI.getInstance().isEnableRedis()) { CoreAPI.getInstance().getJedisPool().close(); + CoreAPI.getInstance().getRedisClient().close(); simpleLogger.info("已关闭 Redis 连接池"); } if (CoreAPI.getInstance().isEnableDatabase()) { diff --git a/core-bungee/build.gradle.kts b/core-bungee/build.gradle.kts index c6d5a2f..21b7f20 100644 --- a/core-bungee/build.gradle.kts +++ b/core-bungee/build.gradle.kts @@ -14,13 +14,16 @@ dependencies { exclude(module = "adventure-api") exclude(group = "org.jetbrains") } - // https://mvnrepository.com/artifact/redis.clients/jedis + + implementation("com.zaxxer:HikariCP:4.0.3") { exclude(group = "org.slf4j") } api("redis.clients:jedis:5.1.4") { exclude(group = "com.google.code.gson") exclude(group = "org.slf4j") } - - implementation("com.zaxxer:HikariCP:4.0.3") { exclude(group = "org.slf4j") } + api("io.lettuce:lettuce-core:6.7.1.RELEASE") { + exclude(group = "io.netty") + exclude(group = "org.slf4j") + } } tasks { diff --git a/core-bungee/src/main/java/cn/hamster3/mc/plugin/core/bungee/HamsterCorePlugin.java b/core-bungee/src/main/java/cn/hamster3/mc/plugin/core/bungee/HamsterCorePlugin.java index 75b2a8a..3c58942 100644 --- a/core-bungee/src/main/java/cn/hamster3/mc/plugin/core/bungee/HamsterCorePlugin.java +++ b/core-bungee/src/main/java/cn/hamster3/mc/plugin/core/bungee/HamsterCorePlugin.java @@ -72,6 +72,7 @@ public class HamsterCorePlugin extends Plugin { long start = System.currentTimeMillis(); if (CoreAPI.getInstance().isEnableRedis()) { CoreAPI.getInstance().getJedisPool().close(); + CoreAPI.getInstance().getRedisClient().close(); simpleLogger.info("已关闭 Redis 连接池"); } if (CoreAPI.getInstance().isEnableDatabase()) { diff --git a/core-common/build.gradle.kts b/core-common/build.gradle.kts index c605abc..fea73de 100644 --- a/core-common/build.gradle.kts +++ b/core-common/build.gradle.kts @@ -17,14 +17,18 @@ dependencies { exclude(group = "com.google.code.gson") } + // https://mvnrepository.com/artifact/com.zaxxer/HikariCP + compileOnly("com.zaxxer:HikariCP:4.0.3") { isTransitive = false } // https://mvnrepository.com/artifact/redis.clients/jedis compileOnlyApi("redis.clients:jedis:5.1.4") { exclude(group = "com.google.code.gson") exclude(group = "org.slf4j") } - - // https://mvnrepository.com/artifact/com.zaxxer/HikariCP - compileOnly("com.zaxxer:HikariCP:4.0.3") { isTransitive = false } + // https://mvnrepository.com/artifact/io.lettuce/lettuce-core + compileOnlyApi("io.lettuce:lettuce-core:6.7.1.RELEASE") { + exclude(group = "io.netty") + exclude(group = "org.slf4j") + } } tasks { diff --git a/core-common/src/main/java/cn/hamster3/mc/plugin/core/common/api/CoreAPI.java b/core-common/src/main/java/cn/hamster3/mc/plugin/core/common/api/CoreAPI.java index 6676b08..c186b90 100644 --- a/core-common/src/main/java/cn/hamster3/mc/plugin/core/common/api/CoreAPI.java +++ b/core-common/src/main/java/cn/hamster3/mc/plugin/core/common/api/CoreAPI.java @@ -6,6 +6,9 @@ import cn.hamster3.mc.plugin.core.common.util.CoreUtils; import cn.hamster3.mc.plugin.core.common.util.SimpleLogger; import com.google.gson.Gson; import com.zaxxer.hikari.HikariDataSource; +import io.lettuce.core.RedisClient; +import io.lettuce.core.api.StatefulRedisConnection; +import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; import lombok.Getter; import net.kyori.adventure.platform.AudienceProvider; import org.jetbrains.annotations.NotNull; @@ -41,6 +44,11 @@ public abstract class CoreAPI { */ @Nullable private JedisPool jedisPool; + /** + * Lettuce Redis 连接池 + */ + @Nullable + private RedisClient redisClient; /** * 公用数据库连接池 */ @@ -57,6 +65,7 @@ public abstract class CoreAPI { if (enableRedis) { logger.info("正在创建 Redis 连接池"); jedisPool = new JedisPool(config.getString("redis-url")); + redisClient = RedisClient.create(config.getString("redis-url")); logger.info("Redis 连接池创建完成"); } else { logger.info("未启用 Redis 功能"); @@ -108,6 +117,24 @@ public abstract class CoreAPI { throw new IllegalStateException("仓鼠核心未启用 Redis 功能"); } + @NotNull + public RedisClient getRedisClient() { + if (redisClient != null) { + return redisClient; + } + throw new IllegalStateException("仓鼠核心未启用 Redis 功能"); + } + + @NotNull + public StatefulRedisConnection getRedisConnect() { + return getRedisClient().connect(); + } + + @NotNull + public StatefulRedisPubSubConnection getRedisPubSub() { + return getRedisClient().connectPubSub(); + } + @NotNull public abstract SimpleLogger getLogger(); diff --git a/core-relocate-lettuce/build.gradle.kts b/core-relocate-lettuce/build.gradle.kts new file mode 100644 index 0000000..3a0c25e --- /dev/null +++ b/core-relocate-lettuce/build.gradle.kts @@ -0,0 +1,21 @@ +// lettuce-core 需要使用 netty,但低版本 bukkit 服务端核心自带的 netty 版本 lettuce 需要的版本有冲突 +// 所以必须 shadow 并 relocate 依赖 io.netty,才能保证两个版本互不冲突 +// 但由于 core-bukkit 同时也 shadow 了 adventure-platform-bukkit,且 adventure 内部通过反射调用 netty +// 如果在 core-bukkit 中直接 relocate netty,会导致 adventure 的反射调用也指向 relocate 后的 netty +// 此时会导致 shadow 后的 adventure 与服务端中其他同样需要使用 netty 的插件关联时发生冲突 +// 例如:服务端上安装了 ViaVersion 时,core-bukkit 内置的 adventure 将会与其发生冲突 +// 因为 adventure 使用 relocate 之后的类路径,ViaVersion 在将类转换成原版 netty 类时,会发生 ClassCastException +// 所以只能先将 lettuce-core 与其需要的 netty 一起打包,并 relocate netty,然后再使 core-bukkit 依赖这个打包后的版本 +// 才能使得 adventure 与 lettuce-core 正常运行 + +dependencies { + implementation("io.lettuce:lettuce-core:6.7.1.RELEASE") { + exclude(group = "org.slf4j") + } +} + +tasks { + shadowJar { + relocate("io.netty", "cn.hamster3.mc.plugin.core.lib.io.netty") + } +} \ No newline at end of file diff --git a/core-velocity/build.gradle.kts b/core-velocity/build.gradle.kts index b63587b..1aada52 100644 --- a/core-velocity/build.gradle.kts +++ b/core-velocity/build.gradle.kts @@ -9,17 +9,18 @@ dependencies { compileOnlyApi("net.kyori:adventure-platform-api:4.3.2") { isTransitive = false } - // https://mvnrepository.com/artifact/redis.clients/jedis + implementation("com.zaxxer:HikariCP:5.1.0") { isTransitive = false } api("redis.clients:jedis:5.1.4") { exclude(group = "com.google.code.gson") exclude(group = "org.slf4j") } - - // https://mvnrepository.com/artifact/com.zaxxer/HikariCP - implementation("com.zaxxer:HikariCP:5.1.0") { isTransitive = false } + api("io.lettuce:lettuce-core:6.7.1.RELEASE") { + exclude(group = "io.netty") + exclude(group = "org.slf4j") + } // https://mvnrepository.com/artifact/com.mysql/mysql-connector-j - runtimeOnly("com.mysql:mysql-connector-j:8.3.0") + runtimeOnly("com.mysql:mysql-connector-j:8.4.0") } sourceSets.create("templates") { diff --git a/core-velocity/src/main/java/cn/hamster3/mc/plugin/core/velocity/HamsterCorePlugin.java b/core-velocity/src/main/java/cn/hamster3/mc/plugin/core/velocity/HamsterCorePlugin.java index de2b8df..5b8c5ae 100644 --- a/core-velocity/src/main/java/cn/hamster3/mc/plugin/core/velocity/HamsterCorePlugin.java +++ b/core-velocity/src/main/java/cn/hamster3/mc/plugin/core/velocity/HamsterCorePlugin.java @@ -85,6 +85,7 @@ public class HamsterCorePlugin { long start = System.currentTimeMillis(); if (CoreAPI.getInstance().isEnableRedis()) { CoreAPI.getInstance().getJedisPool().close(); + CoreAPI.getInstance().getRedisClient().close(); simpleLogger.info("已关闭 Redis 连接池"); } if (CoreAPI.getInstance().isEnableDatabase()) { diff --git a/settings.gradle.kts b/settings.gradle.kts index ed5892d..afbb4c3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,8 +1,6 @@ pluginManagement { repositories { - maven { - url = uri("https://maven.airgame.net/maven-public/") - } + maven("https://maven.airgame.net/maven-public/") } } rootProject.name = "hamster-core" @@ -10,3 +8,4 @@ include("core-common") include("core-bukkit") include("core-bungee") include("core-velocity") +include("core-relocate-lettuce") \ No newline at end of file