Miao-Yunzai/lib/bot.js

231 lines
6.8 KiB
JavaScript
Raw Normal View History

2023-06-26 23:32:52 +08:00
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"
2023-08-20 08:35:47 +08:00
import { WebSocketServer } from "ws"
import _ from "lodash"
2023-05-11 16:03:18 +08:00
export default class Yunzai extends EventEmitter {
2023-06-26 23:32:52 +08:00
constructor() {
super()
this.uin = []
this.adapter = []
2023-07-23 16:39:33 +08:00
this.express = express()
this.server = http.createServer(this.express)
this.server.on("upgrade", (req, socket, head) => {
2023-08-20 08:35:47 +08:00
this.wss.handleUpgrade(req, socket, head, conn => {
conn.id = `${req.connection.remoteAddress}-${req.headers["sec-websocket-key"]}`
this.makeLog("mark", `${logger.blue(`[${conn.id} <=> ${req.url}]`)} 建立连接:${JSON.stringify(req.headers)}`)
conn.on("error", logger.error)
conn.on("close", () => this.makeLog("mark", `${logger.blue(`[${conn.id} <≠> ${req.url}]`)} 断开连接`))
conn.on("message", msg => this.makeLog("debug", `${logger.blue(`[${conn.id} => ${req.url}]`)} 消息:${String(msg).trim()}`))
conn.sendMsg = msg => {
if (typeof msg == "object")
msg = JSON.stringify(msg)
this.makeLog("debug", `${logger.blue(`[${conn.id} <= ${req.url}]`)} 消息:${msg}`)
return conn.send(msg)
}
for (const i of this.wsf[req.url.split("/")[1]] || [])
i(conn, req, socket, head)
})
2023-07-23 16:39:33 +08:00
})
2023-08-20 08:35:47 +08:00
this.wss = new WebSocketServer({ noServer: true })
this.wsf = {}
}
makeLog(level, msg) {
logger[level](_.truncate(msg, { length: cfg.bot.logLength }))
}
em(name = "", data = {}) {
if (data.self_id)
Object.defineProperty(data, "bot", { value: Bot[data.self_id] })
while (true) {
this.emit(name, data)
const i = name.lastIndexOf(".")
if (i == -1) break
name = name.slice(0, i)
}
2023-06-26 23:32:52 +08:00
}
async run() {
await import("./plugins/stdin.js")
2023-05-11 16:03:18 +08:00
await PluginsLoader.load()
await ListenerLoader.load()
2023-06-26 23:32:52 +08:00
this.serverLoad()
2023-06-29 10:41:02 +08:00
this.emit("online", this)
2023-06-26 23:32:52 +08:00
}
serverLoad() {
2023-07-23 16:39:33 +08:00
this.express.use(req => {
2023-08-20 08:35:47 +08:00
logger.mark(`${logger.blue(`[${req.ip} => ${req.url}]`)} HTTP ${req.method} 请求:${JSON.stringify(req.headers)}`)
req.res.redirect("https://github.com/TimeRainStarSky/Yunzai")
})
2023-06-26 23:32:52 +08:00
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}`)}`)
2023-08-20 08:35:47 +08:00
for (const i of Object.keys(this.wsf))
2023-06-26 23:32:52 +08:00
logger.info(`本机 ${i} 连接地址:${logger.blue(`ws://localhost:${port}/${i}`)}`)
})
2023-05-11 16:03:18 +08:00
}
getFriendArray() {
const array = []
2023-07-08 21:40:55 +08:00
for (const bot_id of this.uin)
2023-07-23 16:39:33 +08:00
for (const [id, i] of this[bot_id].fl || [])
array.push({ ...i, bot_id })
2023-05-11 16:03:18 +08:00
return array
}
getFriendList() {
const array = []
2023-07-08 21:40:55 +08:00
for (const bot_id of this.uin)
2023-07-23 16:39:33 +08:00
for (const [id, i] of this[bot_id].fl || [])
array.push(id)
2023-05-11 16:03:18 +08:00
return array
}
getFriendMap() {
2023-08-20 08:35:47 +08:00
const map = new Map
2023-07-08 21:40:55 +08:00
for (const bot_id of this.uin)
2023-07-23 16:39:33 +08:00
for (const [id, i] of this[bot_id].fl || [])
map.set(id, { ...i, bot_id })
2023-05-11 16:03:18 +08:00
return map
}
2023-07-29 13:47:45 +08:00
get fl() { return this.getFriendMap() }
2023-05-11 16:03:18 +08:00
getGroupArray() {
const array = []
2023-07-08 21:40:55 +08:00
for (const bot_id of this.uin)
2023-07-23 16:39:33 +08:00
for (const [id, i] of this[bot_id].gl || [])
array.push({ ...i, bot_id })
2023-05-11 16:03:18 +08:00
return array
}
getGroupList() {
const array = []
2023-07-08 21:40:55 +08:00
for (const bot_id of this.uin)
2023-07-23 16:39:33 +08:00
for (const [id, i] of this[bot_id].gl || [])
array.push(id)
2023-05-11 16:03:18 +08:00
return array
}
getGroupMap() {
2023-08-20 08:35:47 +08:00
const map = new Map
2023-07-08 21:40:55 +08:00
for (const bot_id of this.uin)
2023-07-23 16:39:33 +08:00
for (const [id, i] of this[bot_id].gl || [])
map.set(id, { ...i, bot_id })
2023-05-11 16:03:18 +08:00
return map
}
2023-07-29 13:47:45 +08:00
get gl() { return this.getGroupMap() }
2023-08-20 08:35:47 +08:00
get gml() {
const map = new Map
for (const bot_id of this.uin)
for (const [id, i] of this[bot_id].gml || [])
map.set(id, i)
return map
}
2023-05-11 16:03:18 +08:00
pickFriend(user_id) {
user_id = Number(user_id) || String(user_id)
2023-06-26 23:32:52 +08:00
const user = this.fl.get(user_id)
if (user) return this[user.bot_id].pickFriend(user_id)
2023-05-11 16:03:18 +08:00
logger.error(`获取用户对象失败:找不到用户 ${logger.red(user_id)}`)
}
2023-07-29 13:47:45 +08:00
get pickUser() { return this.pickFriend }
2023-05-11 16:03:18 +08:00
pickGroup(group_id) {
group_id = Number(group_id) || String(group_id)
2023-06-26 23:32:52 +08:00
const group = this.gl.get(group_id)
if (group) return this[group.bot_id].pickGroup(group_id)
2023-05-11 16:03:18 +08:00
logger.error(`获取群对象失败:找不到群 ${logger.red(group_id)}`)
}
pickMember(group_id, user_id) {
2023-06-23 20:50:45 +08:00
const group = this.pickGroup(group_id)
if (group) return group.pickMember(user_id)
2023-05-11 16:03:18 +08:00
}
sendFriendMsg(bot_id, user_id, msg) {
try {
if (!bot_id)
2023-06-26 23:32:52 +08:00
return this.pickFriend(user_id).sendMsg(msg)
2023-05-11 16:03:18 +08:00
2023-06-26 23:32:52 +08:00
if (this[bot_id])
return this[bot_id].pickFriend(user_id).sendMsg(msg)
2023-05-11 16:03:18 +08:00
return new Promise(resolve =>
2023-06-26 23:32:52 +08:00
this.once(`connect.${bot_id}`, data =>
2023-08-20 08:35:47 +08:00
resolve(data.bot.pickFriend(user_id).sendMsg(msg))))
2023-05-11 16:03:18 +08:00
} catch (err) {
logger.error(`${logger.blue(`[${bot_id}]`)} 发送好友消息失败:[$${user_id}] ${err}`)
}
2023-06-29 10:41:02 +08:00
return false
2023-05-11 16:03:18 +08:00
}
sendGroupMsg(bot_id, group_id, msg) {
try {
if (!bot_id)
2023-06-26 23:32:52 +08:00
return this.pickGroup(group_id).sendMsg(msg)
2023-05-11 16:03:18 +08:00
2023-06-26 23:32:52 +08:00
if (this[bot_id])
return this[bot_id].pickGroup(group_id).sendMsg(msg)
2023-05-11 16:03:18 +08:00
return new Promise(resolve =>
2023-06-26 23:32:52 +08:00
this.once(`connect.${bot_id}`, data =>
2023-08-20 08:35:47 +08:00
resolve(data.bot.pickGroup(group_id).sendMsg(msg))))
2023-05-11 16:03:18 +08:00
} catch (err) {
logger.error(`${logger.blue(`[${bot_id}]`)} 发送群消息失败:[$${group_id}] ${err}`)
}
2023-06-29 10:41:02 +08:00
return false
2023-05-11 16:03:18 +08:00
}
2023-07-29 13:47:45 +08:00
async getFriendMsg(fnc = () => true) {
if (typeof fnc != "function") {
const { self_id, user_id } = fnc
fnc = data => data.self_id == self_id && data.user_id == user_id
}
2023-05-11 16:03:18 +08:00
while (true) {
const msg = await new Promise(resolve => {
2023-06-26 23:32:52 +08:00
this.once("message", data => {
2023-07-29 13:47:45 +08:00
if (data.message && fnc(data)) {
2023-05-11 16:03:18 +08:00
let msg = ""
2023-07-29 13:47:45 +08:00
for (const i of data.message)
2023-05-11 16:03:18 +08:00
if (i.type = "text")
msg += i.text.trim()
resolve(msg)
} else {
resolve(false)
}
})
})
if (msg) return msg
}
}
2023-06-18 11:57:31 +08:00
2023-07-29 13:47:45 +08:00
getMasterMsg() {
return this.getFriendMsg(data =>
cfg.master[data.self_id]?.includes(String(data.user_id)))
2023-06-18 11:57:31 +08:00
}
2023-07-29 13:47:45 +08:00
sendMasterMsg(msg) {
for (const bot_id in cfg.master)
for (const user_id of cfg.master[bot_id])
this.sendFriendMsg(bot_id, user_id, msg)
}
makeForwardMsg(msg) { return { type: "node", data: msg } }
async sendForwardMsg(send, msg) {
const messages = []
2023-07-08 21:40:55 +08:00
for (const { message } of msg)
messages.push(await send(message))
return messages
}
2023-05-11 16:03:18 +08:00
}