From bada1567954848c098a59aa9a5e46b0cc5372261 Mon Sep 17 00:00:00 2001 From: Shuiling <1668589925@qq.com> Date: Thu, 28 Nov 2024 03:23:41 -0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=9E=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../catseedlogin/bukkit/Communication.java | 156 ++++++++++-------- .../catseedlogin/bungee/Communication.java | 73 +++++--- 2 files changed, 131 insertions(+), 98 deletions(-) diff --git a/src/main/java/cc/baka9/catseedlogin/bukkit/Communication.java b/src/main/java/cc/baka9/catseedlogin/bukkit/Communication.java index 9f803b4..59c031a 100644 --- a/src/main/java/cc/baka9/catseedlogin/bukkit/Communication.java +++ b/src/main/java/cc/baka9/catseedlogin/bukkit/Communication.java @@ -1,5 +1,12 @@ package cc.baka9.catseedlogin.bukkit; +import cc.baka9.catseedlogin.bukkit.database.Cache; +import cc.baka9.catseedlogin.bukkit.object.LoginPlayer; +import cc.baka9.catseedlogin.bukkit.object.LoginPlayerHelper; +import cc.baka9.catseedlogin.util.CommunicationAuth; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -7,120 +14,123 @@ import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -import cc.baka9.catseedlogin.bukkit.database.Cache; -import cc.baka9.catseedlogin.bukkit.object.LoginPlayer; -import cc.baka9.catseedlogin.bukkit.object.LoginPlayerHelper; -import cc.baka9.catseedlogin.util.CommunicationAuth; +/** + * bukkit 与 bc 的通讯交流 + */ public class Communication { private static ServerSocket serverSocket; - private static final ExecutorService executorService = Executors.newCachedThreadPool(); + /** + * 异步关闭 socket server + */ public static void socketServerStopAsync() { CatSeedLogin.instance.runTaskAsync(Communication::socketServerStop); } - public static synchronized void socketServerStop() { - closeServerSocket(serverSocket); + public static void socketServerStop() { + + if (serverSocket != null && !serverSocket.isClosed()) { + try { + serverSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + /** + * 异步启动 socket server 监听bc端发来的请求 + */ public static void socketServerStartAsync() { CatSeedLogin.instance.runTaskAsync(Communication::socketServerStart); } - private static synchronized void socketServerStart() { + /** + * 启动 socket server 监听bc端发来的请求 + */ + private static void socketServerStart() { try { InetAddress inetAddress = InetAddress.getByName(Config.BungeeCord.Host); serverSocket = new ServerSocket(Integer.parseInt(Config.BungeeCord.Port), 50, inetAddress); - acceptConnections(serverSocket); + while (!serverSocket.isClosed()) { + Socket socket; + try { + socket = serverSocket.accept(); + handleRequest(socket); + } catch (IOException e) { + break; + } + } } catch (UnknownHostException e) { - CatSeedLogin.instance.getLogger().warning("无法解析域名或IP地址: " + e.getMessage()); + CatSeedLogin.instance.getLogger().warning("无法解析域名或IP地址"); + e.printStackTrace(); } catch (IOException e) { - CatSeedLogin.instance.getLogger().warning("启动Socket服务器时发生错误: " + e.getMessage()); + e.printStackTrace(); } } - private static void acceptConnections(ServerSocket serverSocket) { - while (!serverSocket.isClosed()) { - try { - Socket socket = serverSocket.accept(); - executorService.submit(() -> handleRequest(socket)); - } catch (IOException e) { - if (serverSocket.isClosed()) break; - CatSeedLogin.instance.getLogger().warning("接受Socket连接时发生错误: " + e.getMessage()); - } - } - } - private static void handleRequest(Socket socket) { - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()))) { - String requestType = bufferedReader.readLine(); - if (requestType == null) return; - String playerName = bufferedReader.readLine(); - switch (requestType) { - case "Connect": - handleConnectRequest(socket, playerName); - break; - case "KeepLoggedIn": - String time = bufferedReader.readLine(); - String sign = bufferedReader.readLine(); - handleKeepLoggedInRequest(playerName, time, sign); - break; - default: - CatSeedLogin.instance.getLogger().warning("未知请求类型: " + requestType.trim()); - break; - } - } catch (IOException e) { - CatSeedLogin.instance.getLogger().warning("处理请求时发生错误: " + e.getMessage()); + /** + * 处理请求 + */ + private static void handleRequest(Socket socket) throws IOException { + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); + String requestType = bufferedReader.readLine(); + String playerName = bufferedReader.readLine(); + switch (requestType) { + case "Connect": + handleConnectRequest(socket, playerName); + break; + case "KeepLoggedIn": + String time = bufferedReader.readLine(); + String sign = bufferedReader.readLine(); + handleKeepLoggedInRequest(playerName, time, sign); + socket.close(); + break; + default: + break; } } private static void handleKeepLoggedInRequest(String playerName, String time, String sign) { + // 验证请求的合法性 + // 对比玩家名,时间戳,和authKey加密的结果(加密是因为如果登录服不在内网环境下,则可能会被人使用这个功能给发包来直接绕过登录) if (CommunicationAuth.encryption(playerName, time, Config.BungeeCord.AuthKey).equals(sign)) { - CatScheduler.runTask(() -> { + // 切换主线程给予登录状态 + Bukkit.getScheduler().runTask(CatSeedLogin.instance, () -> { LoginPlayer lp = Cache.getIgnoreCase(playerName); if (lp != null) { LoginPlayerHelper.add(lp); Player player = Bukkit.getPlayerExact(playerName); - if (player != null) player.updateInventory(); - } else { - CatSeedLogin.instance.getLogger().warning("玩家 " + playerName.trim() + " 未找到在缓存中。"); + if (player != null) { + player.updateInventory(); + } } + }); } } private static void handleConnectRequest(Socket socket, String playerName) { - CatScheduler.runTask(() -> { + // 切换主线程获取是否已登录 + Bukkit.getScheduler().runTask(CatSeedLogin.instance, () -> { boolean result = LoginPlayerHelper.isLogin(playerName); - sendConnectResultAsync(socket, result); - }); - } - private static void sendConnectResultAsync(Socket socket, boolean result) { - executorService.submit(() -> { - try (Socket autoCloseSocket = socket) { - autoCloseSocket.getOutputStream().write(result ? 1 : 0); - autoCloseSocket.getOutputStream().flush(); - } catch (IOException e) { - CatSeedLogin.instance.getLogger().warning("发送连接结果时发生错误: " + e.getMessage()); - } + // 切换异步线程返回结果 + CatSeedLogin.instance.runTaskAsync(() -> { + try { + socket.getOutputStream().write(result ? 1 : 0); + socket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + }); + }); } - private static void closeServerSocket(ServerSocket serverSocket) { - if (serverSocket != null && !serverSocket.isClosed()) { - try { - serverSocket.close(); - } catch (IOException e) { - CatSeedLogin.instance.getLogger().warning("关闭Socket服务器时发生错误: " + e.getMessage()); - } - } - } + } diff --git a/src/main/java/cc/baka9/catseedlogin/bungee/Communication.java b/src/main/java/cc/baka9/catseedlogin/bungee/Communication.java index e0818b6..05e7bbf 100644 --- a/src/main/java/cc/baka9/catseedlogin/bungee/Communication.java +++ b/src/main/java/cc/baka9/catseedlogin/bungee/Communication.java @@ -1,47 +1,70 @@ package cc.baka9.catseedlogin.bungee; -import java.net.Socket; -import java.io.IOException; +import cc.baka9.catseedlogin.util.CommunicationAuth; +import net.md_5.bungee.api.ProxyServer; + import java.io.BufferedWriter; +import java.io.IOException; import java.io.OutputStreamWriter; - -import cc.baka9.catseedlogin.util.CommunicationAuth; +import java.net.Socket; /** * bc 与 bukkit 的通讯交流 */ public class Communication { - private static final String HOST = Config.Host; - private static final int PORT = Config.Port; public static int sendConnectRequest(String playerName) { - return sendRequest("Connect", playerName); + try (Socket socket = getSocket(); BufferedWriter bufferedWriter = getSocketBufferedWriter(socket)) { + // 请求类型 + bufferedWriter.write("Connect"); + bufferedWriter.newLine(); + // 玩家名 + bufferedWriter.write(playerName); + bufferedWriter.newLine(); + + bufferedWriter.flush(); + return socket.getInputStream().read(); + } catch (IOException e) { + e.printStackTrace(); + } + return 0; } public static void sendKeepLoggedInRequest(String playerName) { - long currentTime = System.currentTimeMillis(); - String time = String.valueOf(currentTime); - String sign = CommunicationAuth.encryption(playerName, time, Config.AuthKey); - sendRequest("KeepLoggedIn", playerName, time, sign); - } + try (Socket socket = getSocket(); BufferedWriter bufferedWriter = getSocketBufferedWriter(socket)) { + // 请求类型 + bufferedWriter.write("KeepLoggedIn"); + bufferedWriter.newLine(); + // 玩家名 + bufferedWriter.write(playerName); + bufferedWriter.newLine(); + // 时间戳 + String time = String.valueOf(System.currentTimeMillis()); + bufferedWriter.write(time); + bufferedWriter.newLine(); + // 根据玩家名,时间戳,和authKey加密的结果(加密是因为如果登录服不在内网环境下,则可能会被人使用这个功能给发包来绕过登录) + String sign = CommunicationAuth.encryption(playerName, time, Config.AuthKey); + bufferedWriter.write(sign); + bufferedWriter.newLine(); - private static int sendRequest(String requestType, String... messages) { - try (Socket socket = new Socket(HOST, PORT); - BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))) { - writeMessage(writer, requestType, messages); - return socket.getInputStream().read(); + bufferedWriter.flush(); } catch (IOException e) { - return 0; + e.printStackTrace(); } } - private static void writeMessage(BufferedWriter writer, String requestType, String... messages) throws IOException { - writer.write(requestType); - writer.newLine(); - for (String message : messages) { - writer.write(message); - writer.newLine(); + private static Socket getSocket() throws IOException { + try { + return new Socket(Config.Host, Config.Port); + } catch (IOException e) { + ProxyServer.getInstance().getLogger().warning("§c请检查装载登录插件的子服是否在 bungeecord.yml 中开启了bungeecord功能,以及Host和Port是否与bc端的配置相同"); + throw new IOException(e); } - writer.flush(); } + + private static BufferedWriter getSocketBufferedWriter(Socket socket) throws IOException { + return new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); + } + + }