From b0e149febb6f4ef559290e392588750ea7511276 Mon Sep 17 00:00:00 2001 From: MiniDay <372403923@qq.com> Date: Mon, 18 Mar 2024 18:05:57 +0800 Subject: [PATCH 1/2] =?UTF-8?q?perf:=20=E7=AE=80=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hamster3/mc/plugin/ball/bukkit/HamsterBallPlugin.java | 2 +- .../hamster3/mc/plugin/ball/bungee/HamsterBallPlugin.java | 2 +- .../java/cn/hamster3/mc/plugin/ball/common/api/BallAPI.java | 4 ++-- .../hamster3/mc/plugin/ball/velocity/HamsterBallPlugin.java | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ball-bukkit/src/main/java/cn/hamster3/mc/plugin/ball/bukkit/HamsterBallPlugin.java b/ball-bukkit/src/main/java/cn/hamster3/mc/plugin/ball/bukkit/HamsterBallPlugin.java index 3aec090..24c47e9 100644 --- a/ball-bukkit/src/main/java/cn/hamster3/mc/plugin/ball/bukkit/HamsterBallPlugin.java +++ b/ball-bukkit/src/main/java/cn/hamster3/mc/plugin/ball/bukkit/HamsterBallPlugin.java @@ -98,7 +98,7 @@ public class HamsterBallPlugin extends JavaPlugin { BallBukkitUtils.uploadPlayerInfo(playerInfo); }); } else { - BallAPI.getInstance().subscribeIgnorePrefix(BallAPI.PLAYER_INFO_CHANNEL); + BallAPI.getInstance().subscribeRaw(BallAPI.PLAYER_INFO_CHANNEL); } sync(() -> { if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) { diff --git a/ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/HamsterBallPlugin.java b/ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/HamsterBallPlugin.java index 1dde4cf..6da3873 100644 --- a/ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/HamsterBallPlugin.java +++ b/ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/HamsterBallPlugin.java @@ -76,7 +76,7 @@ public class HamsterBallPlugin extends Plugin { if (BallAPI.getInstance().getBallConfig().isGameServerUpdatePlayerInfo()) { BallAPI.getInstance().subscribePatterns("*" + BallAPI.PLAYER_INFO_CHANNEL); } else { - BallAPI.getInstance().subscribeIgnorePrefix(BallAPI.PLAYER_INFO_CHANNEL); + BallAPI.getInstance().subscribeRaw(BallAPI.PLAYER_INFO_CHANNEL); } BallAPI.getInstance().sendRawBallMessage( BallAPI.BALL_CHANNEL, BallActions.ServerOnline.name(), diff --git a/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/api/BallAPI.java b/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/api/BallAPI.java index 7470a85..38d85f3 100644 --- a/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/api/BallAPI.java +++ b/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/api/BallAPI.java @@ -179,7 +179,7 @@ public abstract class BallAPI { } getLogger().info("从数据库中加载了 " + allServerInfo.size() + " 条服务器信息"); getLogger().info("从数据库中加载了 " + allPlayerInfo.size() + " 条玩家信息"); - subscribeIgnorePrefix(BALL_CHANNEL); + subscribeRaw(BALL_CHANNEL); } protected void disable() throws SQLException, InterruptedException { @@ -522,7 +522,7 @@ public abstract class BallAPI { * * @param channel 频道名称 */ - public void subscribeIgnorePrefix(@NotNull String... channel) { + public void subscribeRaw(@NotNull String... channel) { CoreAPI.getInstance().getExecutorService().submit( () -> redisSub.subscribe(BallRedisListener.INSTANCE, channel) ); diff --git a/ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/HamsterBallPlugin.java b/ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/HamsterBallPlugin.java index 716e38c..bf5425e 100644 --- a/ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/HamsterBallPlugin.java +++ b/ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/HamsterBallPlugin.java @@ -95,16 +95,16 @@ public class HamsterBallPlugin { return; } BallAPI.getInstance().getEventBus().register(BallVelocityListener.INSTANCE); - logger.info("已注册监听器 BallBungeeListener"); + logger.info("已注册监听器 BallVelocityListener"); proxyServer.getEventManager().register(this, BallVelocityMainListener.INSTANCE); - logger.info("已注册监听器 BallBungeeMainListener"); + logger.info("已注册监听器 BallVelocityMainListener"); proxyServer.getEventManager().register(this, UpdatePlayerInfoListener.INSTANCE); logger.info("已注册监听器 UpdatePlayerInfoListener"); if (BallAPI.getInstance().getBallConfig().isGameServerUpdatePlayerInfo()) { BallAPI.getInstance().subscribePatterns("*" + BallAPI.PLAYER_INFO_CHANNEL); } else { - BallAPI.getInstance().subscribeIgnorePrefix(BallAPI.PLAYER_INFO_CHANNEL); + BallAPI.getInstance().subscribeRaw(BallAPI.PLAYER_INFO_CHANNEL); } BallAPI.getInstance().sendRawBallMessage( BallAPI.BALL_CHANNEL, BallActions.ServerOnline.name(), From 47a183f4cace331e45202247b5319de707abdf65 Mon Sep 17 00:00:00 2001 From: MiniDay <372403923@qq.com> Date: Tue, 19 Mar 2024 10:50:19 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=EF=BC=8C=E6=B7=BB=E5=8A=A0=20auto-register-game-serve?= =?UTF-8?q?r=20=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +-- .../plugin/ball/bukkit/HamsterBallPlugin.java | 4 +- .../plugin/ball/bukkit/api/BallBukkitAPI.java | 5 +- ball-bukkit/src/main/resources/config.yml | 18 ++--- .../plugin/ball/bungee/HamsterBallPlugin.java | 12 +++- .../ball/bungee/api/BallBungeeCordAPI.java | 5 +- .../bungee/listener/BungeeServerListener.java | 59 +++++++++++++++++ ball-bungee/src/main/resources/config.yml | 23 +++---- .../mc/plugin/ball/common/api/BallAPI.java | 4 +- .../ball/common/entity/BallServerInfo.java | 2 +- .../common/event/server/BallServerEvent.java | 18 +++++ .../event/server/ServerOfflineEvent.java | 13 ++-- .../event/server/ServerOnlineEvent.java | 11 ++-- .../common/listener/BallCommonListener.java | 11 ++-- .../ball/velocity/HamsterBallPlugin.java | 12 +++- .../ball/velocity/api/CoreVelocityAPI.java | 5 +- .../listener/VelocityServerListener.java | 65 +++++++++++++++++++ ball-velocity/src/main/resources/config.yml | 23 +++---- build.gradle.kts | 2 +- 19 files changed, 228 insertions(+), 72 deletions(-) create mode 100644 ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/listener/BungeeServerListener.java create mode 100644 ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/event/server/BallServerEvent.java create mode 100644 ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/listener/VelocityServerListener.java diff --git a/README.md b/README.md index e1e476e..8c6ad44 100644 --- a/README.md +++ b/README.md @@ -49,9 +49,9 @@ repositories { dependencies { // 对于 Bukkit 插件 - compileOnly("cn.hamster3.mc.plugin:ball-bukkit:1.6.1") + compileOnly("cn.hamster3.mc.plugin:ball-bukkit:1.6.2-SNAPSHOT") // 对于 BungeeCord 插件 - compileOnly("cn.hamster3.mc.plugin:ball-bungee:1.6.1") + compileOnly("cn.hamster3.mc.plugin:ball-bungee:1.6.2-SNAPSHOT") } ``` @@ -77,13 +77,13 @@ dependencies { cn.hamster3.mc.plugin ball-bukkit - 1.6.1 + 1.6.2-SNAPSHOT cn.hamster3.mc.plugin ball-bungee - 1.6.1 + 1.6.2-SNAPSHOT diff --git a/ball-bukkit/src/main/java/cn/hamster3/mc/plugin/ball/bukkit/HamsterBallPlugin.java b/ball-bukkit/src/main/java/cn/hamster3/mc/plugin/ball/bukkit/HamsterBallPlugin.java index 24c47e9..e496729 100644 --- a/ball-bukkit/src/main/java/cn/hamster3/mc/plugin/ball/bukkit/HamsterBallPlugin.java +++ b/ball-bukkit/src/main/java/cn/hamster3/mc/plugin/ball/bukkit/HamsterBallPlugin.java @@ -9,6 +9,7 @@ import cn.hamster3.mc.plugin.ball.common.api.BallAPI; import cn.hamster3.mc.plugin.ball.common.entity.BallPlayerInfo; import cn.hamster3.mc.plugin.ball.common.event.BallActions; import cn.hamster3.mc.plugin.ball.common.event.server.ServerOnlineEvent; +import cn.hamster3.mc.plugin.core.common.config.YamlConfig; import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; @@ -55,7 +56,8 @@ public class HamsterBallPlugin extends JavaPlugin { StandardCopyOption.REPLACE_EXISTING ); } - BallBukkitAPI.init(configFile); + YamlConfig config = YamlConfig.load(configFile); + BallBukkitAPI.init(config); logger.info("已初始化 BallAPI"); } catch (Exception e) { logger.log(Level.SEVERE, "BallAPI 初始化失败", e); diff --git a/ball-bukkit/src/main/java/cn/hamster3/mc/plugin/ball/bukkit/api/BallBukkitAPI.java b/ball-bukkit/src/main/java/cn/hamster3/mc/plugin/ball/bukkit/api/BallBukkitAPI.java index 8cc0bef..6980187 100644 --- a/ball-bukkit/src/main/java/cn/hamster3/mc/plugin/ball/bukkit/api/BallBukkitAPI.java +++ b/ball-bukkit/src/main/java/cn/hamster3/mc/plugin/ball/bukkit/api/BallBukkitAPI.java @@ -8,8 +8,6 @@ import cn.hamster3.mc.plugin.core.common.config.YamlConfig; import org.bukkit.Bukkit; import org.jetbrains.annotations.NotNull; -import java.io.File; -import java.io.IOException; import java.sql.SQLException; import java.util.logging.Logger; @@ -22,11 +20,10 @@ public class BallBukkitAPI extends BallAPI { return (BallBukkitAPI) instance; } - public static void init(@NotNull File configFile) throws IOException { + public static void init(@NotNull YamlConfig config) { if (instance != null) { return; } - YamlConfig config = YamlConfig.load(configFile); instance = new BallBukkitAPI(config); } diff --git a/ball-bukkit/src/main/resources/config.yml b/ball-bukkit/src/main/resources/config.yml index c13f1bd..780aedb 100644 --- a/ball-bukkit/src/main/resources/config.yml +++ b/ball-bukkit/src/main/resources/config.yml @@ -11,7 +11,7 @@ channel-prefix: "" # 如果一个群组服同时拥有多个 BC 入口 # 且每个 BC 入口为不同的玩家名称分配不同的 UUID # (例如正版、盗版双入口,或网易多入口接同一个子服) -# 则可以启用该功能以防止 UUID 紊乱的问题 +# 则可以启用该功能以防止同一个名称占用多个 UUID 的问题 game-server-update-player-info: false # 该选项仅在 game-server-update-player-info 为 true 时有效 @@ -41,16 +41,18 @@ server-info: # 如果你需要让每个服务器单独存储仓鼠球信息 # 这个选项就会很有用 #datasource: -# # 数据库链接驱动地址 -# driver: "com.mysql.jdbc.Driver" -# # 数据库链接填写格式: +# # 数据库链接驱动地址,旧版服务端(低于1.13)请使用:com.mysql.jdbc.Driver +# driver: "com.mysql.cj.jdbc.Driver" +# # MySQL数据库链接填写格式: # # jdbc:mysql://{数据库地址}:{数据库端口}/{使用的库名}?参数 -# # 除非你知道自己在做什么,否则不建议随意更改参数 -# url: "jdbc:mysql://localhost:3306/Test1?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true" +# url: "jdbc:mysql://localhost:3306/Test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true" +# # 如果你不需要做多端跨服,那么请使用 sqlite 作本地数据库 ↓ +# # driver: "org.sqlite.JDBC" +# # url: "jdbc:sqlite:./plugins/HamsterCore/database.db" # # 用户名 -# username: "Test" +# username: "root" # # 密码 -# password: "Test123.." +# password: "Root123.." # # 最小闲置链接数 # # 推荐值:1~3 # minimum-idle: 0 diff --git a/ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/HamsterBallPlugin.java b/ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/HamsterBallPlugin.java index 6da3873..2be20c5 100644 --- a/ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/HamsterBallPlugin.java +++ b/ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/HamsterBallPlugin.java @@ -3,12 +3,14 @@ package cn.hamster3.mc.plugin.ball.bungee; import cn.hamster3.mc.plugin.ball.bungee.api.BallBungeeCordAPI; import cn.hamster3.mc.plugin.ball.bungee.listener.BallBungeeListener; import cn.hamster3.mc.plugin.ball.bungee.listener.BallBungeeMainListener; +import cn.hamster3.mc.plugin.ball.bungee.listener.BungeeServerListener; import cn.hamster3.mc.plugin.ball.bungee.listener.UpdatePlayerInfoListener; import cn.hamster3.mc.plugin.ball.bungee.util.BallBungeeCordUtils; import cn.hamster3.mc.plugin.ball.common.api.BallAPI; import cn.hamster3.mc.plugin.ball.common.entity.BallPlayerInfo; import cn.hamster3.mc.plugin.ball.common.event.BallActions; import cn.hamster3.mc.plugin.ball.common.event.server.ServerOnlineEvent; +import cn.hamster3.mc.plugin.core.common.config.YamlConfig; import lombok.Getter; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.plugin.Plugin; @@ -22,6 +24,8 @@ import java.util.logging.Logger; public class HamsterBallPlugin extends Plugin { @Getter private static HamsterBallPlugin instance; + @Getter + private YamlConfig config; @Override public void onLoad() { @@ -42,7 +46,8 @@ public class HamsterBallPlugin extends Plugin { StandardCopyOption.REPLACE_EXISTING ); } - BallBungeeCordAPI.init(configFile); + config = YamlConfig.load(configFile); + BallBungeeCordAPI.init(config); logger.info("已初始化 BallAPI"); } catch (Exception e) { logger.log(Level.SEVERE, "BallAPI 初始化失败", e); @@ -72,6 +77,11 @@ public class HamsterBallPlugin extends Plugin { logger.info("已注册监听器 BallBungeeMainListener"); ProxyServer.getInstance().getPluginManager().registerListener(this, UpdatePlayerInfoListener.INSTANCE); logger.info("已注册监听器 UpdatePlayerInfoListener"); + if (config.getBoolean("auto-register-game-server", false)) { + BallAPI.getInstance().getEventBus().register(BungeeServerListener.INSTANCE); + logger.info("已注册监听器 BungeeServerListener"); + BungeeServerListener.INSTANCE.onEnable(); + } if (BallAPI.getInstance().getBallConfig().isGameServerUpdatePlayerInfo()) { BallAPI.getInstance().subscribePatterns("*" + BallAPI.PLAYER_INFO_CHANNEL); diff --git a/ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/api/BallBungeeCordAPI.java b/ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/api/BallBungeeCordAPI.java index a7f8102..cf4d8f4 100644 --- a/ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/api/BallBungeeCordAPI.java +++ b/ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/api/BallBungeeCordAPI.java @@ -9,8 +9,6 @@ import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.config.ListenerInfo; import org.jetbrains.annotations.NotNull; -import java.io.File; -import java.io.IOException; import java.net.InetSocketAddress; import java.sql.SQLException; import java.util.logging.Logger; @@ -24,11 +22,10 @@ public class BallBungeeCordAPI extends BallAPI { return (BallBungeeCordAPI) instance; } - public static void init(@NotNull File configFile) throws IOException { + public static void init(@NotNull YamlConfig config) { if (instance != null) { return; } - YamlConfig config = YamlConfig.load(configFile); instance = new BallBungeeCordAPI(config); } diff --git a/ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/listener/BungeeServerListener.java b/ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/listener/BungeeServerListener.java new file mode 100644 index 0000000..715cc36 --- /dev/null +++ b/ball-bungee/src/main/java/cn/hamster3/mc/plugin/ball/bungee/listener/BungeeServerListener.java @@ -0,0 +1,59 @@ +package cn.hamster3.mc.plugin.ball.bungee.listener; + +import cn.hamster3.mc.plugin.ball.common.api.BallAPI; +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.event.server.ServerOfflineEvent; +import cn.hamster3.mc.plugin.ball.common.event.server.ServerOnlineEvent; +import com.google.common.eventbus.Subscribe; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.config.ServerInfo; + +import java.net.InetSocketAddress; +import java.util.Map; + +public class BungeeServerListener { + public static final BungeeServerListener INSTANCE = new BungeeServerListener(); + + private BungeeServerListener() { + } + + public void onEnable() { + for (BallServerInfo info : BallAPI.getInstance().getAllServerInfo().values()) { + if (info.getType() != BallServerType.GAME) { + continue; + } + ProxyServer.getInstance().getServers().put(info.getId(), getServerInfo(info)); + BallAPI.getInstance().getLogger().info("已添加服务器入口: " + info.getId()); + } + } + + @Subscribe + public void onServerOnline(ServerOnlineEvent event) { + if (event.getType() != BallServerType.GAME) { + return; + } + ProxyServer.getInstance().getServers().put(event.getId(), getServerInfo(event)); + BallAPI.getInstance().getLogger().info("已添加服务器入口: " + event.getId()); + } + + @Subscribe + public void onServerOffline(ServerOfflineEvent event) { + if (event.getType() != BallServerType.GAME) { + return; + } + Map map = ProxyServer.getInstance().getServers(); + if (map.remove(event.getId()) != null) { + BallAPI.getInstance().getLogger().info("已移除服务器入口: " + event.getId()); + } + } + + private ServerInfo getServerInfo(BallServerInfo serverInfo) { + return ProxyServer.getInstance().constructServerInfo( + serverInfo.getId(), + new InetSocketAddress(serverInfo.getHost(), serverInfo.getPort()), + serverInfo.getName(), + false + ); + } +} diff --git a/ball-bungee/src/main/resources/config.yml b/ball-bungee/src/main/resources/config.yml index 4903825..cdee594 100644 --- a/ball-bungee/src/main/resources/config.yml +++ b/ball-bungee/src/main/resources/config.yml @@ -8,12 +8,14 @@ channel-prefix: "" # 是否在子服端更新玩家信息 # 默认情况下,BC 统一管理玩家信息,包括记录 UUID 和玩家名称 -# 如果一个群组服同时拥有多个 BC 入口 -# 且每个 BC 入口为不同的玩家名称分配不同的 UUID +# 如果一个群组服同时拥有多个 BC 入口,且每个 BC 入口为不同的玩家名称分配不同的 UUID # (例如正版、盗版双入口,或网易多入口接同一个子服) -# 则可以启用该功能以防止 UUID 紊乱的问题 +# 则可以启用该功能以防止同一个名称占用多个 UUID 的问题 game-server-update-player-info: false +# 启用后,子服启动时会自动注册该子服的入口配置,关闭时也会自动移除该子服的入口配置 +auto-register-game-server: false + # 本服务器信息 server-info: # 服务器唯一识别码,最长 32 字符 @@ -34,21 +36,20 @@ server-info: # 这个选项就会很有用 #datasource: # # 数据库链接驱动地址 -# driver: "com.mysql.jdbc.Driver" -# # 数据库链接填写格式: +# driver: "com.mysql.cj.jdbc.Driver" +# # MySQL数据库链接填写格式: # # jdbc:mysql://{数据库地址}:{数据库端口}/{使用的库名}?参数 -# # 除非你知道自己在做什么,否则不建议随意更改参数 -# url: "jdbc:mysql://localhost:3306/Test1?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true" +# url: "jdbc:mysql://localhost:3306/Test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true" # # 用户名 -# username: "Test" +# username: "root" # # 密码 -# password: "Test123.." +# password: "Root123.." # # 最小闲置链接数 # # 推荐值:1~3 # minimum-idle: 0 # # 最大链接数 -# # 推荐值:不低于3 -# maximum-pool-size: 3 +# # 推荐值:不低于5 +# maximum-pool-size: 5 # # 保持连接池可用的间隔 # # 除非你的服务器数据库连接经常断开,否则不建议启用该选项 # # 单位:毫秒 diff --git a/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/api/BallAPI.java b/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/api/BallAPI.java index 38d85f3..d2a3716 100644 --- a/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/api/BallAPI.java +++ b/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/api/BallAPI.java @@ -73,7 +73,7 @@ public abstract class BallAPI { @Nullable private ScheduledFuture lockUpdater; - public BallAPI(@NotNull ConfigSection config, BallServerType type) { + public BallAPI(@NotNull ConfigSection config, @NotNull BallServerType type) { ConfigSection serverInfoConfig = config.getSection("server-info"); if (serverInfoConfig == null) { throw new IllegalArgumentException("配置文件中未找到 server-info 节点"); @@ -88,7 +88,7 @@ public abstract class BallAPI { datasource = CoreAPI.getInstance().getDataSource(); } ballConfig = new BallConfig(config); - eventBus = new AsyncEventBus("HamsterBall - EventBus", CoreAPI.getInstance().getExecutorService()); + eventBus = new AsyncEventBus("HamsterBall", CoreAPI.getInstance().getExecutorService()); eventBus.register(BallCommonListener.INSTANCE); allServerInfo = new ConcurrentHashMap<>(); allPlayerInfo = new ConcurrentHashMap<>(); diff --git a/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/entity/BallServerInfo.java b/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/entity/BallServerInfo.java index 5490d2f..5c9899a 100644 --- a/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/entity/BallServerInfo.java +++ b/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/entity/BallServerInfo.java @@ -43,7 +43,7 @@ public class BallServerInfo { */ private int port; - public BallServerInfo(@NotNull ConfigSection config, BallServerType type) { + public BallServerInfo(@NotNull ConfigSection config, @NotNull BallServerType type) { Map env = System.getenv(); id = env.getOrDefault("BALL_SERVER_ID", config.getString("id")); name = env.getOrDefault("BALL_SERVER_NAME", config.getString("name")); diff --git a/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/event/server/BallServerEvent.java b/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/event/server/BallServerEvent.java new file mode 100644 index 0000000..e1ee49e --- /dev/null +++ b/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/event/server/BallServerEvent.java @@ -0,0 +1,18 @@ +package cn.hamster3.mc.plugin.ball.common.event.server; + +import cn.hamster3.mc.plugin.ball.common.entity.BallServerInfo; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 服务器上线 + */ +@Data +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class BallServerEvent extends BallServerInfo { + public BallServerEvent(BallServerInfo info) { + super(info.getId(), info.getName(), info.getType(), info.getHost(), info.getPort()); + } +} diff --git a/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/event/server/ServerOfflineEvent.java b/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/event/server/ServerOfflineEvent.java index 31cd515..57dc7e4 100644 --- a/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/event/server/ServerOfflineEvent.java +++ b/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/event/server/ServerOfflineEvent.java @@ -3,19 +3,16 @@ package cn.hamster3.mc.plugin.ball.common.event.server; import cn.hamster3.mc.plugin.ball.common.entity.BallServerInfo; import lombok.AllArgsConstructor; import lombok.Data; -import org.jetbrains.annotations.NotNull; +import lombok.EqualsAndHashCode; /** * 服务器离线 */ @Data @AllArgsConstructor -public class ServerOfflineEvent { - @NotNull - private final BallServerInfo serverInfo; - - @NotNull - public String getServerID() { - return serverInfo.getId(); +@EqualsAndHashCode(callSuper = true) +public class ServerOfflineEvent extends BallServerEvent { + public ServerOfflineEvent(BallServerInfo info) { + super(info); } } diff --git a/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/event/server/ServerOnlineEvent.java b/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/event/server/ServerOnlineEvent.java index 23e71fe..8a1cd88 100644 --- a/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/event/server/ServerOnlineEvent.java +++ b/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/event/server/ServerOnlineEvent.java @@ -3,15 +3,16 @@ package cn.hamster3.mc.plugin.ball.common.event.server; import cn.hamster3.mc.plugin.ball.common.entity.BallServerInfo; import lombok.AllArgsConstructor; import lombok.Data; -import org.jetbrains.annotations.NotNull; +import lombok.EqualsAndHashCode; /** * 服务器上线 */ @Data @AllArgsConstructor -public class ServerOnlineEvent { - @NotNull - private final BallServerInfo serverInfo; - +@EqualsAndHashCode(callSuper = true) +public class ServerOnlineEvent extends BallServerEvent { + public ServerOnlineEvent(BallServerInfo info) { + super(info); + } } diff --git a/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/listener/BallCommonListener.java b/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/listener/BallCommonListener.java index b3f1ceb..df3cab9 100644 --- a/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/listener/BallCommonListener.java +++ b/ball-common/src/main/java/cn/hamster3/mc/plugin/ball/common/listener/BallCommonListener.java @@ -128,12 +128,11 @@ public class BallCommonListener { @Subscribe public void onServerOnline(ServerOnlineEvent event) { - BallServerInfo info = event.getServerInfo(); - BallAPI.getInstance().getAllServerInfo().put(info.getId(), info); - switch (info.getType()) { + BallAPI.getInstance().getAllServerInfo().put(event.getId(), event); + switch (event.getType()) { case GAME: { BallAPI.getInstance().getAllPlayerInfo().forEach((uuid, playerInfo) -> { - if (playerInfo.getGameServer().equals(info.getId())) { + if (playerInfo.getGameServer().equals(event.getId())) { playerInfo.setOnline(false); } }); @@ -141,7 +140,7 @@ public class BallCommonListener { } case PROXY: { BallAPI.getInstance().getAllPlayerInfo().forEach((uuid, playerInfo) -> { - if (playerInfo.getProxyServer().equals(info.getId())) { + if (playerInfo.getProxyServer().equals(event.getId())) { playerInfo.setOnline(false); } }); @@ -152,7 +151,7 @@ public class BallCommonListener { @Subscribe public void onServerOffline(ServerOfflineEvent event) { - String serverID = event.getServerID(); + String serverID = event.getId(); BallServerInfo info = BallAPI.getInstance().getAllServerInfo().remove(serverID); if (info == null) { return; diff --git a/ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/HamsterBallPlugin.java b/ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/HamsterBallPlugin.java index bf5425e..e6f88a1 100644 --- a/ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/HamsterBallPlugin.java +++ b/ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/HamsterBallPlugin.java @@ -8,7 +8,9 @@ import cn.hamster3.mc.plugin.ball.velocity.api.CoreVelocityAPI; import cn.hamster3.mc.plugin.ball.velocity.listener.BallVelocityListener; import cn.hamster3.mc.plugin.ball.velocity.listener.BallVelocityMainListener; import cn.hamster3.mc.plugin.ball.velocity.listener.UpdatePlayerInfoListener; +import cn.hamster3.mc.plugin.ball.velocity.listener.VelocityServerListener; import cn.hamster3.mc.plugin.ball.velocity.util.BallVelocityUtils; +import cn.hamster3.mc.plugin.core.common.config.YamlConfig; import com.google.inject.Inject; import com.velocitypowered.api.event.PostOrder; import com.velocitypowered.api.event.Subscribe; @@ -48,6 +50,8 @@ public class HamsterBallPlugin { private final ProxyServer proxyServer; @Getter private final File dataFolder; + @Getter + private YamlConfig config; @Inject public HamsterBallPlugin(Logger slf4jLogger, ProxyServer proxyServer, @DataDirectory Path dataPath) { @@ -71,7 +75,8 @@ public class HamsterBallPlugin { StandardCopyOption.REPLACE_EXISTING ); } - CoreVelocityAPI.init(configFile); + config = YamlConfig.load(configFile); + CoreVelocityAPI.init(config); logger.info("已初始化 BallAPI"); } catch (Exception e) { slf4jLogger.error("BallAPI 初始化失败", e); @@ -100,6 +105,11 @@ public class HamsterBallPlugin { logger.info("已注册监听器 BallVelocityMainListener"); proxyServer.getEventManager().register(this, UpdatePlayerInfoListener.INSTANCE); logger.info("已注册监听器 UpdatePlayerInfoListener"); + if (config.getBoolean("auto-register-game-server", false)) { + BallAPI.getInstance().getEventBus().register(VelocityServerListener.INSTANCE); + logger.info("已注册监听器 VelocityServerListener"); + VelocityServerListener.INSTANCE.onEnable(); + } if (BallAPI.getInstance().getBallConfig().isGameServerUpdatePlayerInfo()) { BallAPI.getInstance().subscribePatterns("*" + BallAPI.PLAYER_INFO_CHANNEL); diff --git a/ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/api/CoreVelocityAPI.java b/ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/api/CoreVelocityAPI.java index 2b72dfe..c19f128 100644 --- a/ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/api/CoreVelocityAPI.java +++ b/ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/api/CoreVelocityAPI.java @@ -8,8 +8,6 @@ import cn.hamster3.mc.plugin.core.common.config.YamlConfig; import com.velocitypowered.api.proxy.config.ProxyConfig; import org.jetbrains.annotations.NotNull; -import java.io.File; -import java.io.IOException; import java.lang.reflect.Field; import java.sql.SQLException; import java.util.logging.Logger; @@ -24,11 +22,10 @@ public final class CoreVelocityAPI extends BallAPI { return (CoreVelocityAPI) instance; } - public static void init(@NotNull File configFile) throws IOException { + public static void init(@NotNull YamlConfig config) { if (instance != null) { return; } - YamlConfig config = YamlConfig.load(configFile); instance = new CoreVelocityAPI(config); } diff --git a/ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/listener/VelocityServerListener.java b/ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/listener/VelocityServerListener.java new file mode 100644 index 0000000..d7e2145 --- /dev/null +++ b/ball-velocity/src/main/java/cn/hamster3/mc/plugin/ball/velocity/listener/VelocityServerListener.java @@ -0,0 +1,65 @@ +package cn.hamster3.mc.plugin.ball.velocity.listener; + +import cn.hamster3.mc.plugin.ball.common.api.BallAPI; +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.event.server.ServerOfflineEvent; +import cn.hamster3.mc.plugin.ball.common.event.server.ServerOnlineEvent; +import cn.hamster3.mc.plugin.ball.velocity.HamsterBallPlugin; +import com.google.common.eventbus.Subscribe; +import com.velocitypowered.api.proxy.ProxyServer; +import com.velocitypowered.api.proxy.server.RegisteredServer; +import com.velocitypowered.api.proxy.server.ServerInfo; + +import java.net.InetSocketAddress; + +public class VelocityServerListener { + public static final VelocityServerListener INSTANCE = new VelocityServerListener(); + + private VelocityServerListener() { + } + + public void onEnable() { + for (BallServerInfo info : BallAPI.getInstance().getAllServerInfo().values()) { + if (info.getType() != BallServerType.GAME) { + continue; + } + ProxyServer server = HamsterBallPlugin.getInstance().getProxyServer(); + server.getServer(info.getId()) + .map(RegisteredServer::getServerInfo) + .ifPresent(server::unregisterServer); + ServerInfo serverInfo = new ServerInfo(info.getId(), new InetSocketAddress(info.getHost(), info.getPort())); + server.registerServer(serverInfo); + BallAPI.getInstance().getLogger().info("已添加服务器入口: " + info.getId()); + } + } + + @Subscribe + public void onServerOnline(ServerOnlineEvent event) { + if (event.getType() != BallServerType.GAME) { + return; + } + ProxyServer server = HamsterBallPlugin.getInstance().getProxyServer(); + server.getServer(event.getId()) + .map(RegisteredServer::getServerInfo) + .ifPresent(server::unregisterServer); + ServerInfo serverInfo = new ServerInfo(event.getId(), new InetSocketAddress(event.getHost(), event.getPort())); + server.registerServer(serverInfo); + BallAPI.getInstance().getLogger().info("已添加服务器入口: " + event.getId()); + } + + @Subscribe + public void onServerOffline(ServerOfflineEvent event) { + if (event.getType() != BallServerType.GAME) { + return; + } + ProxyServer server = HamsterBallPlugin.getInstance().getProxyServer(); + ServerInfo serverInfo = server.getServer(event.getId()) + .map(RegisteredServer::getServerInfo) + .orElse(null); + if (serverInfo != null) { + server.unregisterServer(serverInfo); + BallAPI.getInstance().getLogger().info("已移除服务器入口: " + event.getId()); + } + } +} diff --git a/ball-velocity/src/main/resources/config.yml b/ball-velocity/src/main/resources/config.yml index f5d5f93..ac69770 100644 --- a/ball-velocity/src/main/resources/config.yml +++ b/ball-velocity/src/main/resources/config.yml @@ -8,12 +8,14 @@ channel-prefix: "" # 是否在子服端更新玩家信息 # 默认情况下,BC 统一管理玩家信息,包括记录 UUID 和玩家名称 -# 如果一个群组服同时拥有多个 BC 入口 -# 且每个 BC 入口为不同的玩家名称分配不同的 UUID +# 如果一个群组服同时拥有多个 BC 入口,且每个 BC 入口为不同的玩家名称分配不同的 UUID # (例如正版、盗版双入口,或网易多入口接同一个子服) -# 则可以启用该功能以防止 UUID 紊乱的问题 +# 则可以启用该功能以防止同一个名称占用多个 UUID 的问题 game-server-update-player-info: false +# 启用后,子服启动时会自动注册该子服的入口配置,关闭时也会自动移除该子服的入口配置 +auto-register-game-server: false + # 本服务器信息 server-info: # 服务器唯一识别码,最长 32 字符 @@ -34,21 +36,20 @@ server-info: # 这个选项就会很有用 #datasource: # # 数据库链接驱动地址 -# driver: "com.mysql.jdbc.Driver" -# # 数据库链接填写格式: +# driver: "com.mysql.cj.jdbc.Driver" +# # MySQL数据库链接填写格式: # # jdbc:mysql://{数据库地址}:{数据库端口}/{使用的库名}?参数 -# # 除非你知道自己在做什么,否则不建议随意更改参数 -# url: "jdbc:mysql://localhost:3306/Test1?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true" +# url: "jdbc:mysql://localhost:3306/Test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true" # # 用户名 -# username: "Test" +# username: "root" # # 密码 -# password: "Test123.." +# password: "Root123.." # # 最小闲置链接数 # # 推荐值:1~3 # minimum-idle: 0 # # 最大链接数 -# # 推荐值:不低于3 -# maximum-pool-size: 3 +# # 推荐值:不低于5 +# maximum-pool-size: 5 # # 保持连接池可用的间隔 # # 除非你的服务器数据库连接经常断开,否则不建议启用该选项 # # 单位:毫秒 diff --git a/build.gradle.kts b/build.gradle.kts index bd0a56a..40ee939 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } group = "cn.hamster3.mc.plugin" -version = "1.6.1" +version = "1.6.2-SNAPSHOT" subprojects { apply {