diff --git a/.puppeteerrc.cjs b/.puppeteerrc.cjs index 253d90c..25a6268 100644 --- a/.puppeteerrc.cjs +++ b/.puppeteerrc.cjs @@ -1,33 +1,31 @@ -const os = require("os"); -const { existsSync } = require("fs"); -const arch = os.arch(); -let skipDownload = false; -let executablePath; -//win32 存在 Edge 优先选择 -if (process.platform == "win32") { - if ( - existsSync("C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe") - ) { - skipDownload = true; - executablePath = - "C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"; - } -} else if (process.platform == "linux") { - //如果arm64架构跳过下载 - if (arch == "arm64" || arch == "aarch64") { - skipDownload = true; - } - //不管什么架构,如果存在配置则跳过下载,且配置路径 - if (existsSync("/usr/bin/chromium")) { - skipDownload = true; - executablePath = "/usr/bin/chromium"; - } -} - -/** - * @type {import("puppeteer").Configuration} - */ -module.exports = { - skipDownload, - executablePath, +const os = require("os"); +const { existsSync } = require("fs"); +const arch = os.arch(); +let skipDownload = false; +let executablePath; + +// win32 存在 Edge 优先选择 +if (process.platform == "win32") { + if (existsSync("C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe")) { + skipDownload = true; + executablePath = "C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"; + } +} else if (process.platform == "linux") { + // 如果 arm64 架构且存在 Chromium,跳过下载 + if ((arch == "arm64" || arch == "aarch64") && existsSync("/usr/bin/chromium")) { + skipDownload = true; + executablePath = "/usr/bin/chromium"; + } else if (existsSync("/usr/bin/chromium")) { + // 不论什么架构,如果存在 Chromium,跳过下载且配置路径 + skipDownload = true; + executablePath = "/usr/bin/chromium"; + } +} + +/** + * @type {import("puppeteer").Configuration} + */ +module.exports = { + skipDownload, + executablePath, }; \ No newline at end of file diff --git a/lib/common/common.js b/lib/common/common.js index 6de7879..9775360 100644 --- a/lib/common/common.js +++ b/lib/common/common.js @@ -67,6 +67,9 @@ function mkdirs(dirname) { * @param msgsscr 转发信息是否伪装 */ async function makeForwardMsg(e, msg = [], dec = '', msgsscr = false) { + /** 是频道插件直接返回 */ + if (e.QQGuild) return msg + if (!Array.isArray(msg)) msg = [msg] let name = msgsscr ? e.sender.card || e.user_id : Bot.nickname diff --git a/lib/config/qq.js b/lib/config/qq.js index 2a30c70..86b8761 100644 --- a/lib/config/qq.js +++ b/lib/config/qq.js @@ -61,6 +61,11 @@ export default async function createQQ () { name: 'masterQQ' }) } + propmtList.push({ + type: 'input', + message: '请输入签名API地址(可留空):', + name: 'signAPI' + }) const ret = await inquirer.prompt(propmtList) let file = './config/config/' @@ -82,6 +87,10 @@ export default async function createQQ () { fs.writeFileSync(`${file}other.yaml`, other, 'utf8') } + if (ret.signAPI) { + bot = bot.replace(/sign_api_addr:\s*/, `sign_api_addr: ${ret.signAPI}`); + } + fs.writeFileSync(`${file}bot.yaml`, bot, 'utf8') console.log(`\nQQ配置完成,正在登录\n后续修改账号可以运行命令: ${chalk.green('node app login')}\n`) diff --git a/package.json b/package.json index 4faa8dc..2e32221 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "chalk": "^5.2.0", "chokidar": "^3.5.3", "https-proxy-agent": "5.0.1", - "icqq": "^0.4.12", + "icqq": "^0.4.13", "image-size": "^1.0.2", "inquirer": "^8.2.5", "lodash": "^4.17.21", diff --git a/plugins/genshin/apps/mysNews.js b/plugins/genshin/apps/mysNews.js index 7c5eb19..850fc17 100644 --- a/plugins/genshin/apps/mysNews.js +++ b/plugins/genshin/apps/mysNews.js @@ -126,6 +126,8 @@ export class mysNews extends plugin { model = '关闭' msg += `${model}` cfg[type][this.e.self_id] = lodash.difference(cfg[type][this.e.self_id], [this.e.group_id]) + if (lodash.isEmpty(cfg[type][this.e.self_id])) + delete cfg[type][this.e.self_id] } let yaml = YAML.stringify(cfg) diff --git a/plugins/genshin/apps/takeBirthdayPhoto.js b/plugins/genshin/apps/takeBirthdayPhoto.js new file mode 100644 index 0000000..e99c9cb --- /dev/null +++ b/plugins/genshin/apps/takeBirthdayPhoto.js @@ -0,0 +1,143 @@ +import plugin from '../../../lib/plugins/plugin.js' +import gsCfg from '../model/gsCfg.js' +import fetch from 'node-fetch' + +export class takeBirthdayPhoto extends plugin { + constructor () { + super({ + name: '留影叙佳期', + dsc: '留影叙佳期', + /** https://oicqjs.github.io/oicq/#events */ + event: 'message', + priority: 5000, + rule: [ + { + /** 命令正则匹配 */ + reg: '#?留影叙佳期$', + /** 执行方法 */ + fnc: 'birthdaystar' + } + ] + }) + } + + async birthdaystar (e) { + const { user_id } = e + + const userInfo = await this.getCookie(user_id) + if (!userInfo) { + e.reply('请先绑定ck再使用本功能哦~', true) + return true + } + + const e_hk4e_token = await this.getEHK4EToken(userInfo.ck, userInfo.uid) + if (!e_hk4e_token) { + e.reply('获取e-hk4e_token失败,请刷新ck后再试~', true) + return true + } + + const birthday_star_list = await this.getBirthdayStar(userInfo.uid, e_hk4e_token, userInfo.ck) + if (!birthday_star_list) { + e.reply('获取生日角色失败,请稍后再试~', true) + return true + } + + if (birthday_star_list.length === 0) { + e.reply('今天没有生日角色哦~', true) + return true + } + + for (const role of birthday_star_list) { + await e.reply(`正在获取${role.name}的图片,请稍等~`, true) + await e.reply(segment.image(role.take_picture)) + const message = await this.getBirthdayStarImg(userInfo.uid, e_hk4e_token, userInfo.ck, role.role_id) + if (message != 'success') { + await e.reply(message) + return true + } else { + await e.reply(`获取${role.name}的图片成功~`, true) + } + } + + return true + } + + async getCookie (user_id) { + const userInfo = ((await gsCfg.getBingCk()).ckQQ)[user_id] + return userInfo + } + + async getEHK4EToken (ck, uid) { + const isCN = uid.toString().match(/^[125]/) ? true : false + const url = isCN ? 'https://api-takumi.mihoyo.com/common/badge/v1/login/account' : 'https://api-os-takumi.mihoyo.com/common/badge/v1/login/account' + const game_biz = isCN ? 'hk4e_cn' : 'hk4e_global' + const region = await this.getServer(uid) + const headers = { + 'Cookie': ck, + 'Content-Type': 'application/json;charset=UTF-8', + 'Referer': 'https://webstatic.mihoyo.com/', + 'Origin': 'https://webstatic.mihoyo.com' + } + const body = JSON.stringify({ + uid: Number(uid), + game_biz: game_biz, + lang: 'zh-cn', + region: region + }) + let res = await fetch(url, { method: "POST", body, headers }) + const e_hk4e_token = res.headers.get('set-cookie').match(/e_hk4e_token=(.*?);/)[1] + res = await res.json() + if (res.retcode != 0) { + return false + } + return e_hk4e_token + } + + async getServer (uid) { + switch (String(uid)[0]) { + case '1': + case '2': + return 'cn_gf01' + case '5': + return 'cn_qd01' + case '6': + return 'os_usa' + case '7': + return 'os_euro' + case '8': + return 'os_asia' + case '9': + return 'os_cht' + } + return 'cn_gf01' + } + + async getBirthdayStar (uid, e_hk4e_token, ck) { + const cookie = `e_hk4e_token=${e_hk4e_token};${ck}` + const badge_region = await this.getServer(uid) + const isCN = uid.toString().match(/^[125]/) ? true : false + const game_biz = isCN ? 'hk4e_cn' : 'hk4e_global' + const headers = { 'Cookie': cookie } + const url = `https://hk4e-api.mihoyo.com/event/birthdaystar/account/index?lang=zh-cn&badge_uid=${uid}&badge_region=${badge_region}&game_biz=${game_biz}&activity_id=20220301153521` + let res = await fetch(url, { headers }) + res = await res.json() + return res.data.role + } + + async getBirthdayStarImg (uid, e_hk4e_token, ck, role_id) { + const cookie = `e_hk4e_token=${e_hk4e_token};${ck}` + const badge_region = await this.getServer(uid) + const isCN = uid.toString().match(/^[125]/) ? true : false + const game_biz = isCN ? 'hk4e_cn' : 'hk4e_global' + const headers = { 'Cookie': cookie } + const url = `https://hk4e-api.mihoyo.com/event/birthdaystar/account/post_my_draw?lang=zh-cn&badge_uid=${uid}&badge_region=${badge_region}&game_biz=${game_biz}&activity_id=20220301153521` + const body = JSON.stringify({ role_id: Number(role_id) }) + let res = await fetch(url, { method: "POST", body, headers }) + res = await res.json() + if (res.retcode != 0) { + return res.message + } else { + return 'success' + } + } +} \ No newline at end of file diff --git a/plugins/genshin/model/mysNews.js b/plugins/genshin/model/mysNews.js index 96132c6..be5f601 100644 --- a/plugins/genshin/model/mysNews.js +++ b/plugins/genshin/model/mysNews.js @@ -257,14 +257,13 @@ export default class MysNews extends base { return this.replyMsg(img, `${param.data.post.subject}`) } - replyMsg(img, title = '') { + replyMsg(img, title) { if (!img || img.length <= 0) return false if (img.length == 1) { - if (title) img.unshift(title) + if (title) return [title, ...img] return img - } else { - return common.makeForwardMsg(this.e, img, title) } + return common.makeForwardMsg(this.e, img, title) } async mysNewsTask() { diff --git a/plugins/other/sendLog.js b/plugins/other/sendLog.js index 6fbd113..9b7d83b 100644 --- a/plugins/other/sendLog.js +++ b/plugins/other/sendLog.js @@ -1,29 +1,29 @@ -import plugin from '../../lib/plugins/plugin.js' -import common from '../../lib/common/common.js' -import fs from 'node:fs' -import lodash from 'lodash' -import moment from 'moment' +import plugin from "../../lib/plugins/plugin.js" +import common from "../../lib/common/common.js" +import fs from "node:fs" +import lodash from "lodash" +import moment from "moment" export class sendLog extends plugin { constructor() { super({ - name: '发送日志', - dsc: '发送最近100条运行日志', - event: 'message', + name: "发送日志", + dsc: "发送最近100条运行日志", + event: "message", rule: [ { - reg: '^#(运行|错误)*日志[0-9]*(.*)', - fnc: 'sendLog', - permission: 'master' + reg: "^#(运行|错误)*日志[0-9]*(.*)", + fnc: "sendLog", + permission: "master" } ] }) - this.lineNum = 50 - this.maxNum = 800 + this.lineNum = 100 + this.maxNum = 1000 - this.logFile = `./logs/command.${moment().format('YYYY-MM-DD')}.log` - this.errFile = './logs/error.log' + this.logFile = `logs/command.${moment().format("YYYY-MM-DD")}.log` + this.errFile = "logs/error.log" } async sendLog() { @@ -31,53 +31,48 @@ export class sendLog extends plugin { if (lineNum) { this.lineNum = lineNum[0] } else { - this.keyWord = this.e.msg.replace(/#|运行|错误|日志|\d/g, '') + this.keyWord = this.e.msg.replace(/#|运行|错误|日志|\d/g, "") } let logFile = this.logFile - let type = '运行' - if (this.e.msg.includes('错误')) { + let type = "运行" + if (this.e.msg.includes("错误")) { logFile = this.errFile - type = '错误' + type = "错误" } if (this.keyWord) type = this.keyWord - let log = this.getLog(logFile) + const log = this.getLog(logFile) - if (lodash.isEmpty(log)) { - this.reply(`暂无相关日志:${type}`) - return - } - let title = `最近${log.length}条${type}日志` + if (lodash.isEmpty(log)) + return this.reply(`暂无相关日志:${type}`) - let forwardMsg = await common.makeForwardMsg(this.e, [title, log.join("")], title) - - await this.reply(forwardMsg) + return this.reply(await common.makeForwardMsg(this.e, [log.join("\n")], `最近${log.length}条${type}日志`)) } getLog(logFile) { - let log = fs.readFileSync(logFile, { encoding: 'utf-8' }) - log = log.split('\n') + let log = fs.readFileSync(logFile, { encoding: "utf-8" }) + log = log.split("\n") if (this.keyWord) { - for (let i in log) { - if (!log[i].includes(this.keyWord)) delete log[i] - } + for (const i in log) + if (!log[i].includes(this.keyWord)) + delete log[i] } else { log = lodash.slice(log, (Number(this.lineNum) + 1) * -1) } log = log.reverse() - let tmp = [] - log.forEach(v => { - if (!v) return + + const tmp = [] + for (let i of log) { + if (!i) continue if (this.keyWord && tmp.length >= this.maxNum) return /* eslint-disable no-control-regex */ - v = v.replace(/\x1b[[0-9;]*m/g, '') - v = v.replace(/\r|\n/, '') + '\n\n' - tmp.push(v) - }) - + i = i.replace(/\x1b[[0-9;]*m/g, "") + i = i.replace(/\r|\n/, "") + tmp.push(i) + } return tmp } } diff --git a/plugins/system/add.js b/plugins/system/add.js index 9568688..dc750b7 100644 --- a/plugins/system/add.js +++ b/plugins/system/add.js @@ -395,7 +395,7 @@ export class add extends plugin { let num = 0 if (isNaN(keyWord)) { - num = keyWord.charAt(keyWord.length - 1) + num = keyWord.trim().match(/[0-9]+$/)?.[0] if (!isNaN(num) && !textArr[this.group_id].has(keyWord) && !textArr[this.e.bot.uin].has(keyWord)) { keyWord = lodash.trimEnd(keyWord, num).trim() @@ -712,16 +712,17 @@ export class add extends plugin { let keyWord = await this.keyWordTran(arr[i].key) if (!keyWord) continue - + let result = [] if (Array.isArray(keyWord)) { - keyWord.unshift(`${arr[i].num}、`) + keyWord.unshift(`${num + 1}、`) keyWord.push('\n') - keyWord.forEach(v => msg.push(v)) + result.push(...keyWord) } else if (keyWord.type) { - msg.push(`\n${arr[i].num}、`, keyWord, '\n\n') + result.push(`\n${num + 1}、`, keyWord, '\n\n') } else { - msg.push(`${arr[i].num}、${keyWord}\n`) + result.push(`${num + 1}、${keyWord}\n`) } + msg.push(result) num++ } @@ -734,7 +735,7 @@ export class add extends plugin { title = `表情${search},${count}条` } - let forwardMsg = await common.makeForwardMsg(this.e, [title, msg], title) + let forwardMsg = await common.makeForwardMsg(this.e, [title, ...msg], title) this.e.reply(forwardMsg) } @@ -778,4 +779,4 @@ export class add extends plugin { return msg } -} \ No newline at end of file +}