feat: 将redission更换为lettuce
This commit is contained in:
@@ -8,10 +8,8 @@ dependencies {
|
|||||||
|
|
||||||
compileOnly("cn.hamster3.mc.plugin:core-bukkit:+")
|
compileOnly("cn.hamster3.mc.plugin:core-bukkit:+")
|
||||||
compileOnly("me.clip:placeholderapi:+") { isTransitive = false }
|
compileOnly("me.clip:placeholderapi:+") { isTransitive = false }
|
||||||
|
// https://mvnrepository.com/artifact/io.lettuce/lettuce-core
|
||||||
implementation("org.redisson:redisson:+") {
|
implementation("io.lettuce:lettuce-core:6.2.6.RELEASE")
|
||||||
exclude(group = "org.slf4j")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
@@ -3,48 +3,30 @@ package cn.hamster3.mc.plugin.ball.bukkit.api;
|
|||||||
import cn.hamster3.mc.plugin.ball.bukkit.HamsterBallPlugin;
|
import cn.hamster3.mc.plugin.ball.bukkit.HamsterBallPlugin;
|
||||||
import cn.hamster3.mc.plugin.ball.bukkit.util.BallBukkitUtils;
|
import cn.hamster3.mc.plugin.ball.bukkit.util.BallBukkitUtils;
|
||||||
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
||||||
import cn.hamster3.mc.plugin.ball.common.codec.BallMessageInfoCodec;
|
|
||||||
import cn.hamster3.mc.plugin.ball.common.data.BallMessageInfo;
|
|
||||||
import cn.hamster3.mc.plugin.ball.common.entity.BallServerInfo;
|
import cn.hamster3.mc.plugin.ball.common.entity.BallServerInfo;
|
||||||
import cn.hamster3.mc.plugin.ball.common.entity.BallServerType;
|
import cn.hamster3.mc.plugin.ball.common.entity.BallServerType;
|
||||||
import cn.hamster3.mc.plugin.ball.common.listener.BallDebugListener;
|
|
||||||
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
||||||
|
import io.lettuce.core.RedisClient;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.redisson.Redisson;
|
|
||||||
import org.redisson.api.RTopic;
|
|
||||||
import org.redisson.api.RedissonClient;
|
|
||||||
import org.redisson.config.Config;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.StandardCopyOption;
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class BallBukkitAPI extends BallAPI {
|
public class BallBukkitAPI extends BallAPI {
|
||||||
@Nullable
|
public BallBukkitAPI(@NotNull BallServerInfo localServerInfo, @Nullable DataSource datasource, @NotNull RedisClient redisClient, boolean debug) {
|
||||||
private final DataSource datasource;
|
super(localServerInfo, datasource, redisClient, debug);
|
||||||
@NotNull
|
|
||||||
private final RedissonClient redissonClient;
|
|
||||||
|
|
||||||
public BallBukkitAPI(@NotNull BallServerInfo localServerInfo, @Nullable DataSource datasource, @NotNull RedissonClient redissonClient) {
|
|
||||||
super(localServerInfo);
|
|
||||||
this.datasource = datasource;
|
|
||||||
this.redissonClient = redissonClient;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BallBukkitAPI getInstance() {
|
public static BallBukkitAPI getInstance() {
|
||||||
return (BallBukkitAPI) instance;
|
return (BallBukkitAPI) instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init() throws IOException {
|
public static void init() {
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -74,23 +56,9 @@ public class BallBukkitAPI extends BallAPI {
|
|||||||
datasource = CoreAPI.getInstance().getDataSource();
|
datasource = CoreAPI.getInstance().getDataSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
File redissionConfig = new File(plugin.getDataFolder(), "redission.yml");
|
RedisClient redisClient = RedisClient.create(config.getString("redis-url", "redis://localhost:6379?clientName=HamsterBall"));
|
||||||
if (!redissionConfig.exists()) {
|
|
||||||
Files.copy(
|
|
||||||
Objects.requireNonNull(plugin.getResource("redission.yml")),
|
|
||||||
redissionConfig.toPath(),
|
|
||||||
StandardCopyOption.REPLACE_EXISTING
|
|
||||||
);
|
|
||||||
}
|
|
||||||
RedissonClient redissonClient = Redisson.create(Config.fromYAML(redissionConfig));
|
|
||||||
BallBukkitAPI apiInstance = new BallBukkitAPI(serverInfo, datasource, redissonClient);
|
|
||||||
|
|
||||||
RTopic topic = redissonClient.getTopic(BALL_CHANNEL, BallMessageInfoCodec.INSTANCE);
|
instance = new BallBukkitAPI(serverInfo, datasource, redisClient, config.getBoolean("debug", false));
|
||||||
if (config.getBoolean("debug", false)) {
|
|
||||||
topic.addListener(BallMessageInfo.class, BallDebugListener.INSTANCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
instance = apiInstance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -108,13 +76,4 @@ public class BallBukkitAPI extends BallAPI {
|
|||||||
return HamsterBallPlugin.getInstance().getLogger();
|
return HamsterBallPlugin.getInstance().getLogger();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull DataSource getDatasource() {
|
|
||||||
return datasource == null ? CoreAPI.getInstance().getDataSource() : datasource;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull RedissonClient getRedissonClient() {
|
|
||||||
return redissonClient;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,13 @@
|
|||||||
# 是否允许在控制台输出调试信息
|
# 是否允许在控制台输出调试信息
|
||||||
debug: false
|
debug: false
|
||||||
|
|
||||||
|
# redis 连接配置,连接格式如下:
|
||||||
|
# redis://用户名:密码@主机名:端口/数据库索引?参数名=参数值&参数名=参数值
|
||||||
|
# 若没有设置用户名和密码,则可以省略
|
||||||
|
# 若不设置数据库,则默认使用 0
|
||||||
|
# 详细信息:https://github.com/lettuce-io/lettuce-core/wiki/Redis-URI-and-connection-details
|
||||||
|
redis-url: "redis://localhost:6379?clientName=HamsterBall"
|
||||||
|
|
||||||
server-info:
|
server-info:
|
||||||
# 服务器唯一识别码,最长 32 字符
|
# 服务器唯一识别码,最长 32 字符
|
||||||
# 推荐格式:全小写英文+横杠+数字尾号
|
# 推荐格式:全小写英文+横杠+数字尾号
|
||||||
|
@@ -5,18 +5,8 @@ dependencies {
|
|||||||
compileOnly("net.md-5:bungeecord-api:+")
|
compileOnly("net.md-5:bungeecord-api:+")
|
||||||
|
|
||||||
compileOnly("cn.hamster3.mc.plugin:core-bungeecord:+")
|
compileOnly("cn.hamster3.mc.plugin:core-bungeecord:+")
|
||||||
|
// https://mvnrepository.com/artifact/io.lettuce/lettuce-core
|
||||||
implementation("org.redisson:redisson:+") {
|
implementation("io.lettuce:lettuce-core:6.2.6.RELEASE")
|
||||||
// exclude(group = "io.netty", module="netty-codec")
|
|
||||||
// exclude(group = "io.netty", module="netty-codec-dns")
|
|
||||||
// exclude(group = "io.netty", module="netty-buffer")
|
|
||||||
// exclude(group = "io.netty", module="netty-handler")
|
|
||||||
// exclude(group = "io.netty", module="netty-resolver")
|
|
||||||
// exclude(group = "io.netty", module="netty-transport")
|
|
||||||
// exclude(group = "org.yaml")
|
|
||||||
// exclude(group = "io.netty")
|
|
||||||
exclude(group = "org.slf4j")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
@@ -1,49 +1,32 @@
|
|||||||
package cn.hamster3.mc.plugin.core.bungee.api;
|
package cn.hamster3.mc.plugin.core.bungee.api;
|
||||||
|
|
||||||
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
||||||
import cn.hamster3.mc.plugin.ball.common.codec.BallMessageInfoCodec;
|
|
||||||
import cn.hamster3.mc.plugin.ball.common.data.BallMessageInfo;
|
|
||||||
import cn.hamster3.mc.plugin.ball.common.entity.BallServerInfo;
|
import cn.hamster3.mc.plugin.ball.common.entity.BallServerInfo;
|
||||||
import cn.hamster3.mc.plugin.ball.common.entity.BallServerType;
|
import cn.hamster3.mc.plugin.ball.common.entity.BallServerType;
|
||||||
import cn.hamster3.mc.plugin.ball.common.listener.BallDebugListener;
|
|
||||||
import cn.hamster3.mc.plugin.core.bungee.HamsterBallPlugin;
|
import cn.hamster3.mc.plugin.core.bungee.HamsterBallPlugin;
|
||||||
import cn.hamster3.mc.plugin.core.bungee.util.BallBungeeCordUtils;
|
import cn.hamster3.mc.plugin.core.bungee.util.BallBungeeCordUtils;
|
||||||
import cn.hamster3.mc.plugin.core.bungee.util.CoreBungeeCordUtils;
|
import cn.hamster3.mc.plugin.core.bungee.util.CoreBungeeCordUtils;
|
||||||
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
||||||
|
import io.lettuce.core.RedisClient;
|
||||||
import net.md_5.bungee.config.Configuration;
|
import net.md_5.bungee.config.Configuration;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.redisson.Redisson;
|
|
||||||
import org.redisson.api.RTopic;
|
|
||||||
import org.redisson.api.RedissonClient;
|
|
||||||
import org.redisson.config.Config;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.StandardCopyOption;
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class BallBungeeCordAPI extends BallAPI {
|
public class BallBungeeCordAPI extends BallAPI {
|
||||||
@Nullable
|
public BallBungeeCordAPI(@NotNull BallServerInfo localServerInfo, @Nullable DataSource datasource, @NotNull RedisClient redisClient, boolean debug) {
|
||||||
private final DataSource datasource;
|
super(localServerInfo, datasource, redisClient, debug);
|
||||||
@NotNull
|
|
||||||
private final RedissonClient redissonClient;
|
|
||||||
|
|
||||||
public BallBungeeCordAPI(@NotNull BallServerInfo localServerInfo, @Nullable DataSource datasource, @NotNull RedissonClient redissonClient) {
|
|
||||||
super(localServerInfo);
|
|
||||||
this.datasource = datasource;
|
|
||||||
this.redissonClient = redissonClient;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BallBungeeCordAPI getInstance() {
|
public static BallBungeeCordAPI getInstance() {
|
||||||
return (BallBungeeCordAPI) instance;
|
return (BallBungeeCordAPI) instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init() throws IOException {
|
public static void init() {
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -70,23 +53,9 @@ public class BallBungeeCordAPI extends BallAPI {
|
|||||||
datasource = CoreAPI.getInstance().getDataSource();
|
datasource = CoreAPI.getInstance().getDataSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
File redissionConfig = new File(plugin.getDataFolder(), "redission.yml");
|
RedisClient redisClient = RedisClient.create(config.getString("redis-url", "redis://localhost:6379?clientName=HamsterBall"));
|
||||||
if (!redissionConfig.exists()) {
|
|
||||||
Files.copy(
|
|
||||||
plugin.getResourceAsStream("redission.yml"),
|
|
||||||
redissionConfig.toPath(),
|
|
||||||
StandardCopyOption.REPLACE_EXISTING
|
|
||||||
);
|
|
||||||
}
|
|
||||||
RedissonClient redissonClient = Redisson.create(Config.fromYAML(redissionConfig));
|
|
||||||
BallBungeeCordAPI apiInstance = new BallBungeeCordAPI(serverInfo, datasource, redissonClient);
|
|
||||||
|
|
||||||
if (config.getBoolean("debug", false)) {
|
instance = new BallBungeeCordAPI(serverInfo, datasource, redisClient, config.getBoolean("debug", false));
|
||||||
RTopic topic = redissonClient.getTopic(BALL_CHANNEL, BallMessageInfoCodec.INSTANCE);
|
|
||||||
topic.addListener(BallMessageInfo.class, BallDebugListener.INSTANCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
instance = apiInstance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -103,14 +72,4 @@ public class BallBungeeCordAPI extends BallAPI {
|
|||||||
public @NotNull Logger getLogger() {
|
public @NotNull Logger getLogger() {
|
||||||
return HamsterBallPlugin.getInstance().getLogger();
|
return HamsterBallPlugin.getInstance().getLogger();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull DataSource getDatasource() {
|
|
||||||
return datasource == null ? CoreAPI.getInstance().getDataSource() : datasource;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull RedissonClient getRedissonClient() {
|
|
||||||
return redissonClient;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,13 @@
|
|||||||
# 是否允许在控制台输出调试信息
|
# 是否允许在控制台输出调试信息
|
||||||
debug: false
|
debug: false
|
||||||
|
|
||||||
|
# redis 连接配置,连接格式如下:
|
||||||
|
# redis://用户名:密码@主机名:端口/数据库索引?参数名=参数值&参数名=参数值
|
||||||
|
# 若没有设置用户名和密码,则可以省略
|
||||||
|
# 若不设置数据库,则默认使用 0
|
||||||
|
# 详细信息:https://github.com/lettuce-io/lettuce-core/wiki/Redis-URI-and-connection-details
|
||||||
|
redis-url: "redis://localhost:6379?clientName=HamsterBall"
|
||||||
|
|
||||||
server-info:
|
server-info:
|
||||||
# 服务器唯一识别码,最长 32 字符
|
# 服务器唯一识别码,最长 32 字符
|
||||||
id: "BungeeCord"
|
id: "BungeeCord"
|
||||||
|
@@ -3,15 +3,10 @@
|
|||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("cn.hamster3.mc.plugin:core-common:+")
|
compileOnly("cn.hamster3.mc.plugin:core-common:+")
|
||||||
|
|
||||||
compileOnly("io.netty:netty-buffer:4+")
|
|
||||||
compileOnly("com.google.code.gson:gson:2.8.0")
|
compileOnly("com.google.code.gson:gson:2.8.0")
|
||||||
|
|
||||||
implementation("org.redisson:redisson:+") {
|
// https://mvnrepository.com/artifact/io.lettuce/lettuce-core
|
||||||
isTransitive = false
|
compileOnly("io.lettuce:lettuce-core:6.2.6.RELEASE")
|
||||||
exclude(group = "io.netty")
|
|
||||||
exclude(group = "org.yaml")
|
|
||||||
exclude(group = "org.slf4j")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
package cn.hamster3.mc.plugin.ball.common.api;
|
package cn.hamster3.mc.plugin.ball.common.api;
|
||||||
|
|
||||||
import cn.hamster3.mc.plugin.ball.common.codec.BallMessageInfoCodec;
|
|
||||||
import cn.hamster3.mc.plugin.ball.common.data.BallLocation;
|
import cn.hamster3.mc.plugin.ball.common.data.BallLocation;
|
||||||
import cn.hamster3.mc.plugin.ball.common.data.BallMessageInfo;
|
import cn.hamster3.mc.plugin.ball.common.data.BallMessageInfo;
|
||||||
import cn.hamster3.mc.plugin.ball.common.entity.BallPlayerInfo;
|
import cn.hamster3.mc.plugin.ball.common.entity.BallPlayerInfo;
|
||||||
@@ -11,18 +10,18 @@ import cn.hamster3.mc.plugin.ball.common.event.player.BallPlayerConnectServerEve
|
|||||||
import cn.hamster3.mc.plugin.ball.common.event.player.BallPlayerInfoUpdateEvent;
|
import cn.hamster3.mc.plugin.ball.common.event.player.BallPlayerInfoUpdateEvent;
|
||||||
import cn.hamster3.mc.plugin.ball.common.event.server.ServerOfflineEvent;
|
import cn.hamster3.mc.plugin.ball.common.event.server.ServerOfflineEvent;
|
||||||
import cn.hamster3.mc.plugin.ball.common.event.server.ServerOnlineEvent;
|
import cn.hamster3.mc.plugin.ball.common.event.server.ServerOnlineEvent;
|
||||||
|
import cn.hamster3.mc.plugin.ball.common.listener.BallDebugListener;
|
||||||
import cn.hamster3.mc.plugin.ball.common.listener.BallListener;
|
import cn.hamster3.mc.plugin.ball.common.listener.BallListener;
|
||||||
import cn.hamster3.mc.plugin.ball.common.listener.BallMessageListener;
|
import cn.hamster3.mc.plugin.ball.common.listener.BallMessageListener;
|
||||||
import cn.hamster3.mc.plugin.ball.common.listener.ListenerPriority;
|
import cn.hamster3.mc.plugin.ball.common.listener.ListenerPriority;
|
||||||
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
||||||
import cn.hamster3.mc.plugin.core.common.data.DisplayMessage;
|
import cn.hamster3.mc.plugin.core.common.data.DisplayMessage;
|
||||||
import cn.hamster3.mc.plugin.core.lib.net.kyori.adventure.text.Component;
|
import cn.hamster3.mc.plugin.core.lib.net.kyori.adventure.text.Component;
|
||||||
|
import io.lettuce.core.RedisClient;
|
||||||
|
import io.lettuce.core.pubsub.StatefulRedisPubSubConnection;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.redisson.api.RTopic;
|
|
||||||
import org.redisson.api.RedissonClient;
|
|
||||||
import org.redisson.client.codec.StringCodec;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
@@ -47,19 +46,31 @@ public abstract class BallAPI {
|
|||||||
protected final Map<UUID, BallPlayerInfo> playerInfo;
|
protected final Map<UUID, BallPlayerInfo> playerInfo;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final BallServerInfo localServerInfo;
|
private final BallServerInfo localServerInfo;
|
||||||
|
@Nullable
|
||||||
|
private final DataSource datasource;
|
||||||
|
@NotNull
|
||||||
|
private final RedisClient redisClient;
|
||||||
|
@NotNull
|
||||||
|
private final StatefulRedisPubSubConnection<String, BallMessageInfo> pubSubConnection;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private List<BallListener> listeners;
|
private List<BallListener> listeners;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
|
|
||||||
public BallAPI(@NotNull BallServerInfo localServerInfo) {
|
public BallAPI(@NotNull BallServerInfo localServerInfo, @Nullable DataSource datasource, @NotNull RedisClient redisClient, boolean debug) {
|
||||||
this.localServerInfo = localServerInfo;
|
this.localServerInfo = localServerInfo;
|
||||||
|
this.datasource = datasource;
|
||||||
|
this.redisClient = redisClient;
|
||||||
|
pubSubConnection = redisClient.connectPubSub(BallMessageInfo.CODEC);
|
||||||
serverInfo = new ConcurrentHashMap<>();
|
serverInfo = new ConcurrentHashMap<>();
|
||||||
playerInfo = new ConcurrentHashMap<>();
|
playerInfo = new ConcurrentHashMap<>();
|
||||||
listeners = new ArrayList<>();
|
listeners = new ArrayList<>();
|
||||||
|
enabled = false;
|
||||||
|
initListener(debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initListener(boolean debug) {
|
||||||
addListener(new BallListener() {
|
addListener(new BallListener() {
|
||||||
@Override
|
@Override
|
||||||
public ListenerPriority getPriority() {
|
public ListenerPriority getPriority() {
|
||||||
@@ -129,7 +140,10 @@ public abstract class BallAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
enabled = false;
|
if (debug) {
|
||||||
|
getLogger().warning("已启用调试模式");
|
||||||
|
pubSubConnection.addListener(BallDebugListener.INSTANCE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void enable() throws SQLException, InterruptedException {
|
protected void enable() throws SQLException, InterruptedException {
|
||||||
@@ -201,9 +215,9 @@ public abstract class BallAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RTopic topic = getRedissonClient().getTopic(BALL_CHANNEL, BallMessageInfoCodec.INSTANCE);
|
RedisClient client = getRedisClient();
|
||||||
topic.addListener(BallMessageInfo.class, BallMessageListener.INSTANCE);
|
pubSubConnection.addListener(BallMessageListener.INSTANCE);
|
||||||
|
pubSubConnection.async().subscribe("HamsterBall");
|
||||||
enabled = true;
|
enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +240,7 @@ public abstract class BallAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
getLogger().info("正在关闭 redission...");
|
getLogger().info("正在关闭 redission...");
|
||||||
getRedissonClient().shutdown();
|
getRedisClient().close();
|
||||||
getLogger().info("已关闭 redission.");
|
getLogger().info("已关闭 redission.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -535,11 +549,12 @@ public abstract class BallAPI {
|
|||||||
*/
|
*/
|
||||||
public void sendBallMessage(@NotNull BallMessageInfo messageInfo, boolean block) {
|
public void sendBallMessage(@NotNull BallMessageInfo messageInfo, boolean block) {
|
||||||
String string = CoreAPI.getInstance().getGson().toJson(messageInfo);
|
String string = CoreAPI.getInstance().getGson().toJson(messageInfo);
|
||||||
RTopic topic = getRedissonClient().getTopic(BallAPI.BALL_CHANNEL, StringCodec.INSTANCE);
|
try (StatefulRedisPubSubConnection<String, BallMessageInfo> connection = getRedisClient().connectPubSub(BallMessageInfo.CODEC)) {
|
||||||
if (block) {
|
if (block) {
|
||||||
topic.publish(string);
|
connection.sync().publish("HamsterBall", messageInfo);
|
||||||
} else {
|
} else {
|
||||||
topic.publishAsync(string);
|
connection.async().publish("HamsterBall", messageInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (BallListener listener : BallAPI.getInstance().getListeners()) {
|
for (BallListener listener : BallAPI.getInstance().getListeners()) {
|
||||||
try {
|
try {
|
||||||
@@ -709,8 +724,12 @@ public abstract class BallAPI {
|
|||||||
public abstract Logger getLogger();
|
public abstract Logger getLogger();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public abstract DataSource getDatasource();
|
public DataSource getDatasource() {
|
||||||
|
return datasource == null ? CoreAPI.getInstance().getDataSource() : datasource;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public abstract RedissonClient getRedissonClient();
|
public RedisClient getRedisClient() {
|
||||||
|
return redisClient;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,41 +0,0 @@
|
|||||||
package cn.hamster3.mc.plugin.ball.common.codec;
|
|
||||||
|
|
||||||
import cn.hamster3.mc.plugin.ball.common.data.BallMessageInfo;
|
|
||||||
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
|
||||||
import io.netty.util.CharsetUtil;
|
|
||||||
import org.redisson.client.codec.BaseCodec;
|
|
||||||
import org.redisson.client.protocol.Decoder;
|
|
||||||
import org.redisson.client.protocol.Encoder;
|
|
||||||
import org.redisson.codec.JsonCodec;
|
|
||||||
|
|
||||||
public class BallMessageInfoCodec extends BaseCodec implements JsonCodec<BallMessageInfoCodec> {
|
|
||||||
public static final BallMessageInfoCodec INSTANCE = new BallMessageInfoCodec();
|
|
||||||
|
|
||||||
private final Encoder encoder = in -> {
|
|
||||||
ByteBuf out = ByteBufAllocator.DEFAULT.buffer();
|
|
||||||
out.writeCharSequence(in.toString(), CharsetUtil.UTF_8);
|
|
||||||
return out;
|
|
||||||
};
|
|
||||||
|
|
||||||
private final Decoder<Object> decoder = (buf, state) -> {
|
|
||||||
String str = buf.toString(CharsetUtil.UTF_8);
|
|
||||||
buf.readerIndex(buf.readableBytes());
|
|
||||||
return CoreAPI.getInstance().getGson().fromJson(str, BallMessageInfo.class);
|
|
||||||
};
|
|
||||||
|
|
||||||
private BallMessageInfoCodec() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Decoder<Object> getValueDecoder() {
|
|
||||||
return decoder;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Encoder getValueEncoder() {
|
|
||||||
return encoder;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -6,12 +6,15 @@ import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
|||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import io.lettuce.core.codec.RedisCodec;
|
||||||
|
import io.lettuce.core.codec.StringCodec;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,6 +23,31 @@ import java.util.UUID;
|
|||||||
@Data
|
@Data
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class BallMessageInfo {
|
public class BallMessageInfo {
|
||||||
|
/**
|
||||||
|
* 编解码器
|
||||||
|
*/
|
||||||
|
public static final RedisCodec<String, BallMessageInfo> CODEC = new RedisCodec<String, BallMessageInfo>() {
|
||||||
|
@Override
|
||||||
|
public String decodeKey(ByteBuffer bytes) {
|
||||||
|
return StringCodec.UTF8.decodeKey(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BallMessageInfo decodeValue(ByteBuffer bytes) {
|
||||||
|
String string = StringCodec.UTF8.decodeValue(bytes);
|
||||||
|
return CoreAPI.getInstance().getGson().fromJson(string, BallMessageInfo.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuffer encodeKey(String key) {
|
||||||
|
return StringCodec.UTF8.encodeKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuffer encodeValue(BallMessageInfo value) {
|
||||||
|
return StringCodec.UTF8.encodeValue(CoreAPI.getInstance().getGson().toJson(value));
|
||||||
|
}
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* 消息发送者
|
* 消息发送者
|
||||||
*/
|
*/
|
||||||
|
@@ -2,16 +2,42 @@ package cn.hamster3.mc.plugin.ball.common.listener;
|
|||||||
|
|
||||||
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
||||||
import cn.hamster3.mc.plugin.ball.common.data.BallMessageInfo;
|
import cn.hamster3.mc.plugin.ball.common.data.BallMessageInfo;
|
||||||
import org.redisson.api.listener.MessageListener;
|
import io.lettuce.core.pubsub.RedisPubSubListener;
|
||||||
|
|
||||||
public class BallDebugListener implements MessageListener<BallMessageInfo> {
|
public class BallDebugListener implements RedisPubSubListener<String, BallMessageInfo> {
|
||||||
public static final BallDebugListener INSTANCE = new BallDebugListener();
|
public static final BallDebugListener INSTANCE = new BallDebugListener();
|
||||||
|
|
||||||
private BallDebugListener() {
|
private BallDebugListener() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(CharSequence channel, BallMessageInfo event) {
|
public void message(String channel, BallMessageInfo event) {
|
||||||
BallAPI.getInstance().getLogger().info("收到了一条消息: " + event);
|
BallAPI.getInstance().getLogger().info("从 " + channel + " 收到了一条消息: " + event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void message(String pattern, String channel, BallMessageInfo event) {
|
||||||
|
BallAPI.getInstance().getLogger().info("从 " + pattern + "(" + channel + ") 收到了一条消息: " + event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void subscribed(String channel, long count) {
|
||||||
|
BallAPI.getInstance().getLogger().info("已订阅 redis 频道: " + channel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void psubscribed(String pattern, long count) {
|
||||||
|
BallAPI.getInstance().getLogger().info("已取消订阅 redis 频道(正则): " + pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unsubscribed(String channel, long count) {
|
||||||
|
BallAPI.getInstance().getLogger().info("已取消订阅 redis 频道: " + channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void punsubscribed(String pattern, long count) {
|
||||||
|
BallAPI.getInstance().getLogger().info("已取消订阅 redis 频道(正则): " + pattern);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,16 +6,16 @@ import cn.hamster3.mc.plugin.ball.common.event.player.*;
|
|||||||
import cn.hamster3.mc.plugin.ball.common.event.server.ServerOfflineEvent;
|
import cn.hamster3.mc.plugin.ball.common.event.server.ServerOfflineEvent;
|
||||||
import cn.hamster3.mc.plugin.ball.common.event.server.ServerOnlineEvent;
|
import cn.hamster3.mc.plugin.ball.common.event.server.ServerOnlineEvent;
|
||||||
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
||||||
import org.redisson.api.listener.MessageListener;
|
import io.lettuce.core.pubsub.RedisPubSubListener;
|
||||||
|
|
||||||
public class BallMessageListener implements MessageListener<BallMessageInfo> {
|
public class BallMessageListener implements RedisPubSubListener<String, BallMessageInfo> {
|
||||||
public static final BallMessageListener INSTANCE = new BallMessageListener();
|
public static final BallMessageListener INSTANCE = new BallMessageListener();
|
||||||
|
|
||||||
private BallMessageListener() {
|
private BallMessageListener() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(CharSequence channel, BallMessageInfo info) {
|
public void message(String channel, BallMessageInfo info) {
|
||||||
for (BallListener listener : BallAPI.getInstance().getListeners()) {
|
for (BallListener listener : BallAPI.getInstance().getListeners()) {
|
||||||
try {
|
try {
|
||||||
listener.onMessageReceived(info);
|
listener.onMessageReceived(info);
|
||||||
@@ -139,4 +139,29 @@ public class BallMessageListener implements MessageListener<BallMessageInfo> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void message(String pattern, String channel, BallMessageInfo info) {
|
||||||
|
message(channel, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void subscribed(String channel, long count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void psubscribed(String pattern, long count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unsubscribed(String channel, long count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void punsubscribed(String pattern, long count) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,36 +0,0 @@
|
|||||||
singleServerConfig:
|
|
||||||
address: "redis://localhost:6379"
|
|
||||||
password: "Reids123.."
|
|
||||||
username: "default"
|
|
||||||
database: 1
|
|
||||||
clientName: "HamsterBall"
|
|
||||||
idleConnectionTimeout: 10000
|
|
||||||
connectTimeout: 10000
|
|
||||||
timeout: 3000
|
|
||||||
retryAttempts: 3
|
|
||||||
retryInterval: 1500
|
|
||||||
subscriptionsPerConnection: 5
|
|
||||||
sslEnableEndpointIdentification: true
|
|
||||||
sslProvider: "JDK"
|
|
||||||
pingConnectionInterval: 30000
|
|
||||||
keepAlive: false
|
|
||||||
tcpNoDelay: true
|
|
||||||
subscriptionConnectionMinimumIdleSize: 1
|
|
||||||
subscriptionConnectionPoolSize: 50
|
|
||||||
connectionMinimumIdleSize: 1
|
|
||||||
connectionPoolSize: 10
|
|
||||||
dnsMonitoringInterval: 5000
|
|
||||||
threads: 4
|
|
||||||
nettyThreads: 4
|
|
||||||
referenceEnabled: true
|
|
||||||
lockWatchdogTimeout: 30000
|
|
||||||
checkLockSyncedSlaves: true
|
|
||||||
slavesSyncTimeout: 1000
|
|
||||||
reliableTopicWatchdogTimeout: 600000
|
|
||||||
keepPubSubOrder: true
|
|
||||||
useScriptCache: false
|
|
||||||
minCleanUpDelay: 5
|
|
||||||
maxCleanUpDelay: 1800
|
|
||||||
cleanUpKeysAmount: 100
|
|
||||||
useThreadClassLoader: true
|
|
||||||
lazyInitialization: false
|
|
@@ -24,7 +24,8 @@ subprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.jetbrains:annotations:+")
|
compileOnly("org.jetbrains:annotations:+")
|
||||||
|
// https://mvnrepository.com/artifact/org.projectlombok/lombok
|
||||||
compileOnly("org.projectlombok:lombok:+")
|
compileOnly("org.projectlombok:lombok:+")
|
||||||
annotationProcessor("org.projectlombok:lombok:+")
|
annotationProcessor("org.projectlombok:lombok:+")
|
||||||
}
|
}
|
||||||
@@ -44,7 +45,7 @@ subprojects {
|
|||||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
}
|
}
|
||||||
shadowJar {
|
shadowJar {
|
||||||
relocate("org.yaml", "cn.hamster3.mc.plugin.ball.lib.org.yaml")
|
relocate("io.netty", "cn.hamster3.mc.plugin.ball.lib.io.netty")
|
||||||
destinationDirectory = rootProject.buildDir
|
destinationDirectory = rootProject.buildDir
|
||||||
}
|
}
|
||||||
build {
|
build {
|
||||||
|
Reference in New Issue
Block a user