perf: 重写部分代码
This commit is contained in:
@@ -14,6 +14,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.listener.BallListener;
|
||||
import cn.hamster3.mc.plugin.ball.common.listener.ListenerPriority;
|
||||
import cn.hamster3.mc.plugin.ball.common.utils.OS;
|
||||
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.util.CoreUtils;
|
||||
@@ -23,8 +24,7 @@ import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -55,7 +55,7 @@ public abstract class BallAPI {
|
||||
private final List<BallListener> listeners;
|
||||
|
||||
private final Bootstrap bootstrap;
|
||||
private final NioEventLoopGroup executors;
|
||||
private final EventLoopGroup executors;
|
||||
|
||||
protected boolean enabled;
|
||||
protected Channel channel;
|
||||
@@ -63,17 +63,23 @@ public abstract class BallAPI {
|
||||
protected BallAPI(@NotNull BallConfig config) {
|
||||
this.config = config;
|
||||
this.enabled = false;
|
||||
executors = new NioEventLoopGroup(config.getNioThread());
|
||||
|
||||
serverInfo = new ConcurrentHashMap<>();
|
||||
playerInfo = new ConcurrentHashMap<>();
|
||||
listeners = new ArrayList<>();
|
||||
|
||||
bootstrap = new Bootstrap();
|
||||
bootstrap.group(executors)
|
||||
.channel(NioSocketChannel.class)
|
||||
OS currentOS = OS.getCurrentOS();
|
||||
getLogger().info(String.format(
|
||||
"当前操作系统为: %s. 选择 IO 模式为: %s",
|
||||
currentOS.name(), currentOS.getIOModeName()
|
||||
));
|
||||
|
||||
executors = currentOS.getEventLoopGroup(config.getEventLoopThread());
|
||||
bootstrap = new Bootstrap()
|
||||
.group(executors)
|
||||
.channel(currentOS.getSocketChannel())
|
||||
.option(ChannelOption.TCP_NODELAY, true)
|
||||
.handler(BallChannelInitializer.INSTANCE);
|
||||
.handler(new BallChannelInitializer());
|
||||
|
||||
addListener(new BallListener() {
|
||||
@Override
|
||||
@@ -143,6 +149,13 @@ public abstract class BallAPI {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectRefused() {
|
||||
enabled = false;
|
||||
executors.shutdownGracefully();
|
||||
getLogger().info("连接至服务中心的请求被拒绝,已关闭仓鼠球。");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -165,9 +178,7 @@ public abstract class BallAPI {
|
||||
connect();
|
||||
|
||||
try (Connection connection = CoreAPI.getInstance().getConnection()) {
|
||||
|
||||
{
|
||||
Statement statement = connection.createStatement();
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.execute("CREATE TABLE IF NOT EXISTS `hamster_ball_player_info`(" +
|
||||
"`uuid` CHAR(36) PRIMARY KEY," +
|
||||
"`name` VARCHAR(16) NOT NULL," +
|
||||
@@ -186,53 +197,48 @@ public abstract class BallAPI {
|
||||
"`uuid` CHAR(36) NOT NULL," +
|
||||
"`message` TEXT NOT NULL" +
|
||||
") CHARSET utf8mb4;");
|
||||
statement.close();
|
||||
}
|
||||
|
||||
{
|
||||
PreparedStatement statement = connection.prepareStatement("REPLACE INTO `hamster_ball_server_info` VALUES(?, ?, ?, ?, ?);");
|
||||
try (PreparedStatement statement = connection.prepareStatement(
|
||||
"REPLACE INTO `hamster_ball_server_info` VALUES(?, ?, ?, ?, ?);"
|
||||
)) {
|
||||
statement.setString(1, localInfo.getId());
|
||||
statement.setString(2, localInfo.getName());
|
||||
statement.setString(3, localInfo.getType().name());
|
||||
statement.setString(4, localInfo.getHost());
|
||||
statement.setInt(5, localInfo.getPort());
|
||||
statement.executeUpdate();
|
||||
statement.close();
|
||||
}
|
||||
|
||||
{
|
||||
PreparedStatement statement = connection.prepareStatement("SELECT * FROM `hamster_ball_server_info`;");
|
||||
ResultSet set = statement.executeQuery();
|
||||
while (set.next()) {
|
||||
String serverID = set.getString("id");
|
||||
serverInfo.put(serverID, new BallServerInfo(
|
||||
serverID,
|
||||
set.getString("name"),
|
||||
BallServerType.valueOf(set.getString("type")),
|
||||
set.getString("host"),
|
||||
set.getInt("port")
|
||||
));
|
||||
try (PreparedStatement statement = connection.prepareStatement(
|
||||
"SELECT * FROM `hamster_ball_server_info`;"
|
||||
)) {
|
||||
try (ResultSet set = statement.executeQuery()) {
|
||||
while (set.next()) {
|
||||
String serverID = set.getString("id");
|
||||
serverInfo.put(serverID, new BallServerInfo(
|
||||
serverID,
|
||||
set.getString("name"),
|
||||
BallServerType.valueOf(set.getString("type")),
|
||||
set.getString("host"),
|
||||
set.getInt("port")
|
||||
));
|
||||
}
|
||||
}
|
||||
set.close();
|
||||
statement.close();
|
||||
}
|
||||
|
||||
{
|
||||
PreparedStatement statement = connection.prepareStatement("SELECT * FROM `hamster_ball_player_info`;");
|
||||
ResultSet set = statement.executeQuery();
|
||||
while (set.next()) {
|
||||
UUID uuid = UUID.fromString(set.getString("uuid"));
|
||||
playerInfo.put(uuid, new BallPlayerInfo(uuid,
|
||||
set.getString("name"),
|
||||
set.getString("game_server"),
|
||||
set.getString("proxy_server"),
|
||||
set.getBoolean("online")
|
||||
));
|
||||
try (PreparedStatement statement = connection.prepareStatement(
|
||||
"SELECT * FROM `hamster_ball_player_info`;"
|
||||
)) {
|
||||
try (ResultSet set = statement.executeQuery()) {
|
||||
while (set.next()) {
|
||||
UUID uuid = UUID.fromString(set.getString("uuid"));
|
||||
playerInfo.put(uuid, new BallPlayerInfo(uuid,
|
||||
set.getString("name"),
|
||||
set.getString("game_server"),
|
||||
set.getString("proxy_server"),
|
||||
set.getBoolean("online")
|
||||
));
|
||||
}
|
||||
}
|
||||
set.close();
|
||||
statement.close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -15,5 +15,5 @@ public class BallConfig {
|
||||
private String host;
|
||||
private int port;
|
||||
|
||||
private int nioThread;
|
||||
private int eventLoopThread;
|
||||
}
|
||||
|
@@ -16,9 +16,7 @@ import java.util.logging.Level;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public class BallChannelHandler extends SimpleChannelInboundHandler<String> {
|
||||
public static final BallChannelHandler INSTANCE = new BallChannelHandler();
|
||||
|
||||
private BallChannelHandler() {
|
||||
public BallChannelHandler() {
|
||||
super(true);
|
||||
}
|
||||
|
||||
@@ -27,6 +25,12 @@ public class BallChannelHandler extends SimpleChannelInboundHandler<String> {
|
||||
if ("pong".equals(message)) {
|
||||
return;
|
||||
}
|
||||
if ("connection refused".equals(message)) {
|
||||
for (BallListener listener : BallAPI.getInstance().getListeners()) {
|
||||
listener.onConnectRefused();
|
||||
}
|
||||
return;
|
||||
}
|
||||
BallMessageInfo info = CoreUtils.GSON.fromJson(message, BallMessageInfo.class);
|
||||
for (BallListener listener : BallAPI.getInstance().getListeners()) {
|
||||
try {
|
||||
@@ -186,5 +190,4 @@ public class BallChannelHandler extends SimpleChannelInboundHandler<String> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -13,22 +13,19 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class BallChannelInitializer extends ChannelInitializer<NioSocketChannel> {
|
||||
public static final BallChannelInitializer INSTANCE = new BallChannelInitializer();
|
||||
|
||||
private BallChannelInitializer() {
|
||||
public BallChannelInitializer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initChannel(@NotNull NioSocketChannel channel) {
|
||||
channel.pipeline()
|
||||
.addLast(new IdleStateHandler(0, 7, 0, TimeUnit.SECONDS))
|
||||
.addLast(BallKeepAliveHandler.INSTANCE)
|
||||
.addLast(new BallKeepAliveHandler())
|
||||
.addLast(new LengthFieldPrepender(8))
|
||||
.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 8, 0, 8))
|
||||
.addLast(new StringDecoder(StandardCharsets.UTF_8))
|
||||
.addLast(new StringEncoder(StandardCharsets.UTF_8))
|
||||
.addLast(BallChannelHandler.INSTANCE);
|
||||
.addLast(new BallChannelHandler());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@@ -7,12 +7,6 @@ import io.netty.handler.timeout.IdleStateEvent;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public class BallKeepAliveHandler extends ChannelInboundHandlerAdapter {
|
||||
public static final BallKeepAliveHandler INSTANCE = new BallKeepAliveHandler();
|
||||
|
||||
private BallKeepAliveHandler() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void userEventTriggered(ChannelHandlerContext context, Object event) throws Exception {
|
||||
if (event instanceof IdleStateEvent) {
|
||||
|
@@ -106,7 +106,7 @@ public class BallMessageInfo {
|
||||
* @return json对象
|
||||
*/
|
||||
@NotNull
|
||||
public JsonObject saveToJson() {
|
||||
public JsonObject toJson() {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("channel", channel);
|
||||
object.addProperty("senderID", senderID);
|
||||
@@ -191,6 +191,6 @@ public class BallMessageInfo {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return saveToJson().toString();
|
||||
return toJson().toString();
|
||||
}
|
||||
}
|
||||
|
@@ -28,6 +28,9 @@ public interface BallListener {
|
||||
default void onConnectException(Throwable throwable) {
|
||||
}
|
||||
|
||||
default void onConnectRefused() {
|
||||
}
|
||||
|
||||
default void onServiceDead() {
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,84 @@
|
||||
package cn.hamster3.mc.plugin.ball.common.utils;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.ServerChannel;
|
||||
import io.netty.channel.epoll.EpollEventLoopGroup;
|
||||
import io.netty.channel.epoll.EpollServerSocketChannel;
|
||||
import io.netty.channel.epoll.EpollSocketChannel;
|
||||
import io.netty.channel.kqueue.KQueueEventLoopGroup;
|
||||
import io.netty.channel.kqueue.KQueueServerSocketChannel;
|
||||
import io.netty.channel.kqueue.KQueueSocketChannel;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public enum OS {
|
||||
WINDOWS,
|
||||
LINUX,
|
||||
MACOS,
|
||||
OTHER;
|
||||
|
||||
@NotNull
|
||||
public static OS getCurrentOS() {
|
||||
String s = System.getProperties().get("os.name").toString().toLowerCase();
|
||||
if (s.contains("windows")) {
|
||||
return WINDOWS;
|
||||
}
|
||||
if (s.contains("linux")) {
|
||||
return LINUX;
|
||||
}
|
||||
if (s.contains("mac")) {
|
||||
return MACOS;
|
||||
}
|
||||
return OTHER;
|
||||
}
|
||||
|
||||
public String getIOModeName() {
|
||||
switch (this) {
|
||||
case LINUX:
|
||||
return "epoll";
|
||||
case MACOS:
|
||||
return "kqueue";
|
||||
default:
|
||||
return "nio";
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EventLoopGroup getEventLoopGroup(int nThread) {
|
||||
switch (this) {
|
||||
case LINUX:
|
||||
return new EpollEventLoopGroup(nThread);
|
||||
case MACOS:
|
||||
return new KQueueEventLoopGroup(nThread);
|
||||
default:
|
||||
return new NioEventLoopGroup(nThread);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Class<? extends Channel> getSocketChannel() {
|
||||
switch (this) {
|
||||
case LINUX:
|
||||
return EpollSocketChannel.class;
|
||||
case MACOS:
|
||||
return KQueueSocketChannel.class;
|
||||
default:
|
||||
return NioSocketChannel.class;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Class<? extends ServerChannel> getServerSocketChannel() {
|
||||
switch (this) {
|
||||
case LINUX:
|
||||
return EpollServerSocketChannel.class;
|
||||
case MACOS:
|
||||
return KQueueServerSocketChannel.class;
|
||||
default:
|
||||
return NioServerSocketChannel.class;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user