🎨 删除loader尝试适配v4

This commit is contained in:
yeyang
2024-06-14 19:19:12 +08:00
parent 5502ef2c75
commit 6f54d054c0
5 changed files with 85 additions and 320 deletions

View File

@@ -12,9 +12,7 @@ const TimeUnitReg = Object.keys(Time_unit).join("|")
const noactivereg = new RegExp(`^#(查看|清理|确认清理|获取)(${Numreg})个?(${TimeUnitReg})没发言的人(第(${Numreg})页)?$`)
/** 我要自闭正则 */
const Autisticreg = new RegExp(`^#?我要(自闭|禅定)(${Numreg})?个?(${TimeUnitReg})?$`, "i")
/** 获取定时任务 */
const redisTask = await Ga.getRedisMuteTask() || false
Ga.loadRedisMuteTask()
export class GroupAdmin extends plugin {
constructor() {
super({
@@ -100,7 +98,6 @@ export class GroupAdmin extends plugin {
}
]
})
this.task = redisTask
}
get Bot() {

View File

@@ -3,9 +3,6 @@ import chokidar from "chokidar"
import fs from "node:fs"
import YamlReader from "./YamlReader.js"
import cfg from "../../../lib/config/config.js"
import loader from "../../../lib/plugins/loader.js"
import _ from "lodash"
import moment from "moment"
const Path = process.cwd()
const Plugin_Name = "yenai-plugin"
@@ -227,24 +224,6 @@ class Config {
}
}
async change_picApi() {
let tmp = {}
logger.debug("[Yenai-Plugin]api接口修改重载fun.js")
tmp = await import(`../apps/fun.js?${moment().format("x")}`)
_.forEach(tmp, (p) => {
/* eslint-disable new-cap */
let plugin = new p()
for (let i in loader.priority) {
if (loader.priority[i].key == Plugin_Name && loader.priority[i].name == "椰奶娱乐") {
loader.priority[i].class = p
loader.priority[i].priority = plugin.priority
}
}
})
}
async change_pixiv() {
let pixiv = (await import("../model/index.js")).Pixiv
let PixivApi = (await import("../model/Pixiv/api.js")).default

View File

@@ -1,246 +0,0 @@
{
// 是否自动按照 config.default.json 来更新 config.json可以自动向 config.json 添加新增的配置项以及同步说明注释,
// 但 config.json 中你自己写的注释以及不在 config.default.json 中的配置项都会被丢弃,第一次启用前建议先备份一下你的 config.json
"autoUpdateConfig": false,
// 陌生人点赞
"strangers_love": false,
"sese": false,
"sesepro": false,
// 渲染精度
"renderScale": 100,
// 通知相关设置
"notice": {
"notificationsAll": false, // 全部通知
"deltime": 600, // 删除缓存
"default": {
// 群通知类
"groupMessage": false, // 群消息
"grouptemporaryMessage": false, //群临时消息
"groupRecall": false, // 群撤回
"groupInviteRequest": false, // 群邀请
"groupAdminChange": false, // 群管理变动
"groupNumberChange": false, // 群聊列表变动
"groupMemberNumberChange": false, // 群成员变动
"addGroupApplication": false, // 加群申请
// 好友通知类
"privateMessage": false, // 好友消息
"PrivateRecall": false, // 好友撤回
"friendRequest": false, // 好友申请
"friendNumberChange": false, // 好友列表变动
// 其他通知
"flashPhoto": false, // 闪照
"botBeenBanned": false, // 禁言
"input": false // 对方正在输入
},
// 群单独设置
"123456": {
"groupMessage": false,
"grouptemporaryMessage": false
},
"456789": {
"groupMessage": false,
"grouptemporaryMessage": false
}
},
// 代理椰奶绝大部分请求
"proxy": {
// 代理网址 仅支持http
"proxyAddress": "http: //127.0.0.1:7890",
// #开启或关闭使用代理
"switchProxy": false,
// #代理黑名单,可以使用*和?通配符
"blacklist": [
"*.baidu.com"
],
// #代理白名单,在全局关闭的情况下可用
"whitelist": [
"*.google.com"
]
},
// 哔咔设置
"bika": {
// 是否允许私聊使用
"allowPM": true,
// 每名用户每日使用次数限制 0则无限制
"limit": 30,
// 哔咔图片直连,直接使用哔咔原图发送不使用图片反代,国内则需使用代理
"bikaDirectConnection": false,
// 哔咔图片反代
"bikaImageProxy": "s3.go2778.com/static",
// 哔咔图片质量,可选值 ['low', 'medium', 'high', 'original'] 质量依次从低到高
"imageQuality": "medium"
},
// 群管配置
"groupAdmin": {
// 白名单QQ
"whiteQQ": [],
// 白名单禁言自动解禁
"noBan": false,
"vote": {
// # 投票禁言开关
"VoteBan": true,
// # 投票踢人开关
"VoteKick": false,
// # 投票禁言超时时间 单位:秒
"outTime": 180,
// # 投票最低所需票数 不建议太低
"minNum": 4,
// # 投票成功禁言时间 单位:秒
"BanTime": 3600,
// # 是否允许管理员一票否决
"veto": true,
// # 是否允许投票禁言管理员(Bot为群主的情况下)
"voteAdmin": false
},
// 收到进群事件向群里发送通知
"groupAddNot": {
// 开启的群聊
"openGroup": [],
"msg": "有一个加群通知,管理员快去看看吧~"
},
"groupverify": {
// 开启的群聊
"openGroup": [],
// 如需要分群,请按照下列格式添加 <以群号为字段> 的成功提示即可0 字段代表默认回复
"SuccessMsgs": {
"254974507": "✅ 验证成功,欢迎入群,群里有非常多的大佬给你透哦~~",
"0": "✅ 验证成功,欢迎入群"
},
// 答案验证模式,可选:精确、模糊
"mode": "精确",
// 最多允许尝试次数
"times": 7,
// 是否开启最后一分钟提醒(仅在超时时长大于等于 120 秒时有效true 开启false 关闭)
"remindAtLastMinute": true,
// 超时时长建议至少一分钟60 秒)
"time": 300,
// 随机算式的数字的随机范围
"range": {
"min": 10,
"max": 100
},
// 收到进群事件后延迟多少秒再发送验证信息(秒)
"DelayTime": 2
}
},
"state": {
// 将椰奶状态作为默认状态
"setDefaultState": false,
// 网络测试
// show: 是否显示 true - 显示 - false - 不显示 pro - 只有pro显示
// 测试网址列表
// list:
// name: 显示名称
// url: 要访问的网址
// useProxy: 是否使用插件配置中的代理访问
// timeout: 测试超时时间
"psTestSites": {
"show": "pro",
"list": [
{
"name": "Baidu",
"url": "https://baidu.com"
},
{
"name": "Google",
"url": "https://google.com"
},
{
"name": "Google(proxy)",
"url": "https://google.com",
"useProxy": true
}
],
"timeout": 5000
},
// 监控任务
"statusTask": true,
// 如果出现内存异常的情况可将此配置项开启,如果打开后报错请将监控任务关闭
"statusPowerShellStart": false,
// 关闭node的那个圈圈
"closedNodeInfo": true,
// 关闭图表
"closedChart": false,
// 是否显示FastFetch 参数: true, false, pro ,default
// true - 开启
// false - 关闭
// pro - 只有状态pro显示
// default - win默认只有pro显示liunx等其他正常也会显示
"showFastFetch": "default",
// 样式
"style": {
// 背景图片api设置为false则一直使用默认背景
// CF跳板(会损失一点访问时间但后期API地址可以自动更新)
// http: //dir.dengfenglai.icu
// 默认地址(直连但是不确定是否会GG)
// https: //t.mwm.moe/mp/
"backdrop": "http://dir.dengfenglai.icu",
// 当api请求失败时使用的默认背景图请放置在resources/state/img/bg目录下
// random - 随机选择state/img/bg目录里的一张图片
// default_bg.jpg 可直接指定bg目录里一张图片注意请带上后缀名
"backdropDefault": "random",
// Bot昵称的颜色
"BotNameColor": "#000",
// Bot昵称渐变色 设置了该值BotNameColor值将无效 如要使用BotNameColor请将该值设为none或false
// 该值请参考https: //developer.mozilla.org/zh-CN/docs/Web/CSS/gradient/linear-gradient
// xxdeg 为渐变角度 后为渐变颜色
"BotNameColorGradient": "none",
// 主硬件进度条和磁盘进度条的颜色
"progressBar": {
// 严重
"highColor": "#d73403",
// 警告
"mediumColor": "#ffa500",
// 正常
"lowColor": "#84A0DF"
}
}
},
// pixiv相关配置
"pixiv": {
// 是否允许私聊使用
"allowPM": true,
// pixiv图片直连国内需配合代理使用
"pixivDirectConnection": false,
// pixiv图片反代开启直连后反代服务则无效
"pixivImageProxy": "i.pixiv.re",
// 每名用户每日次数限制0 则无限制)
"limit": 30,
// Pixiv 登录凭证刷新令牌 (Refresh Token)
// 获取方法请参考: https: //github.com/mixmoe/HibiAPI/issues/53
"refresh_token": null,
// 返回语言, 会影响标签的翻译
"language": "zh-cn"
},
"picSearch": {
// 是否只有主人能用
"isMasterUse": false,
// 是否允许私聊使用
"allowPM": true,
// 每名用户每日搜索次数限制
"limit": 30,
// SauceNAO搜图apikey 请在 https://saucenao.com/user.php?page=search-api 进行获取
"SauceNAOApiKey": null,
// SauceNAO搜图相似度低于这个百分比将被认定为相似度过低
"SauceNAOMinSim": 60,
// saucanao 得到 NSFW 结果时隐藏缩略图,可选 0~3严格程度依次增加
// 0-不隐藏1-隐藏明确为 NSFW 的缩略图2-隐藏明确和可能为 NSFW 的缩略图3-只显示明确为非 NSFW 的缩略图
"hideImgWhenSaucenaoNSFW": 0,
// 绕过 Cloudflare Challenge 所使用的 TLS 版本,建议可选值:["TLSv1.1", "TLSv1.2"]
"cfTLSVersion": "TLSv1.1",
// 是否使用 Puppeteer 请求 ascii2d 以绕过 cf js challenge
"ascii2dUsePuppeteer": false,
// ascii2d搜图返回结果的最大数量
"ascii2dResultMaxQuantity": 3,
// 隐藏所有搜索结果的缩略图
"hideImg": false,
// whatanime 得到 R18 结果时隐藏结果缩略图
"hideImgWhenWhatanimeR18": false,
// whatanime 发送预览视频R18 结果不会发送
"whatanimeSendVideo": false,
// 是否在 saucenao 相似度过低时自动使用 ascii2d
"useAscii2dWhenLowAcc": true,
// 是否在 saucenao 搜索失败时自动使用 ascii2d
"useAscii2dWhenFailed": true
}
}

View File

@@ -5,7 +5,6 @@ import path from "path"
import fs from "node:fs/promises"
import _ from "lodash"
import moment from "moment"
import loader from "../../../lib/plugins/loader.js"
import { Config } from "../components/index.js"
import { QQApi } from "./index.js"
import { Time_unit, ROLE_MAP } from "../constants/other.js"
@@ -14,8 +13,8 @@ import schedule from "node-schedule"
// 无管理文案
const ROLE_ERROR = "❎ 该命令需要管理员权限"
export default class {
let _task = []
export default class GroupAdmin {
constructor(e) {
this.e = e
this.Bot = e.bot ?? Bot
@@ -269,14 +268,16 @@ segment.image(`https://q1.qlogo.cn/g?b=qq&s=100&nk=${item.user_id}`),
* @returns {Promise<boolean>} - 返回操作结果。如果设置成功,则返回 true否则返回 false。
*/
async setMuteTask(group, cron, type) {
let name = `椰奶群定时${type ? "禁言" : "解禁"}${group}`
if (loader.task.find(item => item.name == name)) return false
let redisTask = JSON.parse(await redis.get(this.MuteTaskKey)) || []
if (_task.find(i => i.group === group && i.type === type)) return false
const bot = this.Bot
let task = {
cron,
name,
group,
type,
bot,
fnc: () => {
this.Bot.pickGroup(group).muteAll(type)
bot.pickGroup(group).muteAll(type)
},
job: schedule.scheduleJob(cron, async() => {
try {
@@ -293,25 +294,40 @@ segment.image(`https://q1.qlogo.cn/g?b=qq&s=100&nk=${item.user_id}`),
}
})
}
loader.task.push(task)
_task.push(task)
redisTask.push({ cron, group, type, botId: this.Bot.uin })
redis.set(this.MuteTaskKey, JSON.stringify(redisTask))
return true
}
/**
* @description 从 Redis 中获取群禁言/解禁任务列表,并将其转换为定时任务列表
* @returns {Promise<Array>} - 返回转换后的定时任务列表,列表中的每一项都包含 cron、name 和 fnc 三个属性。其中cron 表示任务的执行时间name 表示任务的名称fnc 表示任务的执行函数。
*/
static async getRedisMuteTask() {
return JSON.parse(await redis.get("yenai:MuteTasks"))?.map(item => {
return {
cron: item.cron,
name: `椰奶群定时${item.type ? "禁言" : "解禁"}${item.group}`,
static async loadRedisMuteTask() {
const data = JSON.parse(await redis.get("yenai:MuteTasks"))
if (!data) return false
data.forEach((i) => {
const { cron, group, type, botId } = i
const task = {
cron,
group,
type,
fnc: () => {
(Bot[item.botId] ?? Bot).pickGroup(item.group).muteAll(item.type)
}
(Bot[botId] ?? Bot).pickGroup(group).muteAll(type)
},
job: schedule.scheduleJob(cron, async() => {
try {
if (task.log == true) {
logger.mark(`开始定时任务:${task.name}`)
}
await task.fnc()
if (task.log == true) {
logger.mark(`定时任务完成:${task.name}`)
}
} catch (err) {
logger.error(`定时任务报错:${task.name}`)
logger.error(err)
}
})
}
_task.push(task)
})
}
@@ -323,42 +339,54 @@ segment.image(`https://q1.qlogo.cn/g?b=qq&s=100&nk=${item.user_id}`),
*/
async delMuteTask(group, type) {
let redisTask = JSON.parse(await redis.get(this.MuteTaskKey)) || []
const name = `椰奶群定时${type ? "禁言" : "解禁"}${group}`
// 终止任务
const task = loader.task.find(i => i.name === name)
const task = _task.find(i => i.group == group && i.type == type)
task?.job?.cancel()
loader.task = loader.task.filter(item => item.name !== name)
redisTask = redisTask.filter(item => item.group !== group && item.type !== type)
const f = i => !(i.group == group && i.type == type)
_task = _task.filter(f)
redisTask = redisTask.filter(f)
redis.set(this.MuteTaskKey, JSON.stringify(redisTask))
return true
}
/** 获取定时任务 */
getMuteTask() {
let RegEx = /椰奶群定时(禁言|解禁)(\d+)/
let taskList = _.cloneDeep(loader.task)
let MuteList = taskList.filter(item => /椰奶群定时禁言\d+/.test(item.name))
let noMuteList = taskList.filter(item => /椰奶群定时解禁\d+/.test(item.name))
noMuteList.forEach(noitem => {
let index = MuteList.findIndex(item => noitem.name.match(RegEx)[2] == item.name.match(RegEx)[2])
if (index !== -1) {
MuteList[index].nocron = noitem.cron
let taskList = _.cloneDeep(_task)
console.log(taskList)
const taskGroups = new Map()
for (const item of taskList) {
if (item.type) {
if (!taskGroups.has(item.group)) {
taskGroups.set(item.group, { ...item })
} else {
const muteItem = taskGroups.get(item.group)
muteItem.cron = item.cron
}
} else {
noitem.nocron = noitem.cron
delete noitem.cron
MuteList.push(noitem)
if (!taskGroups.has(item.group)) {
const data = { ...item }
data.nocron = data.cron
delete data.cron
taskGroups.set(item.group, { ...item })
} else {
const muteItem = taskGroups.get(item.group)
muteItem.nocron = item.cron
}
}
})
return MuteList.map(item => {
let analysis = item.name.match(RegEx)
return [
segment.image(`https://p.qlogo.cn/gh/${analysis[2]}/${analysis[2]}/100`),
`\n群号:${analysis[2]}`,
item.cron ? `\n禁言时间:"${item.cron}"` : "",
item.nocron ? `\n解禁时间:"${item.nocron}"` : ""
]
})
}
console.log(taskGroups)
const result = []
for (const [ group, item ] of taskGroups) {
const imageSegment = segment.image(`https://p.qlogo.cn/gh/${group}/${group}/100`)
result.push([
imageSegment,
`\n群号:${group}`,
item.cron ? `\n禁言时间:"${item.cron}"` : "",
item.nocron ? `\n解禁时间:"${item.nocron}"` : ""
])
}
return result
}
/**

View File

@@ -2,11 +2,15 @@ import fs from "fs"
import _ from "lodash"
import os from "os"
import path from "path"
import loader from "../../../../lib/plugins/loader.js"
import { Version } from "../../components/index.js"
import { formatDuration } from "../../tools/index.js"
import { osInfo, si } from "./utils.js"
let loader = null
try {
loader = (await import("../../../../lib/plugins/loader.js")).default
} catch {
}
export default function otherInfo(e) {
let otherInfo = []
// 其他信息
@@ -48,9 +52,12 @@ function getPluginNum(e) {
?.filter(item => item.endsWith(".js"))
?.length
const pluginsStr = `${plugins ?? 0} plugins | ${js ?? 0} js`
const { priority, task } = loader
const loaderStr = `${priority?.length} fnc | ${task?.length} task`
return e.isPro ? `${pluginsStr} | ${loaderStr}` : pluginsStr
if (loader && e.isPro) {
const { priority, task } = loader
const loaderStr = `${priority?.length} fnc | ${task?.length} task`
return `${pluginsStr} | ${loaderStr}`
}
return pluginsStr
}
export async function getCopyright() {