dfghfhgfg's picture
Upload 75 files
3b148c3 verified
import path from "node:path"
import { ulid } from "ulid"
Bot.adapter.push(new class OneBotv11Adapter {
constructor() {
this.id = "QQ"
this.name = "OneBotv11"
this.path = this.name
this.echo = {}
this.timeout = 60000
}
makeLog(msg) {
return Bot.String(msg).replace(/base64:\/\/.*?(,|]|")/g, "base64://...$1")
}
sendApi(data, ws, action, params = {}) {
const echo = ulid()
const request = { action, params, echo }
ws.sendMsg(request)
const error = Error()
return new Promise((resolve, reject) =>
this.echo[echo] = {
request, resolve, reject, error,
timeout: setTimeout(() => {
reject(Object.assign(error, request, { timeout: this.timeout }))
delete this.echo[echo]
Bot.makeLog("error", ["请求超时", request], data.self_id)
ws.terminate()
}, this.timeout),
}
)
}
async makeFile(file) {
file = await Bot.Buffer(file, { http: true })
if (Buffer.isBuffer(file))
file = `base64://${file.toString("base64")}`
return file
}
async makeMsg(msg) {
if (!Array.isArray(msg))
msg = [msg]
const msgs = []
const forward = []
for (let i of msg) {
if (typeof i !== "object")
i = { type: "text", data: { text: i }}
else if (!i.data)
i = { type: i.type, data: { ...i, type: undefined }}
switch (i.type) {
case "at":
i.data.qq = String(i.data.qq)
break
case "reply":
i.data.id = String(i.data.id)
break
case "button":
continue
case "node":
forward.push(...i.data)
continue
case "raw":
i = i.data
break
}
if (i.data.file)
i.data.file = await this.makeFile(i.data.file)
msgs.push(i)
}
return [msgs, forward]
}
async sendMsg(msg, send, sendForwardMsg) {
const [message, forward] = await this.makeMsg(msg)
const ret = []
if (forward.length) {
const data = await sendForwardMsg(forward)
if (Array.isArray(data))
ret.push(...data)
else
ret.push(data)
}
if (message.length)
ret.push(await send(message))
if (ret.length === 1) return ret[0]
const message_id = []
for (const i of ret) if (i?.message_id)
message_id.push(i.message_id)
return { data: ret, message_id }
}
sendFriendMsg(data, msg) {
return this.sendMsg(msg, message => {
Bot.makeLog("info", `发送好友消息:${this.makeLog(message)}`, `${data.self_id} => ${data.user_id}`)
data.bot.sendApi("send_msg", {
user_id: data.user_id,
message,
})
}, msg => this.sendFriendForwardMsg(data, msg))
}
sendGroupMsg(data, msg) {
return this.sendMsg(msg, message => {
Bot.makeLog("info", `发送群消息:${this.makeLog(message)}`, `${data.self_id} => ${data.group_id}`)
return data.bot.sendApi("send_msg", {
group_id: data.group_id,
message,
})
}, msg => this.sendGroupForwardMsg(data, msg))
}
sendGuildMsg(data, msg) {
return this.sendMsg(msg, message => {
Bot.makeLog("info", `发送频道消息:${this.makeLog(message)}`, `${data.self_id}] => ${data.guild_id}-${data.channel_id}`)
return data.bot.sendApi("send_guild_channel_msg", {
guild_id: data.guild_id,
channel_id: data.channel_id,
message,
})
}, msg => Bot.sendForwardMsg(msg => this.sendGuildMsg(data, msg), msg))
}
async recallMsg(data, message_id) {
Bot.makeLog("info", `撤回消息:${message_id}`, data.self_id)
if (!Array.isArray(message_id))
message_id = [message_id]
const msgs = []
for (const i of message_id)
msgs.push(await data.bot.sendApi("delete_msg", { message_id: i }))
return msgs
}
parseMsg(msg) {
const array = []
for (const i of Array.isArray(msg) ? msg : [msg])
if (typeof i === "object")
array.push({ ...i.data, type: i.type })
else
array.push({ type: "text", text: String(i) })
return array
}
async getMsg(data, message_id) {
const msg = (await data.bot.sendApi("get_msg", { message_id })).data
if (msg?.message)
msg.message = this.parseMsg(msg.message)
return msg
}
async getGroupMsgHistory(data, message_seq, count) {
const msgs = (await data.bot.sendApi("get_group_msg_history", {
group_id: data.group_id,
message_seq,
count,
})).data?.messages
for (const i of Array.isArray(msgs) ? msgs : [msgs])
if (i?.message)
i.message = this.parseMsg(i.message)
return msgs
}
async getForwardMsg(data, message_id) {
const msgs = (await data.bot.sendApi("get_forward_msg", {
message_id,
})).data?.messages
for (const i of Array.isArray(msgs) ? msgs : [msgs])
if (i?.message)
i.message = this.parseMsg(i.message || i.content)
return msgs
}
async makeForwardMsg(msg) {
const msgs = []
for (const i of msg) {
const [content, forward] = await this.makeMsg(i.message)
if (forward.length)
msgs.push(...await this.makeForwardMsg(forward))
if (content.length)
msgs.push({ type: "node", data: {
name: i.nickname || "匿名消息",
uin: String(Number(i.user_id) || 80000000),
content,
time: i.time,
}})
}
return msgs
}
async sendFriendForwardMsg(data, msg) {
Bot.makeLog("info", `发送好友转发消息:${this.makeLog(msg)}`, `${data.self_id} => ${data.user_id}`)
return data.bot.sendApi("send_private_forward_msg", {
user_id: data.user_id,
messages: await this.makeForwardMsg(msg),
})
}
async sendGroupForwardMsg(data, msg) {
Bot.makeLog("info", `发送群转发消息:${this.makeLog(msg)}`, `${data.self_id} => ${data.group_id}`)
return data.bot.sendApi("send_group_forward_msg", {
group_id: data.group_id,
messages: await this.makeForwardMsg(msg),
})
}
async getFriendArray(data) {
return (await data.bot.sendApi("get_friend_list")).data || []
}
async getFriendList(data) {
const array = []
for (const { user_id } of await this.getFriendArray(data))
array.push(user_id)
return array
}
async getFriendMap(data) {
const map = new Map
for (const i of await this.getFriendArray(data))
map.set(i.user_id, i)
data.bot.fl = map
return map
}
getFriendInfo(data) {
return data.bot.sendApi("get_stranger_info", {
user_id: data.user_id,
})
}
async getGroupArray(data) {
const array = (await data.bot.sendApi("get_group_list")).data
try { for (const guild of await this.getGuildArray(data))
for (const channel of await this.getGuildChannelArray({
...data,
guild_id: guild.guild_id,
}))
array.push({
guild,
channel,
group_id: `${guild.guild_id}-${channel.channel_id}`,
group_name: `${guild.guild_name}-${channel.channel_name}`,
})
} catch (err) {
//Bot.makeLog("error", ["获取频道列表错误", err])
}
return array
}
async getGroupList(data) {
const array = []
for (const { group_id } of await this.getGroupArray(data))
array.push(group_id)
return array
}
async getGroupMap(data) {
const map = new Map
for (const i of await this.getGroupArray(data))
map.set(i.group_id, i)
data.bot.gl = map
return map
}
getGroupInfo(data) {
return data.bot.sendApi("get_group_info", {
group_id: data.group_id,
})
}
async getMemberArray(data) {
return (await data.bot.sendApi("get_group_member_list", {
group_id: data.group_id,
})).data || []
}
async getMemberList(data) {
const array = []
for (const { user_id } of await this.getMemberArray(data))
array.push(user_id)
return array
}
async getMemberMap(data) {
const map = new Map
for (const i of await this.getMemberArray(data))
map.set(i.user_id, i)
data.bot.gml.set(data.group_id, map)
return map
}
async getGroupMemberMap(data) {
for (const [group_id, group] of await this.getGroupMap(data)) {
if (group.guild) continue
await this.getMemberMap({ ...data, group_id })
}
}
getMemberInfo(data) {
return data.bot.sendApi("get_group_member_info", {
group_id: data.group_id,
user_id: data.user_id,
})
}
async getGuildArray(data) {
return (await data.bot.sendApi("get_guild_list")).data || []
}
getGuildInfo(data) {
return data.bot.sendApi("get_guild_meta_by_guest", {
guild_id: data.guild_id,
})
}
async getGuildChannelArray(data) {
return (await data.bot.sendApi("get_guild_channel_list", {
guild_id: data.guild_id,
})).data || []
}
async getGuildChannelMap(data) {
const map = new Map
for (const i of await this.getGuildChannelArray(data))
map.set(i.channel_id, i)
return map
}
async getGuildMemberArray(data) {
const array = []
let next_token = ""
while (true) {
const list = (await data.bot.sendApi("get_guild_member_list", {
guild_id: data.guild_id,
next_token,
})).data
if (!list) break
for (const i of list.members)
array.push({
...i,
user_id: i.tiny_id,
})
if (list.finished) break
next_token = list.next_token
}
return array
}
async getGuildMemberList(data) {
const array = []
for (const { user_id } of await this.getGuildMemberArray(data))
array.push(user_id)
return array.push
}
async getGuildMemberMap(data) {
const map = new Map
for (const i of await this.getGuildMemberArray(data))
map.set(i.user_id, i)
data.bot.gml.set(data.group_id, map)
return map
}
getGuildMemberInfo(data) {
return data.bot.sendApi("get_guild_member_profile", {
guild_id: data.guild_id,
user_id: data.user_id,
})
}
setProfile(data, profile) {
Bot.makeLog("info", `设置资料:${Bot.String(profile)}`, data.self_id)
return data.bot.sendApi("set_qq_profile", profile)
}
async setAvatar(data, file) {
Bot.makeLog("info", `设置头像:${file}`, data.self_id)
return data.bot.sendApi("set_qq_avatar", {
file: await this.makeFile(file),
})
}
sendLike(data, times) {
Bot.makeLog("info", `点赞:${times}次`, `${data.self_id} => ${data.user_id}`)
return data.bot.sendApi("send_like", {
user_id: data.user_id,
times,
})
}
setGroupName(data, group_name) {
Bot.makeLog("info", `设置群名:${group_name}`, `${data.self_id} => ${data.group_id}`)
return data.bot.sendApi("set_group_name", {
group_id: data.group_id,
group_name,
})
}
async setGroupAvatar(data, file) {
Bot.makeLog("info", `设置群头像:${file}`, `${data.self_id} => ${data.group_id}`)
return data.bot.sendApi("set_group_portrait", {
group_id: data.group_id,
file: await this.makeFile(file),
})
}
setGroupAdmin(data, user_id, enable) {
Bot.makeLog("info", `${enable ? "设置" : "取消"}群管理员:${user_id}`, `${data.self_id} => ${data.group_id}`)
return data.bot.sendApi("set_group_admin", {
group_id: data.group_id,
user_id,
enable,
})
}
setGroupCard(data, user_id, card) {
Bot.makeLog("info", `设置群名片:${card}`, `${data.self_id} => ${data.group_id}, ${user_id}`)
return data.bot.sendApi("set_group_card", {
group_id: data.group_id,
user_id,
card,
})
}
setGroupTitle(data, user_id, special_title, duration) {
Bot.makeLog("info", `设置群头衔:${special_title} ${duration}`, `${data.self_id} => ${data.group_id}, ${user_id}`)
return data.bot.sendApi("set_group_special_title", {
group_id: data.group_id,
user_id,
special_title,
duration,
})
}
sendGroupSign(data) {
Bot.makeLog("info", "群打卡", `${data.self_id} => ${data.group_id}`)
return data.bot.sendApi("send_group_sign", {
group_id: data.group_id,
})
}
setGroupBan(data, user_id, duration) {
Bot.makeLog("info", `禁言群成员:${duration}秒`, `${data.self_id} => ${data.group_id}, ${user_id}`)
return data.bot.sendApi("set_group_ban", {
group_id: data.group_id,
user_id,
duration,
})
}
setGroupWholeKick(data, enable) {
Bot.makeLog("info", `${enable ? "开启" : "关闭"}全员禁言`, `${data.self_id} => ${data.group_id}`)
return data.bot.sendApi("set_group_whole_ban", {
group_id: data.group_id,
enable,
})
}
setGroupKick(data, user_id, reject_add_request) {
Bot.makeLog("info", `踢出群成员${reject_add_request ? "拒绝再次加群" : ""}`, `${data.self_id} => ${data.group_id}, ${user_id}`)
return data.bot.sendApi("set_group_kick", {
group_id: data.group_id,
user_id,
reject_add_request,
})
}
setGroupLeave(data, is_dismiss) {
Bot.makeLog("info", is_dismiss ? "解散" : "退群", `${data.self_id} => ${data.group_id}`)
return data.bot.sendApi("set_group_leave", {
group_id: data.group_id,
is_dismiss,
})
}
downloadFile(data, url, thread_count, headers) {
return data.bot.sendApi("download_file", {
url,
thread_count,
headers,
})
}
async sendFriendFile(data, file, name = path.basename(file)) {
Bot.makeLog("info", `发送好友文件:${name}(${file})`, `${data.self_id} => ${data.user_id}`)
return data.bot.sendApi("upload_private_file", {
user_id: data.user_id,
file: await this.makeFile(file),
name,
})
}
async sendGroupFile(data, file, folder, name = path.basename(file)) {
Bot.makeLog("info", `发送群文件:${folder||""}/${name}(${file})`, `${data.self_id} => ${data.group_id}`)
return data.bot.sendApi("upload_group_file", {
group_id: data.group_id,
folder,
file: await this.makeFile(file),
name,
})
}
deleteGroupFile(data, file_id, busid) {
Bot.makeLog("info", `删除群文件:${file_id}(${busid})`, `${data.self_id} => ${data.group_id}`)
return data.bot.sendApi("delete_group_file", {
group_id: data.group_id,
file_id,
busid,
})
}
createGroupFileFolder(data, name) {
Bot.makeLog("info", `创建群文件夹:${name}`, `${data.self_id} => ${data.group_id}`)
return data.bot.sendApi("create_group_file_folder", {
group_id: data.group_id,
name,
})
}
getGroupFileSystemInfo(data) {
return data.bot.sendApi("get_group_file_system_info", {
group_id: data.group_id,
})
}
getGroupFiles(data, folder_id) {
if (folder_id)
return data.bot.sendApi("get_group_files_by_folder", {
group_id: data.group_id,
folder_id,
})
return data.bot.sendApi("get_group_root_files", {
group_id: data.group_id,
})
}
getGroupFileUrl(data, file_id, busid) {
return data.bot.sendApi("get_group_file_url", {
group_id: data.group_id,
file_id,
busid,
})
}
getGroupFs(data) {
return {
upload: (file, folder, name) => this.sendGroupFile(data, file, folder, name),
rm: (file_id, busid) => this.deleteGroupFile(data, file_id, busid),
mkdir: name => this.createGroupFileFolder(data, name),
df: () => this.getGroupFileSystemInfo(data),
ls: folder_id => this.getGroupFiles(data, folder_id),
download: (file_id, busid) => this.getGroupFileUrl(data, file_id, busid),
}
}
setFriendAddRequest(data, flag, approve, remark) {
return data.bot.sendApi("set_friend_add_request", {
flag,
approve,
remark,
})
}
setGroupAddRequest(data, flag, sub_type, approve, reason) {
return data.bot.sendApi("set_group_add_request", {
flag,
sub_type,
approve,
reason,
})
}
pickFriend(data, user_id) {
const i = {
...data.bot.fl.get(user_id),
...data,
user_id,
}
return {
...i,
sendMsg: msg => this.sendFriendMsg(i, msg),
getMsg: message_id => this.getMsg(i, message_id),
recallMsg: message_id => this.recallMsg(i, message_id),
getForwardMsg: message_id => this.getForwardMsg(i, message_id),
sendForwardMsg: msg => this.sendFriendForwardMsg(i, msg),
sendFile: (file, name) => this.sendFriendFile(i, file, name),
getInfo: () => this.getFriendInfo(i),
getAvatarUrl: () => i.avatar || `https://q.qlogo.cn/g?b=qq&s=0&nk=${user_id}`,
thumbUp: times => this.sendLike(i, times),
}
}
pickMember(data, group_id, user_id) {
if (typeof group_id === "string" && group_id.match("-")) {
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, group_id),
...i,
getInfo: () => this.getGuildMemberInfo(i),
getAvatarUrl: async () => (await this.getGuildMemberInfo(i)).avatar_url,
}
}
const i = {
...data.bot.fl.get(user_id),
...data.bot.gml.get(group_id)?.get(user_id),
...data,
group_id,
user_id,
}
return {
...this.pickFriend(i, user_id),
...i,
getInfo: () => this.getMemberInfo(i),
getAvatarUrl: () => i.avatar || `https://q.qlogo.cn/g?b=qq&s=0&nk=${user_id}`,
poke: () => this.sendGroupMsg(i, { type: "poke", qq: user_id }),
mute: duration => this.setGroupBan(i, i.user_id, duration),
kick: reject_add_request => this.setGroupKick(i, i.user_id, reject_add_request),
get is_friend() { return data.bot.fl.has(user_id) },
get is_owner() { return i.role === "owner" },
get is_admin() { return i.role === "admin" },
}
}
pickGroup(data, group_id) {
if (typeof group_id === "string" && group_id.match("-")) {
const guild_id = group_id.split("-")
const i = {
...data.bot.gl.get(group_id),
...data,
guild_id: guild_id[0],
channel_id: guild_id[1],
}
return {
...i,
sendMsg: msg => this.sendGuildMsg(i, msg),
getMsg: message_id => this.getMsg(i, message_id),
recallMsg: message_id => this.recallMsg(i, message_id),
getForwardMsg: message_id => this.getForwardMsg(i, message_id),
getInfo: () => this.getGuildInfo(i),
getChannelArray: () => this.getGuildChannelArray(i),
getChannelList: () => this.getGuildChannelList(i),
getChannelMap: () => this.getGuildChannelMap(i),
getMemberArray: () => this.getGuildMemberArray(i),
getMemberList: () => this.getGuildMemberList(i),
getMemberMap: () => this.getGuildMemberMap(i),
pickMember: user_id => this.pickMember(i, group_id, user_id),
}
}
const i = {
...data.bot.gl.get(group_id),
...data,
group_id,
}
return {
...i,
sendMsg: msg => this.sendGroupMsg(i, msg),
getMsg: message_id => this.getMsg(i, message_id),
recallMsg: message_id => this.recallMsg(i, message_id),
getForwardMsg: message_id => this.getForwardMsg(i, message_id),
sendForwardMsg: msg => this.sendGroupForwardMsg(i, msg),
sendFile: (file, name) => this.sendGroupFile(i, file, undefined, name),
getInfo: () => this.getGroupInfo(i),
getAvatarUrl: () => i.avatar || `https://p.qlogo.cn/gh/${group_id}/${group_id}/0`,
getChatHistory: (seq, cnt) => this.getGroupMsgHistory(i, seq, cnt),
getMemberArray: () => this.getMemberArray(i),
getMemberList: () => this.getMemberList(i),
getMemberMap: () => this.getMemberMap(i),
pickMember: user_id => this.pickMember(i, group_id, user_id),
pokeMember: qq => this.sendGroupMsg(i, { type: "poke", qq }),
setName: group_name => this.setGroupName(i, group_name),
setAvatar: file => this.setGroupAvatar(i, file),
setAdmin: (user_id, enable) => this.setGroupAdmin(i, user_id, enable),
setCard: (user_id, card) => this.setGroupCard(i, user_id, card),
setTitle: (user_id, special_title, duration) => this.setGroupTitle(i, user_id, special_title, duration),
sign: () => this.sendGroupSign(i),
muteMember: (user_id, duration) => this.setGroupBan(i, user_id, duration),
muteAll: enable => this.setGroupWholeKick(i, enable),
kickMember: (user_id, reject_add_request) => this.setGroupKick(i, user_id, reject_add_request),
quit: is_dismiss => this.setGroupLeave(i, is_dismiss),
fs: this.getGroupFs(i),
get is_owner() { return data.bot.gml.get(group_id)?.get(data.self_id)?.role === "owner" },
get is_admin() { return data.bot.gml.get(group_id)?.get(data.self_id)?.role === "admin" },
}
}
async connect(data, ws) {
Bot[data.self_id] = {
adapter: this,
ws: ws,
sendApi: (action, params) => this.sendApi(data, ws, action, params),
stat: {
start_time: data.time,
stat: {},
get lost_pkt_cnt() { return this.stat.packet_lost },
get lost_times() { return this.stat.lost_times },
get recv_msg_cnt() { return this.stat.message_received },
get recv_pkt_cnt() { return this.stat.packet_received },
get sent_msg_cnt() { return this.stat.message_sent },
get sent_pkt_cnt() { return this.stat.packet_sent },
},
model: "TRSS Yunzai ",
info: {},
get uin() { return this.info.user_id },
get nickname() { return this.info.nickname },
get avatar() { return `https://q.qlogo.cn/g?b=qq&s=0&nk=${this.uin}` },
setProfile: profile => this.setProfile(data, profile),
setNickname: nickname => this.setProfile(data, { nickname }),
setAvatar: file => this.setAvatar(data, file),
pickFriend: user_id => this.pickFriend(data, user_id),
get pickUser() { return this.pickFriend },
getFriendArray: () => this.getFriendArray(data),
getFriendList: () => this.getFriendList(data),
getFriendMap: () => this.getFriendMap(data),
fl: new Map,
pickMember: (group_id, user_id) => this.pickMember(data, group_id, user_id),
pickGroup: group_id => this.pickGroup(data, group_id),
getGroupArray: () => this.getGroupArray(data),
getGroupList: () => this.getGroupList(data),
getGroupMap: () => this.getGroupMap(data),
getGroupMemberMap: () => this.getGroupMemberMap(data),
gl: new Map,
gml: new Map,
request_list: [],
getSystemMsg: () => data.bot.request_list,
setFriendAddRequest: (flag, approve, remark) => this.setFriendAddRequest(data, flag, approve, remark),
setGroupAddRequest: (flag, sub_type, approve, reason) => this.setGroupAddRequest(data, flag, sub_type, approve, reason),
}
data.bot = Bot[data.self_id]
if (!Bot.uin.includes(data.self_id))
Bot.uin.push(data.self_id)
data.bot.sendApi("_set_model_show", {
model: data.bot.model,
model_show: data.bot.model,
}).catch(() => {})
data.bot.info = (await data.bot.sendApi("get_login_info").catch(i => i.error)).data
data.bot.guild_info = (await data.bot.sendApi("get_guild_service_profile").catch(i => i.error)).data
data.bot.clients = (await data.bot.sendApi("get_online_clients").catch(i => i.error)).clients
data.bot.version = {
...(await data.bot.sendApi("get_version_info").catch(i => i.error)).data,
id: this.id,
name: this.name,
get version() {
return this.app_full_name || `${this.app_name} v${this.app_version}`
},
}
data.bot.getFriendMap()
data.bot.getGroupMemberMap()
Bot.makeLog("mark", `${this.name}(${this.id}) ${data.bot.version.version} 已连接`, data.self_id)
Bot.em(`connect.${data.self_id}`, data)
}
makeMessage(data) {
data.message = this.parseMsg(data.message)
switch (data.message_type) {
case "private": {
const name = data.sender.card || data.sender.nickname || data.bot.fl.get(data.user_id)?.nickname
Bot.makeLog("info", `好友消息:${name ? `[${name}] ` : ""}${data.raw_message}`, `${data.self_id} <= ${data.user_id}`)
break
} case "group": {
const group_name = data.group_name || data.bot.gl.get(data.group_id)?.group_name
let user_name = data.sender.card || data.sender.nickname
if (!user_name) {
const user = data.bot.gml.get(data.group_id)?.get(data.user_id) || data.bot.fl.get(data.user_id)
if (user) user_name = user?.card || user?.nickname
}
Bot.makeLog("info", `群消息:${user_name ? `[${group_name ? `${group_name}, ` : ""}${user_name}] ` : ""}${data.raw_message}`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`)
break
} case "guild":
data.message_type = "group"
data.group_id = `${data.guild_id}-${data.channel_id}`
Bot.makeLog("info", `频道消息:[${data.sender.nickname}] ${Bot.String(data.message)}`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`)
Object.defineProperty(data, "friend", { get() { return this.member || {}}})
break
default:
Bot.makeLog("warn", `未知消息:${logger.magenta(data.raw)}`, data.self_id)
}
Bot.em(`${data.post_type}.${data.message_type}.${data.sub_type}`, data)
}
async makeNotice(data) {
switch (data.notice_type) {
case "friend_recall":
Bot.makeLog("info", `好友消息撤回:${data.message_id}`, `${data.self_id} <= ${data.user_id}`)
break
case "group_recall":
Bot.makeLog("info", `群消息撤回:${data.operator_id} => ${data.user_id} ${data.message_id}`, `${data.self_id} <= ${data.group_id}`)
break
case "group_increase":
Bot.makeLog("info", `群成员增加:${data.operator_id} => ${data.user_id} ${data.sub_type}`, `${data.self_id} <= ${data.group_id}`)
if (data.user_id === data.self_id)
data.bot.getGroupMemberMap()
else
data.bot.pickGroup(data.group_id).getMemberMap()
break
case "group_decrease":
Bot.makeLog("info", `群成员减少:${data.operator_id} => ${data.user_id} ${data.sub_type}`, `${data.self_id} <= ${data.group_id}`)
if (data.user_id === data.self_id)
data.bot.getGroupMemberMap()
else
data.bot.pickGroup(data.group_id).getMemberMap()
break
case "group_admin":
Bot.makeLog("info", `群管理员变动:${data.sub_type}`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`)
data.set = data.sub_type === "set"
break
case "group_upload":
Bot.makeLog("info", `群文件上传:${Bot.String(data.file)}`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`)
break
case "group_ban":
Bot.makeLog("info", `群禁言:${data.operator_id} => ${data.user_id} ${data.sub_type} ${data.duration}秒`, `${data.self_id} <= ${data.group_id}`)
break
case "friend_add":
Bot.makeLog("info", "好友添加", `${data.self_id} <= ${data.user_id}`)
data.bot.getFriendMap()
break
case "notify":
if (data.group_id)
data.notice_type = "group"
else
data.notice_type = "friend"
switch (data.sub_type) {
case "poke":
data.operator_id = data.user_id
if (data.group_id)
Bot.makeLog("info", `群戳一戳:${data.operator_id} => ${data.target_id}`, `${data.self_id} <= ${data.group_id}`)
else
Bot.makeLog("info", `好友戳一戳:${data.operator_id} => ${data.target_id}`, data.self_id)
break
case "honor":
Bot.makeLog("info", `群荣誉:${data.honor_type}`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`)
break
case "title":
Bot.makeLog("info", `群头衔:${data.title}`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`)
break
default:
Bot.makeLog("warn", `未知通知:${logger.magenta(data.raw)}`, data.self_id)
}
break
case "group_card":
Bot.makeLog("info", `群名片更新:${data.card_old} => ${data.card_new}`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`)
break
case "offline_file":
Bot.makeLog("info", `离线文件:${Bot.String(data.file)}`, `${data.self_id} <= ${data.user_id}`)
break
case "client_status":
Bot.makeLog("info", `客户端${data.online ? "上线" : "下线"}${Bot.String(data.client)}`, data.self_id)
data.clients = (await data.bot.sendApi("get_online_clients")).clients
data.bot.clients = data.clients
break
case "essence":
data.notice_type = "group_essence"
Bot.makeLog("info", `群精华消息:${data.operator_id} => ${data.sender_id} ${data.sub_type} ${data.message_id}`, `${data.self_id} <= ${data.group_id}`)
break
case "guild_channel_recall":
Bot.makeLog("info", `频道消息撤回:${data.operator_id} => ${data.user_id} ${data.message_id}`, `${data.self_id} <= ${data.guild_id}-${data.channel_id}`)
break
case "message_reactions_updated":
data.notice_type = "guild_message_reactions_updated"
Bot.makeLog("info", `频道消息表情贴:${data.message_id} ${Bot.String(data.current_reactions)}`, `${data.self_id} <= ${data.guild_id}-${data.channel_id}, ${data.user_id}`)
break
case "channel_updated":
data.notice_type = "guild_channel_updated"
Bot.makeLog("info", `子频道更新:${Bot.String(data.old_info)} => ${Bot.String(data.new_info)}`, `${data.self_id} <= ${data.guild_id}-${data.channel_id}, ${data.user_id}`)
break
case "channel_created":
data.notice_type = "guild_channel_created"
Bot.makeLog("info", `子频道创建:${Bot.String(data.channel_info)}`, `${data.self_id} <= ${data.guild_id}-${data.channel_id}, ${data.user_id}`)
data.bot.getGroupMap()
break
case "channel_destroyed":
data.notice_type = "guild_channel_destroyed"
Bot.makeLog("info", `子频道删除:${Bot.String(data.channel_info)}`, `${data.self_id} <= ${data.guild_id}-${data.channel_id}, ${data.user_id}`)
data.bot.getGroupMap()
break
default:
Bot.makeLog("warn", `未知通知:${logger.magenta(data.raw)}`, data.self_id)
}
let notice = data.notice_type.split("_")
data.notice_type = notice.shift()
notice = notice.join("_")
if (notice)
data.sub_type = notice
if (data.guild_id && data.channel_id) {
data.group_id = `${data.guild_id}-${data.channel_id}`
Object.defineProperty(data, "friend", { get() { return this.member || {}}})
}
Bot.em(`${data.post_type}.${data.notice_type}.${data.sub_type}`, data)
}
makeRequest(data) {
switch (data.request_type) {
case "friend":
Bot.makeLog("info", `加好友请求:${data.comment}(${data.flag})`, `${data.self_id} <= ${data.user_id}`)
data.sub_type = "add"
data.approve = approve => data.bot.setFriendAddRequest(data.flag, approve)
break
case "group":
Bot.makeLog("info", `加群请求:${data.sub_type} ${data.comment}(${data.flag})`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`)
data.approve = approve => data.bot.setGroupAddRequest(data.flag, data.sub_type, approve)
break
default:
Bot.makeLog("warn", `未知请求:${logger.magenta(data.raw)}`, data.self_id)
}
data.bot.request_list.push(data)
Bot.em(`${data.post_type}.${data.request_type}.${data.sub_type}`, data)
}
heartbeat(data) {
if (data.status)
Object.assign(data.bot.stat, data.status)
}
makeMeta(data, ws) {
switch (data.meta_event_type) {
case "heartbeat":
this.heartbeat(data)
break
case "lifecycle":
this.connect(data, ws)
break
default:
Bot.makeLog("warn", `未知消息:${logger.magenta(data.raw)}`, data.self_id)
}
}
message(data, ws) {
try {
data = {
...JSON.parse(data),
raw: Bot.String(data),
}
} catch (err) {
return Bot.makeLog("error", ["解码数据失败", data, err])
}
if (data.post_type) {
if (data.meta_event_type !== "lifecycle" && !Bot.uin.includes(data.self_id)) {
Bot.makeLog("warn", `找不到对应Bot,忽略消息:${logger.magenta(data.raw)}`, data.self_id)
return false
}
data.bot = Bot[data.self_id]
switch (data.post_type) {
case "meta_event":
this.makeMeta(data, ws)
break
case "message":
this.makeMessage(data)
break
case "notice":
this.makeNotice(data)
break
case "request":
this.makeRequest(data)
break
case "message_sent":
data.post_type = "message"
this.makeMessage(data)
break
default:
Bot.makeLog("warn", `未知消息:${logger.magenta(data.raw)}`, data.self_id)
}
} else if (data.echo && this.echo[data.echo]) {
if (![0, 1].includes(data.retcode))
this.echo[data.echo].reject(Object.assign(
this.echo[data.echo].error,
this.echo[data.echo].request,
{ error: data },
))
else
this.echo[data.echo].resolve(data.data ? new Proxy(data, {
get: (target, prop) => target.data[prop] ?? target[prop],
}) : data)
clearTimeout(this.echo[data.echo].timeout)
delete this.echo[data.echo]
} else {
Bot.makeLog("warn", `未知消息:${logger.magenta(data.raw)}`, data.self_id)
}
}
load() {
for (const i of [this.path, "go-cqhttp"]) {
if (!Array.isArray(Bot.wsf[i]))
Bot.wsf[i] = []
Bot.wsf[i].push((ws, ...args) =>
ws.on("message", data => this.message(data, ws, ...args))
)
}
}
})