From 94b35191003ffe79380e4e111800698a77b12bd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=8C=8C?= Date: Mon, 26 Jun 2023 23:32:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20=E9=80=82=E9=85=8D?= =?UTF-8?q?=E5=99=A8=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.js | 5 +- lib/adapter/WebSocket.js | 45 -------- lib/bot.js | 102 ++++++++++++------ lib/listener/loader.js | 9 +- package.json | 2 +- plugins/.gitignore | 9 +- .../adapter}/ComWeChat.js | 65 +++++++---- .../adapter}/go-cqhttp.js | 99 +++++++++++------ {lib => plugins}/adapter/stdin.js | 81 +++++++------- 9 files changed, 231 insertions(+), 186 deletions(-) delete mode 100644 lib/adapter/WebSocket.js rename {lib/adapter/WebSocket => plugins/adapter}/ComWeChat.js (89%) rename {lib/adapter/WebSocket => plugins/adapter}/go-cqhttp.js (92%) rename {lib => plugins}/adapter/stdin.js (57%) diff --git a/app.js b/app.js index f8ac525..fa3c4ca 100644 --- a/app.js +++ b/app.js @@ -1,4 +1,3 @@ import Yunzai from './lib/bot.js' - -/** 全局变量 bot */ -await Yunzai.run() +global.Bot = new Yunzai() +Bot.run() \ No newline at end of file diff --git a/lib/adapter/WebSocket.js b/lib/adapter/WebSocket.js deleted file mode 100644 index 5f269a2..0000000 --- a/lib/adapter/WebSocket.js +++ /dev/null @@ -1,45 +0,0 @@ -import fs from "node:fs" -import cfg from "../config/config.js" -import express from "express" -import http from "http" - -export default class WebSocketAdapter { - request(req) { - logger.info(`${logger.blue(`[${req.ip}]`)} HTTP ${req.method} 请求:${req.url} ${JSON.stringify(req.rawHeaders)}`) - req.res.redirect("https://github.com/TimeRainStarSky/Yunzai") - } - - async load() { - const wss = {} - for (const file of fs.readdirSync('./lib/adapter/WebSocket').filter(file => file.endsWith('.js'))) { - try { - let adapter = await import(`./WebSocket/${file}`) - if (!adapter.default) continue - adapter = new adapter.default() - wss[file.replace(/.js$/, "")] = await adapter.load() - } catch (e) { - logger.mark(`加载 WebSocket 适配器错误:${file}`) - logger.error(e) - } - } - - const app = express() - app.get("*", this.request) - app.post("*", this.request) - const server = http.createServer(app) - - server.on("upgrade", (req, socket, head) => { - for (const i of Object.keys(wss)) - if (req.url == `/${i}`) - return wss[i].handleUpgrade(req, socket, head, conn => wss[i].emit("connection", conn, req)) - }) - - server.listen(cfg.bot.port, () => { - const host = server.address().address - const port = server.address().port - logger.mark(`启动 WebSocket 服务器:${logger.green(`ws://[${host}]:${port}`)}`) - for (const i of Object.keys(wss)) - logger.info(`本机 ${i} 连接地址:${logger.blue(`ws://localhost:${port}/${i}`)}`) - }) - } -} \ No newline at end of file diff --git a/lib/bot.js b/lib/bot.js index d146e7a..0170d9c 100644 --- a/lib/bot.js +++ b/lib/bot.js @@ -1,37 +1,73 @@ -import './config/init.js' -import cfg from './config/config.js' -import PluginsLoader from './plugins/loader.js' -import ListenerLoader from './listener/loader.js' -import { EventEmitter } from 'events' +import "./config/init.js" +import cfg from "./config/config.js" +import PluginsLoader from "./plugins/loader.js" +import ListenerLoader from "./listener/loader.js" +import { EventEmitter } from "events" +import express from "express" +import http from "http" export default class Yunzai extends EventEmitter { - static async run() { - global.Bot = new Yunzai() + constructor() { + super() + this.uin = [] + this.adapter = [] + this.server = express() + this.wss = {} + } + + async run() { await PluginsLoader.load() await ListenerLoader.load() - Bot.emit("online") + this.serverLoad() + this.emit("online") + } + + serverRequest(req) { + logger.info(`${logger.blue(`[${req.ip}]`)} HTTP ${req.method} 请求:${req.url} ${JSON.stringify(req.rawHeaders)}`) + req.res.redirect("https://github.com/TimeRainStarSky/Yunzai") + } + + serverLoad() { + this.server.get("*", this.serverRequest) + this.server.post("*", this.serverRequest) + this.server = http.createServer(this.server) + + this.server.on("upgrade", (req, socket, head) => { + for (const i of Object.keys(this.wss)) + if (req.url == `/${i}`) + return this.wss[i].handleUpgrade(req, socket, head, conn => + this.wss[i].emit("connection", conn, req)) + }) + + this.server.listen(cfg.bot.port, () => { + const host = this.server.address().address + const port = this.server.address().port + logger.mark(`启动 HTTP 服务器:${logger.green(`http://[${host}]:${port}`)}`) + for (const i of Object.keys(this.wss)) + logger.info(`本机 ${i} 连接地址:${logger.blue(`ws://localhost:${port}/${i}`)}`) + }) } getFriendArray() { const array = [] - for (const i of Bot.uin) - Bot[i].fl?.forEach(value => + for (const i of this.uin) + this[i].fl?.forEach(value => array.push({ ...value, bot_id: i })) return array } getFriendList() { const array = [] - for (const i of Bot.uin) - Bot[i].fl?.forEach((value, key) => + for (const i of this.uin) + this[i].fl?.forEach((value, key) => array.push(key)) return array } getFriendMap() { const map = new Map() - for (const i of Bot.uin) - Bot[i].fl?.forEach((value, key) => + for (const i of this.uin) + this[i].fl?.forEach((value, key) => map.set(key, { ...value, bot_id: i })) return map } @@ -42,24 +78,24 @@ export default class Yunzai extends EventEmitter { getGroupArray() { const array = [] - for (const i of Bot.uin) - Bot[i].gl?.forEach(value => + for (const i of this.uin) + this[i].gl?.forEach(value => array.push({ ...value, bot_id: i })) return array } getGroupList() { const array = [] - for (const i of Bot.uin) - Bot[i].gl?.forEach((value, key) => + for (const i of this.uin) + this[i].gl?.forEach((value, key) => array.push(key)) return array } getGroupMap() { const map = new Map() - for (const i of Bot.uin) - Bot[i].gl?.forEach((value, key) => + for (const i of this.uin) + this[i].gl?.forEach((value, key) => map.set(key, { ...value, bot_id: i })) return map } @@ -74,8 +110,8 @@ export default class Yunzai extends EventEmitter { pickFriend(user_id) { user_id = Number(user_id) || String(user_id) - const user = Bot.fl.get(user_id) - if (user) return Bot[user.bot_id].pickFriend(user_id) + const user = this.fl.get(user_id) + if (user) return this[user.bot_id].pickFriend(user_id) logger.error(`获取用户对象失败:找不到用户 ${logger.red(user_id)}`) return false @@ -83,8 +119,8 @@ export default class Yunzai extends EventEmitter { pickGroup(group_id) { group_id = Number(group_id) || String(group_id) - const group = Bot.gl.get(group_id) - if (group) return Bot[group.bot_id].pickGroup(group_id) + const group = this.gl.get(group_id) + if (group) return this[group.bot_id].pickGroup(group_id) logger.error(`获取群对象失败:找不到群 ${logger.red(group_id)}`) return false @@ -100,13 +136,13 @@ export default class Yunzai extends EventEmitter { sendFriendMsg(bot_id, user_id, msg) { try { if (!bot_id) - return Bot.pickFriend(user_id).sendMsg(msg) + return this.pickFriend(user_id).sendMsg(msg) - if (Bot[bot_id]) - return Bot[bot_id].pickFriend(user_id).sendMsg(msg) + if (this[bot_id]) + return this[bot_id].pickFriend(user_id).sendMsg(msg) return new Promise(resolve => - Bot.once(`connect.${bot_id}`, data => + this.once(`connect.${bot_id}`, data => resolve(data.pickFriend(user_id).sendMsg(msg)))) } catch (err) { logger.error(`${logger.blue(`[${bot_id}]`)} 发送好友消息失败:[$${user_id}] ${err}`) @@ -116,13 +152,13 @@ export default class Yunzai extends EventEmitter { sendGroupMsg(bot_id, group_id, msg) { try { if (!bot_id) - return Bot.pickGroup(group_id).sendMsg(msg) + return this.pickGroup(group_id).sendMsg(msg) - if (Bot[bot_id]) - return Bot[bot_id].pickGroup(group_id).sendMsg(msg) + if (this[bot_id]) + return this[bot_id].pickGroup(group_id).sendMsg(msg) return new Promise(resolve => - Bot.once(`connect.${bot_id}`, data => + this.once(`connect.${bot_id}`, data => resolve(data.pickGroup(group_id).sendMsg(msg)))) } catch (err) { logger.error(`${logger.blue(`[${bot_id}]`)} 发送群消息失败:[$${group_id}] ${err}`) @@ -138,7 +174,7 @@ export default class Yunzai extends EventEmitter { async getMasterMsg() { while (true) { const msg = await new Promise(resolve => { - Bot.once("message", data => { + this.once("message", data => { if (cfg.master[data.self_id]?.includes(String(data.user_id)) && data.message) { let msg = "" for (let i of data.message) diff --git a/lib/listener/loader.js b/lib/listener/loader.js index f838124..cbed4fd 100644 --- a/lib/listener/loader.js +++ b/lib/listener/loader.js @@ -13,6 +13,7 @@ class ListenerLoader { logger.info("加载监听事件中...") let eventCount = 0 for (const file of fs.readdirSync('./lib/events').filter(file => file.endsWith('.js'))) { + logger.debug(`加载监听事件:${file}`) try { let listener = await import(`../events/${file}`) if (!listener.default) continue @@ -39,15 +40,13 @@ class ListenerLoader { logger.info("-----------") logger.info("加载适配器中...") let adapterCount = 0 - for (const file of fs.readdirSync('./lib/adapter').filter(file => file.endsWith('.js'))) { + for (const adapter of Bot.adapter) { try { - let adapter = await import(`../adapter/${file}`) - if (!adapter.default) continue - adapter = new adapter.default() + logger.debug(`加载适配器:${adapter.name}(${adapter.id})`) await adapter.load() adapterCount++ } catch (e) { - logger.mark(`加载适配器错误:${file}`) + logger.mark(`加载适配器错误:${adapter.name}(${adapter.id})`) logger.error(e) } } diff --git a/package.json b/package.json index 7ce4250..baea256 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "eslint": "^8.43.0", "eslint-config-standard": "^17.1.0", "eslint-plugin-import": "^2.27.5", - "eslint-plugin-n": "^16.0.0", + "eslint-plugin-n": "^16.0.1", "eslint-plugin-promise": "^6.1.1" }, "imports": { diff --git a/plugins/.gitignore b/plugins/.gitignore index 4eab821..b82ef0b 100644 --- a/plugins/.gitignore +++ b/plugins/.gitignore @@ -1,10 +1,11 @@ * !.gitignore - +!adapter +!adapter/** +!system !system/** - +!other !other/** - !example/一言.js !example/主动复读.js -!example/进群退群通知.js +!example/进群退群通知.js \ No newline at end of file diff --git a/lib/adapter/WebSocket/ComWeChat.js b/plugins/adapter/ComWeChat.js similarity index 89% rename from lib/adapter/WebSocket/ComWeChat.js rename to plugins/adapter/ComWeChat.js index 30924bd..64b571b 100644 --- a/lib/adapter/WebSocket/ComWeChat.js +++ b/plugins/adapter/ComWeChat.js @@ -3,7 +3,12 @@ import { randomUUID } from "crypto" import path from "node:path" import fs from "node:fs" -export default class ComWeChatAdapter { +Bot.adapter.push(new class ComWeChatAdapter { + constructor() { + this.id = "WeChat" + this.name = "ComWeChat" + } + toStr(data) { switch (typeof data) { case "string": @@ -198,8 +203,13 @@ export default class ComWeChatAdapter { } pickFriend(data, user_id) { - const i = { ...data, user_id } + const i = { + ...Bot[data.self_id].fl.get(user_id), + ...data, + user_id, + } return { + ...i, sendMsg: msg => this.sendFriendMsg(i, msg), recallMsg: () => false, makeForwardMsg: Bot.makeForwardMsg, @@ -211,17 +221,28 @@ export default class ComWeChatAdapter { } pickMember(data, group_id, user_id) { - const i = { ...data, group_id, user_id } + const i = { + ...Bot[data.self_id].fl.get(user_id), + ...data, + group_id, + user_id, + } return { ...this.pickFriend(i, user_id), + ...i, getInfo: () => this.getGroupMemberInfo(i), getAvatarUrl: async () => (await this.getGroupMemberInfo(i))["wx.avatar"], } } pickGroup(data, group_id) { - const i = { ...data, group_id } + const i = { + ...Bot[data.self_id].gl.get(group_id), + ...data, + group_id, + } return { + ...i, sendMsg: msg => this.sendGroupMsg(i, msg), recallMsg: () => false, makeForwardMsg: Bot.makeForwardMsg, @@ -264,19 +285,19 @@ export default class ComWeChatAdapter { Bot[data.self_id].nickname = Bot[data.self_id].info.user_name Bot[data.self_id].avatar = Bot[data.self_id].info["wx.avatar"] - Bot[data.self_id].version = (await data.sendApi("get_version")).data - - Bot[data.self_id].fl = await this.getFriendMap(data) - Bot[data.self_id].gl = await this.getGroupMap(data) - - if (Array.isArray(Bot.uin)) { - if (!Bot.uin.includes(data.self_id)) - Bot.uin.push(data.self_id) - } else { - Bot.uin = [data.self_id] + Bot[data.self_id].version = { + ...(await data.sendApi("get_version")).data, + id: this.id, + name: this.name, } - logger.mark(`${logger.blue(`[${data.self_id}]`)} ComWeChat 已连接`) + Bot[data.self_id].fl = await Bot[data.self_id].getFriendMap() + Bot[data.self_id].gl = await Bot[data.self_id].getGroupMap() + + if (!Bot.uin.includes(data.self_id)) + Bot.uin.push(data.self_id) + + logger.mark(`${logger.blue(`[${data.self_id}]`)} ${this.name}(${this.id}) 已连接`) Bot.emit(`connect.${data.self_id}`, Bot[data.self_id]) Bot.emit(`connect`, Bot[data.self_id]) } @@ -343,15 +364,17 @@ export default class ComWeChatAdapter { return logger.error(err) } - data.sendApi = (action, params) => this.sendApi(ws, action, params) if (data.self?.user_id) { data.self_id = data.self.user_id - data.bot = Bot[data.self_id] } else { data.self_id = data.id } if (data.type) { + if (data.detail_type != "status_update" && !Bot.uin.includes(data.self_id)) + return false + data.sendApi = (action, params) => this.sendApi(ws, action, params) + data.bot = Bot[data.self_id] switch (data.type) { case "meta": this.makeMeta(data) @@ -379,11 +402,11 @@ export default class ComWeChatAdapter { } load() { - const wss = new WebSocketServer({ noServer: true }) - wss.on("connection", ws => { + Bot.wss[this.name] = new WebSocketServer({ noServer: true }) + Bot.wss[this.name].on("connection", ws => { ws.on("error", logger.error) ws.on("message", data => this.message(data, ws)) }) - return wss + return true } -} \ No newline at end of file +}) \ No newline at end of file diff --git a/lib/adapter/WebSocket/go-cqhttp.js b/plugins/adapter/go-cqhttp.js similarity index 92% rename from lib/adapter/WebSocket/go-cqhttp.js rename to plugins/adapter/go-cqhttp.js index b1a56eb..6236044 100644 --- a/lib/adapter/WebSocket/go-cqhttp.js +++ b/plugins/adapter/go-cqhttp.js @@ -2,7 +2,12 @@ import { WebSocketServer } from "ws" import { randomUUID } from "crypto" import path from "node:path" -export default class gocqhttpAdapter { +Bot.adapter.push(new class gocqhttpAdapter { + constructor() { + this.id = "QQ" + this.name = "go-cqhttp" + } + toStr(data) { switch (typeof data) { case "string": @@ -407,42 +412,65 @@ export default class gocqhttpAdapter { } pickFriend(data, user_id) { - const i = { ...data, user_id } + const i = { + ...Bot[data.self_id].fl.get(user_id), + ...data, + user_id, + } return { + ...i, sendMsg: msg => this.sendFriendMsg(i, msg), recallMsg: message_id => this.recallMsg(i, message_id), makeForwardMsg: Bot.makeForwardMsg, sendForwardMsg: msg => this.sendFriendForwardMsg(i, msg), sendFile: (file, name) => this.sendFriendFile(i, file, name), getInfo: () => this.getFriendInfo(i), - getAvatarUrl: () => `https://q1.qlogo.cn/g?b=qq&s=0&nk=${i.user_id}`, + getAvatarUrl: () => `https://q1.qlogo.cn/g?b=qq&s=0&nk=${user_id}`, } } pickMember(data, group_id, user_id) { if (typeof group_id == "string" && group_id.match("-")) { - group_id = group_id.split("-") - const i = { ...data, guild_id: group_id[0], channel_id: group_id[1], user_id } + const guild_id = group_id.split("-") + const i = { + ...data, + guild_id: guild_id[0], + channel_id: guild_id[1], + user_id, + } return { - ...this.pickGroup(i, `${i.guild_id}-${i.channel_id}`), + ...this.pickGroup(i, group_id), + ...i, getInfo: () => this.getGuildMemberInfo(i), getAvatarUrl: async () => (await this.getGuildMemberInfo(i)).avatar_url, } - } else { - const i = { ...data, group_id, user_id } - return { - ...this.pickFriend(i, i.user_id), - getInfo: () => this.getGroupMemberInfo(i), - poke: () => this.sendGroupMsg(i, segment.poke(i.user_id)), - } + } + + const i = { + ...Bot[data.self_id].fl.get(user_id), + ...data, + group_id, + user_id, + } + return { + ...this.pickFriend(i, user_id), + ...i, + getInfo: () => this.getGroupMemberInfo(i), + poke: () => this.sendGroupMsg(i, segment.poke(user_id)), } } pickGroup(data, group_id) { if (typeof group_id == "string" && group_id.match("-")) { - group_id = group_id.split("-") - const i = { ...data, guild_id: group_id[0], channel_id: group_id[1] } + const guild_id = group_id.split("-") + const i = { + ...Bot[data.self_id].gl.get(group_id), + ...data, + guild_id: guild_id[0], + channel_id: guild_id[1], + } return { + ...i, sendMsg: msg => this.sendGuildMsg(i, msg), recallMsg: message_id => this.recallMsg(i, message_id), makeForwardMsg: Bot.makeForwardMsg, @@ -454,23 +482,28 @@ export default class gocqhttpAdapter { getMemberArray: () => this.getGuildMemberArray(i), getMemberList: () => this.getGuildMemberList(i), getMemberMap: () => this.getGuildMemberMap(i), - pickMember: user_id => this.pickMember(i, `${i.guild_id}-${i.channel_id}`, user_id), + pickMember: user_id => this.pickMember(i, group_id, user_id), } } - const i = { ...data, group_id } + const i = { + ...Bot[data.self_id].gl.get(group_id), + ...data, + group_id, + } return { + ...i, sendMsg: msg => this.sendGroupMsg(i, msg), recallMsg: message_id => this.recallMsg(i, message_id), makeForwardMsg: Bot.makeForwardMsg, sendForwardMsg: msg => this.sendGroupForwardMsg(i, msg), sendFile: (file, name) => this.sendGroupFile(i, file, undefined, name), getInfo: () => this.getGroupInfo(i), - getAvatarUrl: () => `https://p.qlogo.cn/gh/${i.group_id}/${i.group_id}/0`, + getAvatarUrl: () => `https://p.qlogo.cn/gh/${group_id}/${group_id}/0`, getMemberArray: () => this.getGroupMemberArray(i), getMemberList: () => this.getGroupMemberList(i), getMemberMap: () => this.getGroupMemberMap(i), - pickMember: user_id => this.pickMember(i, i.group_id, user_id), + pickMember: user_id => this.pickMember(i, group_id, user_id), pokeMember: user_id => this.sendGroupMsg(i, segment.poke(user_id)), setName: group_name => this.setGroupName(i, group_name), setAvatar: file => this.setGroupAvatar(i, file), @@ -508,7 +541,7 @@ export default class gocqhttpAdapter { Bot[data.self_id].info = (await data.sendApi("get_login_info")).data Bot[data.self_id].uin = Bot[data.self_id].info.user_id Bot[data.self_id].nickname = Bot[data.self_id].info.nickname - Bot[data.self_id].avatar = Bot[data.self_id].pickFriend(data.self_id).getAvatarUrl() + Bot[data.self_id].avatar = `https://q1.qlogo.cn/g?b=qq&s=0&nk=${data.self_id}` Bot[data.self_id].guild_info = (await data.sendApi("get_guild_service_profile")).data Bot[data.self_id].tiny_id = Bot[data.self_id].guild_info.tiny_id @@ -530,17 +563,13 @@ export default class gocqhttpAdapter { } Bot[data.self_id].status = Bot[data.self_id].version.protocol_name - Bot[data.self_id].fl = await this.getFriendMap(data) - Bot[data.self_id].gl = await this.getGroupMap(data) + Bot[data.self_id].fl = await Bot[data.self_id].getFriendMap() + Bot[data.self_id].gl = await Bot[data.self_id].getGroupMap() - if (Array.isArray(Bot.uin)) { - if (!Bot.uin.includes(data.self_id)) - Bot.uin.push(data.self_id) - } else { - Bot.uin = [data.self_id] - } + if (!Bot.uin.includes(data.self_id)) + Bot.uin.push(data.self_id) - logger.mark(`${logger.blue(`[${data.self_id}]`)} go-cqhttp 已连接`) + logger.mark(`${logger.blue(`[${data.self_id}]`)} ${this.name}(${this.id}) 已连接`) Bot.emit(`connect.${data.self_id}`, Bot[data.self_id]) Bot.emit(`connect`, Bot[data.self_id]) } @@ -685,7 +714,7 @@ export default class gocqhttpAdapter { if (data.group_id) { data.group = data.bot.pickGroup(data.group_id) data.member = data.group.pickMember(data.user_id) - } else if (data.guild_id && data.channel_id){ + } else if (data.guild_id && data.channel_id) { data.group_id = `${data.guild_id}-${data.channel_id}` data.group = data.bot.pickGroup(data.group_id) data.member = data.group.pickMember(data.user_id) @@ -755,6 +784,8 @@ export default class gocqhttpAdapter { } if (data.post_type) { + if (data.meta_event_type != "lifecycle" && !Bot.uin.includes(data.self_id)) + return false data.sendApi = (action, params) => this.sendApi(ws, action, params) data.bot = Bot[data.self_id] switch (data.post_type) { @@ -786,11 +817,11 @@ export default class gocqhttpAdapter { } load() { - const wss = new WebSocketServer({ noServer: true }) - wss.on("connection", ws => { + Bot.wss[this.name] = new WebSocketServer({ noServer: true }) + Bot.wss[this.name].on("connection", ws => { ws.on("error", logger.error) ws.on("message", data => this.message(data, ws)) }) - return wss + return true } -} \ No newline at end of file +}) \ No newline at end of file diff --git a/lib/adapter/stdin.js b/plugins/adapter/stdin.js similarity index 57% rename from lib/adapter/stdin.js rename to plugins/adapter/stdin.js index 6cade57..afaf254 100644 --- a/lib/adapter/stdin.js +++ b/plugins/adapter/stdin.js @@ -1,7 +1,12 @@ import fs from "node:fs" import path from "node:path" -export default class stdinAdapter { +Bot.adapter.push(new class stdinAdapter { + constructor() { + this.id = "stdin" + this.name = "标准输入" + } + async makeBuffer(file) { if (file.match(/^base64:\/\//)) return Buffer.from(file.replace(/^base64:\/\//, ""), "base64") @@ -25,21 +30,21 @@ export default class stdinAdapter { case "text": if (i.data.text.match("\n")) i.data.text = `\n${i.data.text}` - logger.info(`${logger.blue(`[stdin]`)} 发送文本:${i.data.text}`) + logger.info(`${logger.blue(`[${this.id}]`)} 发送文本:${i.data.text}`) break case "image": - i.file = `${Bot.stdin.data_dir}${Date.now()}.png` - logger.info(`${logger.blue(`[stdin]`)} 发送图片:${i.data.file.replace(/^base64:\/\/.*/, "base64://...")}\n文件已保存到:${logger.cyan(i.file)}`) + i.file = `${Bot[this.id].data_dir}${Date.now()}.png` + logger.info(`${logger.blue(`[${this.id}]`)} 发送图片:${i.data.file.replace(/^base64:\/\/.*/, "base64://...")}\n文件已保存到:${logger.cyan(i.file)}`) fs.writeFileSync(i.file, await this.makeBuffer(i.data.file)) break case "record": - i.file = `${Bot.stdin.data_dir}${Date.now()}.mp3` - logger.info(`${logger.blue(`[stdin]`)} 发送音频:${i.data.file.replace(/^base64:\/\/.*/, "base64://...")}\n文件已保存到:${logger.cyan(i.file)}`) + i.file = `${Bot[this.id].data_dir}${Date.now()}.mp3` + logger.info(`${logger.blue(`[${this.id}]`)} 发送音频:${i.data.file.replace(/^base64:\/\/.*/, "base64://...")}\n文件已保存到:${logger.cyan(i.file)}`) fs.writeFileSync(i.file, await this.makeBuffer(i.data.file)) break case "video": - i.file = `${Bot.stdin.data_dir}${Date.now()}.mp4` - logger.info(`${logger.blue(`[stdin]`)} 发送视频:${i.data.file.replace(/^base64:\/\/.*/, "base64://...")}\n文件已保存到:${logger.cyan(i.file)}`) + i.file = `${Bot[this.id].data_dir}${Date.now()}.mp4` + logger.info(`${logger.blue(`[${this.id}]`)} 发送视频:${i.data.file.replace(/^base64:\/\/.*/, "base64://...")}\n文件已保存到:${logger.cyan(i.file)}`) fs.writeFileSync(i.file, await this.makeBuffer(i.data.file)) break case "reply": @@ -53,14 +58,14 @@ export default class stdinAdapter { i = JSON.stringify(i) if (i.match("\n")) i = `\n${i}` - logger.info(`${logger.blue(`[stdin]`)} 发送消息:${i}`) + logger.info(`${logger.blue(`[${this.id}]`)} 发送消息:${i}`) } } return { message_id: Date.now() } } recallMsg(message_id) { - logger.info(`${logger.blue(`[stdin]`)} 撤回消息:${message_id}`) + logger.info(`${logger.blue(`[${this.id}]`)} 撤回消息:${message_id}`) } sendForwardMsg(msg) { @@ -73,12 +78,12 @@ export default class stdinAdapter { async sendFile(file, name = path.basename(file)) { const buffer = await this.makeBuffer(file) if (!Buffer.isBuffer(buffer)) { - logger.error(`${logger.blue(`[stdin]`)} 发送文件错误:找不到文件 ${logger.red(file)}`) + logger.error(`${logger.blue(`[${this.id}]`)} 发送文件错误:找不到文件 ${logger.red(file)}`) return false } - const files = `${Bot.stdin.data_dir}${Date.now()}-${name}` - logger.info(`${logger.blue(`[stdin]`)} 发送文件:${file}\n文件已保存到:${logger.cyan(files)}`) + const files = `${Bot[this.id].data_dir}${Date.now()}-${name}` + logger.info(`${logger.blue(`[${this.id}]`)} 发送文件:${file}\n文件已保存到:${logger.cyan(files)}`) return fs.writeFileSync(files, buffer) } @@ -94,12 +99,12 @@ export default class stdinAdapter { message(msg) { const data = { - bot: Bot.stdin, - self_id: "stdin", - user_id: "stdin", + bot: Bot[this.id], + self_id: this.id, + user_id: this.id, post_type: "message", message_type: "private", - sender: { nickname: "标准输入" }, + sender: { nickname: this.name }, message: [{ type: "text", text: msg }], raw_message: msg, friend: this.pickFriend(), @@ -111,42 +116,38 @@ export default class stdinAdapter { } load() { - Bot.stdin = { - uin: "stdin", - nickname: "标准输入", + Bot[this.id] = { + uin: this.id, + nickname: this.name, stat: { start_time: Date.now()/1000 }, - version: { impl: "stdin" }, + version: { id: this.id, name: this.name }, pickFriend: () => this.pickFriend(), pickUser: () => this.pickFriend(), pickGroup: () => this.pickFriend(), pickMember: () => this.pickFriend(), - fl: new Map().set("stdin", { - user_id: "stdin", - nickname: "标准输入", + fl: new Map().set(this.id, { + user_id: this.id, + nickname: this.name, }), - gl: new Map().set("stdin", { - group_id: "stdin", - group_name: "标准输入", + gl: new Map().set(this.id, { + group_id: this.id, + group_name: this.name, }), data_dir: `${process.cwd()}/data/stdin/`, } - if (!fs.existsSync(Bot.stdin.data_dir)) - fs.mkdirSync(Bot.stdin.data_dir) + if (!fs.existsSync(Bot[this.id].data_dir)) + fs.mkdirSync(Bot[this.id].data_dir) - if (Array.isArray(Bot.uin)) { - if (!Bot.uin.includes("stdin")) - Bot.uin.push("stdin") - } else { - Bot.uin = ["stdin"] - } + if (!Bot.uin.includes(this.id)) + Bot.uin.push(this.id) - process.stdin.on("data", data => this.message(data.toString())) + process[this.id].on("data", data => this.message(data.toString())) - logger.mark(`${logger.blue(`[stdin]`)} 标准输入 已连接`) - Bot.emit(`connect.stdin`, Bot.stdin) - Bot.emit(`connect`, Bot.stdin) + logger.mark(`${logger.blue(`[${this.id}]`)} ${this.name}(${this.id}) 已连接`) + Bot.emit(`connect.${this.id}`, Bot[this.id]) + Bot.emit(`connect`, Bot[this.id]) } -} \ No newline at end of file +}) \ No newline at end of file