feat(ball-velocity): 添加 velocity 支持
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
package cn.hamster3.mc.plugin.ball.velocity;
|
||||
|
||||
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.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.util.BallVelocityUtils;
|
||||
import com.google.inject.Inject;
|
||||
import com.velocitypowered.api.event.PostOrder;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
|
||||
import com.velocitypowered.api.plugin.Dependency;
|
||||
import com.velocitypowered.api.plugin.Plugin;
|
||||
import com.velocitypowered.api.plugin.annotation.DataDirectory;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import lombok.Getter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@Plugin(
|
||||
id = "hamster-ball",
|
||||
name = "HamsterBall",
|
||||
version = BuildConstants.VERSION,
|
||||
description = BuildConstants.DESCRIPTION,
|
||||
authors = {"MiniDay"},
|
||||
dependencies = @Dependency(id = "hamster-core")
|
||||
)
|
||||
public class HamsterBallPlugin {
|
||||
@Getter
|
||||
private static HamsterBallPlugin instance;
|
||||
@Getter
|
||||
private final java.util.logging.Logger logger;
|
||||
@Getter
|
||||
private final Logger slf4jLogger;
|
||||
@Getter
|
||||
private final ProxyServer proxyServer;
|
||||
@Getter
|
||||
private final File dataFolder;
|
||||
|
||||
@Inject
|
||||
public HamsterBallPlugin(Logger slf4jLogger, ProxyServer proxyServer, @DataDirectory Path dataPath) {
|
||||
long start = System.currentTimeMillis();
|
||||
logger = java.util.logging.Logger.getLogger("hamster-ball");
|
||||
this.slf4jLogger = slf4jLogger;
|
||||
this.proxyServer = proxyServer;
|
||||
dataFolder = dataPath.toFile();
|
||||
logger.info("仓鼠球正在初始化");
|
||||
instance = this;
|
||||
try {
|
||||
File dataFolder = getDataFolder();
|
||||
if (dataFolder.mkdir()) {
|
||||
logger.info("已生成插件存档文件夹");
|
||||
}
|
||||
File configFile = new File(dataFolder, "config.yml");
|
||||
if (!configFile.exists()) {
|
||||
Files.copy(
|
||||
Objects.requireNonNull(getClass().getResourceAsStream("/config.yml")),
|
||||
configFile.toPath(),
|
||||
StandardCopyOption.REPLACE_EXISTING
|
||||
);
|
||||
}
|
||||
CoreVelocityAPI.init(configFile);
|
||||
logger.info("已初始化 BallAPI");
|
||||
} catch (Exception e) {
|
||||
slf4jLogger.error("BallAPI 初始化失败", e);
|
||||
proxyServer.shutdown(Component.text("由于 HamsterBall 初始化失败, 服务器将立即关闭"));
|
||||
}
|
||||
long time = System.currentTimeMillis() - start;
|
||||
logger.info("仓鼠球初始化完成,总计耗时 " + time + " ms");
|
||||
}
|
||||
|
||||
@Subscribe(order = PostOrder.EARLY)
|
||||
public void onProxyInitialization(ProxyInitializeEvent event) {
|
||||
long start = System.currentTimeMillis();
|
||||
java.util.logging.Logger logger = getLogger();
|
||||
logger.info("仓鼠球正在启动");
|
||||
try {
|
||||
CoreVelocityAPI.getInstance().enable();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "仓鼠球启动失败", e);
|
||||
logger.info("由于仓鼠球启动失败,服务器将立即关闭");
|
||||
proxyServer.shutdown(Component.text("仓鼠球启动失败"));
|
||||
return;
|
||||
}
|
||||
BallAPI.getInstance().getEventBus().register(BallVelocityListener.INSTANCE);
|
||||
logger.info("已注册监听器 BallBungeeListener");
|
||||
proxyServer.getEventManager().register(this, BallVelocityMainListener.INSTANCE);
|
||||
logger.info("已注册监听器 BallBungeeMainListener");
|
||||
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().sendRawBallMessage(
|
||||
BallAPI.BALL_CHANNEL, BallActions.ServerOnline.name(),
|
||||
new ServerOnlineEvent(BallAPI.getInstance().getLocalServerInfo())
|
||||
);
|
||||
// 移除失效的在线玩家
|
||||
BallAPI.getInstance().getAllPlayerInfo().values()
|
||||
.stream()
|
||||
.filter(BallPlayerInfo::isOnline)
|
||||
.filter(o -> BallAPI.getInstance().isLocalServer(o.getProxyServer()))
|
||||
.forEach(playerInfo -> {
|
||||
playerInfo.setOnline(false);
|
||||
BallVelocityUtils.uploadPlayerInfo(playerInfo);
|
||||
});
|
||||
long time = System.currentTimeMillis() - start;
|
||||
logger.info("仓鼠球启动完成,总计耗时 " + time + " ms");
|
||||
}
|
||||
|
||||
@Subscribe(order = PostOrder.LATE)
|
||||
public void onProxyShutdown(ProxyShutdownEvent event) {
|
||||
long start = System.currentTimeMillis();
|
||||
java.util.logging.Logger logger = getLogger();
|
||||
logger.info("仓鼠球正在关闭");
|
||||
try {
|
||||
CoreVelocityAPI.getInstance().disable();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "关闭仓鼠球时遇到了一个异常", e);
|
||||
}
|
||||
long time = System.currentTimeMillis() - start;
|
||||
logger.info("仓鼠球已关闭,总计耗时 " + time + " ms");
|
||||
}
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
package cn.hamster3.mc.plugin.ball.velocity.api;
|
||||
|
||||
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
||||
import cn.hamster3.mc.plugin.ball.common.entity.BallServerType;
|
||||
import cn.hamster3.mc.plugin.ball.velocity.HamsterBallPlugin;
|
||||
import cn.hamster3.mc.plugin.core.common.config.ConfigSection;
|
||||
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;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class CoreVelocityAPI extends BallAPI {
|
||||
public CoreVelocityAPI(@NotNull ConfigSection config) {
|
||||
super(config, BallServerType.PROXY);
|
||||
}
|
||||
|
||||
public static CoreVelocityAPI getInstance() {
|
||||
return (CoreVelocityAPI) instance;
|
||||
}
|
||||
|
||||
public static void init(@NotNull File configFile) throws IOException {
|
||||
if (instance != null) {
|
||||
return;
|
||||
}
|
||||
YamlConfig config = YamlConfig.load(configFile);
|
||||
instance = new CoreVelocityAPI(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enable() throws SQLException, InterruptedException {
|
||||
ProxyConfig config = HamsterBallPlugin.getInstance().getProxyServer().getConfiguration();
|
||||
try {
|
||||
Field field = config.getClass().getDeclaredField("bind");
|
||||
field.setAccessible(true);
|
||||
String bind = (String) field.get(config);
|
||||
int i = bind.lastIndexOf(":");
|
||||
String substring = bind.substring(i + 1);
|
||||
instance.getLocalServerInfo().setHost(bind.substring(0, i));
|
||||
instance.getLocalServerInfo().setPort(Integer.parseInt(substring));
|
||||
} catch (Exception e) {
|
||||
HamsterBallPlugin.getInstance().getSlf4jLogger().error("获取 Velocity 监听端口时遇到了一个异常", e);
|
||||
}
|
||||
super.enable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() throws SQLException, InterruptedException {
|
||||
super.disable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Logger getLogger() {
|
||||
return HamsterBallPlugin.getInstance().getLogger();
|
||||
}
|
||||
}
|
@@ -0,0 +1,121 @@
|
||||
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.BallServerType;
|
||||
import cn.hamster3.mc.plugin.ball.common.event.operate.*;
|
||||
import cn.hamster3.mc.plugin.ball.velocity.HamsterBallPlugin;
|
||||
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import com.velocitypowered.api.proxy.ServerConnection;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import com.velocitypowered.api.proxy.server.ServerInfo;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class BallVelocityListener {
|
||||
public static final BallVelocityListener INSTANCE = new BallVelocityListener();
|
||||
|
||||
private BallVelocityListener() {
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDispatchConsoleCommand(DispatchConsoleCommandEvent event) {
|
||||
if (event.getType() != null && event.getType() != BallServerType.PROXY) {
|
||||
return;
|
||||
}
|
||||
if (event.getServerID() != null && !BallAPI.getInstance().isLocalServer(event.getServerID())) {
|
||||
return;
|
||||
}
|
||||
ProxyServer server = HamsterBallPlugin.getInstance().getProxyServer();
|
||||
server.getCommandManager().executeAsync(server.getConsoleCommandSource(), event.getCommand());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDispatchPlayerCommand(DispatchPlayerCommandEvent event) {
|
||||
if (event.getType() != null && event.getType() != BallServerType.GAME) {
|
||||
return;
|
||||
}
|
||||
ProxyServer server = HamsterBallPlugin.getInstance().getProxyServer();
|
||||
if (event.getUuid() != null) {
|
||||
Player player = server.getPlayer(event.getUuid()).orElse(null);
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
server.getCommandManager().executeAsync(player, event.getCommand());
|
||||
return;
|
||||
}
|
||||
for (Player player : server.getAllPlayers()) {
|
||||
server.getCommandManager().executeAsync(player, event.getCommand());
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onKickPlayer(KickPlayerEvent event) {
|
||||
ProxyServer server = HamsterBallPlugin.getInstance().getProxyServer();
|
||||
Player player = server.getPlayer(event.getUuid()).orElse(null);
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
player.disconnect(event.getReason());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSendMessageToPlayer(SendMessageToPlayerEvent event) {
|
||||
for (UUID receiver : event.getReceivers()) {
|
||||
Audience audience = CoreAPI.getInstance().getAudienceProvider().player(receiver);
|
||||
event.getMessage().show(audience);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSendPlayerToLocation(SendPlayerToLocationEvent event) {
|
||||
ProxyServer proxyServer = HamsterBallPlugin.getInstance().getProxyServer();
|
||||
String serverID = event.getLocation().getServerID();
|
||||
RegisteredServer toServer = proxyServer.getServer(serverID).orElse(null);
|
||||
if (toServer == null) {
|
||||
HamsterBallPlugin.getInstance().getLogger().warning("试图传送玩家时失败: 服务器 " + serverID + " 不在线");
|
||||
return;
|
||||
}
|
||||
for (UUID uuid : event.getSendPlayerUUID()) {
|
||||
Player player = proxyServer.getPlayer(uuid).orElse(null);
|
||||
if (player == null) {
|
||||
continue;
|
||||
}
|
||||
RegisteredServer currentServer = player.getCurrentServer().map(ServerConnection::getServer).orElse(null);
|
||||
if (currentServer != null && currentServer.getServerInfo().getName().equals(serverID)) {
|
||||
continue;
|
||||
}
|
||||
player.createConnectionRequest(toServer).fireAndForget();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSendPlayerToPlayer(SendPlayerToPlayerEvent event) {
|
||||
ProxyServer proxyServer = HamsterBallPlugin.getInstance().getProxyServer();
|
||||
UUID toPlayerUUID = event.getToPlayerUUID();
|
||||
Player toPlayer = proxyServer.getPlayer(toPlayerUUID).orElse(null);
|
||||
if (toPlayer == null) {
|
||||
HamsterBallPlugin.getInstance().getLogger().warning("试图传送玩家时失败: 目标玩家 " + toPlayerUUID + " 不在线");
|
||||
return;
|
||||
}
|
||||
RegisteredServer toServer = toPlayer.getCurrentServer().map(ServerConnection::getServer).orElse(null);
|
||||
if (toServer == null) {
|
||||
HamsterBallPlugin.getInstance().getLogger().warning("试图传送玩家时失败: 目标玩家 " + toPlayerUUID + " 不在任何服务器中");
|
||||
return;
|
||||
}
|
||||
for (UUID uuid : event.getSendPlayerUUID()) {
|
||||
Player sendPlayer = proxyServer.getPlayer(uuid).orElse(null);
|
||||
if (sendPlayer == null) {
|
||||
continue;
|
||||
}
|
||||
ServerInfo currentServer = sendPlayer.getCurrentServer().map(ServerConnection::getServerInfo).orElse(null);
|
||||
if (currentServer != null && currentServer.getName().equals(toServer.getServerInfo().getName())) {
|
||||
continue;
|
||||
}
|
||||
sendPlayer.createConnectionRequest(toServer).fireAndForget();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
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.BallPlayerInfo;
|
||||
import cn.hamster3.mc.plugin.ball.common.event.BallActions;
|
||||
import cn.hamster3.mc.plugin.ball.common.event.player.BallPlayerLoginEvent;
|
||||
import cn.hamster3.mc.plugin.ball.common.event.player.BallPlayerPostLoginEvent;
|
||||
import cn.hamster3.mc.plugin.ball.common.event.player.BallPlayerPreLoginEvent;
|
||||
import cn.hamster3.mc.plugin.ball.velocity.util.BallVelocityUtils;
|
||||
import com.velocitypowered.api.event.PostOrder;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.LoginEvent;
|
||||
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||
import com.velocitypowered.api.event.connection.PreLoginEvent;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
|
||||
public final class BallVelocityMainListener {
|
||||
public static final BallVelocityMainListener INSTANCE = new BallVelocityMainListener();
|
||||
|
||||
private BallVelocityMainListener() {
|
||||
}
|
||||
|
||||
@Subscribe(order = PostOrder.LATE)
|
||||
public void onPreLogin(PreLoginEvent event) {
|
||||
BallAPI.getInstance().sendRawBallMessage(
|
||||
BallAPI.BALL_CHANNEL,
|
||||
BallActions.BallPlayerPreLogin.name(),
|
||||
new BallPlayerPreLoginEvent(event.getUsername())
|
||||
);
|
||||
}
|
||||
|
||||
@Subscribe(order = PostOrder.LATE)
|
||||
public void onLogin(LoginEvent event) {
|
||||
if (!event.getResult().isAllowed()) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getPlayer();
|
||||
BallAPI.getInstance().sendRawBallMessage(
|
||||
BallAPI.BALL_CHANNEL,
|
||||
BallActions.BallPlayerLogin.name(),
|
||||
new BallPlayerLoginEvent(new BallPlayerInfo(
|
||||
player.getUniqueId(), player.getUsername(), "connecting",
|
||||
BallAPI.getInstance().getLocalServerId(), true
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
@Subscribe(order = PostOrder.LATE)
|
||||
public void onPostLogin(PostLoginEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
BallPlayerInfo playerInfo = BallVelocityUtils.getPlayerInfo(player, true);
|
||||
BallAPI.getInstance().sendRawBallMessage(
|
||||
BallAPI.BALL_CHANNEL,
|
||||
BallActions.BallPlayerPostLogin.name(),
|
||||
new BallPlayerPostLoginEvent(playerInfo)
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
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.BallPlayerInfo;
|
||||
import cn.hamster3.mc.plugin.ball.common.event.BallActions;
|
||||
import cn.hamster3.mc.plugin.ball.common.event.player.BallPlayerLogoutEvent;
|
||||
import cn.hamster3.mc.plugin.ball.common.event.player.BallPlayerPostConnectServerEvent;
|
||||
import cn.hamster3.mc.plugin.ball.common.event.player.BallPlayerPreConnectServerEvent;
|
||||
import cn.hamster3.mc.plugin.ball.velocity.util.BallVelocityUtils;
|
||||
import com.velocitypowered.api.event.PostOrder;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
|
||||
import com.velocitypowered.api.event.player.ServerPreConnectEvent;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
|
||||
public class UpdatePlayerInfoListener {
|
||||
public static final UpdatePlayerInfoListener INSTANCE = new UpdatePlayerInfoListener();
|
||||
|
||||
private UpdatePlayerInfoListener() {
|
||||
}
|
||||
|
||||
@Subscribe(order = PostOrder.LATE)
|
||||
public void onServerConnect(ServerPreConnectEvent event) {
|
||||
if (event.getResult().isAllowed()) {
|
||||
return;
|
||||
}
|
||||
String name = event.getResult().getServer()
|
||||
.map(o -> o.getServerInfo().getName())
|
||||
.orElse(event.getOriginalServer().getServerInfo().getName());
|
||||
Player player = event.getPlayer();
|
||||
BallPlayerInfo playerInfo = BallVelocityUtils.getPlayerInfo(player, true);
|
||||
playerInfo.setGameServer(name);
|
||||
BallAPI.getInstance().sendRawBallMessage(
|
||||
BallAPI.BALL_CHANNEL,
|
||||
BallActions.BallPlayerPreConnectServer.name(),
|
||||
new BallPlayerPreConnectServerEvent(playerInfo, playerInfo.getGameServer(), name)
|
||||
);
|
||||
BallVelocityUtils.uploadPlayerInfo(playerInfo);
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@Subscribe(order = PostOrder.LATE)
|
||||
public void onServerPostConnect(ServerPostConnectEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
BallPlayerInfo playerInfo = BallVelocityUtils.getPlayerInfo(player, true);
|
||||
playerInfo.setGameServer(player.getCurrentServer().map(o -> o.getServerInfo().getName()).orElse(""));
|
||||
BallAPI.getInstance().sendRawBallMessage(
|
||||
BallAPI.BALL_CHANNEL,
|
||||
BallActions.BallPlayerPostConnectServer.name(),
|
||||
new BallPlayerPostConnectServerEvent(playerInfo)
|
||||
);
|
||||
BallVelocityUtils.uploadPlayerInfo(playerInfo);
|
||||
}
|
||||
|
||||
@Subscribe(order = PostOrder.LATE)
|
||||
public void onDisconnect(DisconnectEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
BallPlayerInfo playerInfo = BallVelocityUtils.getPlayerInfo(player, false);
|
||||
BallAPI.getInstance().sendRawBallMessage(
|
||||
BallAPI.BALL_CHANNEL,
|
||||
BallActions.BallPlayerLogout.name(),
|
||||
new BallPlayerLogoutEvent(playerInfo)
|
||||
);
|
||||
BallVelocityUtils.uploadPlayerInfo(playerInfo);
|
||||
}
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
package cn.hamster3.mc.plugin.ball.velocity.util;
|
||||
|
||||
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.player.BallPlayerInfoUpdateEvent;
|
||||
import cn.hamster3.mc.plugin.core.common.api.CoreAPI;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.ServerConnection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public final class BallVelocityUtils {
|
||||
private BallVelocityUtils() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static BallPlayerInfo getPlayerInfo(@NotNull Player player, boolean online) {
|
||||
ServerConnection server = player.getCurrentServer().orElse(null);
|
||||
return new BallPlayerInfo(
|
||||
player.getUniqueId(),
|
||||
player.getUsername(),
|
||||
server == null ? "connecting" : server.getServerInfo().getName(),
|
||||
BallAPI.getInstance().getLocalServerId(),
|
||||
online
|
||||
);
|
||||
}
|
||||
|
||||
public static void uploadPlayerInfo(@NotNull BallPlayerInfo playerInfo) {
|
||||
CoreAPI.getInstance().getExecutorService().execute(() -> {
|
||||
try (Connection connection = BallAPI.getInstance().getDatasource().getConnection()) {
|
||||
try (PreparedStatement statement = connection.prepareStatement(
|
||||
"REPLACE INTO `hamster_ball_player_info` VALUES(?, ?, ?, ?, ?);"
|
||||
)) {
|
||||
statement.setString(1, playerInfo.getUuid().toString());
|
||||
statement.setString(2, playerInfo.getName());
|
||||
statement.setString(3, playerInfo.getGameServer());
|
||||
statement.setString(4, playerInfo.getProxyServer());
|
||||
statement.setBoolean(5, playerInfo.isOnline());
|
||||
statement.executeUpdate();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
BallAPI.getInstance().getLogger().log(Level.SEVERE, "更新玩家数据时遇到了一个异常", e);
|
||||
}
|
||||
if (!BallAPI.getInstance().getBallConfig().isGameServerUpdatePlayerInfo()) {
|
||||
BallAPI.getInstance().sendRawBallMessage(
|
||||
BallAPI.PLAYER_INFO_CHANNEL,
|
||||
BallActions.BallPlayerInfoUpdate.name(),
|
||||
new BallPlayerInfoUpdateEvent(playerInfo)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
66
ball-velocity/src/main/resources/config.yml
Normal file
66
ball-velocity/src/main/resources/config.yml
Normal file
@@ -0,0 +1,66 @@
|
||||
# 是否允许在控制台输出调试信息
|
||||
debug: false
|
||||
|
||||
# 频道名前缀
|
||||
# 使用这个配置选项可以划分子服消息通信分组
|
||||
# 只有在同一个频道名的子服才能互相通信
|
||||
channel-prefix: ""
|
||||
|
||||
# 是否在子服端更新玩家信息
|
||||
# 默认情况下,BC 统一管理玩家信息,包括记录 UUID 和玩家名称
|
||||
# 如果一个群组服同时拥有多个 BC 入口
|
||||
# 且每个 BC 入口为不同的玩家名称分配不同的 UUID
|
||||
# (例如正版、盗版双入口,或网易多入口接同一个子服)
|
||||
# 则可以启用该功能以防止 UUID 紊乱的问题
|
||||
game-server-update-player-info: false
|
||||
|
||||
# 本服务器信息
|
||||
server-info:
|
||||
# 服务器唯一识别码,最长 32 字符
|
||||
id: "Velocity"
|
||||
# 服务端名称,常用于展示给玩家看
|
||||
name: "代理端"
|
||||
# 当前子服的地址
|
||||
# 不填则自动设置为 0.0.0.0
|
||||
host: 0.0.0.0
|
||||
# 当前子服端口
|
||||
# 不填则自动设置为 25577
|
||||
port: 25577
|
||||
|
||||
# 数据库连接池配置
|
||||
# 如果注释该选项则默认使用 HamsterCore 中的连接池配置
|
||||
# 否则 HamsterBall 将会使用与 HamsterCore 不同的数据库链接
|
||||
# 如果你需要让每个服务器单独存储仓鼠球信息
|
||||
# 这个选项就会很有用
|
||||
#datasource:
|
||||
# # 数据库链接驱动地址
|
||||
# driver: "com.mysql.jdbc.Driver"
|
||||
# # 数据库链接填写格式:
|
||||
# # jdbc:mysql://{数据库地址}:{数据库端口}/{使用的库名}?参数
|
||||
# # 除非你知道自己在做什么,否则不建议随意更改参数
|
||||
# url: "jdbc:mysql://localhost:3306/Test1?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true"
|
||||
# # 用户名
|
||||
# username: "Test"
|
||||
# # 密码
|
||||
# password: "Test123.."
|
||||
# # 最小闲置链接数
|
||||
# # 推荐值:1~3
|
||||
# minimum-idle: 0
|
||||
# # 最大链接数
|
||||
# # 推荐值:不低于3
|
||||
# maximum-pool-size: 3
|
||||
# # 保持连接池可用的间隔
|
||||
# # 除非你的服务器数据库连接经常断开,否则不建议启用该选项
|
||||
# # 单位:毫秒
|
||||
# # 默认值为0(禁用)
|
||||
# keep-alive-time: 0
|
||||
# # 连接闲置回收时间
|
||||
# # 单位:毫秒
|
||||
# # 推荐值:600000(10分钟)
|
||||
# idle-timeout: 600000
|
||||
# # 链接最长存活时间
|
||||
# # 单位:毫秒
|
||||
# max-lifetime: 1800000
|
||||
# # 验证连接存活的超时时间
|
||||
# # 单位:毫秒
|
||||
# validation-timeout: 5000
|
6
ball-velocity/src/main/resources/jenkins.yml
Normal file
6
ball-velocity/src/main/resources/jenkins.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
BUILD_ID: ${BUILD_ID}
|
||||
BUILD_NUMBER: ${BUILD_NUMBER}
|
||||
BUILD_DISPLAY_NAME: ${BUILD_DISPLAY_NAME}
|
||||
JOB_URL: ${JOB_URL}
|
||||
BUILD_URL: ${BUILD_URL}
|
||||
GIT_COMMIT: ${GIT_COMMIT}
|
@@ -0,0 +1,8 @@
|
||||
package cn.hamster3.mc.plugin.ball.velocity;
|
||||
|
||||
// The constants are replaced before compilation
|
||||
@SuppressWarnings("unused")
|
||||
public class BuildConstants {
|
||||
public static final String VERSION = "${version}";
|
||||
public static final String DESCRIPTION = "${description}";
|
||||
}
|
Reference in New Issue
Block a user