修正QQBot无法使用`#绑定主用户指令`,优化部分日志,群前缀支持主人无视。 (#348)

This commit is contained in:
Zyy955 2024-01-10 14:54:20 +08:00 committed by GitHub
parent c1ff63b7a8
commit 4fbc3e088b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 132 additions and 129 deletions

View File

@ -12,7 +12,9 @@ module.exports = {
Bot: true, Bot: true,
redis: true, redis: true,
logger: true, logger: true,
plugin: true plugin: true,
Renderer: true,
segment: true
}, },
rules: { rules: {
eqeqeq: ['off'], eqeqeq: ['off'],

8
app.js
View File

@ -1,9 +1,3 @@
import Yunzai from './lib/bot.js' import Yunzai from './lib/bot.js'
/** 全局变量 bot */ await Yunzai.run()
global.Bot = await Yunzai.run()
if (Bot.uin == 88888) {
/** 跳过登录后加载插件... */
await ((await import('./lib/plugins/loader.js')).default).load()
}

View File

@ -3,7 +3,7 @@ default:
groupGlobalCD: 0 # 群聊中所有指令操作冷却时间,单位毫秒,0则无限制 groupGlobalCD: 0 # 群聊中所有指令操作冷却时间,单位毫秒,0则无限制
singleCD: 1000 # 群聊中个人操作冷却时间,单位毫秒 singleCD: 1000 # 群聊中个人操作冷却时间,单位毫秒
onlyReplyAt: 0 # 是否只仅关注主动@机器人的消息, 0-否 1-是 onlyReplyAt: 0 # 是否只仅关注主动@机器人的消息, 0-否 1-是 2-触发用户非主人只回复@机器人的消息及特定前缀的消息,主人免前缀
botAlias: # 开启后则只回复@机器人的消息及特定前缀的消息,支持多个 botAlias: # 开启后则只回复@机器人的消息及特定前缀的消息,支持多个
- 云崽 - 云崽
- 云宝 - 云宝

View File

@ -12,18 +12,28 @@ export default class Yunzai extends Client {
/** 登录机器人 */ /** 登录机器人 */
static async run () { static async run () {
const bot = new Yunzai(cfg.bot) const bot = new Yunzai(cfg.bot)
/** 加载icqq事件监听 */ /** 加载监听事件 */
await ListenerLoader.load(bot) await ListenerLoader.load(bot)
if (cfg.bot.skip_login) { /** 跳过登录 */
/** 造个假~! */ if (cfg.bot.skip_login) return await this.skip_login(bot)
bot.uin = 88888
bot[bot.uin] = bot /** 正常的登录 */
return bot await bot.login(cfg.qq, cfg.pwd)
} else { bot[bot.uin] = bot
await bot.login(cfg.qq, cfg.pwd)
bot[bot.uin] = bot /** 全局变量 bot */
return bot global.Bot = bot
} return bot
} }
}
/** 跳过登录ICQQ */
static async skip_login (bot) {
bot.uin = 88888
bot[bot.uin] = bot
/** 全局变量 bot */
global.Bot = bot
/** 加载插件 */
return await ((await import('../lib/plugins/loader.js')).default).load()
}
}

View File

@ -8,14 +8,15 @@ import path from 'node:path'
* 发送私聊消息仅给好友发送 * 发送私聊消息仅给好友发送
* @param userId qq号 * @param userId qq号
* @param msg 消息 * @param msg 消息
* @param uin 指定bot发送默认为Bot
*/ */
async function relpyPrivate (userId, msg) { async function relpyPrivate (userId, msg, uin = Bot.uin) {
userId = Number(userId) userId = Number(userId)
let friend = Bot.fl.get(userId) let friend = Bot.fl.get(userId)
if (friend) { if (friend) {
logger.mark(`发送好友消息[${friend.nickname}](${userId})`) logger.mark(`发送好友消息[${friend.nickname}](${userId})`)
return await Bot.pickUser(userId).sendMsg(msg).catch((err) => { return await Bot[uin].pickUser(userId).sendMsg(msg).catch((err) => {
logger.mark(err) logger.mark(err)
}) })
} }
@ -124,7 +125,7 @@ async function makeForwardMsg (e, msg = [], dec = '', msgsscr = false) {
} }
} }
} catch (err) { } } catch (err) { }
return forwardMsg return forwardMsg
} }

View File

