feat: 添加 load-player-info-filter 配置选项

This commit is contained in:
2024-02-24 16:38:31 +08:00
parent 53c582eb4d
commit 68ba097033
11 changed files with 100 additions and 70 deletions

View File

@@ -44,14 +44,16 @@
```groovy ```groovy
// 添加仓库 // 添加仓库
repositories { repositories {
maven("https://maven.airgame.net/maven-public/") maven {
url = uri("https://maven.airgame.net/maven-public/")
}
} }
dependencies { dependencies {
// 对于 Bukkit 插件 // 对于 Bukkit 插件
compileOnly("cn.hamster3.mc.plugin:ball-bukkit:1.5.1") compileOnly("cn.hamster3.mc.plugin:ball-bukkit:1.5.2")
// 对于 BungeeCord 插件 // 对于 BungeeCord 插件
compileOnly("cn.hamster3.mc.plugin:ball-bungee:1.5.1") compileOnly("cn.hamster3.mc.plugin:ball-bungee:1.5.2")
} }
``` ```
@@ -77,13 +79,13 @@ dependencies {
<dependency> <dependency>
<groupId>cn.hamster3.mc.plugin</groupId> <groupId>cn.hamster3.mc.plugin</groupId>
<artifactId>ball-bukkit</artifactId> <artifactId>ball-bukkit</artifactId>
<version>1.5.1</version> <version>1.5.2</version>
</dependency> </dependency>
<!--对于 BungeeCord 插件--> <!--对于 BungeeCord 插件-->
<dependency> <dependency>
<groupId>cn.hamster3.mc.plugin</groupId> <groupId>cn.hamster3.mc.plugin</groupId>
<artifactId>ball-bungee</artifactId> <artifactId>ball-bungee</artifactId>
<version>1.5.1</version> <version>1.5.2</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -1,10 +1,12 @@
@file:Suppress("VulnerableLibrariesLocal")
evaluationDependsOn(":ball-common") evaluationDependsOn(":ball-common")
dependencies { dependencies {
implementation(project(":ball-common")) { implementation(project(":ball-common")) {
isTransitive = false isTransitive = false
} }
compileOnly("org.spigotmc:spigot-api:1.20.4-R0.1-SNAPSHOT") compileOnly("org.spigotmc:spigot-api:1.18.2-R0.1-SNAPSHOT")
compileOnly("cn.hamster3.mc.plugin:core-bukkit:1.2.2") compileOnly("cn.hamster3.mc.plugin:core-bukkit:1.2.2")
compileOnly("me.clip:placeholderapi:2.11.5") { compileOnly("me.clip:placeholderapi:2.11.5") {

View File

@@ -59,6 +59,7 @@ public class BallBukkitAPI extends BallAPI {
config.getBoolean("debug", false), config.getBoolean("debug", false),
config.getString("channel-prefix", "") + ":", config.getString("channel-prefix", "") + ":",
config.getBoolean("game-server-update-player-info", false), config.getBoolean("game-server-update-player-info", false),
config.getStringList("load-player-info-filter"),
serverInfo, serverInfo,
datasource datasource
); );

View File

@@ -14,6 +14,11 @@ channel-prefix: ""
# 则可以启用该功能以防止 UUID 紊乱的问题 # 则可以启用该功能以防止 UUID 紊乱的问题
game-server-update-player-info: false game-server-update-player-info: false
# 该选项仅在 game-server-update-player-info 为 true 时有效
# 服务器在启动时只会从数据库中加载 proxy_server 为下列的字符串的玩家信息
load-player-info-filter:
- "BungeeCord"
# 本服务器信息 # 本服务器信息
server-info: server-info:
# 服务器唯一识别码,最长 32 字符 # 服务器唯一识别码,最长 32 字符

View File

@@ -56,6 +56,7 @@ public class BallBungeeCordAPI extends BallAPI {
config.getBoolean("debug", false), config.getBoolean("debug", false),
config.getString("channel-prefix", "") + ":", config.getString("channel-prefix", "") + ":",
config.getBoolean("game-server-update-player-info", false), config.getBoolean("game-server-update-player-info", false),
config.getStringList("load-player-info-filter"),
serverInfo, serverInfo,
datasource datasource
); );

View File

@@ -14,6 +14,10 @@ channel-prefix: ""
# 则可以启用该功能以防止 UUID 紊乱的问题 # 则可以启用该功能以防止 UUID 紊乱的问题
game-server-update-player-info: false game-server-update-player-info: false
# 服务器在启动时只会从数据库中加载 proxy_server 为下列的字符串的玩家信息
load-player-info-filter:
"BungeeCord"
# 本服务器信息 # 本服务器信息
server-info: server-info:
# 服务器唯一识别码,最长 32 字符 # 服务器唯一识别码,最长 32 字符

View File

@@ -122,6 +122,24 @@ public abstract class BallAPI {
} }
} }
} }
if (getBallConfig().isGameServerUpdatePlayerInfo()) {
try (PreparedStatement statement = connection.prepareStatement(
"SELECT * FROM `hamster_ball_player_info` WHERE `proxy_server` IN (?);"
)) {
statement.setString(1, String.join(",", getBallConfig().getLoadPlayerInfoFilter()));
try (ResultSet set = statement.executeQuery()) {
while (set.next()) {
UUID uuid = UUID.fromString(set.getString("uuid"));
allPlayerInfo.put(uuid, new BallPlayerInfo(uuid,
set.getString("name"),
set.getString("game_server"),
set.getString("proxy_server"),
set.getBoolean("online")
));
}
}
}
} else {
try (PreparedStatement statement = connection.prepareStatement( try (PreparedStatement statement = connection.prepareStatement(
"SELECT * FROM `hamster_ball_player_info`;" "SELECT * FROM `hamster_ball_player_info`;"
)) { )) {
@@ -138,8 +156,11 @@ public abstract class BallAPI {
} }
} }
} }
}
getLogger().info("从数据库中加载了 " + allServerInfo.size() + " 条服务器信息");
getLogger().info("从数据库中加载了 " + allPlayerInfo.size() + " 条玩家信息");
redisPub.addListener(BallRedisListener.INSTANCE); redisPub.addListener(BallRedisListener.INSTANCE);
redisPub.sync().subscribe(BALL_CHANNEL); subscribeIgnorePrefix(BALL_CHANNEL);
} }
protected void disable() throws SQLException, InterruptedException { protected void disable() throws SQLException, InterruptedException {
@@ -462,6 +483,8 @@ public abstract class BallAPI {
/** /**
* 订阅 redis 消息频道 * 订阅 redis 消息频道
* <p>
* 会自动加上 config 中设置的频道前缀
* *
* @param channel 频道名称 * @param channel 频道名称
*/ */
@@ -473,7 +496,7 @@ public abstract class BallAPI {
} }
/** /**
* 忽略仓鼠球频道前缀配置,订阅 redis 消息频道 * 忽略频道前缀配置,订阅 redis 消息频道
* *
* @param channel 频道名称 * @param channel 频道名称
*/ */
@@ -562,22 +585,11 @@ public abstract class BallAPI {
* @return 玩家信息 * @return 玩家信息
*/ */
public BallPlayerInfo getPlayerInfo(@NotNull String playerName) { public BallPlayerInfo getPlayerInfo(@NotNull String playerName) {
if (getBallConfig().isGameServerUpdatePlayerInfo()) {
for (BallPlayerInfo info : allPlayerInfo.values()) {
if (!info.getProxyServer().startsWith(BallAPI.getInstance().getBallConfig().getChannelPrefix())) {
continue;
}
if (info.getName().equalsIgnoreCase(playerName)) {
return info;
}
}
} else {
for (BallPlayerInfo info : allPlayerInfo.values()) { for (BallPlayerInfo info : allPlayerInfo.values()) {
if (info.getName().equalsIgnoreCase(playerName)) { if (info.getName().equalsIgnoreCase(playerName)) {
return info; return info;
} }
} }
}
return null; return null;
} }
@@ -588,22 +600,11 @@ public abstract class BallAPI {
* @return 玩家信息 * @return 玩家信息
*/ */
public BallPlayerInfo getPlayerInfoExact(@NotNull String playerName) { public BallPlayerInfo getPlayerInfoExact(@NotNull String playerName) {
if (getBallConfig().isGameServerUpdatePlayerInfo()) {
for (BallPlayerInfo info : allPlayerInfo.values()) {
if (!info.getProxyServer().startsWith(BallAPI.getInstance().getBallConfig().getChannelPrefix())) {
continue;
}
if (info.getName().equals(playerName)) {
return info;
}
}
} else {
for (BallPlayerInfo info : allPlayerInfo.values()) { for (BallPlayerInfo info : allPlayerInfo.values()) {
if (info.getName().equals(playerName)) { if (info.getName().equals(playerName)) {
return info; return info;
} }
} }
}
return null; return null;
} }

View File

@@ -7,6 +7,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.util.List;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
@@ -15,6 +16,7 @@ public class BallConfig {
@NotNull @NotNull
private String channelPrefix; private String channelPrefix;
private boolean gameServerUpdatePlayerInfo; private boolean gameServerUpdatePlayerInfo;
private List<String> loadPlayerInfoFilter;
@NotNull @NotNull
private BallServerInfo serverInfo; private BallServerInfo serverInfo;
@Nullable @Nullable

View File

@@ -1,8 +1,11 @@
package cn.hamster3.mc.plugin.ball.common.listener; 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.entity.BallPlayerInfo;
import cn.hamster3.mc.plugin.ball.common.event.message.MessageReceivedEvent; import cn.hamster3.mc.plugin.ball.common.event.message.MessageReceivedEvent;
import cn.hamster3.mc.plugin.ball.common.event.message.MessageSentEvent; import cn.hamster3.mc.plugin.ball.common.event.message.MessageSentEvent;
import cn.hamster3.mc.plugin.ball.common.event.player.BallPlayerInfoUpdateEvent;
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
import com.google.common.eventbus.Subscribe; import com.google.common.eventbus.Subscribe;
public class BallDebugListener { public class BallDebugListener {
@@ -20,4 +23,11 @@ public class BallDebugListener {
public void onMessageSent(MessageSentEvent event) { public void onMessageSent(MessageSentEvent event) {
BallAPI.getInstance().getLogger().info("发送了一条消息: " + event); BallAPI.getInstance().getLogger().info("发送了一条消息: " + event);
} }
@Subscribe
public void onBallPlayerInfoUpdate(BallPlayerInfoUpdateEvent event) {
BallPlayerInfo playerInfo = event.getPlayerInfo();
String json = CoreAPI.getInstance().getGson().toJson(playerInfo);
BallAPI.getInstance().getLogger().info("更新了玩家 " + playerInfo.getName() + " 的信息: " + json);
}
} }

View File

@@ -10,6 +10,7 @@ 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 cn.hamster3.mc.plugin.core.lib.io.lettuce.core.pubsub.RedisPubSubListener; import cn.hamster3.mc.plugin.core.lib.io.lettuce.core.pubsub.RedisPubSubListener;
import com.google.common.eventbus.EventBus;
public class BallRedisListener implements RedisPubSubListener<String, BallMessage> { public class BallRedisListener implements RedisPubSubListener<String, BallMessage> {
public static final BallRedisListener INSTANCE = new BallRedisListener(); public static final BallRedisListener INSTANCE = new BallRedisListener();
@@ -22,104 +23,105 @@ public class BallRedisListener implements RedisPubSubListener<String, BallMessag
if (channel.startsWith(BallAPI.getInstance().getBallConfig().getChannelPrefix())) { if (channel.startsWith(BallAPI.getInstance().getBallConfig().getChannelPrefix())) {
channel = channel.substring(BallAPI.getInstance().getBallConfig().getChannelPrefix().length()); channel = channel.substring(BallAPI.getInstance().getBallConfig().getChannelPrefix().length());
} }
BallAPI api = BallAPI.getInstance(); BallAPI ballAPI = BallAPI.getInstance();
if (ballMessage.getReceiverType() != null && ballMessage.getReceiverType() != api.getLocalServerInfo().getType()) { EventBus eventBus = ballAPI.getEventBus();
if (ballMessage.getReceiverType() != null && ballMessage.getReceiverType() != ballAPI.getLocalServerInfo().getType()) {
return; return;
} }
if (ballMessage.getReceiverID() != null && !api.isLocalServer(ballMessage.getReceiverID())) { if (ballMessage.getReceiverID() != null && !ballAPI.isLocalServer(ballMessage.getReceiverID())) {
return; return;
} }
api.getEventBus().post(new MessageReceivedEvent(channel, ballMessage)); eventBus.post(new MessageReceivedEvent(channel, ballMessage));
if (!BallAPI.BALL_CHANNEL.equals(channel)) { if (!BallAPI.BALL_CHANNEL.equals(channel)) {
return; return;
} }
switch (BallActions.valueOf(ballMessage.getAction())) { switch (BallActions.valueOf(ballMessage.getAction())) {
case BroadcastPlayerMessage: { case BroadcastPlayerMessage: {
BroadcastPlayerMessageEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BroadcastPlayerMessageEvent.class); BroadcastPlayerMessageEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BroadcastPlayerMessageEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case DispatchConsoleCommand: { case DispatchConsoleCommand: {
DispatchConsoleCommandEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), DispatchConsoleCommandEvent.class); DispatchConsoleCommandEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), DispatchConsoleCommandEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case DispatchPlayerCommand: { case DispatchPlayerCommand: {
DispatchPlayerCommandEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), DispatchPlayerCommandEvent.class); DispatchPlayerCommandEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), DispatchPlayerCommandEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case KickPlayer: { case KickPlayer: {
KickPlayerEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), KickPlayerEvent.class); KickPlayerEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), KickPlayerEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case SendMessageToPlayer: { case SendMessageToPlayer: {
SendMessageToPlayerEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), SendMessageToPlayerEvent.class); SendMessageToPlayerEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), SendMessageToPlayerEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case SendPlayerToLocation: { case SendPlayerToLocation: {
SendPlayerToLocationEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), SendPlayerToLocationEvent.class); SendPlayerToLocationEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), SendPlayerToLocationEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case SendPlayerToPlayer: { case SendPlayerToPlayer: {
SendPlayerToPlayerEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), SendPlayerToPlayerEvent.class); SendPlayerToPlayerEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), SendPlayerToPlayerEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case BallPlayerPreLogin: { case BallPlayerPreLogin: {
BallPlayerPreLoginEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerPreLoginEvent.class); BallPlayerPreLoginEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerPreLoginEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case BallPlayerLogin: { case BallPlayerLogin: {
BallPlayerLoginEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerLoginEvent.class); BallPlayerLoginEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerLoginEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case BallPlayerPostLogin: { case BallPlayerPostLogin: {
BallPlayerPostLoginEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerPostLoginEvent.class); BallPlayerPostLoginEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerPostLoginEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case BallPlayerPreConnectServer: { case BallPlayerPreConnectServer: {
BallPlayerPreConnectServerEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerPreConnectServerEvent.class); BallPlayerPreConnectServerEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerPreConnectServerEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case BallPlayerConnectServer: { case BallPlayerConnectServer: {
BallPlayerConnectServerEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerConnectServerEvent.class); BallPlayerConnectServerEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerConnectServerEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case BallPlayerPostConnectServer: { case BallPlayerPostConnectServer: {
BallPlayerPostConnectServerEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerPostConnectServerEvent.class); BallPlayerPostConnectServerEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerPostConnectServerEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case BallPlayerLogout: { case BallPlayerLogout: {
BallPlayerLogoutEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerLogoutEvent.class); BallPlayerLogoutEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerLogoutEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case BallPlayerInfoUpdate: { case BallPlayerInfoUpdate: {
BallPlayerInfoUpdateEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerInfoUpdateEvent.class); BallPlayerInfoUpdateEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), BallPlayerInfoUpdateEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case ServerOffline: { case ServerOffline: {
ServerOfflineEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), ServerOfflineEvent.class); ServerOfflineEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), ServerOfflineEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
case ServerOnline: { case ServerOnline: {
ServerOnlineEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), ServerOnlineEvent.class); ServerOnlineEvent event = CoreAPI.getInstance().getGson().fromJson(ballMessage.getContent(), ServerOnlineEvent.class);
api.getEventBus().post(event); eventBus.post(event);
break; break;
} }
} }

View File

@@ -5,7 +5,7 @@ plugins {
} }
group = "cn.hamster3.mc.plugin" group = "cn.hamster3.mc.plugin"
version = "1.5.1" version = "1.5.2"
subprojects { subprojects {
apply { apply {