diff --git a/build.gradle b/build.gradle index 4041c1f..fc2a951 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group 'com.github.jie65535.opencommand' -version 'dev-1.3.0' +version 'dev-1.4.0' sourceCompatibility = 17 targetCompatibility = 17 diff --git a/src/main/java/com/github/jie65535/opencommand/EventListeners.java b/src/main/java/com/github/jie65535/opencommand/EventListeners.java index df27331..dde6596 100644 --- a/src/main/java/com/github/jie65535/opencommand/EventListeners.java +++ b/src/main/java/com/github/jie65535/opencommand/EventListeners.java @@ -1,7 +1,23 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand; import com.github.jie65535.opencommand.socket.SocketClient; -import com.github.jie65535.opencommand.socket.SocketUtils; import com.github.jie65535.opencommand.socket.packet.player.PlayerList; import emu.grasscutter.Grasscutter; import emu.grasscutter.game.player.Player; diff --git a/src/main/java/com/github/jie65535/opencommand/OpenCommandConfig.java b/src/main/java/com/github/jie65535/opencommand/OpenCommandConfig.java index 766bb5d..6b11438 100644 --- a/src/main/java/com/github/jie65535/opencommand/OpenCommandConfig.java +++ b/src/main/java/com/github/jie65535/opencommand/OpenCommandConfig.java @@ -18,12 +18,43 @@ package com.github.jie65535.opencommand; public class OpenCommandConfig { + /** + * 控制台 Token + */ public String consoleToken = ""; + + /** + * 验证码过期时间(单位秒) + */ public int codeExpirationTime_S = 60; + + /** + * 临时Token过期时间(单位秒) + */ public int tempTokenExpirationTime_S = 300; + + /** + * Token 最后使用过期时间(单位小时) + */ public int tokenLastUseExpirationTime_H = 48; + + /** + * Socket 端口 + */ public int socketPort = 5746; + + /** + * Socket Token + */ public String socketToken = ""; + + /** + * Socket 主机地址 + */ public String socketHost = "127.0.0.1"; + + /** + * Socket 显示名称 + */ public String socketDisplayName = ""; } diff --git a/src/main/java/com/github/jie65535/opencommand/OpenCommandHandler.java b/src/main/java/com/github/jie65535/opencommand/OpenCommandHandler.java index 5b2a92a..4ca1722 100644 --- a/src/main/java/com/github/jie65535/opencommand/OpenCommandHandler.java +++ b/src/main/java/com/github/jie65535/opencommand/OpenCommandHandler.java @@ -25,10 +25,8 @@ import emu.grasscutter.utils.Crypto; import emu.grasscutter.utils.MessageHandler; import emu.grasscutter.utils.Utils; -import express.Express; -import express.http.Request; -import express.http.Response; import io.javalin.Javalin; +import io.javalin.http.Context; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; @@ -40,8 +38,8 @@ public final class OpenCommandHandler implements Router { @Override - public void applyRoutes(Express express, Javalin javalin) { - express.post("/opencommand/api", OpenCommandHandler::handle); + public void applyRoutes(Javalin javalin) { + javalin.post("/opencommand/api", OpenCommandHandler::handle); } private static final Map clients = new HashMap<>(); @@ -49,25 +47,24 @@ public void applyRoutes(Express express, Javalin javalin) { private static final Map codes = new HashMap<>(); private static final Int2ObjectMap codeExpireTime = new Int2ObjectOpenHashMap<>(); - public static void handle(Request request, Response response) { + public static void handle(Context context) { // Trigger cleanup action cleanupExpiredData(); var plugin = OpenCommandPlugin.getInstance(); var config = plugin.getConfig(); var now = new Date(); - var req = request.body(JsonRequest.class); - response.type("application/json"); + var req = context.bodyAsClass(JsonRequest.class); if (req.action.equals("sendCode")) { int playerId = (int) req.data; var player = plugin.getServer().getPlayerByUid(playerId); if (player == null) { - response.json(new JsonResponse(404, "Player Not Found.")); + context.json(new JsonResponse(404, "Player Not Found.")); } else { if (codeExpireTime.containsKey(playerId)) { var expireTime = codeExpireTime.get(playerId); if (now.before(expireTime)) { - response.json(new JsonResponse(403, "Requests are too frequent")); + context.json(new JsonResponse(403, "Requests are too frequent")); return; } } @@ -81,52 +78,52 @@ public static void handle(Request request, Response response) { codes.put(token, code); clients.put(token, playerId); player.dropMessage("[Open Command] Verification code: " + code); - response.json(new JsonResponse(token)); + context.json(new JsonResponse(token)); } return; } else if (req.action.equals("ping")) { - response.json(new JsonResponse()); + context.json(new JsonResponse()); return; } else if (req.action.equals("online")) { var p = new ArrayList(); plugin.getServer().getPlayers().forEach((uid, player) -> p.add(player.getNickname())); - response.json(new JsonResponse(200, "Success", new SocketData.OnlinePlayer(p))); + context.json(new JsonResponse(200, "Success", new SocketData.OnlinePlayer(p))); return; } // token is required if (req.token == null || req.token.isEmpty()) { - response.json(new JsonResponse(401, "Unauthorized")); + context.json(new JsonResponse(401, "Unauthorized")); return; } var isConsole = req.token.equals(config.consoleToken); if (!isConsole && !clients.containsKey(req.token)) { - response.json(new JsonResponse(401, "Unauthorized")); + context.json(new JsonResponse(401, "Unauthorized")); return; } if (isConsole) { if (req.action.equals("verify")) { - response.json(new JsonResponse()); + context.json(new JsonResponse()); return; } else if (req.action.equals("command")) { //noinspection SynchronizationOnLocalVariableOrMethodParameter synchronized (plugin) { try { - plugin.getLogger().info(String.format("IP: %s run command in console > %s", request.ip(), req.data)); + plugin.getLogger().info(String.format("IP: %s run command in console > %s", context.ip(), req.data)); var resultCollector = new MessageHandler(); EventListeners.setConsoleMessageHandler(resultCollector); CommandMap.getInstance().invoke(null, null, req.data.toString()); - response.json(new JsonResponse(resultCollector.getMessage())); + context.json(new JsonResponse(resultCollector.getMessage())); } catch (Exception e) { plugin.getLogger().warn("Run command failed.", e); EventListeners.setConsoleMessageHandler(null); - response.json(new JsonResponse(500, "error", e.getLocalizedMessage())); + context.json(new JsonResponse(500, "error", e.getLocalizedMessage())); } } return; } else if (req.action.equals("runmode")) { - response.json(new JsonResponse(200, "Success", 0)); + context.json(new JsonResponse(200, "Success", 0)); return; } } else if (codes.containsKey(req.token)) { @@ -135,10 +132,10 @@ public static void handle(Request request, Response response) { codes.remove(req.token); // update token expire time tokenExpireTime.put(req.token, new Date(now.getTime() + config.tokenLastUseExpirationTime_H * 60L * 60L * 1000L)); - response.json(new JsonResponse()); - plugin.getLogger().info(String.format("Player %d has passed the verification, ip: %s", clients.get(req.token), request.ip())); + context.json(new JsonResponse()); + plugin.getLogger().info(String.format("Player %d has passed the verification, ip: %s", clients.get(req.token), context.ip())); } else { - response.json(new JsonResponse(400, "Verification failed")); + context.json(new JsonResponse(400, "Verification failed")); } return; } @@ -150,7 +147,7 @@ public static void handle(Request request, Response response) { var player = plugin.getServer().getPlayerByUid(playerId); var command = req.data.toString(); if (player == null) { - response.json(new JsonResponse(404, "Player not found")); + context.json(new JsonResponse(404, "Player not found")); return; } // Player MessageHandler do not support concurrency @@ -160,10 +157,10 @@ public static void handle(Request request, Response response) { var resultCollector = new MessageHandler(); player.setMessageHandler(resultCollector); CommandMap.getInstance().invoke(player, player, command); - response.json(new JsonResponse(resultCollector.getMessage())); + context.json(new JsonResponse(resultCollector.getMessage())); } catch (Exception e) { plugin.getLogger().warn("Run command failed.", e); - response.json(new JsonResponse(500, "error", e.getLocalizedMessage())); + context.json(new JsonResponse(500, "error", e.getLocalizedMessage())); } finally { player.setMessageHandler(null); } @@ -171,7 +168,7 @@ public static void handle(Request request, Response response) { return; } } - response.json(new JsonResponse(403, "forbidden")); + context.json(new JsonResponse(403, "forbidden")); } private static void cleanupExpiredData() { diff --git a/src/main/java/com/github/jie65535/opencommand/OpenCommandOnlyHttpHandler.java b/src/main/java/com/github/jie65535/opencommand/OpenCommandOnlyHttpHandler.java index b3674f5..374d4c3 100644 --- a/src/main/java/com/github/jie65535/opencommand/OpenCommandOnlyHttpHandler.java +++ b/src/main/java/com/github/jie65535/opencommand/OpenCommandOnlyHttpHandler.java @@ -29,10 +29,8 @@ import emu.grasscutter.server.http.Router; import emu.grasscutter.utils.Crypto; import emu.grasscutter.utils.Utils; -import express.Express; -import express.http.Request; -import express.http.Response; import io.javalin.Javalin; +import io.javalin.http.Context; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; @@ -43,8 +41,8 @@ public final class OpenCommandOnlyHttpHandler implements Router { @Override - public void applyRoutes(Express express, Javalin javalin) { - express.post("/opencommand/api", OpenCommandOnlyHttpHandler::handle); + public void applyRoutes(Javalin javalin) { + javalin.post("/opencommand/api", OpenCommandOnlyHttpHandler::handle); } private static final Map clients = new HashMap<>(); @@ -52,25 +50,24 @@ public void applyRoutes(Express express, Javalin javalin) { private static final Map codes = new HashMap<>(); private static final Int2ObjectMap codeExpireTime = new Int2ObjectOpenHashMap<>(); - public static void handle(Request request, Response response) { + public static void handle(Context context) { // Trigger cleanup action cleanupExpiredData(); var plugin = OpenCommandPlugin.getInstance(); var config = plugin.getConfig(); var now = new Date(); - var req = request.body(JsonRequest.class); - response.type("application/json"); + var req = context.bodyAsClass(JsonRequest.class); if (req.action.equals("sendCode")) { int playerId = (int) req.data; var player = SocketData.getPlayer(playerId); if (player == null) { - response.json(new JsonResponse(404, "Player Not Found.")); + context.json(new JsonResponse(404, "Player Not Found.")); } else { if (codeExpireTime.containsKey(playerId)) { var expireTime = codeExpireTime.get(playerId); if (now.before(expireTime)) { - response.json(new JsonResponse(403, "Requests are too frequent")); + context.json(new JsonResponse(403, "Requests are too frequent")); return; } } @@ -84,39 +81,39 @@ public static void handle(Request request, Response response) { codes.put(token, code); clients.put(token, playerId); Player.dropMessage(playerId, "[Open Command] Verification code: " + code); - response.json(new JsonResponse(token)); + context.json(new JsonResponse(token)); } return; } else if (req.action.equals("ping")) { - response.json(new JsonResponse()); + context.json(new JsonResponse()); return; } else if (req.action.equals("online")) { - response.json(new JsonResponse(200, "Success", SocketData.getOnlinePlayer())); + context.json(new JsonResponse(200, "Success", SocketData.getOnlinePlayer())); return; } // token is required if (req.token == null || req.token.isEmpty()) { - response.json(new JsonResponse(401, "Unauthorized")); + context.json(new JsonResponse(401, "Unauthorized")); return; } var isConsole = req.token.equals(config.consoleToken); if (!isConsole && !clients.containsKey(req.token)) { - response.json(new JsonResponse(401, "Unauthorized")); + context.json(new JsonResponse(401, "Unauthorized")); return; } if (isConsole) { if (req.action.equals("verify")) { - response.json(new JsonResponse()); + context.json(new JsonResponse()); return; } else if (req.action.equals("command")) { var server = SocketServer.getClientInfoByUuid(req.server); if (server == null) { - response.json(new JsonResponse(404, "Server Not Found.")); + context.json(new JsonResponse(404, "Server Not Found.")); return; } - plugin.getLogger().info(String.format("IP: %s run command in console > %s", request.ip(), req.data)); + plugin.getLogger().info(String.format("IP: %s run command in console > %s", context.ip(), req.data)); var wait = new SocketDataWait(2000L) { @Override public void run() { @@ -135,16 +132,16 @@ public void timeout() { SocketServer.sendPacketAndWait(server.ip, new RunConsoleCommand(req.data.toString()), wait); var data = wait.getData(); if (data == null) { - response.json(new JsonResponse(408, "Timeout")); + context.json(new JsonResponse(408, "Timeout")); return; } - response.json(new JsonResponse(data.code, data.message, data.data)); + context.json(new JsonResponse(data.code, data.message, data.data)); return; } else if (req.action.equals("server")) { - response.json(new JsonResponse(200, "Success", SocketServer.getOnlineClient())); + context.json(new JsonResponse(200, "Success", SocketServer.getOnlineClient())); return; } else if (req.action.equals("runmode")) { - response.json(new JsonResponse(200, "Success", 1)); + context.json(new JsonResponse(200, "Success", 1)); return; } } else if (codes.containsKey(req.token)) { @@ -153,10 +150,10 @@ public void timeout() { codes.remove(req.token); // update token expire time tokenExpireTime.put(req.token, new Date(now.getTime() + config.tokenLastUseExpirationTime_H * 60L * 60L * 1000L)); - response.json(new JsonResponse()); - plugin.getLogger().info(String.format("Player %d has passed the verification, ip: %s", clients.get(req.token), request.ip())); + context.json(new JsonResponse()); + plugin.getLogger().info(String.format("Player %d has passed the verification, ip: %s", clients.get(req.token), context.ip())); } else { - response.json(new JsonResponse(400, "Verification failed")); + context.json(new JsonResponse(400, "Verification failed")); } return; } @@ -187,21 +184,21 @@ public void timeout() { player.data = command; if (!SocketServer.sendUidPacketAndWait(playerId, player, socketDataWait)) { - response.json(new JsonResponse(404, "Player Not Found.")); + context.json(new JsonResponse(404, "Player Not Found.")); return; } HttpPacket httpPacket = socketDataWait.getData(); if (httpPacket == null) { - response.json(new JsonResponse(500, "error", "Wait timeout")); + context.json(new JsonResponse(500, "error", "Wait timeout")); return; } - response.json(new JsonResponse(httpPacket.code, httpPacket.message)); + context.json(new JsonResponse(httpPacket.code, httpPacket.message)); return; } } - response.json(new JsonResponse(403, "forbidden")); + context.json(new JsonResponse(403, "forbidden")); } private static void cleanupExpiredData() { diff --git a/src/main/java/com/github/jie65535/opencommand/OpenCommandPlugin.java b/src/main/java/com/github/jie65535/opencommand/OpenCommandPlugin.java index 6337e37..b33fd71 100644 --- a/src/main/java/com/github/jie65535/opencommand/OpenCommandPlugin.java +++ b/src/main/java/com/github/jie65535/opencommand/OpenCommandPlugin.java @@ -26,11 +26,9 @@ import emu.grasscutter.server.event.game.ReceiveCommandFeedbackEvent; import emu.grasscutter.server.event.player.PlayerJoinEvent; import emu.grasscutter.server.event.player.PlayerQuitEvent; +import emu.grasscutter.utils.JsonUtils; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; public final class OpenCommandPlugin extends Plugin { @@ -42,10 +40,15 @@ public static OpenCommandPlugin getInstance() { private OpenCommandConfig config; + private Grasscutter.ServerRunMode runMode = Grasscutter.ServerRunMode.HYBRID; + @Override public void onLoad() { instance = this; + // 加载配置 loadConfig(); + // 启动Socket + startSocket(); } @Override @@ -54,7 +57,7 @@ public void onEnable() { .priority(HandlerPriority.HIGH) .listener(EventListeners::onCommandResponse) .register(this); - if (Grasscutter.getConfig().server.runMode == Grasscutter.ServerRunMode.GAME_ONLY) { + if (runMode == Grasscutter.ServerRunMode.GAME_ONLY) { // 仅运行游戏服务器时注册玩家加入和离开事件 new EventHandler<>(PlayerJoinEvent.class) .priority(HandlerPriority.HIGH) @@ -64,7 +67,7 @@ public void onEnable() { .priority(HandlerPriority.HIGH) .listener(EventListeners::onPlayerQuit) .register(this); - } else if (Grasscutter.getConfig().server.runMode == Grasscutter.ServerRunMode.DISPATCH_ONLY) { + } else if (runMode == Grasscutter.ServerRunMode.DISPATCH_ONLY) { getHandle().addRouter(OpenCommandOnlyHttpHandler.class); } else { getHandle().addRouter(OpenCommandHandler.class); @@ -86,29 +89,32 @@ private void loadConfig() { if (!configFile.exists()) { config = new OpenCommandConfig(); try (var file = new FileWriter(configFile)) { - file.write(Grasscutter.getGsonFactory().toJson(config)); + file.write(JsonUtils.encode(config)); } catch (IOException e) { getLogger().error("[OpenCommand] Unable to write to config file."); } catch (Exception e) { getLogger().error("[OpenCommand] Unable to save config file."); } } else { - try (var file = new FileReader(configFile)) { - config = Grasscutter.getGsonFactory().fromJson(file, OpenCommandConfig.class); + try { + config = JsonUtils.loadToClass(configFile.getAbsolutePath(), OpenCommandConfig.class); } catch (Exception exception) { config = new OpenCommandConfig(); getLogger().error("[OpenCommand] There was an error while trying to load the configuration from config.json. Please make sure that there are no syntax errors. If you want to start with a default configuration, delete your existing config.json."); } } - // 启动Socket - startSocket(); + try { + runMode = Grasscutter.getConfig().server.runMode; + } catch (Exception ex) { + getLogger().warn("[OpenCommand] Failed to load server configuration, default HYBRID mode is being used."); + } } private void startSocket() { - if (Grasscutter.getConfig().server.runMode == Grasscutter.ServerRunMode.GAME_ONLY) { + if (runMode == Grasscutter.ServerRunMode.GAME_ONLY) { getLogger().info("[OpenCommand] Starting socket client..."); SocketClient.connectServer(); - } else if (Grasscutter.getConfig().server.runMode == Grasscutter.ServerRunMode.DISPATCH_ONLY) { + } else if (runMode == Grasscutter.ServerRunMode.DISPATCH_ONLY) { getLogger().info("[OpenCommand] Starting socket server..."); try { SocketServer.startServer(); diff --git a/src/main/java/com/github/jie65535/opencommand/socket/ClientInfo.java b/src/main/java/com/github/jie65535/opencommand/socket/ClientInfo.java index df004f7..2d1e767 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/ClientInfo.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/ClientInfo.java @@ -1,3 +1,20 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket; public class ClientInfo { diff --git a/src/main/java/com/github/jie65535/opencommand/socket/SocketClient.java b/src/main/java/com/github/jie65535/opencommand/socket/SocketClient.java index 92245e5..2c92501 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/SocketClient.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/SocketClient.java @@ -1,3 +1,20 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket; import com.github.jie65535.opencommand.EventListeners; @@ -8,6 +25,7 @@ import com.github.jie65535.opencommand.socket.packet.player.PlayerList; import emu.grasscutter.Grasscutter; import emu.grasscutter.command.CommandMap; +import emu.grasscutter.utils.JsonUtils; import emu.grasscutter.utils.MessageHandler; import org.slf4j.Logger; @@ -122,18 +140,17 @@ public ReceiveThread(Socket socket) { @Override public void run() { - //noinspection InfiniteLoopStatement while (true) { try { if (exit) { return; } String data = SocketUtils.readString(is); - Packet packet = Grasscutter.getGsonFactory().fromJson(data, Packet.class); + Packet packet = JsonUtils.decode(data, Packet.class); switch (packet.type) { // 玩家类 case Player: - var player = Grasscutter.getGsonFactory().fromJson(packet.data, Player.class); + var player = JsonUtils.decode(packet.data, Player.class); switch (player.type) { // 运行命令 case RunCommand -> { @@ -170,7 +187,7 @@ public void run() { } break; case RunConsoleCommand: - var consoleCommand = Grasscutter.getGsonFactory().fromJson(packet.data, RunConsoleCommand.class); + var consoleCommand = JsonUtils.decode(packet.data, RunConsoleCommand.class); var plugin = OpenCommandPlugin.getInstance(); //noinspection SynchronizationOnLocalVariableOrMethodParameter synchronized (plugin) { diff --git a/src/main/java/com/github/jie65535/opencommand/socket/SocketData.java b/src/main/java/com/github/jie65535/opencommand/socket/SocketData.java index b05ba6b..9bf266c 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/SocketData.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/SocketData.java @@ -1,3 +1,20 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket; import com.github.jie65535.opencommand.socket.packet.player.PlayerList; diff --git a/src/main/java/com/github/jie65535/opencommand/socket/SocketDataWait.java b/src/main/java/com/github/jie65535/opencommand/socket/SocketDataWait.java index e1f8e0e..7a1ed71 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/SocketDataWait.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/SocketDataWait.java @@ -1,3 +1,20 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket; // 异步等待数据返回 diff --git a/src/main/java/com/github/jie65535/opencommand/socket/SocketServer.java b/src/main/java/com/github/jie65535/opencommand/socket/SocketServer.java index 4f2dde4..5837a34 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/SocketServer.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/SocketServer.java @@ -1,9 +1,26 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket; import com.github.jie65535.opencommand.OpenCommandPlugin; import com.github.jie65535.opencommand.socket.packet.*; import com.github.jie65535.opencommand.socket.packet.player.PlayerList; -import emu.grasscutter.Grasscutter; +import emu.grasscutter.utils.JsonUtils; import org.slf4j.Logger; import java.io.IOException; @@ -190,13 +207,12 @@ public boolean sendPacket(String packet, SocketDataWait socketDataWait) { @Override public void run() { - // noinspection InfiniteLoopStatement while (true) { try { String data = SocketUtils.readString(is); - Packet packet = Grasscutter.getGsonFactory().fromJson(data, Packet.class); + Packet packet = JsonUtils.decode(data, Packet.class); if (packet.type == PacketEnum.AuthPacket) { - AuthPacket authPacket = Grasscutter.getGsonFactory().fromJson(packet.data, AuthPacket.class); + AuthPacket authPacket = JsonUtils.decode(packet.data, AuthPacket.class); if (authPacket.token.equals(token)) { auth = true; displayName = authPacket.displayName; @@ -217,12 +233,12 @@ public void run() { switch (packet.type) { // 缓存玩家列表 case PlayerList -> { - PlayerList playerList = Grasscutter.getGsonFactory().fromJson(packet.data, PlayerList.class); + PlayerList playerList = JsonUtils.decode(packet.data, PlayerList.class); SocketData.playerList.put(address, playerList); } // Http信息返回 case HttpPacket -> { - HttpPacket httpPacket = Grasscutter.getGsonFactory().fromJson(packet.data, HttpPacket.class); + HttpPacket httpPacket = JsonUtils.decode(packet.data, HttpPacket.class); var socketWait = socketDataWaitList.get(packet.packetID); if (socketWait == null) { mLogger.error("[OpenCommand] HttpPacket: " + packet.packetID + " not found"); @@ -232,9 +248,7 @@ public void run() { socketDataWaitList.remove(packet.packetID); } // 心跳包 - case HeartBeat -> { - clientTimeout.put(address, 0); - } + case HeartBeat -> clientTimeout.put(address, 0); } } catch (Throwable e) { e.printStackTrace(); diff --git a/src/main/java/com/github/jie65535/opencommand/socket/SocketUtils.java b/src/main/java/com/github/jie65535/opencommand/socket/SocketUtils.java index 79ad9e9..7c7739a 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/SocketUtils.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/SocketUtils.java @@ -1,9 +1,25 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket; -import com.github.jie65535.opencommand.OpenCommandPlugin; import com.github.jie65535.opencommand.socket.packet.BasePacket; import com.github.jie65535.opencommand.socket.packet.Packet; -import emu.grasscutter.Grasscutter; +import emu.grasscutter.utils.JsonUtils; import java.io.IOException; import java.io.InputStream; @@ -26,7 +42,7 @@ public static String getPacket(BasePacket bPacket) { packet.type = bPacket.getType(); packet.data = bPacket.getPacket(); packet.packetID = UUID.randomUUID().toString(); - return Grasscutter.getGsonFactory().toJson(packet); + return JsonUtils.encode(packet); } /** @@ -43,7 +59,7 @@ public static List getPacketAndPackID(BasePacket bPacket) { List list = new ArrayList<>(); list.add(packet.packetID); - list.add(Grasscutter.getGsonFactory().toJson(packet)); + list.add(JsonUtils.encode(packet)); return list; } @@ -59,7 +75,7 @@ public static String getPacketAndPackID(BasePacket bPacket, String packetID) { packet.type = bPacket.getType(); packet.data = bPacket.getPacket(); packet.packetID = packetID; - return Grasscutter.getGsonFactory().toJson(packet); + return JsonUtils.encode(packet); } /** @@ -117,8 +133,7 @@ public static String readString(InputStream is) { } catch (IOException e) { e.printStackTrace(); } - String s = new String(sByte); - return s; + return new String(sByte); } /** diff --git a/src/main/java/com/github/jie65535/opencommand/socket/packet/AuthPacket.java b/src/main/java/com/github/jie65535/opencommand/socket/packet/AuthPacket.java index 768beea..dc0b4c8 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/packet/AuthPacket.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/packet/AuthPacket.java @@ -1,6 +1,23 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket.packet; -import emu.grasscutter.Grasscutter; +import emu.grasscutter.utils.JsonUtils; public class AuthPacket extends BasePacket { public String token; @@ -13,7 +30,7 @@ public AuthPacket(String token, String displayName) { @Override public String getPacket() { - return Grasscutter.getGsonFactory().toJson(this); + return JsonUtils.encode(this); } @Override diff --git a/src/main/java/com/github/jie65535/opencommand/socket/packet/BasePacket.java b/src/main/java/com/github/jie65535/opencommand/socket/packet/BasePacket.java index a04d977..8f52b09 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/packet/BasePacket.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/packet/BasePacket.java @@ -1,3 +1,20 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket.packet; // 基本数据包 diff --git a/src/main/java/com/github/jie65535/opencommand/socket/packet/HeartBeat.java b/src/main/java/com/github/jie65535/opencommand/socket/packet/HeartBeat.java index d109e40..cf202c2 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/packet/HeartBeat.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/packet/HeartBeat.java @@ -1,6 +1,23 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket.packet; -import emu.grasscutter.Grasscutter; +import emu.grasscutter.utils.JsonUtils; // 心跳包 public class HeartBeat extends BasePacket { @@ -12,7 +29,7 @@ public HeartBeat(String ping) { @Override public String getPacket() { - return Grasscutter.getGsonFactory().toJson(this); + return JsonUtils.encode(this); } @Override diff --git a/src/main/java/com/github/jie65535/opencommand/socket/packet/HttpPacket.java b/src/main/java/com/github/jie65535/opencommand/socket/packet/HttpPacket.java index 4e81e7d..ba3339d 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/packet/HttpPacket.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/packet/HttpPacket.java @@ -1,6 +1,23 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket.packet; -import emu.grasscutter.Grasscutter; +import emu.grasscutter.utils.JsonUtils; // http返回数据 public class HttpPacket extends BasePacket { @@ -24,7 +41,7 @@ public HttpPacket(String data) { @Override public String getPacket() { - return Grasscutter.getGsonFactory().toJson(this); + return JsonUtils.encode(this); } @Override diff --git a/src/main/java/com/github/jie65535/opencommand/socket/packet/Packet.java b/src/main/java/com/github/jie65535/opencommand/socket/packet/Packet.java index 6fe303a..3e3b175 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/packet/Packet.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/packet/Packet.java @@ -1,3 +1,20 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket.packet; // 数据包结构 diff --git a/src/main/java/com/github/jie65535/opencommand/socket/packet/PacketEnum.java b/src/main/java/com/github/jie65535/opencommand/socket/packet/PacketEnum.java index 54a8fdf..a8dc4ab 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/packet/PacketEnum.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/packet/PacketEnum.java @@ -1,3 +1,20 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket.packet; // 数据包类型列表 diff --git a/src/main/java/com/github/jie65535/opencommand/socket/packet/RunConsoleCommand.java b/src/main/java/com/github/jie65535/opencommand/socket/packet/RunConsoleCommand.java index 48d8d5a..36674ef 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/packet/RunConsoleCommand.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/packet/RunConsoleCommand.java @@ -1,6 +1,23 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket.packet; -import emu.grasscutter.Grasscutter; +import emu.grasscutter.utils.JsonUtils; public class RunConsoleCommand extends BasePacket { public String command; @@ -11,7 +28,7 @@ public RunConsoleCommand(String command) { @Override public String getPacket() { - return Grasscutter.getGsonFactory().toJson(this); + return JsonUtils.encode(this); } @Override diff --git a/src/main/java/com/github/jie65535/opencommand/socket/packet/player/Player.java b/src/main/java/com/github/jie65535/opencommand/socket/packet/player/Player.java index dd3f324..c821267 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/packet/player/Player.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/packet/player/Player.java @@ -1,9 +1,26 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket.packet.player; import com.github.jie65535.opencommand.socket.SocketServer; import com.github.jie65535.opencommand.socket.packet.BasePacket; import com.github.jie65535.opencommand.socket.packet.PacketEnum; -import emu.grasscutter.Grasscutter; +import emu.grasscutter.utils.JsonUtils; // 玩家操作类 public class Player extends BasePacket { @@ -13,7 +30,7 @@ public class Player extends BasePacket { @Override public String getPacket() { - return Grasscutter.getGsonFactory().toJson(this); + return JsonUtils.encode(this); } @Override diff --git a/src/main/java/com/github/jie65535/opencommand/socket/packet/player/PlayerEnum.java b/src/main/java/com/github/jie65535/opencommand/socket/packet/player/PlayerEnum.java index 155d45e..1fa1ce8 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/packet/player/PlayerEnum.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/packet/player/PlayerEnum.java @@ -1,3 +1,20 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket.packet.player; // 玩家操作列表 diff --git a/src/main/java/com/github/jie65535/opencommand/socket/packet/player/PlayerList.java b/src/main/java/com/github/jie65535/opencommand/socket/packet/player/PlayerList.java index a2782dc..faf8866 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/packet/player/PlayerList.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/packet/player/PlayerList.java @@ -1,9 +1,25 @@ +/* + * gc-opencommand + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package com.github.jie65535.opencommand.socket.packet.player; import com.github.jie65535.opencommand.socket.packet.BasePacket; import com.github.jie65535.opencommand.socket.packet.PacketEnum; -import emu.grasscutter.Grasscutter; -import emu.grasscutter.game.player.Player; +import emu.grasscutter.utils.JsonUtils; import java.util.ArrayList; import java.util.HashMap; @@ -18,7 +34,7 @@ public class PlayerList extends BasePacket { @Override public String getPacket() { - return Grasscutter.getGsonFactory().toJson(this); + return JsonUtils.encode(this); } @Override diff --git a/src/main/resources/plugin.json b/src/main/resources/plugin.json index b28721c..1b13d9c 100644 --- a/src/main/resources/plugin.json +++ b/src/main/resources/plugin.json @@ -1,7 +1,7 @@ { "name": "opencommand-plugin", "description": "Open command interface for third-party clients", - "version": "dev-1.3.0", + "version": "dev-1.4.0", "mainClass": "com.github.jie65535.opencommand.OpenCommandPlugin", "authors": ["jie65535"] } \ No newline at end of file