From f0fd57b6ac09d9ee50e6c7dbf3eb6fffdde91655 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sun, 1 Jun 2025 01:01:36 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix:=E5=8F=98=E9=87=8F=E8=A6=86=E7=9B=96?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/bot/bot.controller.ts | 6 ++--- src/modules/bot/bot.service.ts | 43 ++++++++++++++++++------------- src/test/wsTestClient.ts | 4 +-- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/modules/bot/bot.controller.ts b/src/modules/bot/bot.controller.ts index bc5f901..eb3b34f 100644 --- a/src/modules/bot/bot.controller.ts +++ b/src/modules/bot/bot.controller.ts @@ -111,11 +111,11 @@ class BotController { try { const token = req.body.token; if (tools.checkToken(token.toString())) { - const groupId: number = req.body.groupId; - const message: string = req.body.message; + const groupId: number = Number(req.body.groupId); + const message: string = req.body.message.toString(); const flag: boolean = await BotService.sendMessage(groupId, message); if (flag) { - await response.success(res, {}); + await response.success(res, { message: '消息发送成功..' }); } else { await response.error(res); } diff --git a/src/modules/bot/bot.service.ts b/src/modules/bot/bot.service.ts index 2eab80e..8b67746 100644 --- a/src/modules/bot/bot.service.ts +++ b/src/modules/bot/bot.service.ts @@ -149,32 +149,39 @@ class BotService { } for (const [groupId, botEntries] of groupMap.entries()) { + logger.debug(`[群 ${groupId}] 候选Bot列表: ${JSON.stringify(botEntries)}`); const clientGroups = new Map(); botEntries.forEach(({ botId, clientId }) => { if (!clientGroups.has(clientId)) clientGroups.set(clientId, []); clientGroups.get(clientId)!.push(botId); }); const selectedClientId = tools.getRandomItem([...clientGroups.keys()]); + logger.debug(`[群 ${groupId}] 随机选中 Client: ${selectedClientId}`); const botCandidates = clientGroups.get(selectedClientId)!; + logger.debug(`[群 ${groupId}] 该 Client 下候选 Bot: ${botCandidates}`); const selectedBotId = tools.getRandomItem(botCandidates); - const delay = tools.getRandomDelay(30_000, 90_000); - setTimeout(() => { - const sendData = { - type: 'sendMessage', - data: { - botId: selectedBotId, - groupId, - clientId: selectedClientId, - message, - }, - }; - logger.info( - `[广播] 向群 ${groupId} 使用Bot ${selectedBotId}(客户端 ${selectedClientId})发送消息,延迟 ${delay / 1000} 秒` - ); - wsClientManager.send(selectedClientId, sendData).catch((e) => { - logger.error(`发送到群${groupId}失败:`, e); - }); - }, delay); + logger.debug(`[群 ${groupId}] 最终选中 Bot: ${selectedBotId}`); + const delay = tools.getRandomDelay(10_000, 150_000); + //解决闭包导致的变量覆盖问题 + ((groupId, selectedClientId, selectedBotId, delay) => { + setTimeout(() => { + const sendData = { + type: 'sendMessage', + data: { + botId: selectedBotId, + groupId: groupId, + clientId: selectedClientId, + message: message, + }, + }; + logger.info( + `[广播] 向群 ${groupId} 使用Bot ${selectedBotId}(客户端 ${selectedClientId})发送消息${message},延迟 ${delay / 1000} 秒` + ); + wsClientManager.send(selectedClientId, sendData).catch((e) => { + logger.error(`发送到群${groupId}失败:`, e); + }); + }, delay); + })(groupId, selectedClientId, selectedBotId, delay); } } diff --git a/src/test/wsTestClient.ts b/src/test/wsTestClient.ts index e7c6158..2e4c508 100644 --- a/src/test/wsTestClient.ts +++ b/src/test/wsTestClient.ts @@ -50,8 +50,8 @@ async function testGetAPI() { async function testPostAPI() { try { const response = await axios.post('https://core.crystelf.top/api/bot/getGroupInfo', { - token: '阿弥诺斯', - groupId: '1042721418', + token: '114113', + groupId: 796070855, }); logger.info('[HTTP][POST] Response:', response.data); } catch (err) { From 78748fd04c539991de4d43bfe07db93ed4a353b9 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sun, 1 Jun 2025 01:37:42 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix:=E9=80=BB=E8=BE=91=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/bot/bot.service.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/modules/bot/bot.service.ts b/src/modules/bot/bot.service.ts index 8b67746..fb9b568 100644 --- a/src/modules/bot/bot.service.ts +++ b/src/modules/bot/bot.service.ts @@ -137,8 +137,11 @@ class BotService { const clientId = path.basename(fileName, '.json'); const botList = await redisService.fetch('crystelfBots', fileName); if (!Array.isArray(botList)) continue; + if (!botList[0]) continue; for (const bot of botList) { if (!bot.uin || !bot.groups) continue; + if (typeof bot.uin != 'number' || typeof bot.groups != 'number') continue; + logger.debug(JSON.stringify(bot)); for (const group of bot.groups) { if (!groupMap.has(group.group_id)) { groupMap.set(group.group_id, []); From 4846e27e6a1b639fd03d3088fd29a8e3276f500f Mon Sep 17 00:00:00 2001 From: Jerry Date: Sun, 1 Jun 2025 01:51:15 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix:=E9=80=BB=E8=BE=91=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/bot/bot.service.ts | 119 ++++++++++++++++----------------- 1 file changed, 56 insertions(+), 63 deletions(-) diff --git a/src/modules/bot/bot.service.ts b/src/modules/bot/bot.service.ts index fb9b568..197b4df 100644 --- a/src/modules/bot/bot.service.ts +++ b/src/modules/bot/bot.service.ts @@ -21,26 +21,16 @@ class BotService { if (!fileName.endsWith('.json')) continue; try { - const raw: [] | undefined = await redisService.fetch('crystelfBots', fileName); - if (!raw) continue; + const raw = await redisService.fetch('crystelfBots', fileName); + if (!raw || !Array.isArray(raw)) continue; - let botList: any[]; - try { - botList = raw; - if (!Array.isArray(botList)) { - logger.warn(`${fileName}不是数组,已跳过`); - continue; + for (const bot of raw) { + const uin = Number(bot.uin); + const nickName = bot.nickName || ''; + if (!isNaN(uin)) { + uins.push({ uin, nickName }); } - } catch (e) { - logger.warn(`解析 ${fileName} 出错: ${e}`); - continue; } - botList.forEach((bot) => { - //logger.debug(bot); - if (bot.uin) { - uins.push({ uin: bot.uin, nickName: bot.nickName }); - } - }); } catch (err) { logger.error(`读取或解析 ${fileName} 出错: ${err}`); } @@ -50,7 +40,7 @@ class BotService { } /** - * 获取群聊消息 + * 获取群聊信息 * @param data */ public async getGroupInfo(data: { @@ -59,30 +49,24 @@ class BotService { clientId?: string; }): Promise { logger.debug('GetGroupInfo..'); - const sendBot: number | undefined = data.botId - ? data.botId - : await this.getGroupBot(data.groupId); + const sendBot: number | undefined = data.botId ?? (await this.getGroupBot(data.groupId)); if (!sendBot) { logger.warn(`不存在能向群聊${data.groupId}发送消息的Bot!`); return undefined; } - let sendData = { + + const sendData = { type: 'getGroupInfo', data: { botId: sendBot, groupId: data.groupId, - clientID: data.clientId ? data.clientId : await this.getBotClient(sendBot), + clientID: data.clientId ?? (await this.getBotClient(sendBot)), }, }; - //logger.debug(sendData); + if (sendData.data.clientID) { const returnData = await wsClientManager.sendAndWait(sendData.data.clientID, sendData); - if (returnData) { - return returnData; - } else { - logger.warn(`未查询到${data.groupId}的信息..`); - return undefined; - } + return returnData ?? undefined; } return undefined; } @@ -94,14 +78,14 @@ class BotService { */ public async sendMessage(groupId: number, message: string): Promise { logger.info(`发送${message}到${groupId}..`); - const sendBot: number | undefined = await this.getGroupBot(groupId); + const sendBot = await this.getGroupBot(groupId); if (!sendBot) { logger.warn(`不存在能向群聊${groupId}发送消息的Bot!`); return false; } const client = await this.getBotClient(sendBot); if (!client) { - logger.warn(`不存${sendBot}对应的client!`); + logger.warn(`不存在${sendBot}对应的client!`); return false; } const sendData = { @@ -113,11 +97,8 @@ class BotService { message: message, }, }; - if (client) { - await wsClientManager.send(sendData.data.clientId, sendData); - return true; - } - return false; + await wsClientManager.send(client, sendData); + return true; } /** @@ -137,35 +118,40 @@ class BotService { const clientId = path.basename(fileName, '.json'); const botList = await redisService.fetch('crystelfBots', fileName); if (!Array.isArray(botList)) continue; - if (!botList[0]) continue; + for (const bot of botList) { - if (!bot.uin || !bot.groups) continue; - if (typeof bot.uin != 'number' || typeof bot.groups != 'number') continue; - logger.debug(JSON.stringify(bot)); - for (const group of bot.groups) { - if (!groupMap.has(group.group_id)) { - groupMap.set(group.group_id, []); + const botId = Number(bot.uin); + const groups = bot.groups; + + if (!botId || !Array.isArray(groups)) continue; + + for (const group of groups) { + if (group.group_id === '未知') continue; + const groupId = Number(group.group_id); + if (isNaN(groupId)) continue; + + if (!groupMap.has(groupId)) { + groupMap.set(groupId, []); } - groupMap.get(group.group_id)?.push({ botId: bot.uin, clientId }); + groupMap.get(groupId)!.push({ botId, clientId }); } } } for (const [groupId, botEntries] of groupMap.entries()) { logger.debug(`[群 ${groupId}] 候选Bot列表: ${JSON.stringify(botEntries)}`); + const clientGroups = new Map(); botEntries.forEach(({ botId, clientId }) => { if (!clientGroups.has(clientId)) clientGroups.set(clientId, []); clientGroups.get(clientId)!.push(botId); }); + const selectedClientId = tools.getRandomItem([...clientGroups.keys()]); - logger.debug(`[群 ${groupId}] 随机选中 Client: ${selectedClientId}`); const botCandidates = clientGroups.get(selectedClientId)!; - logger.debug(`[群 ${groupId}] 该 Client 下候选 Bot: ${botCandidates}`); const selectedBotId = tools.getRandomItem(botCandidates); - logger.debug(`[群 ${groupId}] 最终选中 Bot: ${selectedBotId}`); const delay = tools.getRandomDelay(10_000, 150_000); - //解决闭包导致的变量覆盖问题 + ((groupId, selectedClientId, selectedBotId, delay) => { setTimeout(() => { const sendData = { @@ -189,7 +175,7 @@ class BotService { } /** - * 获取`botId`对应的`client` + * 获取botId对应的client * @param botId * @private */ @@ -197,14 +183,20 @@ class BotService { const userPath = paths.get('userData'); const botsPath = path.join(userPath, '/crystelfBots'); const dirData = await fs.readdir(botsPath); + for (const clientId of dirData) { if (!clientId.endsWith('.json')) continue; + try { - const raw: - | { uin: number; groups: { group_id: number; group_name: string }[]; nickName: string }[] - | undefined = await redisService.fetch('crystelfBots', clientId); - if (!raw) continue; - if (raw.find((bot) => bot.uin == botId)) return path.basename(clientId, '.json'); + const raw = await redisService.fetch('crystelfBots', clientId); + if (!Array.isArray(raw)) continue; + + for (const bot of raw) { + const uin = Number(bot.uin); + if (!isNaN(uin) && uin === botId) { + return path.basename(clientId, '.json'); + } + } } catch (err) { logger.error(`读取${clientId}出错..`); } @@ -213,7 +205,7 @@ class BotService { } /** - * 获取`groupId`对应的`botId` + * 获取groupId对应的botId * @param groupId * @private */ @@ -226,15 +218,16 @@ class BotService { if (!clientId.endsWith('.json')) continue; try { - const raw: - | { uin: number; groups: { group_id: number; group_name: string }[]; nickName: string }[] - | undefined = await redisService.fetch('crystelfBots', clientId); - if (!raw) continue; + const raw = await redisService.fetch('crystelfBots', clientId); + if (!Array.isArray(raw)) continue; for (const bot of raw) { - if (bot.uin && bot.groups) { - const found = bot.groups.find((group) => group.group_id == groupId); - if (found) return bot.uin; + const uin = Number(bot.uin); + const groups = bot.groups; + if (!uin || !Array.isArray(groups)) continue; + + if (groups.find((g) => Number(g.group_id) === groupId)) { + return uin; } } } catch (err) {