优化 适配器加载
This commit is contained in:
parent
8088a85aae
commit
94b3519100
5
app.js
5
app.js
|
@ -1,4 +1,3 @@
|
||||||
import Yunzai from './lib/bot.js'
|
import Yunzai from './lib/bot.js'
|
||||||
|
global.Bot = new Yunzai()
|
||||||
/** 全局变量 bot */
|
Bot.run()
|
||||||
await Yunzai.run()
|
|
|
@ -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}`)}`)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
102
lib/bot.js
102
lib/bot.js
|
@ -1,37 +1,73 @@
|
||||||
import './config/init.js'
|
import "./config/init.js"
|
||||||
import cfg from './config/config.js'
|
import cfg from "./config/config.js"
|
||||||
import PluginsLoader from './plugins/loader.js'
|
import PluginsLoader from "./plugins/loader.js"
|
||||||
import ListenerLoader from './listener/loader.js'
|
import ListenerLoader from "./listener/loader.js"
|
||||||
import { EventEmitter } from 'events'
|
import { EventEmitter } from "events"
|
||||||
|
import express from "express"
|
||||||
|
import http from "http"
|
||||||
|
|
||||||
export default class Yunzai extends EventEmitter {
|
export default class Yunzai extends EventEmitter {
|
||||||
static async run() {
|
constructor() {
|
||||||
global.Bot = new Yunzai()
|
super()
|
||||||
|
this.uin = []
|
||||||
|
this.adapter = []
|
||||||
|
this.server = express()
|
||||||
|
this.wss = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
async run() {
|
||||||
await PluginsLoader.load()
|
await PluginsLoader.load()
|
||||||
await ListenerLoader.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() {
|
getFriendArray() {
|
||||||
const array = []
|
const array = []
|
||||||
for (const i of Bot.uin)
|
for (const i of this.uin)
|
||||||
Bot[i].fl?.forEach(value =>
|
this[i].fl?.forEach(value =>
|
||||||
array.push({ ...value, bot_id: i }))
|
array.push({ ...value, bot_id: i }))
|
||||||
return array
|
return array
|
||||||
}
|
}
|
||||||
|
|
||||||
getFriendList() {
|
getFriendList() {
|
||||||
const array = []
|
const array = []
|
||||||
for (const i of Bot.uin)
|
for (const i of this.uin)
|
||||||
Bot[i].fl?.forEach((value, key) =>
|
this[i].fl?.forEach((value, key) =>
|
||||||
array.push(key))
|
array.push(key))
|
||||||
return array
|
return array
|
||||||
}
|
}
|
||||||
|
|
||||||
getFriendMap() {
|
getFriendMap() {
|
||||||
const map = new Map()
|
const map = new Map()
|
||||||
for (const i of Bot.uin)
|
for (const i of this.uin)
|
||||||
Bot[i].fl?.forEach((value, key) =>
|
this[i].fl?.forEach((value, key) =>
|
||||||
map.set(key, { ...value, bot_id: i }))
|
map.set(key, { ...value, bot_id: i }))
|
||||||
return map
|
return map
|
||||||
}
|
}
|
||||||
|
@ -42,24 +78,24 @@ export default class Yunzai extends EventEmitter {
|
||||||
|
|
||||||
getGroupArray() {
|
getGroupArray() {
|
||||||
const array = []
|
const array = []
|
||||||
for (const i of Bot.uin)
|
for (const i of this.uin)
|
||||||
Bot[i].gl?.forEach(value =>
|
this[i].gl?.forEach(value =>
|
||||||
array.push({ ...value, bot_id: i }))
|
array.push({ ...value, bot_id: i }))
|
||||||
return array
|
return array
|
||||||
}
|
}
|
||||||
|
|
||||||
getGroupList() {
|
getGroupList() {
|
||||||
const array = []
|
const array = []
|
||||||
for (const i of Bot.uin)
|
for (const i of this.uin)
|
||||||
Bot[i].gl?.forEach((value, key) =>
|
this[i].gl?.forEach((value, key) =>
|
||||||
array.push(key))
|
array.push(key))
|
||||||
return array
|
return array
|
||||||
}
|
}
|
||||||
|
|
||||||
getGroupMap() {
|
getGroupMap() {
|
||||||
const map = new Map()
|
const map = new Map()
|
||||||
for (const i of Bot.uin)
|
for (const i of this.uin)
|
||||||
Bot[i].gl?.forEach((value, key) =>
|
this[i].gl?.forEach((value, key) =>
|
||||||
map.set(key, { ...value, bot_id: i }))
|
map.set(key, { ...value, bot_id: i }))
|
||||||
return map
|
return map
|
||||||
}
|
}
|
||||||
|
@ -74,8 +110,8 @@ export default class Yunzai extends EventEmitter {
|
||||||
|
|
||||||
pickFriend(user_id) {
|
pickFriend(user_id) {
|
||||||
user_id = Number(user_id) || String(user_id)
|
user_id = Number(user_id) || String(user_id)
|
||||||
const user = Bot.fl.get(user_id)
|
const user = this.fl.get(user_id)
|
||||||
if (user) return Bot[user.bot_id].pickFriend(user_id)
|
if (user) return this[user.bot_id].pickFriend(user_id)
|
||||||
|
|
||||||
logger.error(`获取用户对象失败:找不到用户 ${logger.red(user_id)}`)
|
logger.error(`获取用户对象失败:找不到用户 ${logger.red(user_id)}`)
|
||||||
return false
|
return false
|
||||||
|
@ -83,8 +119,8 @@ export default class Yunzai extends EventEmitter {
|
||||||
|
|
||||||
pickGroup(group_id) {
|
pickGroup(group_id) {
|
||||||
group_id = Number(group_id) || String(group_id)
|
group_id = Number(group_id) || String(group_id)
|
||||||
const group = Bot.gl.get(group_id)
|
const group = this.gl.get(group_id)
|
||||||
if (group) return Bot[group.bot_id].pickGroup(group_id)
|
if (group) return this[group.bot_id].pickGroup(group_id)
|
||||||
|
|
||||||
logger.error(`获取群对象失败:找不到群 ${logger.red(group_id)}`)
|
logger.error(`获取群对象失败:找不到群 ${logger.red(group_id)}`)
|
||||||
return false
|
return false
|
||||||
|
@ -100,13 +136,13 @@ export default class Yunzai extends EventEmitter {
|
||||||
sendFriendMsg(bot_id, user_id, msg) {
|
sendFriendMsg(bot_id, user_id, msg) {
|
||||||
try {
|
try {
|
||||||
if (!bot_id)
|
if (!bot_id)
|
||||||
return Bot.pickFriend(user_id).sendMsg(msg)
|
return this.pickFriend(user_id).sendMsg(msg)
|
||||||
|
|
||||||
if (Bot[bot_id])
|
if (this[bot_id])
|
||||||
return Bot[bot_id].pickFriend(user_id).sendMsg(msg)
|
return this[bot_id].pickFriend(user_id).sendMsg(msg)
|
||||||
|
|
||||||
return new Promise(resolve =>
|
return new Promise(resolve =>
|
||||||
Bot.once(`connect.${bot_id}`, data =>
|
this.once(`connect.${bot_id}`, data =>
|
||||||
resolve(data.pickFriend(user_id).sendMsg(msg))))
|
resolve(data.pickFriend(user_id).sendMsg(msg))))
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(`${logger.blue(`[${bot_id}]`)} 发送好友消息失败:[$${user_id}] ${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) {
|
sendGroupMsg(bot_id, group_id, msg) {
|
||||||
try {
|
try {
|
||||||
if (!bot_id)
|
if (!bot_id)
|
||||||
return Bot.pickGroup(group_id).sendMsg(msg)
|
return this.pickGroup(group_id).sendMsg(msg)
|
||||||
|
|
||||||
if (Bot[bot_id])
|
if (this[bot_id])
|
||||||
return Bot[bot_id].pickGroup(group_id).sendMsg(msg)
|
return this[bot_id].pickGroup(group_id).sendMsg(msg)
|
||||||
|
|
||||||
return new Promise(resolve =>
|
return new Promise(resolve =>
|
||||||
Bot.once(`connect.${bot_id}`, data =>
|
this.once(`connect.${bot_id}`, data =>
|
||||||
resolve(data.pickGroup(group_id).sendMsg(msg))))
|
resolve(data.pickGroup(group_id).sendMsg(msg))))
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(`${logger.blue(`[${bot_id}]`)} 发送群消息失败:[$${group_id}] ${err}`)
|
logger.error(`${logger.blue(`[${bot_id}]`)} 发送群消息失败:[$${group_id}] ${err}`)
|
||||||
|
@ -138,7 +174,7 @@ export default class Yunzai extends EventEmitter {
|
||||||
async getMasterMsg() {
|
async getMasterMsg() {
|
||||||
while (true) {
|
while (true) {
|
||||||
const msg = await new Promise(resolve => {
|
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) {
|
if (cfg.master[data.self_id]?.includes(String(data.user_id)) && data.message) {
|
||||||
let msg = ""
|
let msg = ""
|
||||||
for (let i of data.message)
|
for (let i of data.message)
|
||||||
|
|
|
@ -13,6 +13,7 @@ class ListenerLoader {
|
||||||
logger.info("加载监听事件中...")
|
logger.info("加载监听事件中...")
|
||||||
let eventCount = 0
|
let eventCount = 0
|
||||||
for (const file of fs.readdirSync('./lib/events').filter(file => file.endsWith('.js'))) {
|
for (const file of fs.readdirSync('./lib/events').filter(file => file.endsWith('.js'))) {
|
||||||
|
logger.debug(`加载监听事件:${file}`)
|
||||||
try {
|
try {
|
||||||
let listener = await import(`../events/${file}`)
|
let listener = await import(`../events/${file}`)
|
||||||
if (!listener.default) continue
|
if (!listener.default) continue
|
||||||
|
@ -39,15 +40,13 @@ class ListenerLoader {
|
||||||
logger.info("-----------")
|
logger.info("-----------")
|
||||||
logger.info("加载适配器中...")
|
logger.info("加载适配器中...")
|
||||||
let adapterCount = 0
|
let adapterCount = 0
|
||||||
for (const file of fs.readdirSync('./lib/adapter').filter(file => file.endsWith('.js'))) {
|
for (const adapter of Bot.adapter) {
|
||||||
try {
|
try {
|
||||||
let adapter = await import(`../adapter/${file}`)
|
logger.debug(`加载适配器:${adapter.name}(${adapter.id})`)
|
||||||
if (!adapter.default) continue
|
|
||||||
adapter = new adapter.default()
|
|
||||||
await adapter.load()
|
await adapter.load()
|
||||||
adapterCount++
|
adapterCount++
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.mark(`加载适配器错误:${file}`)
|
logger.mark(`加载适配器错误:${adapter.name}(${adapter.id})`)
|
||||||
logger.error(e)
|
logger.error(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
"eslint": "^8.43.0",
|
"eslint": "^8.43.0",
|
||||||
"eslint-config-standard": "^17.1.0",
|
"eslint-config-standard": "^17.1.0",
|
||||||
"eslint-plugin-import": "^2.27.5",
|
"eslint-plugin-import": "^2.27.5",
|
||||||
"eslint-plugin-n": "^16.0.0",
|
"eslint-plugin-n": "^16.0.1",
|
||||||
"eslint-plugin-promise": "^6.1.1"
|
"eslint-plugin-promise": "^6.1.1"
|
||||||
},
|
},
|
||||||
"imports": {
|
"imports": {
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
*
|
*
|
||||||
!.gitignore
|
!.gitignore
|
||||||
|
!adapter
|
||||||
|
!adapter/**
|
||||||
|
!system
|
||||||
!system/**
|
!system/**
|
||||||
|
!other
|
||||||
!other/**
|
!other/**
|
||||||
|
|
||||||
!example/一言.js
|
!example/一言.js
|
||||||
!example/主动复读.js
|
!example/主动复读.js
|
||||||
!example/进群退群通知.js
|
!example/进群退群通知.js
|
|
@ -3,7 +3,12 @@ import { randomUUID } from "crypto"
|
||||||
import path from "node:path"
|
import path from "node:path"
|
||||||
import fs from "node:fs"
|
import fs from "node:fs"
|
||||||
|
|
||||||
export default class ComWeChatAdapter {
|
Bot.adapter.push(new class ComWeChatAdapter {
|
||||||
|
constructor() {
|
||||||
|
this.id = "WeChat"
|
||||||
|
this.name = "ComWeChat"
|
||||||
|
}
|
||||||
|
|
||||||
toStr(data) {
|
toStr(data) {
|
||||||
switch (typeof data) {
|
switch (typeof data) {
|
||||||
case "string":
|
case "string":
|
||||||
|
@ -198,8 +203,13 @@ export default class ComWeChatAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
pickFriend(data, user_id) {
|
pickFriend(data, user_id) {
|
||||||
const i = { ...data, user_id }
|
const i = {
|
||||||
|
...Bot[data.self_id].fl.get(user_id),
|
||||||
|
...data,
|
||||||
|
user_id,
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
|
...i,
|
||||||
sendMsg: msg => this.sendFriendMsg(i, msg),
|
sendMsg: msg => this.sendFriendMsg(i, msg),
|
||||||
recallMsg: () => false,
|
recallMsg: () => false,
|
||||||
makeForwardMsg: Bot.makeForwardMsg,
|
makeForwardMsg: Bot.makeForwardMsg,
|
||||||
|
@ -211,17 +221,28 @@ export default class ComWeChatAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
pickMember(data, group_id, user_id) {
|
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 {
|
return {
|
||||||
...this.pickFriend(i, user_id),
|
...this.pickFriend(i, user_id),
|
||||||
|
...i,
|
||||||
getInfo: () => this.getGroupMemberInfo(i),
|
getInfo: () => this.getGroupMemberInfo(i),
|
||||||
getAvatarUrl: async () => (await this.getGroupMemberInfo(i))["wx.avatar"],
|
getAvatarUrl: async () => (await this.getGroupMemberInfo(i))["wx.avatar"],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pickGroup(data, group_id) {
|
pickGroup(data, group_id) {
|
||||||
const i = { ...data, group_id }
|
const i = {
|
||||||
|
...Bot[data.self_id].gl.get(group_id),
|
||||||
|
...data,
|
||||||
|
group_id,
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
|
...i,
|
||||||
sendMsg: msg => this.sendGroupMsg(i, msg),
|
sendMsg: msg => this.sendGroupMsg(i, msg),
|
||||||
recallMsg: () => false,
|
recallMsg: () => false,
|
||||||
makeForwardMsg: Bot.makeForwardMsg,
|
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].nickname = Bot[data.self_id].info.user_name
|
||||||
Bot[data.self_id].avatar = Bot[data.self_id].info["wx.avatar"]
|
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].version = {
|
||||||
|
...(await data.sendApi("get_version")).data,
|
||||||
Bot[data.self_id].fl = await this.getFriendMap(data)
|
id: this.id,
|
||||||
Bot[data.self_id].gl = await this.getGroupMap(data)
|
name: this.name,
|
||||||
|
|
||||||
if (Array.isArray(Bot.uin)) {
|
|
||||||
if (!Bot.uin.includes(data.self_id))
|
|
||||||
Bot.uin.push(data.self_id)
|
|
||||||
} else {
|
|
||||||
Bot.uin = [data.self_id]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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.${data.self_id}`, Bot[data.self_id])
|
||||||
Bot.emit(`connect`, Bot[data.self_id])
|
Bot.emit(`connect`, Bot[data.self_id])
|
||||||
}
|
}
|
||||||
|
@ -343,15 +364,17 @@ export default class ComWeChatAdapter {
|
||||||
return logger.error(err)
|
return logger.error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data.sendApi = (action, params) => this.sendApi(ws, action, params)
|
|
||||||
if (data.self?.user_id) {
|
if (data.self?.user_id) {
|
||||||
data.self_id = data.self.user_id
|
data.self_id = data.self.user_id
|
||||||
data.bot = Bot[data.self_id]
|
|
||||||
} else {
|
} else {
|
||||||
data.self_id = data.id
|
data.self_id = data.id
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.type) {
|
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) {
|
switch (data.type) {
|
||||||
case "meta":
|
case "meta":
|
||||||
this.makeMeta(data)
|
this.makeMeta(data)
|
||||||
|
@ -379,11 +402,11 @@ export default class ComWeChatAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
load() {
|
load() {
|
||||||
const wss = new WebSocketServer({ noServer: true })
|
Bot.wss[this.name] = new WebSocketServer({ noServer: true })
|
||||||
wss.on("connection", ws => {
|
Bot.wss[this.name].on("connection", ws => {
|
||||||
ws.on("error", logger.error)
|
ws.on("error", logger.error)
|
||||||
ws.on("message", data => this.message(data, ws))
|
ws.on("message", data => this.message(data, ws))
|
||||||
})
|
})
|
||||||
return wss
|
return true
|
||||||
}
|
}
|
||||||
}
|
})
|
|
@ -2,7 +2,12 @@ import { WebSocketServer } from "ws"
|
||||||
import { randomUUID } from "crypto"
|
import { randomUUID } from "crypto"
|
||||||
import path from "node:path"
|
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) {
|
toStr(data) {
|
||||||
switch (typeof data) {
|
switch (typeof data) {
|
||||||
case "string":
|
case "string":
|
||||||
|
@ -407,42 +412,65 @@ export default class gocqhttpAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
pickFriend(data, user_id) {
|
pickFriend(data, user_id) {
|
||||||
const i = { ...data, user_id }
|
const i = {
|
||||||
|
...Bot[data.self_id].fl.get(user_id),
|
||||||
|
...data,
|
||||||
|
user_id,
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
|
...i,
|
||||||
sendMsg: msg => this.sendFriendMsg(i, msg),
|
sendMsg: msg => this.sendFriendMsg(i, msg),
|
||||||
recallMsg: message_id => this.recallMsg(i, message_id),
|
recallMsg: message_id => this.recallMsg(i, message_id),
|
||||||
makeForwardMsg: Bot.makeForwardMsg,
|
makeForwardMsg: Bot.makeForwardMsg,
|
||||||
sendForwardMsg: msg => this.sendFriendForwardMsg(i, msg),
|
sendForwardMsg: msg => this.sendFriendForwardMsg(i, msg),
|
||||||
sendFile: (file, name) => this.sendFriendFile(i, file, name),
|
sendFile: (file, name) => this.sendFriendFile(i, file, name),
|
||||||
getInfo: () => this.getFriendInfo(i),
|
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) {
|
pickMember(data, group_id, user_id) {
|
||||||
if (typeof group_id == "string" && group_id.match("-")) {
|
if (typeof group_id == "string" && group_id.match("-")) {
|
||||||
group_id = group_id.split("-")
|
const guild_id = group_id.split("-")
|
||||||
const i = { ...data, guild_id: group_id[0], channel_id: group_id[1], user_id }
|
const i = {
|
||||||
|
...data,
|
||||||
|
guild_id: guild_id[0],
|
||||||
|
channel_id: guild_id[1],
|
||||||
|
user_id,
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...this.pickGroup(i, `${i.guild_id}-${i.channel_id}`),
|
...this.pickGroup(i, group_id),
|
||||||
|
...i,
|
||||||
getInfo: () => this.getGuildMemberInfo(i),
|
getInfo: () => this.getGuildMemberInfo(i),
|
||||||
getAvatarUrl: async () => (await this.getGuildMemberInfo(i)).avatar_url,
|
getAvatarUrl: async () => (await this.getGuildMemberInfo(i)).avatar_url,
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
const i = { ...data, group_id, user_id }
|
|
||||||
return {
|
const i = {
|
||||||
...this.pickFriend(i, i.user_id),
|
...Bot[data.self_id].fl.get(user_id),
|
||||||
getInfo: () => this.getGroupMemberInfo(i),
|
...data,
|
||||||
poke: () => this.sendGroupMsg(i, segment.poke(i.user_id)),
|
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) {
|
pickGroup(data, group_id) {
|
||||||
if (typeof group_id == "string" && group_id.match("-")) {
|
if (typeof group_id == "string" && group_id.match("-")) {
|
||||||
group_id = group_id.split("-")
|
const guild_id = group_id.split("-")
|
||||||
const i = { ...data, guild_id: group_id[0], channel_id: group_id[1] }
|
const i = {
|
||||||
|
...Bot[data.self_id].gl.get(group_id),
|
||||||
|
...data,
|
||||||
|
guild_id: guild_id[0],
|
||||||
|
channel_id: guild_id[1],
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
|
...i,
|
||||||
sendMsg: msg => this.sendGuildMsg(i, msg),
|
sendMsg: msg => this.sendGuildMsg(i, msg),
|
||||||
recallMsg: message_id => this.recallMsg(i, message_id),
|
recallMsg: message_id => this.recallMsg(i, message_id),
|
||||||
makeForwardMsg: Bot.makeForwardMsg,
|
makeForwardMsg: Bot.makeForwardMsg,
|
||||||
|
@ -454,23 +482,28 @@ export default class gocqhttpAdapter {
|
||||||
getMemberArray: () => this.getGuildMemberArray(i),
|
getMemberArray: () => this.getGuildMemberArray(i),
|
||||||
getMemberList: () => this.getGuildMemberList(i),
|
getMemberList: () => this.getGuildMemberList(i),
|
||||||
getMemberMap: () => this.getGuildMemberMap(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 {
|
return {
|
||||||
|
...i,
|
||||||
sendMsg: msg => this.sendGroupMsg(i, msg),
|
sendMsg: msg => this.sendGroupMsg(i, msg),
|
||||||
recallMsg: message_id => this.recallMsg(i, message_id),
|
recallMsg: message_id => this.recallMsg(i, message_id),
|
||||||
makeForwardMsg: Bot.makeForwardMsg,
|
makeForwardMsg: Bot.makeForwardMsg,
|
||||||
sendForwardMsg: msg => this.sendGroupForwardMsg(i, msg),
|
sendForwardMsg: msg => this.sendGroupForwardMsg(i, msg),
|
||||||
sendFile: (file, name) => this.sendGroupFile(i, file, undefined, name),
|
sendFile: (file, name) => this.sendGroupFile(i, file, undefined, name),
|
||||||
getInfo: () => this.getGroupInfo(i),
|
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),
|
getMemberArray: () => this.getGroupMemberArray(i),
|
||||||
getMemberList: () => this.getGroupMemberList(i),
|
getMemberList: () => this.getGroupMemberList(i),
|
||||||
getMemberMap: () => this.getGroupMemberMap(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)),
|
pokeMember: user_id => this.sendGroupMsg(i, segment.poke(user_id)),
|
||||||
setName: group_name => this.setGroupName(i, group_name),
|
setName: group_name => this.setGroupName(i, group_name),
|
||||||
setAvatar: file => this.setGroupAvatar(i, file),
|
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].info = (await data.sendApi("get_login_info")).data
|
||||||
Bot[data.self_id].uin = Bot[data.self_id].info.user_id
|
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].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].guild_info = (await data.sendApi("get_guild_service_profile")).data
|
||||||
Bot[data.self_id].tiny_id = Bot[data.self_id].guild_info.tiny_id
|
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].status = Bot[data.self_id].version.protocol_name
|
||||||
|
|
||||||
Bot[data.self_id].fl = await this.getFriendMap(data)
|
Bot[data.self_id].fl = await Bot[data.self_id].getFriendMap()
|
||||||
Bot[data.self_id].gl = await this.getGroupMap(data)
|
Bot[data.self_id].gl = await Bot[data.self_id].getGroupMap()
|
||||||
|
|
||||||
if (Array.isArray(Bot.uin)) {
|
if (!Bot.uin.includes(data.self_id))
|
||||||
if (!Bot.uin.includes(data.self_id))
|
Bot.uin.push(data.self_id)
|
||||||
Bot.uin.push(data.self_id)
|
|
||||||
} else {
|
|
||||||
Bot.uin = [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.${data.self_id}`, Bot[data.self_id])
|
||||||
Bot.emit(`connect`, Bot[data.self_id])
|
Bot.emit(`connect`, Bot[data.self_id])
|
||||||
}
|
}
|
||||||
|
@ -685,7 +714,7 @@ export default class gocqhttpAdapter {
|
||||||
if (data.group_id) {
|
if (data.group_id) {
|
||||||
data.group = data.bot.pickGroup(data.group_id)
|
data.group = data.bot.pickGroup(data.group_id)
|
||||||
data.member = data.group.pickMember(data.user_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_id = `${data.guild_id}-${data.channel_id}`
|
||||||
data.group = data.bot.pickGroup(data.group_id)
|
data.group = data.bot.pickGroup(data.group_id)
|
||||||
data.member = data.group.pickMember(data.user_id)
|
data.member = data.group.pickMember(data.user_id)
|
||||||
|
@ -755,6 +784,8 @@ export default class gocqhttpAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.post_type) {
|
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.sendApi = (action, params) => this.sendApi(ws, action, params)
|
||||||
data.bot = Bot[data.self_id]
|
data.bot = Bot[data.self_id]
|
||||||
switch (data.post_type) {
|
switch (data.post_type) {
|
||||||
|
@ -786,11 +817,11 @@ export default class gocqhttpAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
load() {
|
load() {
|
||||||
const wss = new WebSocketServer({ noServer: true })
|
Bot.wss[this.name] = new WebSocketServer({ noServer: true })
|
||||||
wss.on("connection", ws => {
|
Bot.wss[this.name].on("connection", ws => {
|
||||||
ws.on("error", logger.error)
|
ws.on("error", logger.error)
|
||||||
ws.on("message", data => this.message(data, ws))
|
ws.on("message", data => this.message(data, ws))
|
||||||
})
|
})
|
||||||
return wss
|
return true
|
||||||
}
|
}
|
||||||
}
|
})
|
|
@ -1,7 +1,12 @@
|
||||||
import fs from "node:fs"
|
import fs from "node:fs"
|
||||||
import path from "node:path"
|
import path from "node:path"
|
||||||
|
|
||||||
export default class stdinAdapter {
|
Bot.adapter.push(new class stdinAdapter {
|
||||||
|
constructor() {
|
||||||
|
this.id = "stdin"
|
||||||
|
this.name = "标准输入"
|
||||||
|
}
|
||||||
|
|
||||||
async makeBuffer(file) {
|
async makeBuffer(file) {
|
||||||
if (file.match(/^base64:\/\//))
|
if (file.match(/^base64:\/\//))
|
||||||
return Buffer.from(file.replace(/^base64:\/\//, ""), "base64")
|
return Buffer.from(file.replace(/^base64:\/\//, ""), "base64")
|
||||||
|
@ -25,21 +30,21 @@ export default class stdinAdapter {
|
||||||
case "text":
|
case "text":
|
||||||
if (i.data.text.match("\n"))
|
if (i.data.text.match("\n"))
|
||||||
i.data.text = `\n${i.data.text}`
|
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
|
break
|
||||||
case "image":
|
case "image":
|
||||||
i.file = `${Bot.stdin.data_dir}${Date.now()}.png`
|
i.file = `${Bot[this.id].data_dir}${Date.now()}.png`
|
||||||
logger.info(`${logger.blue(`[stdin]`)} 发送图片:${i.data.file.replace(/^base64:\/\/.*/, "base64://...")}\n文件已保存到:${logger.cyan(i.file)}`)
|
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))
|
fs.writeFileSync(i.file, await this.makeBuffer(i.data.file))
|
||||||
break
|
break
|
||||||
case "record":
|
case "record":
|
||||||
i.file = `${Bot.stdin.data_dir}${Date.now()}.mp3`
|
i.file = `${Bot[this.id].data_dir}${Date.now()}.mp3`
|
||||||
logger.info(`${logger.blue(`[stdin]`)} 发送音频:${i.data.file.replace(/^base64:\/\/.*/, "base64://...")}\n文件已保存到:${logger.cyan(i.file)}`)
|
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))
|
fs.writeFileSync(i.file, await this.makeBuffer(i.data.file))
|
||||||
break
|
break
|
||||||
case "video":
|
case "video":
|
||||||
i.file = `${Bot.stdin.data_dir}${Date.now()}.mp4`
|
i.file = `${Bot[this.id].data_dir}${Date.now()}.mp4`
|
||||||
logger.info(`${logger.blue(`[stdin]`)} 发送视频:${i.data.file.replace(/^base64:\/\/.*/, "base64://...")}\n文件已保存到:${logger.cyan(i.file)}`)
|
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))
|
fs.writeFileSync(i.file, await this.makeBuffer(i.data.file))
|
||||||
break
|
break
|
||||||
case "reply":
|
case "reply":
|
||||||
|
@ -53,14 +58,14 @@ export default class stdinAdapter {
|
||||||
i = JSON.stringify(i)
|
i = JSON.stringify(i)
|
||||||
if (i.match("\n"))
|
if (i.match("\n"))
|
||||||
i = `\n${i}`
|
i = `\n${i}`
|
||||||
logger.info(`${logger.blue(`[stdin]`)} 发送消息:${i}`)
|
logger.info(`${logger.blue(`[${this.id}]`)} 发送消息:${i}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { message_id: Date.now() }
|
return { message_id: Date.now() }
|
||||||
}
|
}
|
||||||
|
|
||||||
recallMsg(message_id) {
|
recallMsg(message_id) {
|
||||||
logger.info(`${logger.blue(`[stdin]`)} 撤回消息:${message_id}`)
|
logger.info(`${logger.blue(`[${this.id}]`)} 撤回消息:${message_id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
sendForwardMsg(msg) {
|
sendForwardMsg(msg) {
|
||||||
|
@ -73,12 +78,12 @@ export default class stdinAdapter {
|
||||||
async sendFile(file, name = path.basename(file)) {
|
async sendFile(file, name = path.basename(file)) {
|
||||||
const buffer = await this.makeBuffer(file)
|
const buffer = await this.makeBuffer(file)
|
||||||
if (!Buffer.isBuffer(buffer)) {
|
if (!Buffer.isBuffer(buffer)) {
|
||||||
logger.error(`${logger.blue(`[stdin]`)} 发送文件错误:找不到文件 ${logger.red(file)}`)
|
logger.error(`${logger.blue(`[${this.id}]`)} 发送文件错误:找不到文件 ${logger.red(file)}`)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
const files = `${Bot.stdin.data_dir}${Date.now()}-${name}`
|
const files = `${Bot[this.id].data_dir}${Date.now()}-${name}`
|
||||||
logger.info(`${logger.blue(`[stdin]`)} 发送文件:${file}\n文件已保存到:${logger.cyan(files)}`)
|
logger.info(`${logger.blue(`[${this.id}]`)} 发送文件:${file}\n文件已保存到:${logger.cyan(files)}`)
|
||||||
return fs.writeFileSync(files, buffer)
|
return fs.writeFileSync(files, buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,12 +99,12 @@ export default class stdinAdapter {
|
||||||
|
|
||||||
message(msg) {
|
message(msg) {
|
||||||
const data = {
|
const data = {
|
||||||
bot: Bot.stdin,
|
bot: Bot[this.id],
|
||||||
self_id: "stdin",
|
self_id: this.id,
|
||||||
user_id: "stdin",
|
user_id: this.id,
|
||||||
post_type: "message",
|
post_type: "message",
|
||||||
message_type: "private",
|
message_type: "private",
|
||||||
sender: { nickname: "标准输入" },
|
sender: { nickname: this.name },
|
||||||
message: [{ type: "text", text: msg }],
|
message: [{ type: "text", text: msg }],
|
||||||
raw_message: msg,
|
raw_message: msg,
|
||||||
friend: this.pickFriend(),
|
friend: this.pickFriend(),
|
||||||
|
@ -111,42 +116,38 @@ export default class stdinAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
load() {
|
load() {
|
||||||
Bot.stdin = {
|
Bot[this.id] = {
|
||||||
uin: "stdin",
|
uin: this.id,
|
||||||
nickname: "标准输入",
|
nickname: this.name,
|
||||||
stat: { start_time: Date.now()/1000 },
|
stat: { start_time: Date.now()/1000 },
|
||||||
version: { impl: "stdin" },
|
version: { id: this.id, name: this.name },
|
||||||
pickFriend: () => this.pickFriend(),
|
pickFriend: () => this.pickFriend(),
|
||||||
pickUser: () => this.pickFriend(),
|
pickUser: () => this.pickFriend(),
|
||||||
pickGroup: () => this.pickFriend(),
|
pickGroup: () => this.pickFriend(),
|
||||||
pickMember: () => this.pickFriend(),
|
pickMember: () => this.pickFriend(),
|
||||||
|
|
||||||
fl: new Map().set("stdin", {
|
fl: new Map().set(this.id, {
|
||||||
user_id: "stdin",
|
user_id: this.id,
|
||||||
nickname: "标准输入",
|
nickname: this.name,
|
||||||
}),
|
}),
|
||||||
gl: new Map().set("stdin", {
|
gl: new Map().set(this.id, {
|
||||||
group_id: "stdin",
|
group_id: this.id,
|
||||||
group_name: "标准输入",
|
group_name: this.name,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
data_dir: `${process.cwd()}/data/stdin/`,
|
data_dir: `${process.cwd()}/data/stdin/`,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fs.existsSync(Bot.stdin.data_dir))
|
if (!fs.existsSync(Bot[this.id].data_dir))
|
||||||
fs.mkdirSync(Bot.stdin.data_dir)
|
fs.mkdirSync(Bot[this.id].data_dir)
|
||||||
|
|
||||||
if (Array.isArray(Bot.uin)) {
|
if (!Bot.uin.includes(this.id))
|
||||||
if (!Bot.uin.includes("stdin"))
|
Bot.uin.push(this.id)
|
||||||
Bot.uin.push("stdin")
|
|
||||||
} else {
|
|
||||||
Bot.uin = ["stdin"]
|
|
||||||
}
|
|
||||||
|
|
||||||
process.stdin.on("data", data => this.message(data.toString()))
|
process[this.id].on("data", data => this.message(data.toString()))
|
||||||
|
|
||||||
logger.mark(`${logger.blue(`[stdin]`)} 标准输入 已连接`)
|
logger.mark(`${logger.blue(`[${this.id}]`)} ${this.name}(${this.id}) 已连接`)
|
||||||
Bot.emit(`connect.stdin`, Bot.stdin)
|
Bot.emit(`connect.${this.id}`, Bot[this.id])
|
||||||
Bot.emit(`connect`, Bot.stdin)
|
Bot.emit(`connect`, Bot[this.id])
|
||||||
}
|
}
|
||||||
}
|
})
|
Loading…
Reference in New Issue