@ -12,7 +12,7 @@ import common from '../common/common.js'
import Runtime from './runtime.js' import Runtime from './runtime.js'
import Handler from './handler.js' import Handler from './handler.js'
segment.button = () => "" segment.button = () => ''
/** 全局变量 plugin */ /** 全局变量 plugin */
global.plugin = plugin global.plugin = plugin
@ -83,7 +83,7 @@ class PluginsLoader {
lodash.forEach(plugin.handler, ({ fn, key, priority }) => { lodash.forEach(plugin.handler, ({ fn, key, priority }) => {
Handler.add({ Handler.add({
ns: plugin.namespace || File.name, ns: plugin.namespace || File.name,
key: key, key,
self: plugin, self: plugin,
property: priority || plugin.priority || 500, property: priority || plugin.priority || 500,
fn: plugin[fn] fn: plugin[fn]
@ -164,7 +164,6 @@ class PluginsLoader {
/** 监听热更新 */ /** 监听热更新 */
this.watch(val.name, app.name) this.watch(val.name, app.name)
} }
} }
@ -265,50 +264,50 @@ class PluginsLoader {
/* eslint-disable no-labels */ /* eslint-disable no-labels */
a: a:
for (let plugin of priority) { for (let plugin of priority) {
/** 正则匹配 */ /** 正则匹配 */
if (plugin.rule) { if (plugin.rule) {
for (let v of plugin.rule) { for (let v of plugin.rule) {
/** 判断事件 */ /** 判断事件 */
if (v.event && !this.filtEvent(e, v)) continue if (v.event && !this.filtEvent(e, v)) continue
const regExp = new RegExp(v.reg) const regExp = new RegExp(v.reg)
/** 匹配消息或者小程序 */ /** 匹配消息或者小程序 */
const messageOrApplet = e.msg || e.message?.[0]?.data const messageOrApplet = e.msg || e.message?.[0]?.data
if (regExp.test(messageOrApplet)) { if (regExp.test(messageOrApplet)) {
e.logFnc = `[${plugin.name}][${v.fnc}]` e.logFnc = `[${plugin.name}][${v.fnc}]`
if (v.log !== false) { if (v.log !== false) {
logger.mark(`${e.logFnc}${e.logText} ${lodash.truncate(e.msg, { length: 80 })}`) logger.mark(`${e.logFnc}${e.logText} ${lodash.truncate(e.msg, { length: 80 })}`)
} }
/** 判断权限 */ /** 判断权限 */
if (!this.filtPermission(e, v)) break a if (!this.filtPermission(e, v)) break a
try { try {
let res = plugin[v.fnc] && plugin[v.fnc](e) let res = plugin[v.fnc] && plugin[v.fnc](e)
let start = Date.now() let start = Date.now()
if (util.types.isPromise(res)) res = await res if (util.types.isPromise(res)) res = await res
if (res !== false) { if (res !== false) {
/** 设置冷却cd */ /** 设置冷却cd */
this.setLimit(e) this.setLimit(e)
if (v.log !== false) { if (v.log !== false) {
logger.info(`${e.logFnc} ${lodash.truncate(e.msg, { length: 80 })} 处理完成 ${Date.now() - start}ms`) logger.info(`${e.logFnc} ${lodash.truncate(e.msg, { length: 80 })} 处理完成 ${Date.now() - start}ms`)
}
break a
} }
} catch (error) {
logger.error(`${e.logFnc}`)
logger.error(error.stack)
break a break a
} }
} catch (error) {
logger.error(`${e.logFnc}`)
logger.error(error.stack)
break a
} }
} }
} }
} }
}
} }
/** 过滤事件 */ /** 过滤事件 */
@ -465,7 +464,7 @@ class PluginsLoader {
e.isGuild = true e.isGuild = true
} }
if (e.user_id && cfg.masterQQ.includes(Number(e.user_id) || e.user_id)) { if (e.user_id && cfg.masterQQ.includes(Number(e.user_id) || String(e.user_id))) {
e.isMaster = true e.isMaster = true
} }
@ -511,7 +510,7 @@ class PluginsLoader {
text = lodash.truncate(e.sender.card, { length: 10 }) text = lodash.truncate(e.sender.card, { length: 10 })
} }
if (at === true) { if (at === true) {
at = Number(e.user_id) || e.user_id at = Number(e.user_id) || String(e.user_id)
} else if (!isNaN(at)) { } else if (!isNaN(at)) {
if (e.isGuild) { if (e.isGuild) {
text = e.sender?.nickname text = e.sender?.nickname
@ -539,7 +538,7 @@ class PluginsLoader {
} }
logger.error(`发送消息错误:${msg}`) logger.error(`发送消息错误:${msg}`)
logger.error(err) logger.error(err)
if(cfg.bot.sendmsg_error) Bot[Bot.uin].pickUser(cfg.masterQQ[0]).sendMsg(`发送消息错误:${msg}`) if (cfg.bot.sendmsg_error) Bot[Bot.uin].pickUser(cfg.masterQQ[0]).sendMsg(`发送消息错误:${msg}`)
} }
// 频道一下是不是频道 // 频道一下是不是频道
@ -705,7 +704,11 @@ class PluginsLoader {
let groupCfg = cfg.getGroup(e.group_id) let groupCfg = cfg.getGroup(e.group_id)
if (groupCfg.onlyReplyAt != 1 || !groupCfg.botAlias) return true /** 模式0未开启前缀 */
if (groupCfg.onlyReplyAt == 0 || !groupCfg.botAlias) return true
/** 模式2非主人需带前缀或at机器人 */
if (groupCfg.onlyReplyAt == 2 && e.isMaster) return true
/** at机器人 */ /** at机器人 */
if (e.atBot) return true if (e.atBot) return true
@ -730,10 +733,10 @@ class PluginsLoader {
/** 黑名单qq */ /** 黑名单qq */
if (other.blackQQ) { if (other.blackQQ) {
if (other.blackQQ.includes(Number(e.user_id) || e.user_id)) { if (other.blackQQ.includes(Number(e.user_id) || String(e.user_id))) {
return false return false
} }
if (e.at && other.blackQQ.includes(Number(e.at) || e.at)) { if (e.at && other.blackQQ.includes(Number(e.at) || String(e.at))) {
return false return false
} }
} }
@ -741,11 +744,11 @@ class PluginsLoader {
if (e.group_id) { if (e.group_id) {
/** 白名单群 */ /** 白名单群 */
if (Array.isArray(other.whiteGroup) && other.whiteGroup.length > 0) { if (Array.isArray(other.whiteGroup) && other.whiteGroup.length > 0) {
return other.whiteGroup.includes(Number(e.group_id) || e.group_id) return other.whiteGroup.includes(Number(e.group_id) || String(e.group_id))
} }
/** 黑名单群 */ /** 黑名单群 */
if (Array.isArray(other.blackGroup) && other.blackGroup.length > 0) { if (Array.isArray(other.blackGroup) && other.blackGroup.length > 0) {
return !other.blackGroup.includes(Number(e.group_id) || e.group_id) return !other.blackGroup.includes(Number(e.group_id) || String(e.group_id))
} }
} }
@ -807,12 +810,11 @@ class PluginsLoader {
} }
} }
if (plugin.handler) { if (plugin.handler) {
lodash.forEach(plugin.handler, ({ fn, key, priority }) => { lodash.forEach(plugin.handler, ({ fn, key, priority }) => {
Handler.add({ Handler.add({
ns: plugin.namespace || File.name, ns: plugin.namespace || File.name,
key: key, key,
self: plugin, self: plugin,
property: priority || plugin.priority || 500, property: priority || plugin.priority || 500,
fn: plugin[fn] fn: plugin[fn]

View File

@ -54,7 +54,7 @@ export class user extends plugin {
fnc: 'checkCkStatus' fnc: 'checkCkStatus'
}, },
{ {
reg: '^#(接受)?绑定(主|子)?(用户|账户|账号)(\\[\\w+\\]){0,2}$', reg: '^#(接受)?绑定(主|子)?(用户|账户|账号)(\\[[a-zA-Z0-9_\\-:\\]+\\]){0,2}$',
fnc: 'bindNoteUser' fnc: 'bindNoteUser'
}, },
{ {

View File

@ -137,17 +137,17 @@ export default class User extends base {
'【#面板】【#更新面板】面板信息' '【#面板】【#更新面板】面板信息'
) )
button.push([ button.push([
{ text: "#uid", callback: "#uid" }, { text: '#uid', callback: '#uid' },
{ text: "#我的ck", callback: "#我的ck" }, { text: '#我的ck', callback: '#我的ck' },
{ text: "#删除ck", callback: "#删除ck" }, { text: '#删除ck', callback: '#删除ck' }
],[ ], [
{ text: "#体力", callback: "#体力" }, { text: '#体力', callback: '#体力' },
{ text: "#原石", callback: "#原石" }, { text: '#原石', callback: '#原石' },
{ text: "#原石统计", callback: "#原石统计" }, { text: '#原石统计', callback: '#原石统计' }
],[ ], [
{ text: "#练度统计", callback: "#练度统计" }, { text: '#练度统计', callback: '#练度统计' },
{ text: "#面板", callback: "#面板" }, { text: '#面板', callback: '#面板' },
{ text: "#更新面板", callback: "#更新面板" }, { text: '#更新面板', callback: '#更新面板' }
]) ])
} }
if (mys.hasGame('sr')) { if (mys.hasGame('sr')) {
@ -159,12 +159,12 @@ export default class User extends base {
'【*面板】【*更新面板】面板信息' '【*面板】【*更新面板】面板信息'
) )
button.push([ button.push([
{ text: "*uid", callback: "*uid" }, { text: '*uid', callback: '*uid' },
{ text: "*删除ck", callback: "*删除ck" }, { text: '*删除ck', callback: '*删除ck' },
{ text: "*体力", callback: "*体力" }, { text: '*体力', callback: '*体力' }
],[ ], [
{ text: "*面板", callback: "*面板" }, { text: '*面板', callback: '*面板' },
{ text: "*更新面板", callback: "*更新面板" }, { text: '*更新面板', callback: '*更新面板' }
]) ])
} }
msg = await common.makeForwardMsg(this.e, [[msg.join('\n'), segment.button(...button)]], '绑定成功:使用命令说明') msg = await common.makeForwardMsg(this.e, [[msg.join('\n'), segment.button(...button)]], '绑定成功:使用命令说明')
@ -173,16 +173,16 @@ export default class User extends base {
/** 删除绑定ck */ /** 删除绑定ck */
async delCk () { async delCk () {
let game; let game
if (this.e.game) { if (this.e.game) {
game = this.e.game; game = this.e.game
} else { } else {
game = 'gs'; game = 'gs'
} }
//判断是原神还是星铁 // 判断是原神还是星铁
let user = await this.user() let user = await this.user()
// 获取当前uid // 获取当前uid
let uidData = user.getUidData('' , game=game, this.e) let uidData = user.getUidData('', game = game, this.e)
if (!uidData || uidData.type !== 'ck' || !uidData.ltuid) { if (!uidData || uidData.type !== 'ck' || !uidData.ltuid) {
return `删除失败当前的UID${uidData?.uid}无CK信息` return `删除失败当前的UID${uidData?.uid}无CK信息`
} }
@ -211,15 +211,15 @@ export default class User extends base {
let uidList = user.getUidList(game) let uidList = user.getUidList(game)
if (index > uidList.length) { if (index > uidList.length) {
return await this.e.reply(['uid序号输入错误', segment.button([ return await this.e.reply(['uid序号输入错误', segment.button([
{ text: "删除uid", input: "#删除uid" }, { text: '删除uid', input: '#删除uid' }
])]) ])])
} }
index = Number(index) - 1 index = Number(index) - 1
let uidObj = uidList[index] let uidObj = uidList[index]
if (uidObj.type === 'ck') { if (uidObj.type === 'ck') {
return await this.e.reply(['CK对应UID无法直接删除请通过【#删除ck】命令来删除', segment.button([ return await this.e.reply(['CK对应UID无法直接删除请通过【#删除ck】命令来删除', segment.button([
{ text: "删除ck", callback: "#删除ck" }, { text: '删除ck', callback: '#删除ck' }
])]) ])])
} }
await user.delRegUid(uidObj.uid, game) await user.delRegUid(uidObj.uid, game)
return await this.showUid() return await this.showUid()
@ -274,25 +274,25 @@ export default class User extends base {
} }
}) })
}) })
return this.e.reply([await this.e.runtime.render('genshin', 'html/user/uid-list', { uids }, { retType: "base64" }), segment.button([ return this.e.reply([await this.e.runtime.render('genshin', 'html/user/uid-list', { uids }, { retType: 'base64' }), segment.button([
{ text: "绑定UID", input: "#绑定uid" }, { text: '绑定UID', input: '#绑定uid' },
{ text: "切换UID", input: "#uid" }, { text: '切换UID', input: '#uid' },
{ text: "删除UID", input: "#删除uid" }, { text: '删除UID', input: '#删除uid' }
],[ ], [
{ text: "角色", callback: "#角色" }, { text: '角色', callback: '#角色' },
{ text: "探索", callback: "#探索" }, { text: '探索', callback: '#探索' },
{ text: "武器", callback: "#武器" }, { text: '武器', callback: '#武器' },
{ text: "深渊", callback: "#深渊" }, { text: '深渊', callback: '#深渊' }
],[ ], [
{ text: "统计", callback: "#练度统计" }, { text: '统计', callback: '#练度统计' },
{ text: "面板", callback: "#面板" }, { text: '面板', callback: '#面板' },
{ text: "体力", callback: "#体力" }, { text: '体力', callback: '#体力' },
{ text: "原石", callback: "#原石" }, { text: '原石', callback: '#原石' }
],[ ], [
{ text: "留影", callback: "#留影叙佳期" }, { text: '留影', callback: '#留影叙佳期' },
{ text: "七圣", callback: "#七圣召唤查询牌组" }, { text: '七圣', callback: '#七圣召唤查询牌组' },
{ text: "抽卡", callback: "#抽卡记录" }, { text: '抽卡', callback: '#抽卡记录' },
{ text: "充值", callback: "#充值记录" }, { text: '充值', callback: '#充值记录' }
])]) ])])
} }
@ -303,7 +303,7 @@ export default class User extends base {
let uidList = user.getUidList(game) let uidList = user.getUidList(game)
if (index > uidList.length) { if (index > uidList.length) {
return await this.e.reply(['uid序号输入错误', segment.button([ return await this.e.reply(['uid序号输入错误', segment.button([
{ text: "切换uid", input: "#uid" }, { text: '切换uid', input: '#uid' }
])]) ])])
} }
index = Number(index) - 1 index = Number(index) - 1
@ -500,7 +500,7 @@ export default class User extends base {
let user = await this.user() let user = await this.user()
if (!user.hasCk) { if (!user.hasCk) {
this.e.reply(['当前尚未绑定Cookie', segment.button([ this.e.reply(['当前尚未绑定Cookie', segment.button([
{ text: "帮助", input: "#Cookie帮助" }, { text: '帮助', input: '#Cookie帮助' }
])]) ])])
} }
let mys = user.getMysUser(this.e) let mys = user.getMysUser(this.e)
@ -540,9 +540,9 @@ export default class User extends base {
} }
await this.e.reply([cks.join('\n----\n'), segment.button([ await this.e.reply([cks.join('\n----\n'), segment.button([
{ text: "绑定UID", input: "#绑定uid" }, { text: '绑定UID', input: '#绑定uid' },
{ text: "切换UID", input: "#uid" }, { text: '切换UID', input: '#uid' },
{ text: "删除UID", input: "#删除uid" }, { text: '删除UID', input: '#删除uid' }
])], false, { at: true }) ])], false, { at: true })
} }
@ -591,13 +591,13 @@ export default class User extends base {
e.reply(`已删除${count}个子用户...`) e.reply(`已删除${count}个子用户...`)
await redis.del(`Yz:NoteUser:subIds:${id}`) await redis.del(`Yz:NoteUser:subIds:${id}`)
} else { } else {
e.reply(`当前用户没有子用户,通过【#绑定用户】可绑定子用户...`) e.reply('当前用户没有子用户,通过【#绑定用户】可绑定子用户...')
} }
} }
return true return true
} }
msg = msg.replace(/^#\s*(接受)?绑定(主|子)?(用户|账户|账号)/, '') msg = msg.replace(/^#\s*(接受)?绑定(主|子)?(用户|账户|账号)/, '')
let idRet = /^\[(\w{5,})](?:\[(\w+)])?$/.exec(msg) let idRet = /^\[([a-zA-Z0-9-]{5,})](?:\[([a-zA-Z0-9-]+)])?$/.exec(msg)
if (idRet && idRet[1]) { if (idRet && idRet[1]) {
let mainId = idRet[1] let mainId = idRet[1]
let currId = id.toString() let currId = id.toString()

View File

@ -43,14 +43,8 @@ export class Restart extends plugin {
Bot[uin].pickUser(restart.id).sendMsg(msg) Bot[uin].pickUser(restart.id).sendMsg(msg)
} }
} catch (error) { } catch (error) {
/** 发送失败后等待5s重试一次适配器可能没连接bot */ /** 不发了,发不出去... */
await new Promise((resolve) => setTimeout(resolve, 5000)) logger.debug(error)
msg = `重启成功:耗时${(time + 5).toFixed(2)}`
if (restart.isGroup) {
Bot[uin].pickGroup(restart.id).sendMsg(msg)
} else {
Bot[uin].pickUser(restart.id).sendMsg(msg)
}
} }
redis.del(this.key) redis.del(this.key)
} }
@ -130,4 +124,4 @@ export class Restart extends plugin {
} }
}) })
} }
} }