From c3c2ed08a7c75b55ee6b396d12a7307e7cb0ba44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=AD=B1=E5=82=91?= Date: Sun, 21 May 2023 20:50:34 +0800 Subject: [PATCH] Update player command response handler --- .../jie65535/opencommand/EventListeners.java | 53 +++++++++++++++++-- .../opencommand/OpenCommandHandler.java | 18 ++----- .../opencommand/OpenCommandPlugin.java | 6 +++ .../opencommand/socket/SocketClient.java | 10 ++-- 4 files changed, 62 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/github/jie65535/opencommand/EventListeners.java b/src/main/java/com/github/jie65535/opencommand/EventListeners.java index 17eddb5..fa41be9 100644 --- a/src/main/java/com/github/jie65535/opencommand/EventListeners.java +++ b/src/main/java/com/github/jie65535/opencommand/EventListeners.java @@ -24,24 +24,54 @@ import emu.grasscutter.game.player.Player; import emu.grasscutter.server.event.game.ReceiveCommandFeedbackEvent; import emu.grasscutter.server.event.player.PlayerJoinEvent; import emu.grasscutter.server.event.player.PlayerQuitEvent; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import java.util.ArrayList; public final class EventListeners { private static StringBuilder consoleMessageHandler; + private static final Int2ObjectMap playerMessageHandlers = new Int2ObjectOpenHashMap<>(); public static void setConsoleMessageHandler(StringBuilder handler) { consoleMessageHandler = handler; } + /** + * 获取新的玩家消息处理类 + * 获取时将创建或清空消息处理器并返回实例,**在执行命令前获取!** + * @param uid 玩家uid + * @return 新的玩家消息处理类 + */ + public static StringBuilder getPlayerNewMessageHandler(int uid) { + var handler = playerMessageHandlers.get(uid); + if (handler == null) { + handler = new StringBuilder(); + playerMessageHandlers.put(uid, handler); + } else { + handler.setLength(0); + } + return handler; + } + + /** + * 命令执行反馈事件处理 + */ public static void onCommandResponse(ReceiveCommandFeedbackEvent event) { - if (consoleMessageHandler != null && event.getPlayer() == null) { - if (!consoleMessageHandler.isEmpty()) { + StringBuilder handler; + if (event.getPlayer() == null) { + handler = consoleMessageHandler; + } else { + handler = playerMessageHandlers.get(event.getPlayer().getUid()); + } + + if (handler != null) { + if (!handler.isEmpty()) { // New line - consoleMessageHandler.append(System.lineSeparator()); + handler.append(System.lineSeparator()); } - consoleMessageHandler.append(event.getMessage()); + handler.append(event.getMessage()); } } @@ -60,6 +90,10 @@ public final class EventListeners { SocketClient.sendPacket(playerList); } + /** + * 仅游戏模式下玩家离开事件处理方法 + * 用于更新玩家列表 + */ public static void onPlayerQuit(PlayerQuitEvent playerQuitEvent) { PlayerList playerList = new PlayerList(); playerList.player = Grasscutter.getGameServer().getPlayers().size(); @@ -73,4 +107,15 @@ public final class EventListeners { playerList.playerList = playerNames; SocketClient.sendPacket(playerList); } + + /** + * 玩家离开事件处理 2 + * 用于清理内存 + */ + public static void onPlayerQuit2(PlayerQuitEvent playerQuitEvent) { + var uid = playerQuitEvent.getPlayer().getUid(); + if (playerMessageHandlers.containsKey(uid)) { + playerMessageHandlers.remove(uid); + } + } } diff --git a/src/main/java/com/github/jie65535/opencommand/OpenCommandHandler.java b/src/main/java/com/github/jie65535/opencommand/OpenCommandHandler.java index 51793d4..9f8595b 100644 --- a/src/main/java/com/github/jie65535/opencommand/OpenCommandHandler.java +++ b/src/main/java/com/github/jie65535/opencommand/OpenCommandHandler.java @@ -24,7 +24,6 @@ import com.github.jie65535.opencommand.socket.SocketData; import emu.grasscutter.command.CommandMap; import emu.grasscutter.server.http.Router; import emu.grasscutter.utils.Crypto; -import emu.grasscutter.utils.MessageHandler; import emu.grasscutter.utils.Utils; import io.javalin.Javalin; import io.javalin.http.Context; @@ -46,7 +45,6 @@ public final class OpenCommandHandler implements Router { private static final Map codes = new HashMap<>(); private static final Int2ObjectMap codeExpireTime = new Int2ObjectOpenHashMap<>(); - private static final Int2ObjectMap playerMessageHandlers = new Int2ObjectOpenHashMap<>(); public static void handle(Context context) { var plugin = OpenCommandPlugin.getInstance(); @@ -154,24 +152,16 @@ public final class OpenCommandHandler implements Router { context.json(new JsonResponse(404, "Player not found")); return; } - // Player MessageHandler do not support concurrency - var handler = playerMessageHandlers.get(player.getUid()); - if (handler == null) { - handler = new MessageHandler(); - playerMessageHandlers.put(player.getUid(), handler); - } //noinspection SynchronizationOnLocalVariableOrMethodParameter - synchronized (handler) { + synchronized (player) { + // Player MessageHandler do not support concurrency + var handler = EventListeners.getPlayerNewMessageHandler(player.getUid()); try { - handler.setMessage(""); - player.setMessageHandler(handler); CommandMap.getInstance().invoke(player, player, command); - context.json(new JsonResponse(handler.getMessage())); + context.json(new JsonResponse(handler.toString())); } catch (Exception e) { plugin.getLogger().warn("Run command failed.", e); context.json(new JsonResponse(500, "error", e.getLocalizedMessage())); - } finally { - player.setMessageHandler(null); } } return; diff --git a/src/main/java/com/github/jie65535/opencommand/OpenCommandPlugin.java b/src/main/java/com/github/jie65535/opencommand/OpenCommandPlugin.java index 9d9aa2c..aefcda5 100644 --- a/src/main/java/com/github/jie65535/opencommand/OpenCommandPlugin.java +++ b/src/main/java/com/github/jie65535/opencommand/OpenCommandPlugin.java @@ -59,10 +59,16 @@ public final class OpenCommandPlugin extends Plugin { @Override public void onEnable() { + // 监听命令执行反馈 new EventHandler<>(ReceiveCommandFeedbackEvent.class) .priority(HandlerPriority.HIGH) .listener(EventListeners::onCommandResponse) .register(this); + // 监听玩家离开事件 + new EventHandler<>(PlayerQuitEvent.class) + .priority(HandlerPriority.NORMAL) + .listener(EventListeners::onPlayerQuit2) + .register(this); if (runMode == Grasscutter.ServerRunMode.GAME_ONLY) { // 仅运行游戏服务器时注册玩家加入和离开事件 new EventHandler<>(PlayerJoinEvent.class) 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 645a12b..4c9e0b2 100644 --- a/src/main/java/com/github/jie65535/opencommand/socket/SocketClient.java +++ b/src/main/java/com/github/jie65535/opencommand/socket/SocketClient.java @@ -26,7 +26,6 @@ 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; import java.io.IOException; @@ -160,19 +159,16 @@ public class SocketClient { sendPacket(new HttpPacket(404, "Player not found."), packet.packetID); return; } - // Player MessageHandler do not support concurrency //noinspection SynchronizationOnLocalVariableOrMethodParameter synchronized (playerData) { + // Player MessageHandler do not support concurrency + var handler = EventListeners.getPlayerNewMessageHandler(playerData.getUid()); try { - var resultCollector = new MessageHandler(); - playerData.setMessageHandler(resultCollector); CommandMap.getInstance().invoke(playerData, playerData, command); - sendPacket(new HttpPacket(200, resultCollector.getMessage()), packet.packetID); + sendPacket(new HttpPacket(200, handler.toString()), packet.packetID); } catch (Exception e) { OpenCommandPlugin.getInstance().getLogger().warn("[OpenCommand] Run command failed.", e); sendPacket(new HttpPacket(500, "error", e.getLocalizedMessage()), packet.packetID); - } finally { - playerData.setMessageHandler(null); } } }