diff --git a/mateclaw-server/src/main/java/vip/mate/channel/qq/QQChannelAdapter.java b/mateclaw-server/src/main/java/vip/mate/channel/qq/QQChannelAdapter.java index 72bdc0b9..31b1f1a8 100644 --- a/mateclaw-server/src/main/java/vip/mate/channel/qq/QQChannelAdapter.java +++ b/mateclaw-server/src/main/java/vip/mate/channel/qq/QQChannelAdapter.java @@ -424,7 +424,7 @@ public class QQChannelAdapter extends AbstractChannelAdapter { switch (op) { case OP_HELLO -> handleHello((Map) data, ws); - case OP_DISPATCH -> handleDispatch(eventType, (Map) data); + case OP_DISPATCH -> handleDispatch(eventType, data); case OP_HEARTBEAT_ACK -> log.trace("[qq] Heartbeat ACK received"); case OP_RECONNECT -> { log.info("[qq] Server requested reconnect"); @@ -515,34 +515,51 @@ public class QQChannelAdapter extends AbstractChannelAdapter { /** * 处理 DISPATCH 事件 + *

+ * `data` payload shape varies by event: object for messages/READY, empty string for RESUMED. */ @SuppressWarnings("unchecked") - private void handleDispatch(String eventType, Map data) { - if (eventType == null || data == null) return; + private void handleDispatch(String eventType, Object data) { + if (eventType == null) return; switch (eventType) { + case "RESUMED" -> { + // RESUMED carries no payload (`d` is an empty string); don't read from it. + reconnectAttempts = 0; + connectionState.set(ConnectionState.CONNECTED); + lastError = null; + log.info("[qq] RESUMED successfully"); + } case "READY" -> { - sessionId = (String) data.get("session_id"); + if (!(data instanceof Map map)) { + log.warn("[qq] READY event has non-object data: {}", data); + return; + } + Map readyData = (Map) map; + sessionId = (String) readyData.get("session_id"); reconnectAttempts = 0; quickDisconnectCount = 0; connectionState.set(ConnectionState.CONNECTED); lastError = null; log.info("[qq] READY received, session_id={}", sessionId); } - case "RESUMED" -> { - reconnectAttempts = 0; - connectionState.set(ConnectionState.CONNECTED); - lastError = null; - log.info("[qq] RESUMED successfully"); - } - case "C2C_MESSAGE_CREATE" -> handleMessageEvent("c2c", data); - case "GROUP_AT_MESSAGE_CREATE" -> handleMessageEvent("group", data); - case "AT_MESSAGE_CREATE" -> handleMessageEvent("guild", data); - case "DIRECT_MESSAGE_CREATE" -> handleMessageEvent("dm", data); + case "C2C_MESSAGE_CREATE" -> dispatchMessage("c2c", eventType, data); + case "GROUP_AT_MESSAGE_CREATE" -> dispatchMessage("group", eventType, data); + case "AT_MESSAGE_CREATE" -> dispatchMessage("guild", eventType, data); + case "DIRECT_MESSAGE_CREATE" -> dispatchMessage("dm", eventType, data); default -> log.debug("[qq] Unhandled event: {}", eventType); } } + @SuppressWarnings("unchecked") + private void dispatchMessage(String messageType, String eventType, Object data) { + if (!(data instanceof Map map)) { + log.warn("[qq] {} event has non-object data, skipping: {}", eventType, data); + return; + } + handleMessageEvent(messageType, (Map) map); + } + /** * 处理消息事件(C2C / Group / Guild / DM) */