diff --git a/config/default_config/bot.yaml b/config/default_config/bot.yaml index 0e0fc3c..6348f11 100644 --- a/config/default_config/bot.yaml +++ b/config/default_config/bot.yaml @@ -6,16 +6,18 @@ ignore_self: true # 被风控时是否尝试用分片发送 resend: false # ffmpeg -ffmpeg_path: -ffprobe_path: +ffmpeg_path: +ffprobe_path: # chromium其他路径 -chromium_path: +chromium_path: # puppeteer接口地址 -puppeteer_ws: - +puppeteer_ws: +# puppeteer截图超时时间 +puppeteer_timeout: + # 米游社接口代理地址,国际服用 -proxyAddress: +proxyAddress: # 上线时给首个主人QQ推送帮助 online_msg: true @@ -23,6 +25,6 @@ online_msg: true online_msg_exp: 86400 # 签名API地址(如:http://127.0.0.1:8080/sign?key=114514) -sign_api_addr: +sign_api_addr: # 传入的QQ版本(如:8.9.63、8.9.68) -ver: \ No newline at end of file +ver: diff --git a/plugins/genshin/model/user.js b/plugins/genshin/model/user.js index 0aed94c..26a416f 100644 --- a/plugins/genshin/model/user.js +++ b/plugins/genshin/model/user.js @@ -64,7 +64,7 @@ export default class User extends base { } // TODO:独立的mys数据,不走缓存ltuid - let mys = await MysUser.create(param.ltuid || param.ltuid_v2 || param.ltmid_v2) + let mys = await MysUser.create(param.ltuid || param.ltuid_v2 || param.account_id_v2 || param.ltmid_v2) if (!mys) { await this.e.reply('发送cookie不完整或数据错误') return @@ -82,7 +82,7 @@ export default class User extends base { data.ck += ` mi18nLang=${param.mi18nLang};` } /** 拼接ck */ - data.ltuid = param.ltuid || param.ltmid_v2 + data.ltuid = param.ltuid || param.ltuid_v2 || param.account_id_v2 || param.ltmid_v2 /** 米游币签到字段 */ data.login_ticket = param.login_ticket ?? '' @@ -98,7 +98,8 @@ export default class User extends base { return await this.e.reply(`绑定cookie失败:${this.checkMsg || 'cookie错误'}`) } - if (flagV2) { + // 判断data.ltuid是否是数字 + if (flagV2 && isNaN(data.ltuid)) { // 获取米游社通行证id let userFullInfo = await mys.getUserFullInfo() if (userFullInfo?.data?.user_info) { @@ -119,7 +120,7 @@ export default class User extends base { logger.mark(`${this.e.logFnc} 保存cookie成功 [ltuid:${mys.ltuid}]`) - let uidMsg = [`绑定cookie成功`, mys.getUidInfo()] + let uidMsg = ['绑定cookie成功', mys.getUidInfo()] await this.e.reply(uidMsg.join('\n')) let msg = [] if (mys.hasGame('gs')) { @@ -159,7 +160,7 @@ export default class User extends base { if (!mys) { return `删除失败:当前的UID${uidData?.uid}无CK信息` } - let msg = [`绑定cookie已删除`, mys.getUidInfo()] + let msg = ['绑定cookie已删除', mys.getUidInfo()] await user.delMysUser(uidData.ltuid) return msg.join('\n') } @@ -344,7 +345,7 @@ export default class User extends base { async loadOldUid () { // 从DB中导入 - await sequelize.query(`delete from UserGames where userId is null or data is null`, {}) + await sequelize.query('delete from UserGames where userId is null or data is null', {}) let games = await UserGameDB.findAll() let count = 0 await Data.forEach(games, async (game) => { @@ -380,7 +381,7 @@ export default class User extends base { } redis.del(key) } - await sequelize.query(`delete from Users where (ltuids is null or ltuids='') and games is null`, {}) + await sequelize.query('delete from Users where (ltuids is null or ltuids=\'\') and games is null', {}) console.log('load Uid Data Done...') } diff --git a/renderers/puppeteer/config_default.yaml b/renderers/puppeteer/config_default.yaml index b3e1b39..7737a55 100644 --- a/renderers/puppeteer/config_default.yaml +++ b/renderers/puppeteer/config_default.yaml @@ -18,3 +18,6 @@ args: - --disable-setuid-sandbox - --no-sandbox - --no-zygote + +# puppeteer截图超时时间 +puppeteerTimeout: diff --git a/renderers/puppeteer/lib/puppeteer.js b/renderers/puppeteer/lib/puppeteer.js index 9635743..9daf954 100644 --- a/renderers/puppeteer/lib/puppeteer.js +++ b/renderers/puppeteer/lib/puppeteer.js @@ -9,9 +9,11 @@ import { Data } from '#miao' const _path = process.cwd() // mac地址 let mac = '' +// 超时计时器 +let overtimeList = [] export default class Puppeteer extends Renderer { - constructor(config) { + constructor (config) { super({ id: 'puppeteer', type: 'image', @@ -41,12 +43,14 @@ export default class Puppeteer extends Renderer { /** chromium其他路径 */ this.config.wsEndpoint = config.puppeteerWS || cfg?.bot?.puppeteer_ws } + /** puppeteer超时超时时间 */ + this.puppeteerTimeout = config.puppeteerTimeout || cfg?.bot?.puppeteer_timeout || 0 } /** * 初始化chromium */ - async browserInit() { + async browserInit () { if (this.browser) return this.browser if (this.lock) return false this.lock = true @@ -64,7 +68,7 @@ export default class Puppeteer extends Renderer { const browserUrl = (await redis.get(this.browserMacKey)) || this.config.wsEndpoint if (browserUrl) { logger.info(`puppeteer Chromium from ${browserUrl}`) - const browserWSEndpoint = await puppeteer.connect({ browserWSEndpoint: browserUrl }).catch((err) => { + const browserWSEndpoint = await puppeteer.connect({ browserWSEndpoint: browserUrl }).catch(() => { logger.error('puppeteer Chromium 缓存的实例已关闭') redis.del(this.browserMacKey) }) @@ -117,7 +121,7 @@ export default class Puppeteer extends Renderer { } /** 监听Chromium实例是否断开 */ - this.browser.on('disconnected', (e) => { + this.browser.on('disconnected', () => { logger.error('Chromium 实例关闭或崩溃!') this.browser = false }) @@ -127,23 +131,31 @@ export default class Puppeteer extends Renderer { // 获取Mac地址 getMac () { - const mac = '00:00:00:00:00:00' + let mac = '00:00:00:00:00:00' try { const network = os.networkInterfaces() + let macFlag = false for (const a in network) { for (const i of network[a]) { - if (i.mac && i.mac != mac) { - return i.mac + if (i.mac && i.mac !== mac) { + macFlag = true + mac = i.mac + break } } + if (macFlag) { + break + } } } catch (e) { } + mac = mac.replace(/:/g, '') return mac } /** * `chromium` 截图 + * @param name * @param data 模板参数 * @param data.tplFile 模板路径,必传 * @param data.saveId 生成html名称,为空name代替 @@ -154,9 +166,9 @@ export default class Puppeteer extends Renderer { * @param data.multiPage 是否分页截图,默认false * @param data.multiPageHeight 分页状态下页面高度,默认4000 * @param data.pageGotoParams 页面goto时的参数 - * @return img/[]img 不做segment包裹 + * @return img 不做segment包裹 */ - async screenshot(name, data = {}) { + async screenshot (name, data = {}) { if (!await this.browserInit()) { return false } @@ -173,6 +185,23 @@ export default class Puppeteer extends Renderer { let ret = [] this.shoting.push(name) + const puppeteerTimeout = this.puppeteerTimeout + let overtime + let overtimeFlag = false + if (puppeteerTimeout > 0) { + // TODO 截图超时处理 + overtime = setTimeout(() => { + if (!overtimeFlag) { + logger.error(`[图片生成][${name}] 截图超时,当前等待队列:${this.shoting.join(',')}`) + this.restart(true) + this.shoting = [] + overtimeList.forEach(item => { + clearTimeout(item) + }) + } + }, puppeteerTimeout) + } + try { const page = await this.browser.newPage() let pageGotoParams = lodash.extend({ timeout: 120000 }, data.pageGotoParams || {}) @@ -254,6 +283,12 @@ export default class Puppeteer extends Renderer { this.browser = false ret = [] return false + } finally { + if (overtime) { + overtimeFlag = true + clearTimeout(overtime) + overtimeList = [] + } } this.shoting.pop() @@ -263,22 +298,22 @@ export default class Puppeteer extends Renderer { return false } - this.restart() + this.restart(false) return data.multiPage ? ret : ret[0] } /** 重启 */ - restart() { + restart (force = false) { /** 截图超过重启数时,自动关闭重启浏览器,避免生成速度越来越慢 */ - if (this.renderNum % this.restartNum === 0) { - if (this.shoting.length <= 0) { + if (this.renderNum % this.restartNum === 0 || force) { + if (this.shoting.length <= 0 || force) { setTimeout(async () => { if (this.browser) { await this.browser.close().catch((err) => logger.error(err)) } this.browser = false - logger.info('puppeteer Chromium 关闭重启...') + logger.info(`puppeteer Chromium ${force ? '强制' : ''}关闭重启...`) }, 100) } }