⏰
This commit is contained in:
@@ -14,7 +14,8 @@ module.exports = {
|
||||
redis: true,
|
||||
logger: true,
|
||||
plugin: true,
|
||||
segment: true
|
||||
segment: true,
|
||||
ReplyError: true
|
||||
},
|
||||
rules: {
|
||||
'eqeqeq': ['off'],
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# 1.4.1
|
||||
* 删除匿名相关功能
|
||||
|
||||
|
||||
# 1.4.0
|
||||
* 增加开发依赖`eslint` `eslint-config-standard` `eslint-plugin-import` `eslint-plugin-jsdoc` `eslint-plugin-promise` `husky` `lint-staged`
|
||||
* 使用`husky`和`lint-staged`进行提交时eslint检测和自动格式化
|
||||
|
||||
@@ -280,13 +280,12 @@ Tip:具体可使用 **#椰奶群管帮助** 查看
|
||||
|
||||
1. 功能仅限内部交流与小范围使用,请勿将Yunzai-Bot及Yenai-Plugin用于任何以盈利为目的的场景.
|
||||
2. 图片与其他素材均来自于网络,仅供交流学习使用,如有侵权请联系,会立即删除.
|
||||
3. 本插件为防止滥用,内置部分开发者权限,包括但不限于`更新`和`设置`的权限,通常情况下不会被使用,如介意请勿使用本插件.
|
||||
|
||||
## 联系方式 <img src="https://media.giphy.com/media/VgCDAzcKvsR6OM0uWg/giphy.gif" width="50">
|
||||
|
||||
🐧:746659424
|
||||
|
||||
💬:(暂无)
|
||||
💬:914247840
|
||||
|
||||
❤️:[打赏](https://yenai.trss.me/donate.html)
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ const OtherCfgType = {
|
||||
const SeSeCfgType = {
|
||||
涩涩: 'sese',
|
||||
涩涩pro: 'sesepro',
|
||||
匿名: 'anonymous',
|
||||
代理: {
|
||||
name: 'proxy',
|
||||
key: 'switchProxy'
|
||||
@@ -181,12 +180,11 @@ export class Admin extends plugin {
|
||||
async SeSe_Settings (e) {
|
||||
let set = setu.getSeSeConfig(e)
|
||||
let { proxy, pixiv, bika } = Config
|
||||
let { sese, sesepro, anonymous } = Config.getGroup(e.group_id)
|
||||
let { sese: _sese, sesepro: _sesepro, anonymous: _anonymous } = Config.getConfig('group')[e.group_id] ?? {}
|
||||
let { sese, sesepro } = Config.getGroup(e.group_id)
|
||||
let { sese: _sese, sesepro: _sesepro } = Config.getConfig('group')[e.group_id] ?? {}
|
||||
let data = {
|
||||
sese: getStatus(sese, _sese),
|
||||
sesepro: getStatus(sesepro, _sesepro),
|
||||
anonymous: getStatus(anonymous, _anonymous),
|
||||
r18: getStatus(set.r18),
|
||||
cd: Number(set.cd),
|
||||
recall: set.recall ? set.recall : '无',
|
||||
|
||||
@@ -44,10 +44,6 @@ export class GroupAdmin extends plugin {
|
||||
reg: '^#(设置|取消)管理(\\d+)?$',
|
||||
fnc: 'SetAdmin'
|
||||
},
|
||||
{
|
||||
reg: '^#(允许|禁止|开启|关闭)匿名$',
|
||||
fnc: 'AllowAnony'
|
||||
},
|
||||
{
|
||||
reg: '^#发群公告',
|
||||
fnc: 'AddAnnounce'
|
||||
@@ -248,15 +244,6 @@ export class GroupAdmin extends plugin {
|
||||
type ? e.reply(`已经把「${name}」设置为管理啦!!`) : e.reply(`「${name}」的管理已经被我吃掉啦~`)
|
||||
}
|
||||
|
||||
// 匿名
|
||||
async AllowAnony (e) {
|
||||
if (!common.checkPermission(e, 'admin', 'admin')) { return true }
|
||||
let type = /(允许|开启)匿名/.test(e.msg)
|
||||
let res = await e.group.allowAnony(type)
|
||||
if (!res) return e.reply('❎ 未知错误', true)
|
||||
type ? e.reply('已把匿名开启了哦,可以藏起来了~') : e.reply('已关闭匿名,小贼们不准藏了~')
|
||||
}
|
||||
|
||||
// 发群公告
|
||||
async AddAnnounce (e) {
|
||||
if (!common.checkPermission(e, 'admin', 'admin')) { return true }
|
||||
|
||||
@@ -109,11 +109,7 @@ export class NewGroupBannedWords extends plugin {
|
||||
*/
|
||||
#mute (time) {
|
||||
const e = this.e
|
||||
if (e.anonymous) {
|
||||
e.group.muteAnony(e.anonymous.flag, time)
|
||||
} else {
|
||||
e.member.mute(time)
|
||||
}
|
||||
e.member.mute(time)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -195,7 +195,7 @@ export class NewPixiv extends plugin {
|
||||
if (ispro && !await this._Authentication(e, 'sesepro', false)) return
|
||||
|
||||
await Pixiv.pximg(ispro)
|
||||
.then(res => ispro ? common.recallSendForwardMsg(e, [res]) : common.recallsendMsg(e, res, false, { anony: true }))
|
||||
.then(res => ispro ? common.recallSendForwardMsg(e, [res]) : common.recallsendMsg(e, res, false))
|
||||
.catch(err => common.handleException(e, err))
|
||||
}
|
||||
|
||||
|
||||
239
apps/update.js
239
apps/update.js
@@ -1,19 +1,5 @@
|
||||
import plugin from '../../../lib/plugins/plugin.js'
|
||||
import { createRequire } from 'module'
|
||||
import _ from 'lodash'
|
||||
import { Restart } from '../../other/restart.js'
|
||||
import common from '../lib/common/common.js'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const { exec, execSync } = require('child_process')
|
||||
|
||||
// 是否在更新中
|
||||
let uping = false
|
||||
|
||||
/**
|
||||
* 处理插件更新
|
||||
*/
|
||||
export class Update extends plugin {
|
||||
import { update as Update } from '../../other/update.js'
|
||||
export class YenaiUpdate extends plugin {
|
||||
constructor () {
|
||||
super({
|
||||
name: '椰奶更新插件',
|
||||
@@ -28,221 +14,10 @@ export class Update extends plugin {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* rule - 更新椰奶插件
|
||||
* @param e
|
||||
*/
|
||||
async update (e) {
|
||||
if (!common.checkPermission(e, 'master')) return true
|
||||
|
||||
/** 检查是否正在更新中 */
|
||||
if (uping) {
|
||||
await this.reply('已有命令更新中..请勿重复操作')
|
||||
return
|
||||
}
|
||||
|
||||
/** 检查git安装 */
|
||||
if (!(await this.checkGit())) return
|
||||
|
||||
const isForce = this.e.msg.includes('强制')
|
||||
|
||||
/** 执行更新 */
|
||||
await this.runUpdate(isForce)
|
||||
|
||||
/** 是否需要重启 */
|
||||
if (this.isUp) {
|
||||
// await this.reply("更新完毕,请重启云崽后生效")
|
||||
setTimeout(() => this.restart(), 2000)
|
||||
}
|
||||
}
|
||||
|
||||
restart () {
|
||||
new Restart(this.e).restart()
|
||||
}
|
||||
|
||||
/**
|
||||
* 椰奶插件更新函数
|
||||
* @param {boolean} isForce 是否为强制更新
|
||||
*/
|
||||
async runUpdate (isForce) {
|
||||
const _path = './plugins/yenai-plugin/'
|
||||
let command = `git -C ${_path} pull --no-rebase`
|
||||
if (isForce) {
|
||||
command = `git -C ${_path} reset --hard origin && ${command}`
|
||||
this.e.reply('正在执行强制更新操作,请稍等')
|
||||
} else {
|
||||
this.e.reply('正在执行更新操作,请稍等')
|
||||
}
|
||||
/** 获取上次提交的commitId,用于获取日志时判断新增的更新日志 */
|
||||
this.oldCommitId = await this.getcommitId('yenai-plugin')
|
||||
uping = true
|
||||
let ret = await this.execSync(command)
|
||||
uping = false
|
||||
|
||||
if (ret.error) {
|
||||
logger.mark(`${this.e.logFnc} 更新失败:椰奶插件`)
|
||||
this.gitErr(ret.error, ret.stdout)
|
||||
return false
|
||||
}
|
||||
|
||||
/** 获取插件提交的最新时间 */
|
||||
let time = await this.getTime('yenai-plugin')
|
||||
|
||||
if (/(Already up[ -]to[ -]date|已经是最新的)/.test(ret.stdout)) {
|
||||
await this.reply(`椰奶插件已经是最新版本\n最后更新时间:${time}`)
|
||||
} else {
|
||||
await this.reply(`椰奶插件\n最后更新时间:${time}`)
|
||||
this.isUp = true
|
||||
/** 获取椰奶组件的更新日志 */
|
||||
let log = await this.getLog('yenai-plugin')
|
||||
await this.reply(log)
|
||||
}
|
||||
|
||||
logger.mark(`${this.e.logFnc} 最后更新时间:${time}`)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取椰奶插件的更新日志
|
||||
* @param {string} plugin 插件名称
|
||||
*/
|
||||
async getLog (plugin = '') {
|
||||
let cm = `cd ./plugins/${plugin}/ && git log -20 --oneline --pretty=format:"%h||[%cd] %s" --date=format:"%m-%d %H:%M"`
|
||||
|
||||
let logAll
|
||||
try {
|
||||
logAll = await execSync(cm, { encoding: 'utf-8' })
|
||||
} catch (error) {
|
||||
logger.error(error.toString())
|
||||
this.reply(error.toString())
|
||||
}
|
||||
|
||||
if (!logAll) return false
|
||||
|
||||
logAll = logAll.split('\n')
|
||||
|
||||
let log = []
|
||||
for (let str of logAll) {
|
||||
str = str.split('||')
|
||||
if (str[0] == this.oldCommitId) break
|
||||
if (str[1].includes('Merge branch')) continue
|
||||
log.push(str[1])
|
||||
}
|
||||
let line = log.length
|
||||
log = log.join('\n\n')
|
||||
|
||||
if (log.length <= 0) return ''
|
||||
|
||||
let end = ''
|
||||
end =
|
||||
'更多详细信息,请前往gitee查看\nhttps://gitee.com/yeyang52/yenai-plugin/blob/master/CHANGELOG.md'
|
||||
let forwardMsg = [
|
||||
`椰奶插件更新日志,共${line}条`, log, end
|
||||
]
|
||||
log = await common.getforwardMsg(this.e, forwardMsg, {
|
||||
shouldSendMsg: false
|
||||
})
|
||||
|
||||
return log
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上次提交的commitId
|
||||
* @param {string} plugin 插件名称
|
||||
*/
|
||||
async getcommitId (plugin = '') {
|
||||
let cm = `git -C ./plugins/${plugin}/ rev-parse --short HEAD`
|
||||
|
||||
let commitId = await execSync(cm, { encoding: 'utf-8' })
|
||||
commitId = _.trim(commitId)
|
||||
|
||||
return commitId
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本次更新插件的最后一次提交时间
|
||||
* @param {string} plugin 插件名称
|
||||
*/
|
||||
async getTime (plugin = '') {
|
||||
let cm = `cd ./plugins/${plugin}/ && git log -1 --oneline --pretty=format:"%cd" --date=format:"%m-%d %H:%M"`
|
||||
|
||||
let time = ''
|
||||
try {
|
||||
time = await execSync(cm, { encoding: 'utf-8' })
|
||||
time = _.trim(time)
|
||||
} catch (error) {
|
||||
logger.error(error.toString())
|
||||
time = '获取时间失败'
|
||||
}
|
||||
return time
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理更新失败的相关函数
|
||||
* @param {string} err
|
||||
* @param {string} stdout
|
||||
*/
|
||||
async gitErr (err, stdout) {
|
||||
let msg = '更新失败!'
|
||||
let errMsg = err.toString()
|
||||
stdout = stdout.toString()
|
||||
|
||||
if (errMsg.includes('Timed out')) {
|
||||
let remote = errMsg.match(/'(.+?)'/g)[0].replace(/'/g, '')
|
||||
await this.reply(msg + `\n连接超时:${remote}`)
|
||||
return
|
||||
}
|
||||
|
||||
if (/Failed to connect|unable to access/g.test(errMsg)) {
|
||||
let remote = errMsg.match(/'(.+?)'/g)[0].replace(/'/g, '')
|
||||
await this.reply(msg + `\n连接失败:${remote}`)
|
||||
return
|
||||
}
|
||||
|
||||
if (errMsg.includes('be overwritten by merge')) {
|
||||
await this.reply(
|
||||
msg +
|
||||
`存在冲突:\n${errMsg}\n` +
|
||||
'请解决冲突后再更新,或者执行#强制更新,放弃本地修改'
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if (stdout.includes('CONFLICT')) {
|
||||
await this.reply([
|
||||
msg + '存在冲突\n',
|
||||
errMsg,
|
||||
stdout,
|
||||
'\n请解决冲突后再更新,或者执行#强制更新,放弃本地修改'
|
||||
])
|
||||
return
|
||||
}
|
||||
|
||||
await this.reply([errMsg, stdout])
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步执行git相关命令
|
||||
* @param {string} cmd git命令
|
||||
*/
|
||||
async execSync (cmd) {
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(cmd, { windowsHide: true }, (error, stdout, stderr) => {
|
||||
resolve({ error, stdout, stderr })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查git是否安装
|
||||
*/
|
||||
async checkGit () {
|
||||
let ret = await execSync('git --version', { encoding: 'utf-8' })
|
||||
if (!ret || !ret.includes('git version')) {
|
||||
await this.reply('请先安装git')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
async update (e = this.e) {
|
||||
e.msg = `#${e.msg.includes('强制') ? '强制' : ''}更新yenai-plugin`
|
||||
const up = new Update(e)
|
||||
up.e = e
|
||||
return up.update()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,5 +17,5 @@ statusTask: true
|
||||
#如果出现内存异常的情况可将此配置项开启,如果打开后报错请将监控任务关闭
|
||||
statusPowerShellStart: false
|
||||
|
||||
#背景图片api 默认https://api.suyanw.cn/api/comic2
|
||||
backdrop: "https://api.suyanw.cn/api/comic2"
|
||||
#背景图片api 默认 https://api.sretna.cn/layout/pe.php
|
||||
backdrop: "https://api.sretna.cn/layout/pe.php"
|
||||
|
||||
@@ -24,4 +24,3 @@ state: false #状态
|
||||
deltime: 600 #删除缓存
|
||||
sesepro: false #涩涩增强
|
||||
renderScale: 100 #渲染精度
|
||||
anonymous: false #匿名
|
||||
|
||||
6
index.js
6
index.js
@@ -15,6 +15,12 @@ if (!global.segment) {
|
||||
}
|
||||
}
|
||||
|
||||
global.ReplyError = class ReplyError extends Error {
|
||||
constructor (message) {
|
||||
super(message)
|
||||
this.name = 'ReplyError'
|
||||
}
|
||||
}
|
||||
// 加载监听事件
|
||||
const eventsPath = './plugins/yenai-plugin/apps/events'
|
||||
const events = fs.readdirSync(eventsPath)
|
||||
|
||||
9
lib/common/error.js
Normal file
9
lib/common/error.js
Normal file
@@ -0,0 +1,9 @@
|
||||
// 直接回复错误类型
|
||||
global.ReplyError = class ReplyError extends Error {
|
||||
constructor (message) {
|
||||
super(message)
|
||||
this.name = 'ReplyError'
|
||||
}
|
||||
}
|
||||
|
||||
throw new ReplyError('a')
|
||||
@@ -33,7 +33,6 @@ export default class {
|
||||
* @param {boolean} [options.isxml] - 处理卡片
|
||||
* @param {boolean} [options.xmlTitle] - XML 标题
|
||||
* @param {boolean} [options.oneMsg] - 用于只有一条消息,不用再转成二维数组
|
||||
* @param {boolean | import("icqq").Anonymous} [options.anony] - 匿名消息,若为true则发送匿名消息
|
||||
* @param {boolean} [options.shouldSendMsg] - 是否直接发送消息,true为直接发送,否则返回需要发送的消息
|
||||
* @returns {Promise<import("icqq").MessageRet|import("icqq").XmlElem|import("icqq").JsonElem>} 消息发送结果的Promise对象
|
||||
*/
|
||||
@@ -44,11 +43,10 @@ export default class {
|
||||
isxml,
|
||||
xmlTitle,
|
||||
oneMsg,
|
||||
anony,
|
||||
shouldSendMsg = true
|
||||
} = {}) {
|
||||
let forwardMsg = []
|
||||
if (_.isEmpty(message)) throw Error('[Yenai-Plugin][sendforwardMsg][Error]发送的转发消息不能为空')
|
||||
if (_.isEmpty(message)) throw new ReplyError('[Yenai-Plugin][sendforwardMsg][Error]发送的转发消息不能为空')
|
||||
let add = (msg) => forwardMsg.push(
|
||||
{
|
||||
message: msg,
|
||||
@@ -84,7 +82,6 @@ export default class {
|
||||
}
|
||||
if (shouldSendMsg) {
|
||||
let msgRes = await this.reply(e, forwardMsg, false, {
|
||||
anony,
|
||||
fkmsg,
|
||||
recallMsg
|
||||
})
|
||||
@@ -103,15 +100,13 @@ export default class {
|
||||
* @param {object} data 其他参数
|
||||
* @param {number} data.recallMsg 撤回时间
|
||||
* @param {boolean} data.fkmsg 风控消息
|
||||
* @param {boolean | import("icqq").Anonymous} data.anony 匿名消息
|
||||
* @param {boolean | number} data.at 是否艾特该成员
|
||||
* @returns {Promise<import("icqq").MessageRet>} 返回发送消息后的结果对象
|
||||
*/
|
||||
async reply (e, msg, quote, {
|
||||
recallMsg = 0,
|
||||
fkmsg = '',
|
||||
at = false,
|
||||
anony
|
||||
at = false
|
||||
} = {}) {
|
||||
if (at && e.isGroup) {
|
||||
let text = ''
|
||||
@@ -136,15 +131,7 @@ export default class {
|
||||
let msgRes = null
|
||||
// 发送消息
|
||||
if (e.isGroup) {
|
||||
// 判断是否开启匿名
|
||||
if (anony) {
|
||||
let getAnonyInfo = await e.group.getAnonyInfo()
|
||||
if (!getAnonyInfo.enable) {
|
||||
e.reply('[警告]该群未开启匿名,请启用匿名再使用匿名功能')
|
||||
anony = false
|
||||
}
|
||||
}
|
||||
msgRes = await e.group.sendMsg(msg, quote ? e : undefined, anony)
|
||||
msgRes = await e.group.sendMsg(msg, quote ? e : undefined)
|
||||
} else {
|
||||
msgRes = await e.reply(msg, quote)
|
||||
if (!msgRes) await e.reply(fkmsg || '消息发送失败,可能被风控')
|
||||
@@ -167,17 +154,42 @@ export default class {
|
||||
* @param {object} data 其他参数
|
||||
* @param {number} data.recallMsg 撤回时间
|
||||
* @param {boolean} data.fkmsg 风控消息
|
||||
* @param {boolean | import("icqq").Anonymous} data.anony 匿名消息
|
||||
* @returns {Promise<import("icqq").MessageRet>}
|
||||
*/
|
||||
async recallsendMsg (e, msg, quote, data = {}) {
|
||||
let recallMsg = setu.getRecallTime(e.group_id)
|
||||
let anony = Config.getGroup(e.group_id).anonymous
|
||||
let msgRes = this.reply(e, msg, quote, {
|
||||
recallMsg,
|
||||
anony,
|
||||
...data
|
||||
})
|
||||
return msgRes
|
||||
}
|
||||
|
||||
/**
|
||||
* 转发消息并根据权限撤回
|
||||
* @async
|
||||
* @param {object} e - 反馈的对象
|
||||
* @param {string | object} msg - 要发送的消息字符串或对象
|
||||
* @param {object} [data] - 附加的数据对象
|
||||
* @param {number} [data.recallMsg] - 消息撤回时间
|
||||
* @param {object} [data.info] - 附加消息信息
|
||||
* @param {string} [data.info.nickname] - 用户昵称
|
||||
* @param {number} [data.info.user_id] - 用户ID
|
||||
* @param {boolean} [data.isxml] - 是否特殊处理转发消息
|
||||
* @param {string} [data.xmlTitle] - XML 标题
|
||||
* @returns {Promise<any>} - Promise 对象,返回函数 `getforwardMsg()` 的返回值
|
||||
*/
|
||||
async recallSendForwardMsg (e, msg, data = {}) {
|
||||
let recalltime = setu.getRecallTime(e.group_id)
|
||||
return await this.getforwardMsg(e, msg, {
|
||||
recallMsg: recalltime,
|
||||
info: {
|
||||
nickname: '🐔🏀',
|
||||
user_id: 2854196306
|
||||
},
|
||||
isxml: true,
|
||||
xmlTitle: e.logFnc + e.msg,
|
||||
...data
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,13 @@ class HTTPResponseError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
class RequestError extends Error {
|
||||
constructor (message) {
|
||||
super(message)
|
||||
this.name = 'RequestError'
|
||||
}
|
||||
}
|
||||
|
||||
const checkStatus = response => {
|
||||
if (response.ok) {
|
||||
// response.status >= 200 && response.status < 300
|
||||
@@ -65,8 +72,8 @@ export default new class {
|
||||
return res
|
||||
} catch (err) {
|
||||
logger.error(err)
|
||||
throw Error(
|
||||
`Request Get Error,${err.message.match(/reason:(.*)/i) || err.message}`
|
||||
throw RequestError(
|
||||
`Get Error,${err.message.match(/reason:(.*)/)?.[1] || err.message}`
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -120,8 +127,8 @@ export default new class {
|
||||
return res
|
||||
} catch (err) {
|
||||
logger.error(err)
|
||||
throw Error(
|
||||
`Request Post Error,reason:${err.message.match(/reason:(.*)/)[1]}`
|
||||
throw RequestError(
|
||||
`Post Error,reason:${err.message.match(/reason:(.*)/)?.[1] || err.message}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,10 +47,10 @@ export default new (class {
|
||||
.then(res => res.json())
|
||||
.catch(err => {
|
||||
logger.error(err)
|
||||
throw Error(`bika search Error,${err.message.match(/reason:(.*)/i) || err.message}`)
|
||||
throw new ReplyError(`bika search Error,${err.message.match(/reason:(.*)/i) || err.message}`)
|
||||
})
|
||||
let { docs, total, page: pg, pages } = res.data.comics
|
||||
if (total == 0) throw Error(`未找到作品,换个${type.alias[0]}试试吧`)
|
||||
if (total == 0) throw new ReplyError(`未找到作品,换个${type.alias[0]}试试吧`)
|
||||
this.searchCaching = docs
|
||||
let msg = [
|
||||
`共找到${total}个关于「${keyword}」${type.alias[0]}的作品`,
|
||||
@@ -87,9 +87,9 @@ export default new (class {
|
||||
.then((res) => res.json())
|
||||
.catch(err => {
|
||||
logger.error(err)
|
||||
throw Error(`bika comicPage Error,${err.message.match(/reason:(.*)/i) || err.message}`)
|
||||
throw new ReplyError(`bika comicPage Error,${err.message.match(/reason:(.*)/i) || err.message}`)
|
||||
})
|
||||
if (res.error) throw Error(res.message)
|
||||
if (res.error) throw new ReplyError(res.message)
|
||||
this.idNext = {
|
||||
id, page, order
|
||||
}
|
||||
@@ -103,9 +103,9 @@ export default new (class {
|
||||
}
|
||||
|
||||
async viewComicPage (num) {
|
||||
if (!this.searchCaching) throw Error('请先搜索后再使用此命令')
|
||||
if (!this.searchCaching) throw new ReplyError('请先搜索后再使用此命令')
|
||||
let id = this.searchCaching[num]._id
|
||||
if (!id) throw Error('未获取到目标作品,请使用id进行查看')
|
||||
if (!id) throw new ReplyError('未获取到目标作品,请使用id进行查看')
|
||||
return this.comicPage(id)
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ export default new (class {
|
||||
* @throws {Error} - 如果未找到上一个id,则抛出异常
|
||||
*/
|
||||
async next (type = 'comicPage') {
|
||||
if (!this.idNext) throw Error('未找到上一个id')
|
||||
if (!this.idNext) throw new ReplyError('未找到上一个id')
|
||||
let { id, page, order } = this.idNext
|
||||
if (type == 'chapter') {
|
||||
order++
|
||||
@@ -140,9 +140,9 @@ export default new (class {
|
||||
.then((res) => res.json())
|
||||
.catch(err => {
|
||||
logger.error(err)
|
||||
throw Error(`bika categories Error,${err.message.match(/reason:(.*)/i) || err.message}`)
|
||||
throw new ReplyError(`bika categories Error,${err.message.match(/reason:(.*)/i) || err.message}`)
|
||||
})
|
||||
if (res.error) throw Error(res.message)
|
||||
if (res.error) throw new ReplyError(res.message)
|
||||
res = res.data.categories.filter(item => !item.isWeb)
|
||||
await redis.set(key, JSON.stringify(res), { EX: 43200 })
|
||||
}
|
||||
@@ -167,9 +167,9 @@ export default new (class {
|
||||
.then((res) => res.json())
|
||||
.catch(err => {
|
||||
logger.error(err)
|
||||
throw Error(`bika comicDetail Error,${err.message.match(/reason:(.*)/i) || err.message}`)
|
||||
throw new ReplyError(`bika comicDetail Error,${err.message.match(/reason:(.*)/i) || err.message}`)
|
||||
})
|
||||
if (res.error) throw Error(res.message)
|
||||
if (res.error) throw new ReplyError(res.message)
|
||||
let {
|
||||
_id, title, description, author, chineseTeam, categories, tags, pagesCount, epsCount, finished, totalLikes, totalViews, totalComments, thumb
|
||||
} = res.data.comic
|
||||
|
||||
@@ -27,7 +27,7 @@ export default new class {
|
||||
) {
|
||||
let data = Data.readJSON(`${groupId}.json`, this.root)
|
||||
if (!data.bannedWords) data.bannedWords = {}
|
||||
if (data.bannedWords[words]) throw Error(`❎ 违禁词${words}已存在`)
|
||||
if (data.bannedWords[words]) throw new ReplyError(`❎ 违禁词${words}已存在`)
|
||||
// 翻转对象
|
||||
let matchTypeMapMirr = _.invert(this.matchTypeMap)
|
||||
let penaltyTypeMapMirr = _.invert(this.penaltyTypeMap)
|
||||
@@ -48,7 +48,7 @@ export default new class {
|
||||
|
||||
delBannedWords (groupId, words) {
|
||||
let data = Data.readJSON(`${groupId}.json`, this.root)
|
||||
if (!data.bannedWords[words]) throw Error(`❎ 违禁词${words}不存在`)
|
||||
if (!data.bannedWords[words]) throw new ReplyError(`❎ 违禁词${words}不存在`)
|
||||
delete data.bannedWords[words]
|
||||
this.dataCach.delete(groupId)
|
||||
Data.writeJSON(`${groupId}.json`, data, this.root)
|
||||
@@ -57,7 +57,7 @@ export default new class {
|
||||
|
||||
queryBannedWords (groupId, words) {
|
||||
let data = Data.readJSON(`${groupId}.json`, this.root)
|
||||
if (!data.bannedWords[words]) throw Error(`❎ 违禁词${words}不存在`)
|
||||
if (!data.bannedWords[words]) throw new ReplyError(`❎ 违禁词${words}不存在`)
|
||||
let { matchType, penaltyType } = data.bannedWords[words]
|
||||
return {
|
||||
...data.bannedWords[words],
|
||||
|
||||
@@ -15,7 +15,7 @@ async function importCheerio () {
|
||||
try {
|
||||
cheerio = await import('cheerio')
|
||||
} catch (e) {
|
||||
throw Error('未检测到依赖cheerio,请安装后再使用Ascii2D搜图,安装命令:pnpm add cheerio -w 或 pnpm install -P')
|
||||
throw new ReplyError('未检测到依赖cheerio,请安装后再使用Ascii2D搜图,安装命令:pnpm add cheerio -w 或 pnpm install -P')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,14 +28,14 @@ export default async function doSearch (url) {
|
||||
const { ascii2dUsePuppeteer, ascii2dResultMaxQuantity } = Config.picSearch
|
||||
const callApi = ascii2dUsePuppeteer ? callAscii2dUrlApiWithPuppeteer : callAscii2dUrlApi
|
||||
let ret = await callApi(url)
|
||||
if (!ret) throw Error('Ascii2D搜图请求失败')
|
||||
if (!ret) throw new ReplyError('Ascii2D搜图请求失败')
|
||||
const colorURL = ret.url
|
||||
if (!colorURL.includes('/color/')) {
|
||||
const $ = cheerio.load(ret.data, { decodeEntities: false })
|
||||
logger.error('[error] ascii2d url:', colorURL)
|
||||
logger.debug(ret.data)
|
||||
let isCloudflare = ret.data.includes('cloudflare') ? '绕过Cloudflare盾失败' : false
|
||||
throw Error(`Ascii2D搜索失败,错误原因:${isCloudflare || $('.container > .row > div:first-child > p').text().trim()}`)
|
||||
throw new ReplyError(`Ascii2D搜索失败,错误原因:${isCloudflare || $('.container > .row > div:first-child > p').text().trim()}`)
|
||||
}
|
||||
const bovwURL = colorURL.replace('/color/', '/bovw/')
|
||||
let bovwDetail = await (ascii2dUsePuppeteer ? getAscii2dWithPuppeteer(bovwURL) : request.cfGet(bovwURL))
|
||||
@@ -47,7 +47,7 @@ export default async function doSearch (url) {
|
||||
}
|
||||
let colorData = (await parse(ret.data)).slice(0, ascii2dResultMaxQuantity)
|
||||
let bovwData = (await parse(bovwDetail.data)).slice(0, ascii2dResultMaxQuantity)
|
||||
if (_.isEmpty(colorData)) throw Error('Ascii2D数据获取失败')
|
||||
if (_.isEmpty(colorData)) throw new ReplyError('Ascii2D数据获取失败')
|
||||
let mapfun = item => [
|
||||
Config.picSearch.hideImg ? '' : segment.image(item.image),
|
||||
`${item.info}\n`,
|
||||
@@ -72,7 +72,7 @@ const callAscii2dUrlApi = async (imgUrl) => {
|
||||
let res = await request.cfGet(`${domain}/search/url/${imgUrl}`).catch(
|
||||
err => {
|
||||
if (err.stack?.includes('legacy sigalg disallowed or unsupported')) {
|
||||
throw Error(`Error Tls版本过低 请尝试将配置文件的‘cfTLSVersion’字段改为‘TLS1.2’\n详情请参考:https://www.yenai.ren/faq.html#openssl-%E9%94%99%E8%AF%AF\n错误信息:${err.stack}`)
|
||||
throw new ReplyError(`Error Tls版本过低 请尝试将配置文件的‘cfTLSVersion’字段改为‘TLS1.2’\n详情请参考:https://www.yenai.ren/faq.html#openssl-%E9%94%99%E8%AF%AF\n错误信息:${err.stack}`)
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ import Ascii2D from './ascii2d.js'
|
||||
export default async function doSearch (url) {
|
||||
let res = await getSearchResult(url)
|
||||
logger.debug('SauceNAO result:', res)
|
||||
if (res.header.status != 0) throw Error('SauceNAO搜图,错误信息:' + res.header.message?.replace(/<.*?>/g, ''))
|
||||
if (res.header.status != 0) throw new ReplyError('SauceNAO搜图,错误信息:' + res.header.message?.replace(/<.*?>/g, ''))
|
||||
let format = sagiri(res)
|
||||
if (_.isEmpty(format)) throw Error('SauceNAO搜图无数据')
|
||||
if (_.isEmpty(format)) throw new ReplyError('SauceNAO搜图无数据')
|
||||
|
||||
let msgMap = async item => [
|
||||
`SauceNAO (${item.similarity}%)\n`,
|
||||
@@ -61,7 +61,7 @@ export default async function doSearch (url) {
|
||||
async function getSearchResult (imgURL, db = 999) {
|
||||
logger.debug(`saucenao [${imgURL}]}`)
|
||||
let api_key = Config.picSearch.SauceNAOApiKey
|
||||
if (!api_key) throw Error('未配置SauceNAOApiKey,无法使用SauceNAO搜图,请在 https://saucenao.com/user.php?page=search-api 进行获取,请用指令:#设置SauceNAOapiKey <apikey> 进行添加')
|
||||
if (!api_key) throw new ReplyError('未配置SauceNAOApiKey,无法使用SauceNAO搜图,请在 https://saucenao.com/user.php?page=search-api 进行获取,请用指令:#设置SauceNAOapiKey <apikey> 进行添加')
|
||||
return await request.get('https://saucenao.com/search.php', {
|
||||
params: {
|
||||
api_key,
|
||||
@@ -75,7 +75,7 @@ async function getSearchResult (imgURL, db = 999) {
|
||||
timeout: 60000
|
||||
}).then(res => {
|
||||
if (res.status === 429) {
|
||||
throw Error('SauceNAO搜图 搜索次数已达单位时间上限,请稍候再试')
|
||||
throw new ReplyError('SauceNAO搜图 搜索次数已达单位时间上限,请稍候再试')
|
||||
} else {
|
||||
return res.json()
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import _ from 'lodash'
|
||||
*/
|
||||
export default async function doSearch (imgURL) {
|
||||
let result = await getSearchResult(imgURL)
|
||||
if (result.error) throw Error(result.error)
|
||||
if (result.error) throw new ReplyError(result.error)
|
||||
|
||||
let {
|
||||
result: [{
|
||||
@@ -21,7 +21,7 @@ export default async function doSearch (imgURL) {
|
||||
// image // 预览图片
|
||||
}]
|
||||
} = result
|
||||
if (_.isEmpty(result)) throw Error('未获取到相关信息')
|
||||
if (_.isEmpty(result)) throw new ReplyError('未获取到相关信息')
|
||||
similarity = (similarity * 100).toFixed(2) // 相似度
|
||||
const time = (() => {
|
||||
const s = Math.floor(from)
|
||||
|
||||
@@ -19,7 +19,7 @@ export default new class Pixiv {
|
||||
if (!this.PixivClient?.auth) {
|
||||
await this.PixivClient.login()
|
||||
}
|
||||
if (!this.PixivClient.auth?.user) throw Error('❎ 未获取到登录信息')
|
||||
if (!this.PixivClient.auth?.user) throw new ReplyError('❎ 未获取到登录信息')
|
||||
const { profile_image_urls: { px_170x170 }, id, name, account, mail_address, is_premium, x_restrict } = this.PixivClient.auth.user
|
||||
return [
|
||||
await this._requestPixivImg(px_170x170),
|
||||
@@ -67,7 +67,7 @@ export default new class Pixiv {
|
||||
} else {
|
||||
res = await request.get(`${this.domain}/illust`, { params }).then(res => res.json())
|
||||
}
|
||||
if (res.error) throw Error(res.error?.user_message || '无法获取数据')
|
||||
if (res.error) throw new ReplyError(res.error?.user_message || '无法获取数据')
|
||||
let illust = this._format(res.illust)
|
||||
let { id, title, user, tags, total_bookmarks, total_view, url, create_date, x_restrict, illust_ai_type } = illust
|
||||
let msg = [
|
||||
@@ -90,7 +90,7 @@ export default new class Pixiv {
|
||||
} else {
|
||||
linkmsg.push(`https://pixiv.re/${id}.jpg`)
|
||||
}
|
||||
throw Error(linkmsg.join('\n'))
|
||||
throw new ReplyError(linkmsg.join('\n'))
|
||||
}
|
||||
let img = await Promise.all(url.map(async item => await this._requestPixivImg(item)))
|
||||
return { msg, img }
|
||||
@@ -114,13 +114,13 @@ export default new class Pixiv {
|
||||
// r18处理
|
||||
if (r18) {
|
||||
let R18 = this.ranktype[mode].r18
|
||||
if (!R18) throw Error('该排行没有不适合所有年龄段的分类哦~')
|
||||
if (!R18) throw new ReplyError('该排行没有不适合所有年龄段的分类哦~')
|
||||
type = R18.type
|
||||
pageSizeAll = R18.total
|
||||
}
|
||||
// 总页数
|
||||
let pageAll = Math.ceil(pageSizeAll / 30)
|
||||
if (page > pageAll) throw Error('哪有那么多图片给你辣(•̀へ •́ ╮ )')
|
||||
if (page > pageAll) throw new ReplyError('哪有那么多图片给你辣(•̀へ •́ ╮ )')
|
||||
|
||||
if (!date) date = moment().subtract(moment().utcOffset(9).hour() >= 12 ? 1 : 2, 'days').format('YYYY-MM-DD')
|
||||
|
||||
@@ -135,8 +135,8 @@ export default new class Pixiv {
|
||||
} else {
|
||||
res = await request.get(`${this.domain}/rank`, { params }).then(res => res.json())
|
||||
}
|
||||
if (res.error) throw Error(res.error.message)
|
||||
if (_.isEmpty(res.illusts)) throw Error('暂无数据,请等待榜单更新哦(。-ω-)zzz')
|
||||
if (res.error) throw new ReplyError(res.error.message)
|
||||
if (_.isEmpty(res.illusts)) throw new ReplyError('暂无数据,请等待榜单更新哦(。-ω-)zzz')
|
||||
|
||||
let illusts = await Promise.all(res.illusts.map(async (item, index) => {
|
||||
let list = this._format(item)
|
||||
@@ -186,11 +186,11 @@ export default new class Pixiv {
|
||||
offset: (page - 1) * 30
|
||||
}
|
||||
let res = await request.get(api, { params }).then(res => res.json())
|
||||
if (res.data.count == 0) throw Error('呜呜呜,人家没有找到相关的插画(ó﹏ò。)')
|
||||
if (res.data.count == 0) throw new ReplyError('呜呜呜,人家没有找到相关的插画(ó﹏ò。)')
|
||||
|
||||
let pageall = Math.ceil(res.data.count / 30)
|
||||
|
||||
if (page > pageall) throw Error('啊啊啊,淫家给不了你那么多辣d(ŐдŐ๑)')
|
||||
if (page > pageall) throw new ReplyError('啊啊啊,淫家给不了你那么多辣d(ŐдŐ๑)')
|
||||
|
||||
let list = [
|
||||
`当前为第${page}页,共${pageall}页,本页共${res.data.rows.length}张,总共${res.data.count}张`
|
||||
@@ -230,8 +230,8 @@ export default new class Pixiv {
|
||||
} else {
|
||||
res = await request.get(`${this.domain}/search`, { params }).then(res => res.json())
|
||||
}
|
||||
if (res.error) throw Error(res.error.message)
|
||||
if (_.isEmpty(res.illusts)) throw Error('宝~没有数据了哦(๑>︶<)و')
|
||||
if (res.error) throw new ReplyError(res.error.message)
|
||||
if (_.isEmpty(res.illusts)) throw new ReplyError('宝~没有数据了哦(๑>︶<)و')
|
||||
let sortIllusts = _.orderBy(res.illusts, 'total_bookmarks', 'desc')
|
||||
let illusts = []
|
||||
let filterNum = 0
|
||||
@@ -252,7 +252,7 @@ export default new class Pixiv {
|
||||
await this._requestPixivImg(image_urls.large)
|
||||
])
|
||||
}
|
||||
if (_.isEmpty(illusts)) throw Error('该页全为涩涩内容已全部过滤(#/。\#)')
|
||||
if (_.isEmpty(illusts)) throw new ReplyError('该页全为涩涩内容已全部过滤(#/。\#)')
|
||||
|
||||
return [
|
||||
`本页共${NowNum}张${filterNum ? `,过滤${filterNum}张` : ''}\n可尝试使用 "#tagpro搜图${tag}第${page - 0 + 1}页" 翻页\n无数据则代表无下一页`,
|
||||
@@ -272,7 +272,7 @@ export default new class Pixiv {
|
||||
res = await fetch(`${this.domain}/tags`).then(res => res.json())
|
||||
}
|
||||
|
||||
if (!res.trend_tags) throw Error('呜呜呜,没有获取到数据(๑ १д१)')
|
||||
if (!res.trend_tags) throw new ReplyError('呜呜呜,没有获取到数据(๑ १д१)')
|
||||
|
||||
let list = []
|
||||
for (let i of res.trend_tags) {
|
||||
@@ -310,7 +310,7 @@ export default new class Pixiv {
|
||||
}
|
||||
}).then(res => res.json())
|
||||
}
|
||||
if (_.isEmpty(wordlist.user_previews)) throw Error('呜呜呜,人家没有找到这个淫d(ŐдŐ๑)')
|
||||
if (_.isEmpty(wordlist.user_previews)) throw new ReplyError('呜呜呜,人家没有找到这个淫d(ŐдŐ๑)')
|
||||
keyword = wordlist.user_previews[0].user.id
|
||||
}
|
||||
const params = {
|
||||
@@ -324,9 +324,9 @@ export default new class Pixiv {
|
||||
res = await request.get(`${this.domain}/member_illust`, { params }).then(res => res.json())
|
||||
}
|
||||
|
||||
if (res.error) throw Error(res.error.message)
|
||||
if (res.error) throw new ReplyError(res.error.message)
|
||||
// 没有作品直接返回信息
|
||||
if (_.isEmpty(res.illusts)) throw Error(page >= 2 ? '这一页没有作品辣(>人<;)' : 'Σ(っ °Д °;)っ这个淫居然没有作品')
|
||||
if (_.isEmpty(res.illusts)) throw new ReplyError(page >= 2 ? '这一页没有作品辣(>人<;)' : 'Σ(っ °Д °;)っ这个淫居然没有作品')
|
||||
|
||||
let illusts = []
|
||||
let filter = 0
|
||||
@@ -346,7 +346,7 @@ export default new class Pixiv {
|
||||
await this._requestPixivImg(url[0])
|
||||
])
|
||||
}
|
||||
if (_.isEmpty(illusts)) throw Error('该页全为涩涩内容已全部过滤(#/。\#)')
|
||||
if (_.isEmpty(illusts)) throw new ReplyError('该页全为涩涩内容已全部过滤(#/。\#)')
|
||||
let { id: uid, name, profile_image_urls } = res.user
|
||||
return [
|
||||
[
|
||||
@@ -378,8 +378,8 @@ export default new class Pixiv {
|
||||
} else {
|
||||
user = await request.get(`${this.domain}/search_user`, { params }).then(res => res.json())
|
||||
}
|
||||
if (user.error) throw Error(user.error.message)
|
||||
if (_.isEmpty(user.user_previews)) throw Error('呜呜呜,人家没有找到这个淫d(ŐдŐ๑)')
|
||||
if (user.error) throw new ReplyError(user.error.message)
|
||||
if (_.isEmpty(user.user_previews)) throw new ReplyError('呜呜呜,人家没有找到这个淫d(ŐдŐ๑)')
|
||||
|
||||
let msg = await Promise.all(user.user_previews.slice(0, 10).map(async (item, index) => {
|
||||
let { id, name, profile_image_urls } = item.user
|
||||
@@ -410,7 +410,7 @@ export default new class Pixiv {
|
||||
async vilipixRandomImg (limit) {
|
||||
let api = `https://www.vilipix.com/api/v1/picture/recommand?limit=${limit}&offset=${_.random(1, 700)}`
|
||||
let res = await request.get(api).then(res => res.json())
|
||||
if (!res.data || !res.data.rows) throw Error('呜呜呜,没拿到瑟瑟的图片(˃ ⌑ ˂ഃ )')
|
||||
if (!res.data || !res.data.rows) throw new ReplyError('呜呜呜,没拿到瑟瑟的图片(˃ ⌑ ˂ഃ )')
|
||||
return res.data.rows.map(item => {
|
||||
let { picture_id, title, regular_url, tags, like_total } = item
|
||||
return [
|
||||
@@ -437,8 +437,8 @@ export default new class Pixiv {
|
||||
} else {
|
||||
res = await request.get(`${this.domain}/related`, { params }).then(res => res.json())
|
||||
}
|
||||
if (res.error) throw Error(res.error.user_message)
|
||||
if (_.isEmpty(res.illusts)) throw Error('呃...没有数据(•ิ_•ิ)')
|
||||
if (res.error) throw new ReplyError(res.error.user_message)
|
||||
if (_.isEmpty(res.illusts)) throw new ReplyError('呃...没有数据(•ิ_•ิ)')
|
||||
|
||||
let illusts = []
|
||||
let filter = 0
|
||||
@@ -458,7 +458,7 @@ export default new class Pixiv {
|
||||
await this._requestPixivImg(image_urls.large)
|
||||
])
|
||||
}
|
||||
if (_.isEmpty(illusts)) throw Error('啊啊啊!!!居然全是瑟瑟哒不给你看(*/ω\*)')
|
||||
if (_.isEmpty(illusts)) throw new ReplyError('啊啊啊!!!居然全是瑟瑟哒不给你看(*/ω\*)')
|
||||
|
||||
return [
|
||||
`Pid:${pid}的相关作品,共${res.illusts.length}张${filter ? `,过滤${filter}张` : ''}`,
|
||||
|
||||
@@ -15,9 +15,9 @@ export default class PixivApi {
|
||||
|
||||
async login () {
|
||||
if (!this.refresh_token) {
|
||||
throw Error('[Yenai][Pixiv] 未配置refresh_token刷新令牌')
|
||||
throw new ReplyError('[Yenai][Pixiv] 未配置refresh_token刷新令牌')
|
||||
}
|
||||
const response = login(this.refresh_token)
|
||||
const response = await login(this.refresh_token)
|
||||
this.access_token = response.access_token
|
||||
this.refresh_token = response.refresh_token
|
||||
this.auth = response
|
||||
@@ -30,7 +30,7 @@ export default class PixivApi {
|
||||
} catch (error) {
|
||||
if (this._once) {
|
||||
this._once = false
|
||||
throw error
|
||||
throw new ReplyError()
|
||||
}
|
||||
await this.login()
|
||||
this._once = true
|
||||
|
||||
@@ -19,8 +19,8 @@ export const headers = {
|
||||
|
||||
export async function login (refresh_token) {
|
||||
const local_time = moment().format()
|
||||
const headers = {
|
||||
...this.headers,
|
||||
let _headers = {
|
||||
...headers,
|
||||
'X-Client-Time': local_time,
|
||||
'X-Client-Hash': md5(`${local_time}${HASH_SECRET}`)
|
||||
}
|
||||
@@ -32,9 +32,9 @@ export async function login (refresh_token) {
|
||||
}
|
||||
const { response, error } = await request.post('https://oauth.secure.pixiv.net/auth/token', {
|
||||
data,
|
||||
headers
|
||||
headers: _headers
|
||||
}).then(res => res.json())
|
||||
if (error) throw Error(`[Yenai][Pixiv]login Error Response: ${error}`)
|
||||
if (error) throw new ReplyError(`[Yenai][Pixiv]login Error Response: ${error}`)
|
||||
if (response.access_token) {
|
||||
const { id, name, account } = this.auth.user
|
||||
logger.info(`[Yenai][Pixiv]login ${logger.yellow(`${name}(${id}) @${account}`)} ${logger.green('success')}`)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { formatDuration } from '../../tools/index.js'
|
||||
import { Version, Plugin_Name } from '../../components/index.js'
|
||||
import moment from 'moment'
|
||||
import os from 'os'
|
||||
import { status } from '../../constants/other.js'
|
||||
import { createRequire } from 'module'
|
||||
@@ -10,7 +9,6 @@ export default async function getBotState (botList) {
|
||||
const defaultAvatar = `../../../../../plugins/${Plugin_Name}/resources/state/img/default_avatar.jpg`
|
||||
const BotName = Version.name
|
||||
const systime = formatDuration(os.uptime(), 'dd天hh小时mm分', false)
|
||||
const calendar = moment().format('YYYY-MM-DD HH:mm:ss')
|
||||
|
||||
const dataPromises = botList.map(async (i) => {
|
||||
const bot = Bot[i]
|
||||
@@ -40,10 +38,10 @@ export default async function getBotState (botList) {
|
||||
<div class="header">
|
||||
<h1>${nickname}</h1>
|
||||
<hr noshade>
|
||||
<p> ${BotName} 已运行 ${runTime}</p>
|
||||
<p>${onlineStatus}(${platform}) | ${botVersion}</p>
|
||||
<p>收${recv || 0} | 发${sent || 0} | 图片${screenshot || 0} | 好友${friendQuantity} | 群${groupQuantity} | 群员${groupMemberQuantity}</p>
|
||||
<p>${BotName} 已运行 ${runTime} | 系统运行 ${systime}</p>
|
||||
<p>${calendar} | Node.js ${process.version} | ${process.platform} ${process.arch}</p>
|
||||
<p>Node.js ${process.version} | ${process.platform} ${process.arch} | 系统运行 ${systime}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
@@ -19,7 +19,7 @@ export async function pandadiu (type = 'cos', keywords = '') {
|
||||
logger.debug('[Yenai-Plugin][acg]作品索引页:' + homeUrl)
|
||||
const home = await request.get(homeUrl).then(res => res.text())
|
||||
const href = _.sample(_.map(cheerio.load(home)('div.cos-list.clearfix > ul > a, div.cover.mod_imgLight > a'), item => item.attribs.href))
|
||||
if (!href) throw Error('未找到结果')
|
||||
if (!href) throw new ReplyError('未找到结果')
|
||||
logger.debug('[Yenai-Plugin][acg]图片详情页:' + domain + href)
|
||||
const details = await request.get(domain + href).then(res => res.text())
|
||||
const $ = cheerio.load(details)
|
||||
@@ -50,7 +50,7 @@ export async function mengdui (keywords, isSearch) {
|
||||
const home = await request.get(url).then(res => res.text())
|
||||
const $ = cheerio.load(home)
|
||||
href = _.sample(_.map($('div.md-wide > ul > li > a'), item => item.attribs.href))
|
||||
if (!href) throw Error($('div.no-tips > p:nth-of-type(1)').text().trim())
|
||||
if (!href) throw new ReplyError($('div.no-tips > p:nth-of-type(1)').text().trim())
|
||||
const maxPage = $('div.pagebar.md-flex-wc.mb20 > a:not(:last-child)').length
|
||||
mengduipage[keywords] = maxPage
|
||||
await redis.set('yenai:mengduipage', JSON.stringify(mengduipage))
|
||||
@@ -119,7 +119,7 @@ export async function coser () {
|
||||
(item) => item.attribs.href
|
||||
)
|
||||
)
|
||||
if (!href) throw Error('未知错误')
|
||||
if (!href) throw new ReplyError('未知错误')
|
||||
logger.debug('[Yenai-Plugin][coser]图片详情页:' + domain + href)
|
||||
const imgPage = await request.get(domain + href).then(res => res.text())
|
||||
const $1 = cheerio.load(imgPage)
|
||||
|
||||
@@ -21,7 +21,7 @@ export default async function thumbUp (e) {
|
||||
/** 判断是否为好友 */
|
||||
let isFriend = await (e.bot ?? Bot).fl.get(userId)
|
||||
let allowLikeByStrangers = Config.whole.Strangers_love
|
||||
if (!isFriend && !allowLikeByStrangers) return e.reply(`不加好友不${_do}🙄`, true)
|
||||
if (!isFriend && !allowLikeByStrangers) { return (e.message?.[0]?.text == '#全部赞我') ? false : e.reply(`不加好友不${_do}🙄`, true) }
|
||||
/** 执行点赞 */
|
||||
let n = 0
|
||||
let failsMsg = `今天已经${_do}过了,还搁这讨${_do}呢!!!`
|
||||
@@ -60,14 +60,16 @@ export default async function thumbUp (e) {
|
||||
segment.image((await memes[successFn](avatar)) ||
|
||||
_.sample(successImgs) + userId)
|
||||
]
|
||||
: [
|
||||
: (e.message?.[0]?.text == '#全部赞我')
|
||||
? []
|
||||
: [
|
||||
`\n${failsMsg}`,
|
||||
segment.image((await memes.crawl(avatar)) ||
|
||||
_.sample(faildsImgs) + userId)
|
||||
]
|
||||
]
|
||||
|
||||
/** 回复 */
|
||||
e.reply(msg, true, { at: userId })
|
||||
if (msg.length) { return e.reply(msg, true, { at: userId }) }
|
||||
}
|
||||
|
||||
class ThumbUpApi {
|
||||
@@ -114,7 +116,7 @@ class ThumbUpApi {
|
||||
|
||||
async origThumbUp (uid, times) {
|
||||
const friend = this.Bot.pickFriend(uid)
|
||||
if (!friend?.thumbUp) throw Error('当前协议端不支持点赞,详情查看\nhttps://gitee.com/TimeRainStarSky/Yunzai')
|
||||
if (!friend?.thumbUp) throw new ReplyError('当前协议端不支持点赞,详情查看\nhttps://gitee.com/TimeRainStarSky/Yunzai')
|
||||
const res = { ...await friend.thumbUp(times) }
|
||||
if (res.retcode && !res.code) { res.code = res.retcode }
|
||||
if (res.message && !res.msg) { res.msg = res.message }
|
||||
|
||||
@@ -9,7 +9,7 @@ export async function _importDependency () {
|
||||
if (cheerio) return cheerio
|
||||
cheerio = await import('cheerio')
|
||||
.catch(() => {
|
||||
throw Error('未检测到依赖cheerio,请安装后再使用该功能,安装命令:pnpm add cheerio -w 或 pnpm install -P')
|
||||
throw new ReplyError('未检测到依赖cheerio,请安装后再使用该功能,安装命令:pnpm add cheerio -w 或 pnpm install -P')
|
||||
})
|
||||
return cheerio
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ export default new class setu {
|
||||
excludeAI
|
||||
}
|
||||
let result = await request.post(api, { data: parans }).then(res => res.json())
|
||||
if (_.isEmpty(result.data)) throw Error('没有找到相关的tag')
|
||||
if (_.isEmpty(result.data)) throw new ReplyError('没有找到相关的tag')
|
||||
// 消息
|
||||
return await Promise.all(result.data.map(async item => {
|
||||
let { pid, title, tags, author, r18, urls, aiType } = item
|
||||
|
||||
@@ -124,14 +124,6 @@
|
||||
</div>
|
||||
<div class="cfg-desc">可选值:低质量,中等质量,高质量,原图</div>
|
||||
</li>
|
||||
<li class="cfg-li">
|
||||
<div class="cfg-line">
|
||||
匿名
|
||||
<span class="cfg-hint">#椰奶设置匿名 + 开启/关闭</span>
|
||||
{{@anonymous}}
|
||||
</div>
|
||||
<div class="cfg-desc">群聊使用匿名发送</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{{/block}}
|
||||
@@ -7,7 +7,7 @@
|
||||
:root {
|
||||
--high-color: #d73403;
|
||||
--medium-color: #ffa500;
|
||||
--low-color: #90ee90;
|
||||
--low-color: #87CEEB;
|
||||
}
|
||||
|
||||
.container {
|
||||
@@ -35,7 +35,7 @@ body {
|
||||
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: 10px;
|
||||
border-radius: 27px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||
font-weight: 700;
|
||||
}
|
||||
@@ -120,7 +120,7 @@ hr {
|
||||
.cpu {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: #eee;
|
||||
background: rgba(238, 238, 238, 0.6);
|
||||
position: relative;
|
||||
border-radius: 50%;
|
||||
}
|
||||
@@ -169,7 +169,7 @@ hr {
|
||||
transform: translate(-50%, -50%);
|
||||
color: #999;
|
||||
font-size: 20px;
|
||||
background: white;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.memory li {
|
||||
@@ -186,11 +186,13 @@ hr {
|
||||
margin: 0 5px;
|
||||
position: relative;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.memory .progress .current {
|
||||
background: #90ee90;
|
||||
height: 25px;
|
||||
border-radius: 5px;
|
||||
border-radius: 0 10px 10px 0;
|
||||
}
|
||||
.memory .progress .word {
|
||||
position: absolute;
|
||||
|
||||
@@ -39,16 +39,6 @@ export default function formatDuration (time, format, repair = true) {
|
||||
return format(timeObj)
|
||||
}
|
||||
|
||||
if (typeof format === 'string') {
|
||||
format = format
|
||||
.replace(/dd/g, day)
|
||||
.replace(/hh/g, timeObj.hour)
|
||||
.replace(/mm/g, timeObj.minute)
|
||||
.replace(/ss/g, timeObj.second)
|
||||
|
||||
return format
|
||||
}
|
||||
|
||||
if (format == 'default') {
|
||||
let result = ''
|
||||
|
||||
@@ -67,5 +57,15 @@ export default function formatDuration (time, format, repair = true) {
|
||||
return result
|
||||
}
|
||||
|
||||
if (typeof format === 'string') {
|
||||
format = format
|
||||
.replace(/dd/g, day)
|
||||
.replace(/hh/g, timeObj.hour)
|
||||
.replace(/mm/g, timeObj.minute)
|
||||
.replace(/ss/g, timeObj.second)
|
||||
|
||||
return format
|
||||
}
|
||||
|
||||
return timeObj
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user