modify
This commit is contained in:
36
README.en.md
36
README.en.md
@@ -1,36 +0,0 @@
|
||||
# Yenai-Plugin
|
||||
|
||||
#### Description
|
||||
适用于Yunzai-Botv3的plugin
|
||||
|
||||
#### Software Architecture
|
||||
Software architecture description
|
||||
|
||||
#### Installation
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### Instructions
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### Contribution
|
||||
|
||||
1. Fork the repository
|
||||
2. Create Feat_xxx branch
|
||||
3. Commit your code
|
||||
4. Create Pull Request
|
||||
|
||||
|
||||
#### Gitee Feature
|
||||
|
||||
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
|
||||
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
|
||||
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
|
||||
4. The most valuable open source project [GVP](https://gitee.com/gvp)
|
||||
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
|
||||
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
91
apps/curve.js
Normal file
91
apps/curve.js
Normal file
@@ -0,0 +1,91 @@
|
||||
import plugin from '../../../lib/plugins/plugin.js'
|
||||
import gsCfg from '../../genshin/model/gsCfg.js'
|
||||
import { segment } from 'oicq'
|
||||
import fs from 'node:fs'
|
||||
import common from '../../../lib/common/common.js'
|
||||
let image;
|
||||
export class curve extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
name: 'nga收益曲线',
|
||||
dsc: '收益曲线',
|
||||
event: 'message',
|
||||
priority: 500,
|
||||
rule: [
|
||||
{
|
||||
reg: '^#*(.*)收益曲线(帮助)?$',
|
||||
fnc: 'curve'
|
||||
},
|
||||
]
|
||||
})
|
||||
this.path = './plugins/yenai-plugin/resources/curveimg'
|
||||
this.json = './plugins/yenai-plugin/config/curve.json'
|
||||
|
||||
}
|
||||
//初始化
|
||||
async init() {
|
||||
if (!fs.existsSync(this.path)) {
|
||||
fs.mkdirSync(this.path)
|
||||
}
|
||||
}
|
||||
|
||||
async curve() {
|
||||
let role = {}
|
||||
if (/#?收益曲线帮助/.test(this.e.msg)) role.name = "帮助"
|
||||
else role = gsCfg.getRole(this.e.msg, '收益曲线')
|
||||
|
||||
if (!role) return
|
||||
|
||||
|
||||
/** 主角特殊处理 */
|
||||
if (['10000005', '10000007', '20000000'].includes(String(role.roleId))) {
|
||||
if (!['风主', '岩主', '雷主', '草主'].includes(role.alias)) {
|
||||
await this.e.reply('请选择:风主收益曲线、岩主收益曲线、雷主收益曲线、草主收益曲线')
|
||||
return
|
||||
} else {
|
||||
role.name = role.alias
|
||||
}
|
||||
}
|
||||
|
||||
image = await fs.promises
|
||||
.readFile(this.json, 'utf8')
|
||||
.then((data) => {
|
||||
return JSON.parse(data)
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error('读取失败')
|
||||
console.error(err)
|
||||
return false
|
||||
})
|
||||
|
||||
if (!image[role.name]) return this.e.reply("暂时无该角色收益曲线~>_<")
|
||||
|
||||
this.imgPath = `${this.path}/${role.name}.png`
|
||||
|
||||
if (!fs.existsSync(this.imgPath)) {
|
||||
await this.getImg(role.name)
|
||||
}
|
||||
|
||||
|
||||
if (fs.existsSync(this.imgPath)) {
|
||||
await this.e.reply(segment.image(this.imgPath));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//下载图片
|
||||
async getImg(name) {
|
||||
logger.mark(`${this.e.logFnc} 下载${name}素材图`)
|
||||
|
||||
if (!await common.downFile(image[name], this.imgPath)) {
|
||||
return false
|
||||
}
|
||||
|
||||
logger.mark(`${this.e.logFnc} 下载${name}素材成功`)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
49
apps/help.js
Normal file
49
apps/help.js
Normal file
@@ -0,0 +1,49 @@
|
||||
import plugin from '../../../lib/plugins/plugin.js'
|
||||
import { segment } from 'oicq'
|
||||
|
||||
export class Help extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
name: '帮助',
|
||||
dsc: '通知帮助',
|
||||
event: 'message',
|
||||
priority: 5000,
|
||||
rule: [
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#?通知帮助$',
|
||||
/** 执行方法 */
|
||||
fnc: 'help'
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 帮助
|
||||
async help() {
|
||||
let msg = [
|
||||
segment.image('https://api.ixiaowai.cn/api/api.php'),
|
||||
'通知帮助 by 超市椰羊\n',
|
||||
'---------------------\n',
|
||||
'#闪照通知 (开启|关闭)\n',
|
||||
'#禁言通知 (开启|关闭)\n',
|
||||
'#群撤回通知 (开启|关闭)\n',
|
||||
'#群消息通知 (开启|关闭)\n',
|
||||
'#群邀请通知 (开启|关闭)\n',
|
||||
'#好友撤回通知 (开启|关闭)\n',
|
||||
'#好友消息通知 (开启|关闭)\n',
|
||||
'#好友申请通知 (开启|关闭)\n',
|
||||
'#全部管理通知 (开启|关闭)\n',
|
||||
'#群临时消息通知 (开启|关闭)\n',
|
||||
'#群管理变动通知 (开启|关闭)\n',
|
||||
'#群成员变动通知 (开启|关闭)\n',
|
||||
'#好友列表变动通知 (开启|关闭)\n',
|
||||
'#群聊列表变动通知 (开启|关闭)\n',
|
||||
'#设置删除缓存时间 <时间>(s)\n',
|
||||
'#查看通知设置\n',
|
||||
'#刷新通知设置'
|
||||
]
|
||||
this.e.reply(msg)
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,8 @@
|
||||
/*
|
||||
* @作者: 超市椰羊(746659424)
|
||||
* @介绍: 提供账号的一些事件通知,如:闪照,撤回,好友申请,群邀请,群|好友列表变动...
|
||||
* @使用: 可用 "通知帮助" 来查看指令
|
||||
* @可用指令来开启或关闭某项功能 或 直接修改配置文件(生成在当前文件夹下可参考655行的注释来修改配置文件)修改后重启或用指令来刷新配置
|
||||
*/
|
||||
import plugin from '../../lib/plugins/plugin.js'
|
||||
import plugin from '../../../lib/plugins/plugin.js'
|
||||
import { segment } from 'oicq'
|
||||
import cfg from '../../lib/config/config.js'
|
||||
import common from '../../lib/common/common.js'
|
||||
import fs from 'fs'
|
||||
import cfg from '../../../lib/config/config.js'
|
||||
import common from '../../../lib/common/common.js'
|
||||
import xcfg from "../model/Config"
|
||||
|
||||
let config = {}
|
||||
|
||||
@@ -27,6 +21,11 @@ export class Friends extends plugin {
|
||||
event: 'notice.friend',
|
||||
priority: 5000
|
||||
})
|
||||
this.configpath = './plugins/yenai-plugin/config/config.json'
|
||||
}
|
||||
|
||||
async init() {
|
||||
config = await xcfg.getread(this.configpath)
|
||||
}
|
||||
|
||||
async accept(e) {
|
||||
@@ -756,176 +755,7 @@ export class anotice extends plugin {
|
||||
.catch((err) => e.reply(`❎ 发送失败\n错误信息为:${err.message}`))
|
||||
}
|
||||
}
|
||||
export class NewConfig extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
name: '配置',
|
||||
dsc: '配置文件',
|
||||
event: 'message',
|
||||
priority: 5000,
|
||||
rule: [
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#?(.*)通知(开启|关闭)$',
|
||||
/** 执行方法 */
|
||||
fnc: 'Config_manage'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#?设置删除缓存时间(.*)$',
|
||||
/** 执行方法 */
|
||||
fnc: 'Config_deltime'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#?通知帮助$',
|
||||
/** 执行方法 */
|
||||
fnc: 'help'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#?查看通知设置$',
|
||||
/** 执行方法 */
|
||||
fnc: 'SeeConfig'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#?刷新通知设置$',
|
||||
/** 执行方法 */
|
||||
fnc: 'SeeConfig'
|
||||
}
|
||||
]
|
||||
})
|
||||
this.path = './plugins/example/通知配置'
|
||||
this.configpath = './plugins/example/通知配置/config.json'
|
||||
}
|
||||
|
||||
// 初始化
|
||||
async init() {
|
||||
if (!fs.existsSync(this.path)) {
|
||||
fs.mkdirSync(this.path)
|
||||
}
|
||||
// 检测有无配置文件,没有就创建默认配置文件
|
||||
if (!fs.existsSync(this.configpath)) {
|
||||
let configs = {
|
||||
privateMessage: true, // 好友消息
|
||||
groupMessage: false, // 群|讨论组消息(不建议开启)
|
||||
grouptemporaryMessage: true, // 群临时消息
|
||||
groupRecall: true, // 群撤回
|
||||
PrivateRecall: true, // 好友撤回
|
||||
// 申请通知
|
||||
friendRequest: true, // 好友申请
|
||||
groupInviteRequest: true, // 群邀请
|
||||
// 信息变动
|
||||
groupAdminChange: true, // 群管理变动
|
||||
// 列表变动
|
||||
friendNumberChange: true, // 好友列表变动
|
||||
groupNumberChange: true, // 群聊列表变动
|
||||
groupMemberNumberChange: false, // 群成员变动
|
||||
// 其他通知
|
||||
flashPhoto: true, // 闪照
|
||||
botBeenBanned: true, // 机器人被禁言
|
||||
// 是否给全部管理发送通知(默认只通知第一个管理)
|
||||
notificationsAll: false,
|
||||
// 设置删除消息缓存的时间单位s(用于撤回监听)
|
||||
deltime: 600 // 不建议太大
|
||||
}
|
||||
await getwrite(this.configpath, configs)
|
||||
}
|
||||
// 读取配置
|
||||
config = await getread(this.configpath)
|
||||
}
|
||||
|
||||
// 帮助
|
||||
async help() {
|
||||
let msg = [
|
||||
segment.image('https://api.ixiaowai.cn/api/api.php'),
|
||||
'通知帮助 by 超市椰羊\n',
|
||||
'---------------------\n',
|
||||
'#闪照通知 (开启|关闭)\n',
|
||||
'#禁言通知 (开启|关闭)\n',
|
||||
'#群撤回通知 (开启|关闭)\n',
|
||||
'#群消息通知 (开启|关闭)\n',
|
||||
'#群邀请通知 (开启|关闭)\n',
|
||||
'#好友撤回通知 (开启|关闭)\n',
|
||||
'#好友消息通知 (开启|关闭)\n',
|
||||
'#好友申请通知 (开启|关闭)\n',
|
||||
'#全部管理通知 (开启|关闭)\n',
|
||||
'#群临时消息通知 (开启|关闭)\n',
|
||||
'#群管理变动通知 (开启|关闭)\n',
|
||||
'#群成员变动通知 (开启|关闭)\n',
|
||||
'#好友列表变动通知 (开启|关闭)\n',
|
||||
'#群聊列表变动通知 (开启|关闭)\n',
|
||||
'#设置删除缓存时间 <时间>(s)\n',
|
||||
'#查看通知设置\n',
|
||||
'#刷新通知设置'
|
||||
]
|
||||
this.e.reply(msg)
|
||||
}
|
||||
|
||||
// 更改配置
|
||||
async Config_manage(e) {
|
||||
this.init()
|
||||
if (!e.isMaster) return
|
||||
// 解析消息
|
||||
let index = e.msg.indexOf('通知')
|
||||
let option = e.msg.slice(0, index)
|
||||
option = option.replace(/#/, '').trim()
|
||||
// 开启还是关闭
|
||||
let yes = false
|
||||
if (/开启/.test(e.msg)) yes = true
|
||||
// 回复
|
||||
if (await getcfg(option, yes)) {
|
||||
e.reply(`✅ 已${yes ? '开启' : '关闭'}${option}通知`)
|
||||
}
|
||||
}
|
||||
|
||||
// 设置删除缓存时间
|
||||
async Config_deltime(e) {
|
||||
this.init()
|
||||
if (!e.isMaster) return
|
||||
|
||||
let time = e.msg.replace(/#|设置删除缓存时间/, '').trim()
|
||||
|
||||
time = time.match(/\d*/g)
|
||||
|
||||
if (!time) return e.reply('❎ 请输入正确的时间(单位s)')
|
||||
|
||||
if (time < 120) return e.reply('❎ 时间不能小于两分钟')
|
||||
|
||||
if (await getcfg('缓存时间', Number(time))) {
|
||||
e.reply(`✅ 已设置删除缓存时间为${getsecond(time)}`)
|
||||
}
|
||||
}
|
||||
|
||||
async SeeConfig() {
|
||||
this.init()
|
||||
|
||||
if (/刷新通知设置/.test(this.e.msg)) {
|
||||
config = await getread(this.configpath)
|
||||
await this.e.reply('✅ 已刷新,当前的设置为:')
|
||||
}
|
||||
|
||||
let msg = [
|
||||
`闪照 ${config.flashPhoto ? '✅' : '❎'}\n`,
|
||||
`禁言 ${config.botBeenBanned ? '✅' : '❎'}\n`,
|
||||
`群消息 ${config.groupMessage ? '✅' : '❎'}\n`,
|
||||
`群撤回 ${config.groupRecall ? '✅' : '❎'}\n`,
|
||||
`群邀请 ${config.groupInviteRequest ? '✅' : '❎'}\n`,
|
||||
`好友消息 ${config.privateMessage ? '✅' : '❎'}\n`,
|
||||
`好友撤回 ${config.PrivateRecall ? '✅' : '❎'}\n`,
|
||||
`好友申请 ${config.friendRequest ? '✅' : '❎'}\n`,
|
||||
`群成员变动 ${config.groupMemberNumberChange ? '✅' : '❎'}\n`,
|
||||
`群管理变动 ${config.groupAdminChange ? '✅' : '❎'}\n`,
|
||||
`群临时消息 ${config.grouptemporaryMessage ? '✅' : '❎'}\n`,
|
||||
`好友列表变动 ${config.friendNumberChange ? '✅' : '❎'}\n`,
|
||||
`群聊列表变动 ${config.groupNumberChange ? '✅' : '❎'}\n`,
|
||||
`全部管理发送 ${config.notificationsAll ? '✅' : '❎'}\n`,
|
||||
`删除缓存时间:${config.deltime}`
|
||||
]
|
||||
await this.e.reply(msg)
|
||||
}
|
||||
}
|
||||
|
||||
/** 发消息 */
|
||||
async function getSend(msg) {
|
||||
@@ -992,67 +822,4 @@ function getsecond(value) {
|
||||
result = parseInt(hourTime) + '小时' + result
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/** 读取文件 */
|
||||
async function getread(path) {
|
||||
return await fs.promises
|
||||
.readFile(path, 'utf8')
|
||||
.then((data) => {
|
||||
return JSON.parse(data)
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error('读取失败')
|
||||
console.error(err)
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
/** 写入文件 */
|
||||
async function getwrite(path, cot) {
|
||||
return await fs.promises
|
||||
.writeFile(path, JSON.stringify(cot, '', '\t'))
|
||||
.then(() => {
|
||||
return true
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error('写入失败')
|
||||
console.error(err)
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
async function getcfg(key, value) {
|
||||
// 路径
|
||||
let path = './plugins/example/通知配置/config.json'
|
||||
// 配置类
|
||||
const parameter = {
|
||||
好友消息: 'privateMessage',
|
||||
群消息: 'groupMessage',
|
||||
群临时消息: 'grouptemporaryMessage',
|
||||
群撤回: 'groupRecall',
|
||||
好友撤回: 'PrivateRecall',
|
||||
好友申请: 'friendRequest',
|
||||
群邀请: 'groupInviteRequest',
|
||||
群管理变动: 'groupAdminChange',
|
||||
好友列表变动: 'friendNumberChange',
|
||||
群聊列表变动: 'groupNumberChange',
|
||||
群成员变动: 'groupMemberNumberChange',
|
||||
闪照: 'flashPhoto',
|
||||
禁言: 'botBeenBanned',
|
||||
全部管理: 'notificationsAll',
|
||||
缓存时间: 'deltime'
|
||||
}
|
||||
// 判断是否有这一项类
|
||||
if (!parameter.hasOwnProperty(key)) return false
|
||||
// 读取配置
|
||||
let cfg = await getread(path)
|
||||
// 更改配置
|
||||
cfg[parameter[key]] = value
|
||||
// 写入
|
||||
await getwrite(path, cfg)
|
||||
// 刷新
|
||||
config = await getread(path)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* @作者: 超市椰羊(746659424)
|
||||
* @介绍:
|
||||
*/
|
||||
import { segment } from "oicq"
|
||||
|
||||
//由于oicq不加好友点不上赞
|
||||
/**没加好友回复 */
|
||||
let notFriend = "不加好友不点🙄"
|
||||
/** 点赞成功回复 n是点赞数 普通用户为 10,svip 为 20*/
|
||||
let success = "给你点了[n]下哦,记得回我~"
|
||||
/** 点赞失败的回复(一般是点赞上限) */
|
||||
let failds = "今天点过了,害搁这讨赞呐";
|
||||
/**是否需要要回复的图片*/
|
||||
let picture = true
|
||||
|
||||
export class example extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
/** 功能名称 */
|
||||
name: '点赞插件',
|
||||
/** 功能描述 */
|
||||
dsc: '给自己资料卡点赞',
|
||||
/** https://oicqjs.github.io/oicq/#events */
|
||||
event: 'message',
|
||||
/** 优先级,数字越小等级越高 */
|
||||
priority: 5000,
|
||||
rule: [
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^(我要|给我)?(资料卡)?(点赞|赞我)$',
|
||||
/** 执行方法 */
|
||||
fnc: 'zan'
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
async zan(e) {
|
||||
|
||||
/**判断是否为好友 */
|
||||
let isFriend = await Bot.fl.get(e.user_id)
|
||||
if (!isFriend) return e.reply(notFriend, true)
|
||||
|
||||
/** 点赞成功回复的图片*/
|
||||
let imgs = [
|
||||
"https://xiaobai.klizi.cn/API/ce/zan.php?qq=",
|
||||
"https://xiaobapi.top/api/xb/api/bixin.php?qq=",
|
||||
"https://xiaobapi.top/api/xb/api/zan.php?qq="]
|
||||
/** 一个随机数 */
|
||||
let random = Math.floor(Math.random() * (imgs.length - 0))
|
||||
let success_img = segment.image(imgs[random] + e.user_id)
|
||||
|
||||
|
||||
/** 点赞失败的图片 */
|
||||
let failds_img = segment.image(`https://xiaobai.klizi.cn/API/ce/paa.php?qq=${e.user_id}`)
|
||||
|
||||
|
||||
/** 执行点赞*/
|
||||
let n = 0;
|
||||
while (true) {
|
||||
let res = await Bot.sendLike(e.user_id, 10)
|
||||
if (!res) {
|
||||
break;
|
||||
} else {
|
||||
n += 10;
|
||||
}
|
||||
}
|
||||
|
||||
let success_ = success.replace(/\[n]/g, String(n))
|
||||
let success_result = ""
|
||||
let failds_result = ""
|
||||
if (picture) {
|
||||
success_result = ["\n", success_, success_img]
|
||||
failds_result = ["\n", failds, failds_img]
|
||||
} else {
|
||||
success_result = "\b" + success_
|
||||
failds_result = "\b" + failds
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**判断点赞是否成功*/
|
||||
let msg = n > 0 ? success_result : failds_result
|
||||
/**回复 */
|
||||
e.reply(msg, false, { at: true })
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
871
apps/小助手.js
871
apps/小助手.js
@@ -1,871 +0,0 @@
|
||||
/*
|
||||
* @作者: 超市椰羊(746659424)
|
||||
* @介绍: 提供一些对机器人的远程操作 可使用 "助手帮助" 查看命令
|
||||
*/
|
||||
|
||||
import plugin from '../../lib/plugins/plugin.js';
|
||||
import { segment } from "oicq";
|
||||
import fetch from 'node-fetch';
|
||||
import cfg from '../../lib/config/config.js';
|
||||
let Qzonedetermine;
|
||||
let groupPhotoid;
|
||||
|
||||
export class example extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
name: '小助手',
|
||||
dsc: '远程对机器人进行一些操作',
|
||||
event: 'message',
|
||||
priority: 5000,
|
||||
rule: [
|
||||
{
|
||||
reg: '^#?助手帮助$',
|
||||
fnc: 'help'
|
||||
},
|
||||
{
|
||||
reg: '^#?改头像.*$',
|
||||
fnc: 'Photo'
|
||||
},
|
||||
{
|
||||
reg: '^#?改昵称.*$',
|
||||
fnc: 'Myname'
|
||||
},
|
||||
{
|
||||
reg: '^#?改签名.*$',
|
||||
fnc: 'Sign'
|
||||
},
|
||||
{
|
||||
reg: '^#?改状态.*$',
|
||||
fnc: 'State'
|
||||
},
|
||||
{
|
||||
reg: '^#?发好友.*$',
|
||||
fnc: 'Friends'
|
||||
},
|
||||
{
|
||||
reg: '^#?发群聊.*$',
|
||||
fnc: 'Groupmsg'
|
||||
},
|
||||
{
|
||||
reg: '^#?退群.*$',
|
||||
fnc: 'Quit'
|
||||
},
|
||||
{
|
||||
reg: '^#?删好友.*$',
|
||||
fnc: 'Deletes'
|
||||
},
|
||||
{
|
||||
reg: '^#?改性别.*$',
|
||||
fnc: 'Sex'
|
||||
},
|
||||
{
|
||||
reg: '^#?取直链.*$',
|
||||
fnc: 'Picture'
|
||||
},
|
||||
{
|
||||
reg: '^#?取face.*$',
|
||||
fnc: 'Face'
|
||||
},
|
||||
{
|
||||
reg: '^#?查(Q|q)绑.*$',
|
||||
fnc: 'Qbang'
|
||||
},
|
||||
{
|
||||
reg: '^#?取说说列表.*$',
|
||||
fnc: 'Qzonelist'
|
||||
},
|
||||
{
|
||||
reg: '^#?删说说.*$',
|
||||
fnc: 'Qzonedel'
|
||||
},
|
||||
{
|
||||
reg: '^#?发说说.*$',
|
||||
fnc: 'Qzonesay'
|
||||
},
|
||||
{
|
||||
reg: '^#?(清空说说|清空留言)$',
|
||||
fnc: 'QzoneEmpty'
|
||||
},
|
||||
{
|
||||
reg: '^#?改群名片.*$',
|
||||
fnc: 'MyGroupname'
|
||||
},
|
||||
{
|
||||
reg: '^#?改群头像.*$',
|
||||
fnc: 'GroupPhoto'
|
||||
},
|
||||
{
|
||||
reg: '^#?改群昵称.*$',
|
||||
fnc: 'Groupname'
|
||||
},
|
||||
{
|
||||
reg: '^#?获取(群|好友)列表$',
|
||||
fnc: 'Grouplist'
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
//帮助
|
||||
async help(e) {
|
||||
let msg = [
|
||||
segment.image("https://api.ixiaowai.cn/api/api.php"),
|
||||
"小助手 by 超市椰羊 \n",
|
||||
"--------------------\n",
|
||||
"#发群聊 <群号> <内容> \n",
|
||||
"#发好友 <QQ> <内容> \n",
|
||||
"#改头像 <图片> \n",
|
||||
"#改状态 <状态> \n",
|
||||
"#改昵称 <昵称> \n",
|
||||
"#改签名 <签名> \n",
|
||||
"#改性别 <性别> \n",
|
||||
"#改群名片 <名片> \n",
|
||||
"#改群昵称 <昵称> \n",
|
||||
"#改群头像 <图片> \n",
|
||||
"#删好友 <QQ> \n",
|
||||
"#退群 <群号> \n",
|
||||
"#获取群列表\n",
|
||||
"#获取好友列表\n",
|
||||
"#取说说列表 <页数> \n",
|
||||
"#发说说 <内容> \n",
|
||||
"#删说说 <序号>\n",
|
||||
"#清空说说\n",
|
||||
"#清空留言\n",
|
||||
"#取直链 <图片>\n",
|
||||
"#取face <face表情>",
|
||||
"#查Q绑 <QQ>"
|
||||
]
|
||||
e.reply(msg);
|
||||
}
|
||||
|
||||
/**改头像*/
|
||||
async Photo(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
if (!e.img) {
|
||||
this.setContext('Photos')
|
||||
e.reply("✳️ 请发送图片");
|
||||
return;
|
||||
}
|
||||
|
||||
await Bot.setAvatar(e.img[0])
|
||||
.then(() => { e.reply("✅ 头像修改成功") })
|
||||
.catch((err) => {
|
||||
e.reply("❎ 头像修改失败");
|
||||
console.log(err);
|
||||
})
|
||||
|
||||
}
|
||||
async Photos() {
|
||||
let img = this.e.img
|
||||
if (this.e.msg === "取消") {
|
||||
this.finish('Photos')
|
||||
await this.reply('✅ 已取消')
|
||||
return;
|
||||
}
|
||||
if (!img) {
|
||||
this.setContext('Photos')
|
||||
await this.reply('❎ 请发送图片或取消')
|
||||
return;
|
||||
}
|
||||
await Bot.setAvatar(img[0])
|
||||
.then(() => this.e.reply("✅ 头像修改成功"))
|
||||
.catch((err) => {
|
||||
this.e.reply("❎ 头像修改失败");
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
this.finish('Photos')
|
||||
}
|
||||
|
||||
/** 改昵称*/
|
||||
async Myname(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
let name = e.msg.replace(/#|改昵称/g, "").trim()
|
||||
|
||||
await Bot.setNickname(name)
|
||||
.then(() => e.reply("✅ 昵称修改成功"))
|
||||
.catch((err) => {
|
||||
e.reply("❎ 昵称修改失败");
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
|
||||
/** 改群名片 */
|
||||
async MyGroupname(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
|
||||
let group = '';
|
||||
let card = '';
|
||||
|
||||
if (e.isPrivate) {
|
||||
let msg = e.msg.split(" ")
|
||||
|
||||
group = msg[1].match(/[1-9]\d*/g);
|
||||
|
||||
card = msg.slice(2).join(" ");
|
||||
|
||||
if (!group) return e.reply("❎ 群号不能为空");
|
||||
|
||||
if (!Bot.gl.get(Number(msg[1]))) return e.reply("❎ 群聊列表查无此群");
|
||||
|
||||
} else {
|
||||
group = e.group_id;
|
||||
card = e.msg.replace(/#|改群名片/g, "").trim()
|
||||
}
|
||||
|
||||
if (!card) return e.reply("❎ 名片不能为空");
|
||||
|
||||
Bot.pickGroup(group).setCard(cfg.qq, card)
|
||||
.then(() => e.reply("✅ 群名片修改成功"))
|
||||
.catch(err => {
|
||||
e.reply("✅ 群名片修改失败")
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
|
||||
/**改群头像 */
|
||||
async GroupPhoto(e) {
|
||||
if (e.isPrivate) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
groupPhotoid = e.msg.replace(/#|改群头像/g, "").trim()
|
||||
|
||||
if (!groupPhotoid) return e.reply("❎ 群号不能为空");
|
||||
|
||||
if (!(/^\d+$/.test(groupPhotoid))) return e.reply("❎ 您的群号不合法");
|
||||
|
||||
if (!Bot.gl.get(Number(groupPhotoid))) return e.reply("❎ 群聊列表查无此群");
|
||||
} else {
|
||||
//判断身份
|
||||
if (e.member.is_admin || e.member.is_owner || e.isMaster) {
|
||||
groupPhotoid = e.group_id
|
||||
} else {
|
||||
return e.reply(["哼~你不是管理员人家不听你的", segment.face(231)])
|
||||
}
|
||||
}
|
||||
groupPhotoid = Number(groupPhotoid);
|
||||
|
||||
if (Bot.pickGroup(groupPhotoid).is_admin || Bot.pickGroup(groupPhotoid).is_owner) {
|
||||
if (!e.img) {
|
||||
this.setContext('picture')
|
||||
e.reply("✳️ 请发送图片");
|
||||
return;
|
||||
}
|
||||
|
||||
Bot.pickGroup(groupPhotoid).setAvatar(e.img[0])
|
||||
.then(() => e.reply("✅ 群头像修改成功"))
|
||||
.catch((err) => {
|
||||
e.reply("✅ 群头像修改失败")
|
||||
console.log(err);
|
||||
})
|
||||
} else {
|
||||
return e.reply("❎ 没有管理员人家做不到啦~>_<");
|
||||
}
|
||||
}
|
||||
|
||||
picture() {
|
||||
let img = this.e.img
|
||||
if (this.e.msg === "取消") {
|
||||
this.finish('picture')
|
||||
this.e.reply('✅ 已取消')
|
||||
return;
|
||||
}
|
||||
if (!img) {
|
||||
this.setContext('picture')
|
||||
this.e.reply('❎ 请发送图片或取消')
|
||||
return;
|
||||
}
|
||||
Bot.pickGroup(groupPhotoid).setAvatar(this.e.img[0])
|
||||
.then(() => this.e.reply("✅ 群头像修改成功"))
|
||||
.catch((err) => {
|
||||
this.e.reply("✅ 群头像修改失败")
|
||||
console.log(err);
|
||||
})
|
||||
|
||||
this.finish('picture')
|
||||
}
|
||||
|
||||
/**改群昵称 */
|
||||
async Groupname(e) {
|
||||
let group = '';
|
||||
let card = '';
|
||||
|
||||
if (e.isPrivate) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
let msg = e.msg.split(" ")
|
||||
|
||||
group = msg[1].match(/[1-9]\d*/g);
|
||||
|
||||
card = msg.slice(2).join(" ");
|
||||
|
||||
if (!group) return e.reply("❎ 群号不能为空");
|
||||
|
||||
if (!Bot.gl.get(Number(msg[1]))) return e.reply("❎ 群聊列表查无此群");
|
||||
|
||||
} else {
|
||||
if (e.member.is_admin || e.member.is_owner || e.isMaster) {
|
||||
group = e.group_id
|
||||
card = e.msg.replace(/#|改群昵称/g, "").trim()
|
||||
} else {
|
||||
return e.reply(["哼~你不是管理员人家不听你的", segment.face(231)])
|
||||
}
|
||||
}
|
||||
|
||||
if (!card) return e.reply("❎ 昵称不能为空");
|
||||
|
||||
group = Number(group);
|
||||
|
||||
if (Bot.pickGroup(group).is_admin || Bot.pickGroup(group).is_owner) {
|
||||
Bot.pickGroup(group).setName(card)
|
||||
.then(() => e.reply("✅ 群昵称修改成功"))
|
||||
.catch(err => {
|
||||
e.reply("✅ 群昵称修改失败")
|
||||
console.log(err);
|
||||
})
|
||||
} else {
|
||||
return e.reply("❎ 没有管理员人家做不到啦~>_<");
|
||||
}
|
||||
}
|
||||
|
||||
/** 改签名*/
|
||||
async Sign(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
let signs = e.msg.replace(/#|改签名/g, "").trim()
|
||||
await Bot.setSignature(signs)
|
||||
.then(() => e.reply("✅ 签名修改成功"))
|
||||
.catch((err) => {
|
||||
e.reply("❎ 签名修改失败");
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
/** 改状态*/
|
||||
async State(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
let signs = e.msg.replace(/#|改状态/g, "").trim()
|
||||
|
||||
if (!signs) return e.reply("❎ 状态不为空,可选值:我在线上,离开,隐身,忙碌,Q我吧,请勿打扰");
|
||||
|
||||
let res = {
|
||||
"离开": 31,
|
||||
"忙碌": 50,
|
||||
"隐身": 41,
|
||||
"Q我吧": 60,
|
||||
"请勿打扰": 70,
|
||||
"我在线上": 11,
|
||||
}
|
||||
|
||||
let status = {
|
||||
31: "离开",
|
||||
50: "忙碌",
|
||||
70: "请勿打扰",
|
||||
41: "隐身",
|
||||
11: "我在线上",
|
||||
60: "Q我吧",
|
||||
};
|
||||
|
||||
if (!(signs in res)) return e.reply("❎ 可选值:我在线上,离开,隐身,忙碌,Q我吧,请勿打扰")
|
||||
|
||||
await Bot.setOnlineStatus(res[signs])
|
||||
.then(() => e.reply("✅ 在线状态修改成功"))
|
||||
.then(() => e.reply(`✅ 现在的在线状态为【${status[Bot.status]}】`))
|
||||
.catch(err => {
|
||||
e.reply("❎ 在线状态修改失败");
|
||||
console.log(err);
|
||||
})
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 发好友*/
|
||||
async Friends(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
let msgs = e.message[0].text.split(" ")
|
||||
if (msgs.length == 1 && !(/\d/.test(msgs[0]))) return e.reply("❎ QQ号不能为空");
|
||||
let qq
|
||||
if (/\d/.test(msgs[0])) {
|
||||
qq = msgs[0].match(/[1-9]\d*/g)
|
||||
e.message[0].text = msgs.slice(1).join(" ");
|
||||
} else {
|
||||
qq = msgs[1]
|
||||
e.message[0].text = msgs.slice(2).join(" ");
|
||||
}
|
||||
|
||||
if (!/^\d+$/.test(qq)) return e.reply("❎ QQ号不正确,人家做不到的啦>_<~");
|
||||
|
||||
if (!Bot.fl.get(Number(qq))) return e.reply("❎ 好友列表查无此人");
|
||||
|
||||
if (!e.message[0].text) e.message.shift()
|
||||
|
||||
if (e.message.length === 0) return e.reply("❎ 消息不能为空");
|
||||
|
||||
await Bot.pickFriend(qq).sendMsg(e.message)
|
||||
.then(() => e.reply("✅ 私聊消息已送达"))
|
||||
.catch(err => e.reply(`❎ 发送失败\n错误信息为:${err.message}`))
|
||||
|
||||
}
|
||||
|
||||
/** 发群聊*/
|
||||
async Groupmsg(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
let msgs = e.message[0].text.split(" ")
|
||||
|
||||
e.message[0].text = msgs.slice(2).join(" ");
|
||||
|
||||
if (msgs.length < 2) return e.reply("❎ 您输入的指令不合法");
|
||||
|
||||
if (!/^\d+$/.test(msgs[1])) return e.reply("❎ 您输入的群号不合法");
|
||||
|
||||
if (!Bot.gl.get(Number(msgs[1]))) return e.reply("❎ 群聊列表查无此群");
|
||||
|
||||
if (!e.message[0].text) e.message.shift()
|
||||
|
||||
if (e.message.length === 0) return e.reply("❎ 消息不能为空");
|
||||
|
||||
|
||||
await Bot.pickGroup(msgs[1]).sendMsg(e.message)
|
||||
.then(() => e.reply("✅ 群聊消息已送达"))
|
||||
.catch((err) => e.reply(`❎ 发送失败\n错误信息为:${err.message}`))
|
||||
}
|
||||
|
||||
/**退群 */
|
||||
async Quit(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
let quits = e.msg.replace(/#|退群/g, "").trim()
|
||||
|
||||
if (!quits) return e.reply("❎ 群号不能为空");
|
||||
|
||||
if (!/^\d+$/.test(quits)) return e.reply("❎ 群号不合法");
|
||||
|
||||
if (!Bot.gl.get(Number(quits))) return e.reply("❎ 群聊列表查无此群")
|
||||
|
||||
await Bot.pickGroup(quits).quit()
|
||||
.then(() => e.reply(`✅ 已退出群聊`))
|
||||
.catch((err) => {
|
||||
e.reply("❎ 退出失败");
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
/**删好友 */
|
||||
async Deletes(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true)
|
||||
|
||||
let quits = e.msg.replace(/#|删好友/g, "").trim()
|
||||
|
||||
if (e.message[1]) {
|
||||
quits = e.message[1].qq
|
||||
} else {
|
||||
quits = quits.match(/[1-9]\d*/g)
|
||||
}
|
||||
if (!quits) return e.reply("❎ 请输入正确的QQ号")
|
||||
|
||||
if (!Bot.fl.get(Number(quits))) return e.reply("❎ 好友列表查无此人");
|
||||
|
||||
await Bot.pickFriend(quits).delete()
|
||||
.then(() => e.reply(`✅ 已删除好友`))
|
||||
.catch((err) => {
|
||||
e.reply("❎ 删除失败");
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
|
||||
/**改性别 */
|
||||
async Sex(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
let sex = e.msg.replace(/#|改性别/g, "").trim();
|
||||
|
||||
if (!sex) return e.reply("❎ 性别不能为空 可选值:男,女,无\n(改为无,为无性别)");
|
||||
|
||||
let res = {
|
||||
"无": 0,
|
||||
"男": 1,
|
||||
"女": 2,
|
||||
}
|
||||
if (!(sex in res)) return e.reply("❎ 可选值:男,女,无(改为无,为无性别)");
|
||||
|
||||
await Bot.setGender(res[sex])
|
||||
.then(() => e.reply(`✅ 已修改性别`))
|
||||
.catch((err) => {
|
||||
e.reply("❎ 修改失败");
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
|
||||
/**取直链 */
|
||||
async Picture(e) {
|
||||
if (!e.img) {
|
||||
this.setContext('imgs')
|
||||
await this.reply('✳️ 请发送图片')
|
||||
return;
|
||||
}
|
||||
await e.reply(`✅ 检测到${e.img.length}张图片`)
|
||||
for (let i of e.img) {
|
||||
await e.reply([segment.image(i), "直链:", i])
|
||||
}
|
||||
|
||||
}
|
||||
async imgs() {
|
||||
let img = this.e.img
|
||||
if (this.e.msg === "取消") {
|
||||
this.finish('imgs')
|
||||
await this.reply('✅ 已取消')
|
||||
return;
|
||||
}
|
||||
if (!img) {
|
||||
this.setContext('imgs')
|
||||
await this.reply('❎ 请发送图片或取消')
|
||||
return;
|
||||
}
|
||||
await this.e.reply(img[0])
|
||||
this.finish('imgs')
|
||||
}
|
||||
|
||||
/** 取Face表情 */
|
||||
async Face(e) {
|
||||
let face = [];
|
||||
for (let m of e.message) {
|
||||
if (m.type === "face") {
|
||||
let s = false;
|
||||
for (let i of face) { if (i.id === m.id) s = true }
|
||||
if (!s) face.push(m)
|
||||
}
|
||||
}
|
||||
if (face.length === 0) return e.reply("❎ 表情参数不可为空", true);
|
||||
|
||||
let res = face.map(function (item) {
|
||||
return [
|
||||
`表情:`,
|
||||
item,
|
||||
`\nid:${item.id}`,
|
||||
`\n描述:${item.text}`
|
||||
]
|
||||
})
|
||||
|
||||
for (let i of res) {
|
||||
await e.reply(i)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** 查Q绑 */
|
||||
async Qbang(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
let qq = e.message[0].text.replace(/#|查(Q|q)绑/g, "").trim()
|
||||
|
||||
if (e.message[1]) {
|
||||
qq = e.message[1].qq
|
||||
} else {
|
||||
qq = qq.match(/[1-9]\d*/g)
|
||||
}
|
||||
|
||||
if (!qq) return e.reply("❎ 请输入正确的QQ号")
|
||||
|
||||
|
||||
let qbang = await fetch(`https://zy.xywlapi.cc/qqapi?qq=${qq}`).then(res => res.json()).catch(err => console.log(err))
|
||||
|
||||
let lol = await fetch(`https://api.xywlapi.cc/qqlol?qq=${qq}`).then(res => res.json()).catch(err => console.log(err))
|
||||
|
||||
if (!qbang) return e.reply("❎ 接口查询失败");
|
||||
|
||||
if (qbang.status != 200) {
|
||||
try {
|
||||
e.reply(`❎ 错误信息:${qbang.message}`)
|
||||
} catch {
|
||||
e.reply(`❎ 此QQ号无法查询`)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
let wb = await fetch(`https://api.xywlapi.cc/wbphone?phone=${qbang.phone}`).then(res => res.json()).catch(err => console.log(err))
|
||||
|
||||
let msg = [
|
||||
`🐧:${qbang.qq}\n`,
|
||||
`📱:${qbang.phone}\n`,
|
||||
`🌏:${qbang.phonediqu}`
|
||||
]
|
||||
|
||||
try {
|
||||
if (lol.status == 200) {
|
||||
msg.push(`\nLOL:${lol.name}(${lol.daqu})`)
|
||||
}
|
||||
} catch {
|
||||
console.log(`LOL没有找到`);
|
||||
}
|
||||
|
||||
try {
|
||||
if (wb.status == 200) {
|
||||
msg.push(`\n微博uid:${wb.id}`)
|
||||
}
|
||||
} catch {
|
||||
console.log(`微博没有找到`);
|
||||
}
|
||||
|
||||
let timeout = 600000; //0表示不撤回,单位毫秒
|
||||
let msgRes = await e.reply(msg);
|
||||
if (timeout != 0 && msgRes && msgRes.message_id) {
|
||||
let target = null;
|
||||
if (e.isGroup) {
|
||||
target = e.group;
|
||||
} else {
|
||||
target = e.friend;
|
||||
}
|
||||
if (target != null) {
|
||||
setTimeout(() => {
|
||||
target.recallMsg(msgRes.message_id);
|
||||
target.recallMsg(e.message_id);
|
||||
}, timeout);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**QQ空间 说说列表*/
|
||||
async Qzonelist(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
let res = e.message[0].text.replace(/#|取说说列表/g, "").trim()
|
||||
if (!res) res = 1
|
||||
if (!parseInt(res)) return e.reply(`❎ 请检查页数是否正确`)
|
||||
|
||||
let list = await getlist()
|
||||
list = list.msglist
|
||||
if (!list) return e.reply(`❎ 说说列表为空`)
|
||||
let msg = [
|
||||
"✅ 获取成功,说说列表如下:\n"
|
||||
]
|
||||
let page = 5 * (res - 1)
|
||||
for (let i = 0 + page; i < 5 + page; i++) {
|
||||
if (!list[i]) break
|
||||
let arr = `${i + 1}.${getLimit(list[i].content)}\n- [${list[i].secret ? "私密" : "公开"}] | ${formatDate(list[i].created_time)} | ${list[i].commentlist ? list[i].commentlist.length : 0}条评论\n`
|
||||
msg.push(arr)
|
||||
}
|
||||
if (res > Math.ceil(list.length / 5)) return e.reply(`❎ 页数超过最大值`)
|
||||
msg.push(`页数:[${res}/${Math.ceil(list.length / 5)}]`)
|
||||
e.reply(msg)
|
||||
}
|
||||
|
||||
/** 删除说说 */
|
||||
async Qzonedel(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
let res = e.message[0].text.replace(/#|删说说/g, "").trim()
|
||||
if (!res) return e.reply(`❎ 序号不可为空`)
|
||||
res = res.match(/\d/)
|
||||
if (!res) return e.reply(`❎ 请检查序号是否正确`)
|
||||
|
||||
let list = await getlist()
|
||||
|
||||
if (!list.msglist) return e.reply(`❎ 说说列表为空`)
|
||||
let ck = getck()
|
||||
if ((res - 1) >= list.msglist.length) return e.reply(`❎ 序号超过最大值`)
|
||||
let something = list.msglist[res - 1]
|
||||
|
||||
let url = `https://xiaobai.klizi.cn/API/qqgn/ss_delete.php?data=&uin=${cfg.qq}&skey=${ck.skey}&pskey=${ck.p_skey}&tid=${something.tid}`
|
||||
let result = await fetch(url).then(res => res.text()).catch(err => console.log(err))
|
||||
if (!result) return e.reply(`❎ 接口请求失败`)
|
||||
|
||||
if (/删除说说成功/.test(result)) {
|
||||
e.reply(`✅ 删除说说成功:\n ${res}.${getLimit(something.content)} \n - [${something.secret ? "私密" : "公开"}] | ${formatDate(something.created_time)} | ${something.commentlist ? something.commentlist.length : 0} 条评论`)
|
||||
} else if (/删除失败/.test(result)) {
|
||||
e.reply(`❎ 删除失败`)
|
||||
}
|
||||
}
|
||||
|
||||
/** 发说说 */
|
||||
async Qzonesay(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
let res = e.message[0].text.replace(/#|发说说/g, "").trim()
|
||||
let ck = getck()
|
||||
let url;
|
||||
if (e.img) {
|
||||
url = `https://xiaobai.klizi.cn/API/qqgn/ss_sendimg.php?uin=${cfg.qq}&skey=${ck.skey}&pskey=${ck.p_skey}&url=${e.img[0]}&msg=${res}`
|
||||
} else {
|
||||
url = `http://xiaobai.klizi.cn/API/qqgn/ss_send.php?data=json&uin=${cfg.qq}&skey=${ck.skey}&pskey=${ck.p_skey}&msg=${res}`
|
||||
}
|
||||
let result = await fetch(url).then(res => res.json()).catch(err => console.log(err))
|
||||
let msg = [`✅ 说说发表成功,内容:\n`, getLimit(result.content)]
|
||||
if (result.code != 0) return e.reply(`❎ 说说发表失败\n错误信息:${result.message}`)
|
||||
if (result.pic) {
|
||||
msg.push(segment.image(result.pic[0].url1))
|
||||
}
|
||||
msg.push(`\n- [${result.secret ? "私密" : "公开"}] | ${formatDate(result.t1_ntime)}`)
|
||||
e.reply(msg)
|
||||
}
|
||||
|
||||
/** 清空说说和留言*/
|
||||
async QzoneEmpty(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
if (/清空说说/.test(e.msg)) {
|
||||
this.setContext('QzonedelAll')
|
||||
e.reply("✳️ 即将删除全部说说请发送:\n" + "------确认清空或取消------");
|
||||
Qzonedetermine = true;
|
||||
return true;
|
||||
} else if (/清空留言/.test(e.msg)) {
|
||||
this.setContext('QzonedelAll')
|
||||
e.reply("✳️ 即将删除全部留言请发送:\n" + "------确认清空或取消------");
|
||||
Qzonedetermine = false
|
||||
return true;
|
||||
}
|
||||
}
|
||||
async QzonedelAll() {
|
||||
let msg = this.e.msg
|
||||
if (msg == "确认清空") {
|
||||
this.finish('QzonedelAll')
|
||||
let ck = getck()
|
||||
|
||||
let url
|
||||
if (Qzonedetermine) {
|
||||
url = `https://xiaobai.klizi.cn/API/qqgn/ss_empty.php?data=&uin=${cfg.qq}&skey=${ck.skey}&pskey=${ck.p_skey}`
|
||||
} else {
|
||||
url = `https://xiaobai.klizi.cn/API/qqgn/qzone_emptymsgb.php?data=&uin=${cfg.qq}&skey=${ck.skey}&pskey=${ck.p_skey}`
|
||||
}
|
||||
|
||||
let result = await fetch(url).then(res => res.text()).catch(err => console.log(err))
|
||||
this.e.reply(`✅ ${result}`)
|
||||
return true;
|
||||
|
||||
} else if (msg == "取消") {
|
||||
this.finish('QzonedelAll')
|
||||
this.e.reply("✅ 已取消")
|
||||
return false;
|
||||
} else {
|
||||
this.setContext('QzonedelAll')
|
||||
this.e.reply("❎ 请输入:确认清空或取消")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//获取群|好友列表
|
||||
async Grouplist(e) {
|
||||
if (!e.isMaster) return e.reply("❎ 该命令仅限管理员可用", true);
|
||||
|
||||
let listMap;
|
||||
let message = [];
|
||||
let list = []
|
||||
let yes = false
|
||||
if (/群列表/.test(e.msg)) {
|
||||
//获取群列表并转换为数组
|
||||
listMap = Array.from(Bot.gl.values())
|
||||
//添加有几个群
|
||||
message.push(`群列表如下,共${listMap.length}个群`)
|
||||
//遍历添加
|
||||
listMap.forEach((item, index) => {
|
||||
list.push(`${index + 1}、${item.group_name}(${item.group_id})\n`)
|
||||
})
|
||||
yes = true
|
||||
} else if (/好友列表/.test(e.msg)) {
|
||||
//获取好友列表并转换为数组
|
||||
listMap = Array.from(Bot.fl.values())
|
||||
//添加有多少个好友
|
||||
message.push(`好友列表如下,共${listMap.length}个好友`)
|
||||
//遍历添加
|
||||
listMap.forEach((item, index) => {
|
||||
list.push(`${index + 1}、${item.nickname}(${item.user_id})\n`)
|
||||
})
|
||||
}
|
||||
|
||||
//去除最后一个的换行符
|
||||
list[list.length - 1] = list[list.length - 1].replace(/\n/, "")
|
||||
message.push(list)
|
||||
if (yes) {
|
||||
message.push("可使用 #退群123456789 来退出某群")
|
||||
} else {
|
||||
message.push("可使用 #删好友123456789 来删除某人")
|
||||
}
|
||||
|
||||
//制作转发消息
|
||||
let forwardMsg = []
|
||||
for (let i of message) {
|
||||
forwardMsg.push(
|
||||
{
|
||||
message: i,
|
||||
nickname: Bot.nickname,
|
||||
user_id: Bot.uin
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (e.isGroup) {
|
||||
forwardMsg = await e.group.makeForwardMsg(forwardMsg)
|
||||
} else {
|
||||
forwardMsg = await e.friend.makeForwardMsg(forwardMsg)
|
||||
}
|
||||
|
||||
//发送消息
|
||||
e.reply(forwardMsg)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**字数限制 */
|
||||
function getLimit(str) {
|
||||
let s = str.slice(0, 10)
|
||||
return str.length > 10 ? s + "..." : str
|
||||
}
|
||||
|
||||
/**时间格式化 */
|
||||
function formatDate(time) {
|
||||
var now = new Date(parseFloat(time) * 1000);
|
||||
var month = now.getMonth() + 1;
|
||||
var date = now.getDate();
|
||||
if (month >= 1 && month <= 9) {
|
||||
month = "0" + month;
|
||||
}
|
||||
if (date >= 0 && date <= 9) {
|
||||
date = "0" + date;
|
||||
}
|
||||
var hour = now.getHours();
|
||||
var minute = now.getMinutes();
|
||||
if (hour >= 1 && hour <= 9) {
|
||||
hour = "0" + hour;
|
||||
}
|
||||
if (minute >= 0 && minute <= 9) {
|
||||
minute = "0" + minute;
|
||||
}
|
||||
return month + "/" + date + " " + hour + ":" + minute
|
||||
}
|
||||
|
||||
/**取说说列表*/
|
||||
async function getlist() {
|
||||
let ck = getck()
|
||||
let url = `https://xiaobai.klizi.cn/API/qqgn/ss_list.php?data=json&uin=${cfg.qq}&skey=${ck.skey}&pskey=${ck.p_skey}&qq=${cfg.qq}`
|
||||
let list = await fetch(url).then(res => res.json()).catch(err => console.log(err))
|
||||
|
||||
if (!list) {
|
||||
return e.reply("❎ 取说说列表失败")
|
||||
} else {
|
||||
return list
|
||||
}
|
||||
|
||||
}
|
||||
/**取cookies */
|
||||
function getck() {
|
||||
let cookie = Bot.cookies['qzone.qq.com']
|
||||
let ck = cookie.replace(/=/g, `":"`).replace(/;/g, `","`).replace(/ /g, "").trim()
|
||||
ck = ck.substring(0, ck.length - 2)
|
||||
ck = `{"`.concat(ck).concat("}")
|
||||
return JSON.parse(ck)
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
import fs from 'fs'
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
/**
|
||||
* 在“resources”文件夹下 新建“头像”文件夹把要修改的头像扔进去
|
||||
* 随机修改一个头像文件夹里面的头像,默认每五分钟修改一次
|
||||
*/
|
||||
export class example extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
/** 功能名称 */
|
||||
name: '头像',
|
||||
/** 功能描述 */
|
||||
dsc: '定时随机修改头像',
|
||||
/** https://oicqjs.github.io/oicq/#events */
|
||||
event: 'message',
|
||||
/** 优先级,数字越小等级越高 */
|
||||
priority: 5000,
|
||||
rule: [
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#?换头像$',
|
||||
/** 执行方法 */
|
||||
fnc: 'avatar'
|
||||
}]
|
||||
})
|
||||
/** 定时任务 */
|
||||
this.task = {
|
||||
/**Cron表达式 每五分钟执行一次 */
|
||||
cron: '0 */10 * * * ?',
|
||||
name: '定时随机修改头像',
|
||||
fnc: () => this.avatar()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async avatar() {
|
||||
//项目路径
|
||||
let _path = process.cwd();
|
||||
//头像路径
|
||||
let paths = `${_path}/resources/头像`
|
||||
|
||||
let data;
|
||||
let random;
|
||||
try {
|
||||
//获取头像文件夹下的文件
|
||||
data = fs.readdirSync("././././resources/头像")
|
||||
//随机数
|
||||
random = Math.floor(Math.random() * (data.length - 0)) + 0;
|
||||
} catch { console.log("无头像文件夹"); }
|
||||
|
||||
let url;
|
||||
if (Math.random() > 0.5) {
|
||||
url = await fetch("https://api.uomg.com/api/rand.avatar?sort=动漫女&format=json").then(res => res.json()).then(res => res.imgurl).catch(err => console.log(err))
|
||||
} else {
|
||||
url = "http://api.btstu.cn/sjtx/api.php?lx=c2&format=images"
|
||||
}
|
||||
|
||||
|
||||
//修改头像
|
||||
try {
|
||||
Bot.setAvatar(url).then(() => { logger.mark("[头像]修改网络头像") }).catch(
|
||||
err => {
|
||||
logger.error("[头像]API失效")
|
||||
console.log(err);
|
||||
}
|
||||
)
|
||||
} catch {
|
||||
Bot.setAvatar(`file:///${paths}/${data[random]}`).then(() => { logger.mark("[头像]修改本地头像") }).catch(
|
||||
err => {
|
||||
logger.error("[头像]本地头像报错")
|
||||
console.log(err);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
import plugin from "../../lib/plugins/plugin.js";
|
||||
import fetch from 'node-fetch'
|
||||
import cfg from '../../lib/config/config.js'
|
||||
import common from '../../lib/common/common.js'
|
||||
|
||||
//设置会员参数 (普通、vip、svip)
|
||||
const member = "svip"
|
||||
const myck = {
|
||||
"code": 0,
|
||||
"uin": "746659424",
|
||||
"skey": "@qPj9eqrJZ",
|
||||
"gtk": "1674138517",
|
||||
"pt4token": "s4xN*kb8Bf-7rWDdbtkWVRj-xg5LL3ydX4t7jC6NLTM_",
|
||||
"pskey": "YAfPtfubqFp4-4K0j3KWqb-B-O07H9tpX7eESL30zsw_",
|
||||
"superkey": "vLB8ZIs8Pr*r-zdlZcBYzas5l9fU2ExoG7LQko3d0QQ_",
|
||||
"state": "登录成功!",
|
||||
"name": "超市椰羊"
|
||||
}
|
||||
export class example extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
/** 功能名称 */
|
||||
name: "百变气泡",
|
||||
/** 功能描述 */
|
||||
dsc: "百变气泡",
|
||||
/** https://oicqjs.github.io/oicq/#events */
|
||||
event: "message",
|
||||
/** 优先级,数字越小等级越高 */
|
||||
priority: 5000,
|
||||
rule: [
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: "^换气泡$",
|
||||
/** 执行方法 */
|
||||
fnc: "Changeable",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
/** 定时任务默认每10分钟一次不建议太短 */
|
||||
this.task = {
|
||||
cron: '0 */10 * * * ?',
|
||||
name: '百变气泡',
|
||||
fnc: () => this.Changeable()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async Changeable() {
|
||||
//获取ck
|
||||
let cookie = Bot.cookies['vip.qq.com']
|
||||
let ck = cookie.replace(/=/g, `":"`).replace(/;/g, `","`).replace(/ /g, "").trim()
|
||||
ck = ck.substring(0, ck.length - 2)
|
||||
ck = `{"`.concat(ck).concat("}")
|
||||
ck = JSON.parse(ck)
|
||||
|
||||
|
||||
let url = `http://www.dreamling.xyz/API/QQ/multivariant_bubbles/api.php?uin=${cfg.qq}&skey=${ck.skey}&pskey=${ck.p_skey}&type=text&member=${member}`
|
||||
let result = await fetch(url).then(res => res.text())
|
||||
|
||||
let myurl = `http://www.dreamling.xyz/API/QQ/multivariant_bubbles/api.php?uin=${myck.uin}&skey=${myck.skey}&pskey=${myck.pskey}&type=text&member=${member}`
|
||||
|
||||
let my = await fetch(myurl).then(res => res.text()).catch(common.relpyPrivate(746659424, "ck失效"))
|
||||
|
||||
logger.mark(`[百变气泡] ${result}`)
|
||||
logger.mark(`[百变气泡自己] ${my}`)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
import plugin from '../../lib/plugins/plugin.js'
|
||||
import fetch from 'node-fetch'
|
||||
import { segment } from "oicq";
|
||||
|
||||
export class example extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
/** 功能名称 */
|
||||
name: '随机唱鸭',
|
||||
/** 功能描述 */
|
||||
dsc: '随机唱鸭',
|
||||
/** https://oicqjs.github.io/oicq/#events */
|
||||
event: 'message',
|
||||
/** 优先级,数字越小等级越高 */
|
||||
priority: 5000,
|
||||
rule: [
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^唱歌$',
|
||||
/** 执行方法 */
|
||||
fnc: 'Sing'
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
async Sing(e) {
|
||||
let url = "https://xiaobai.klizi.cn/API/music/changya.php"
|
||||
let res = await fetch(url).catch(err => console.log(err))
|
||||
if (!res) {
|
||||
e.reply("❎ 接口请求失败")
|
||||
return false;
|
||||
}
|
||||
res = await res.json()
|
||||
|
||||
if (res.code != 200) {
|
||||
e.reply("❎ 接口请求错误")
|
||||
return false;
|
||||
}
|
||||
let data = res.data
|
||||
await e.reply(segment.record(data.audioSrc))
|
||||
//处理歌词
|
||||
let lyric = data.lyrics.map(function (item) {
|
||||
return `${item}\n`
|
||||
})
|
||||
lyric[lyric.length - 1] = data.lyrics[data.lyrics.length - 1]
|
||||
await e.reply(lyric)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import fs from 'fs'
|
||||
import lodash from 'lodash'
|
||||
|
||||
const _path = process.cwd()
|
||||
const _cfgPath = `${_path}/plugins/xiaofei-plugin/components/`
|
||||
let cfg = {}
|
||||
|
||||
try {
|
||||
if (fs.existsSync(_cfgPath + 'cfg.json')) {
|
||||
cfg = JSON.parse(fs.readFileSync(_cfgPath + 'cfg.json', 'utf8')) || {}
|
||||
}
|
||||
} catch (e) {
|
||||
// do nth
|
||||
}
|
||||
|
||||
let Cfg = {
|
||||
get (rote, def = '') {
|
||||
return lodash.get(cfg, rote, def)
|
||||
},
|
||||
set (rote, val) {
|
||||
lodash.set(cfg, rote, val)
|
||||
fs.writeFileSync(_cfgPath + 'cfg.json', JSON.stringify(cfg, null, '\t'))
|
||||
},
|
||||
del (rote) {
|
||||
lodash.set(cfg, rote, undefined)
|
||||
fs.writeFileSync(_cfgPath + 'cfg.json', JSON.stringify(cfg, null, '\t'))
|
||||
},
|
||||
scale (pct = 1) {
|
||||
let scale = Cfg.get('sys.scale', 100)
|
||||
scale = Math.min(2, Math.max(0.5, scale / 100))
|
||||
pct = pct * scale
|
||||
return `style=transform:scale(${pct})`
|
||||
},
|
||||
isDisable (e, rote) {
|
||||
if (Cfg.get(rote, true)) {
|
||||
return false
|
||||
}
|
||||
if (/^#*小飞/.test(e.msg || '')) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export default Cfg
|
||||
@@ -1,13 +0,0 @@
|
||||
import Cfg from './Cfg.js'
|
||||
import render from './common-lib/render.js'
|
||||
|
||||
function sleep (ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
export default {
|
||||
render,
|
||||
cfg: Cfg.get,
|
||||
isDisable: Cfg.isDisable,
|
||||
sleep
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
import YAML from 'yaml'
|
||||
import chokidar from 'chokidar'
|
||||
import fs from 'node:fs'
|
||||
|
||||
const Path = process.cwd();
|
||||
const Plugin_Name = 'xiaofei-plugin'
|
||||
const Plugin_Path = `${Path}/plugins/${Plugin_Name}`;
|
||||
class Config {
|
||||
constructor () {
|
||||
this.config = {}
|
||||
|
||||
/** 监听文件 */
|
||||
this.watcher = {}
|
||||
|
||||
this.ignore = []
|
||||
}
|
||||
|
||||
/**
|
||||
* @param app 功能
|
||||
* @param name 配置文件名称
|
||||
*/
|
||||
getdefSet (app, name) {
|
||||
return this.getYaml(app, name, 'defSet')
|
||||
}
|
||||
|
||||
/** 用户配置 */
|
||||
getConfig (app, name) {
|
||||
return this.getYaml(app, name, 'config')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置yaml
|
||||
* @param app 功能
|
||||
* @param name 名称
|
||||
* @param type 默认跑配置-defSet,用户配置-config
|
||||
*/
|
||||
getYaml (app, name, type) {
|
||||
let file = this.getFilePath(app, name, type)
|
||||
let key = `${app}.${name}`
|
||||
|
||||
if (this.config[type][key]) return this.config[type][key]
|
||||
|
||||
try {
|
||||
this.config[type][key] = YAML.parse(
|
||||
fs.readFileSync(file, 'utf8')
|
||||
)
|
||||
} catch (error) {
|
||||
logger.error(`[${app}][${name}] 格式错误 ${error}`)
|
||||
return false
|
||||
}
|
||||
|
||||
this.watch(file, app, name, type)
|
||||
|
||||
return this[type][key]
|
||||
}
|
||||
|
||||
getFilePath (app, name, type) {
|
||||
if(!this.config[type]){
|
||||
this.config[type] = {};
|
||||
}
|
||||
|
||||
if(!this.watcher[type]){
|
||||
this.watcher[type] = {};
|
||||
}
|
||||
|
||||
let config_path = `${Plugin_Path}/${type}/`;
|
||||
let file = `${config_path}${app}.${name}.yaml`;
|
||||
try{
|
||||
if(!fs.existsSync(file)){
|
||||
let default_file = `${config_path}default/${app}.${name}.yaml`;
|
||||
fs.copyFileSync(default_file,file);
|
||||
}
|
||||
}catch(err){}
|
||||
return file;
|
||||
}
|
||||
|
||||
/** 监听配置文件 */
|
||||
watch (file, app, name, type = 'defSet') {
|
||||
let key = `${app}.${name}`
|
||||
|
||||
if (this.watcher[type][key]) return
|
||||
|
||||
const watcher = chokidar.watch(file)
|
||||
watcher.on('change', path => {
|
||||
delete this[type][key]
|
||||
logger.mark(`[修改配置文件][${type}][${app}][${name}]`)
|
||||
if (this[`change_${app}${name}`]) {
|
||||
this[`change_${app}${name}`]()
|
||||
}
|
||||
})
|
||||
|
||||
this.watcher[type][key] = watcher
|
||||
}
|
||||
|
||||
|
||||
save (app, name, type) {
|
||||
let file = this.getFilePath(app, name, type)
|
||||
if (lodash.isEmpty(data)) {
|
||||
fs.existsSync(file) && fs.unlinkSync(file)
|
||||
} else {
|
||||
let yaml = YAML.stringify(data)
|
||||
fs.writeFileSync(file, yaml, 'utf8')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
export default new Config()
|
||||
@@ -1,224 +0,0 @@
|
||||
import lodash from 'lodash'
|
||||
import fs from 'fs'
|
||||
|
||||
const _path = process.cwd()
|
||||
const plugin = 'xiaofei-plugin'
|
||||
const getRoot = (root = '') => {
|
||||
if (root === 'root' || root === 'yunzai') {
|
||||
root = `${_path}/`
|
||||
} else if (!root) {
|
||||
root = `${_path}/plugins/${plugin}/`
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
||||
let Data = {
|
||||
|
||||
/*
|
||||
* 根据指定的path依次检查与创建目录
|
||||
* */
|
||||
createDir (path = '', root = '', includeFile = false) {
|
||||
root = getRoot(root)
|
||||
let pathList = path.split('/')
|
||||
let nowPath = root
|
||||
pathList.forEach((name, idx) => {
|
||||
name = name.trim()
|
||||
if (!includeFile && idx <= pathList.length - 1) {
|
||||
nowPath += name + '/'
|
||||
if (name) {
|
||||
if (!fs.existsSync(nowPath)) {
|
||||
fs.mkdirSync(nowPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/*
|
||||
* 读取json
|
||||
* */
|
||||
readJSON (file = '', root = '') {
|
||||
root = getRoot(root)
|
||||
if (fs.existsSync(`${root}/${file}`)) {
|
||||
try {
|
||||
return JSON.parse(fs.readFileSync(`${root}/${file}`, 'utf8'))
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
return {}
|
||||
},
|
||||
|
||||
/*
|
||||
* 写JSON
|
||||
* */
|
||||
writeJSON (file, data, space = '\t', root = '') {
|
||||
// 检查并创建目录
|
||||
Data.createDir(file, root, true)
|
||||
root = getRoot(root)
|
||||
delete data._res
|
||||
return fs.writeFileSync(`${root}/${file}`, JSON.stringify(data, null, space))
|
||||
},
|
||||
|
||||
async getCacheJSON (key) {
|
||||
try {
|
||||
let txt = await redis.get(key)
|
||||
if (txt) {
|
||||
return JSON.parse(txt)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
return {}
|
||||
},
|
||||
|
||||
async setCacheJSON (key, data, EX = 3600 * 24 * 90) {
|
||||
await redis.set(key, JSON.stringify(data), { EX })
|
||||
},
|
||||
|
||||
async importModule (file, root = '') {
|
||||
root = getRoot(root)
|
||||
if (!/\.js$/.test(file)) {
|
||||
file = file + '.js'
|
||||
}
|
||||
if (fs.existsSync(`${root}/${file}`)) {
|
||||
try {
|
||||
let data = await import(`file://${root}/${file}?t=${new Date() * 1}`)
|
||||
return data || {}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
return {}
|
||||
},
|
||||
|
||||
async importDefault (file, root) {
|
||||
let ret = await Data.importModule(file, root)
|
||||
return ret.default || {}
|
||||
},
|
||||
|
||||
async import (name) {
|
||||
return await Data.importModule(`components/optional-lib/${name}.js`)
|
||||
},
|
||||
|
||||
async importCfg (key) {
|
||||
let sysCfg = await Data.importModule(`config/system/${key}_system.js`)
|
||||
let diyCfg = await Data.importModule(`config/${key}.js`)
|
||||
if (diyCfg.isSys) {
|
||||
console.error(`miao-plugin: config/${key}.js无效,已忽略`)
|
||||
console.error(`如需配置请复制config/${key}_default.js为config/${key}.js,请勿复制config/system下的系统文件`)
|
||||
diyCfg = {}
|
||||
}
|
||||
return {
|
||||
sysCfg,
|
||||
diyCfg
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* 返回一个从 target 中选中的属性的对象
|
||||
*
|
||||
* keyList : 获取字段列表,逗号分割字符串
|
||||
* key1, key2, toKey1:fromKey1, toKey2:fromObj.key
|
||||
*
|
||||
* defaultData: 当某个字段为空时会选取defaultData的对应内容
|
||||
* toKeyPrefix:返回数据的字段前缀,默认为空。defaultData中的键值无需包含toKeyPrefix
|
||||
*
|
||||
* */
|
||||
|
||||
getData (target, keyList = '', cfg = {}) {
|
||||
target = target || {}
|
||||
let defaultData = cfg.defaultData || {}
|
||||
let ret = {}
|
||||
// 分割逗号
|
||||
if (typeof (keyList) === 'string') {
|
||||
keyList = keyList.split(',')
|
||||
}
|
||||
|
||||
lodash.forEach(keyList, (keyCfg) => {
|
||||
// 处理通过:指定 toKey & fromKey
|
||||
let _keyCfg = keyCfg.split(':')
|
||||
let keyTo = _keyCfg[0].trim()
|
||||
let keyFrom = (_keyCfg[1] || _keyCfg[0]).trim()
|
||||
let keyRet = keyTo
|
||||
if (cfg.lowerFirstKey) {
|
||||
keyRet = lodash.lowerFirst(keyRet)
|
||||
}
|
||||
if (cfg.keyPrefix) {
|
||||
keyRet = cfg.keyPrefix + keyRet
|
||||
}
|
||||
// 通过Data.getVal获取数据
|
||||
ret[keyRet] = Data.getVal(target, keyFrom, defaultData[keyTo], cfg)
|
||||
})
|
||||
return ret
|
||||
},
|
||||
|
||||
getVal (target, keyFrom, defaultValue) {
|
||||
return lodash.get(target, keyFrom, defaultValue)
|
||||
},
|
||||
|
||||
// 异步池,聚合请求
|
||||
async asyncPool (poolLimit, array, iteratorFn) {
|
||||
const ret = [] // 存储所有的异步任务
|
||||
const executing = [] // 存储正在执行的异步任务
|
||||
for (const item of array) {
|
||||
// 调用iteratorFn函数创建异步任务
|
||||
const p = Promise.resolve().then(() => iteratorFn(item, array))
|
||||
// 保存新的异步任务
|
||||
ret.push(p)
|
||||
|
||||
// 当poolLimit值小于或等于总任务个数时,进行并发控制
|
||||
if (poolLimit <= array.length) {
|
||||
// 当任务完成后,从正在执行的任务数组中移除已完成的任务
|
||||
const e = p.then(() => executing.splice(executing.indexOf(e), 1))
|
||||
executing.push(e) // 保存正在执行的异步任务
|
||||
if (executing.length >= poolLimit) {
|
||||
// 等待较快的任务执行完成
|
||||
await Promise.race(executing)
|
||||
}
|
||||
}
|
||||
}
|
||||
return Promise.all(ret)
|
||||
},
|
||||
|
||||
// sleep
|
||||
sleep (ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms))
|
||||
},
|
||||
|
||||
// 获取默认值
|
||||
def () {
|
||||
for (let idx in arguments) {
|
||||
if (!lodash.isUndefined(arguments[idx])) {
|
||||
return arguments[idx]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 循环字符串回调
|
||||
eachStr: (arr, fn) => {
|
||||
if (lodash.isString(arr)) {
|
||||
arr = arr.replace(/\s*(;|;|、|,)\s*/, ',')
|
||||
arr = arr.split(',')
|
||||
} else if (lodash.isNumber(arr)) {
|
||||
arr = [arr.toString()]
|
||||
}
|
||||
lodash.forEach(arr, (str, idx) => {
|
||||
if (!lodash.isUndefined(str)) {
|
||||
fn(str.trim ? str.trim() : str, idx)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
regRet (reg, txt, idx) {
|
||||
if (reg && txt) {
|
||||
let ret = reg.exec(txt)
|
||||
if (ret && ret[idx]) {
|
||||
return ret[idx]
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export default Data
|
||||
@@ -1,100 +0,0 @@
|
||||
import fs from 'fs'
|
||||
import lodash from 'lodash'
|
||||
import cfg from '../../../lib/config/config.js'
|
||||
const Plugin_Path = `${process.cwd()}/plugins/xiaofei-plugin`;
|
||||
const README_path = `${Plugin_Path}/README.md`
|
||||
const CHANGELOG_path = `${Plugin_Path}/CHANGELOG.md`
|
||||
const yunzai_ver = `v${cfg.package.version}`;
|
||||
|
||||
let logs = {}
|
||||
let changelogs = []
|
||||
let currentVersion
|
||||
let versionCount = 6
|
||||
|
||||
const getLine = function (line) {
|
||||
line = line.replace(/(^\s*\*|\r)/g, '')
|
||||
line = line.replace(/\s*`([^`]+`)/g, '<span class="cmd">$1')
|
||||
line = line.replace(/`\s*/g, '</span>')
|
||||
line = line.replace(/\s*\*\*([^\*]+\*\*)/g, '<span class="strong">$1')
|
||||
line = line.replace(/\*\*\s*/g, '</span>')
|
||||
line = line.replace(/ⁿᵉʷ/g, '<span class="new"></span>')
|
||||
return line
|
||||
}
|
||||
|
||||
try {
|
||||
if (fs.existsSync(CHANGELOG_path)) {
|
||||
logs = fs.readFileSync(CHANGELOG_path, 'utf8') || ''
|
||||
logs = logs.replace(/\t/g,' ').split('\n')
|
||||
let temp = {};
|
||||
let lastLine = {}
|
||||
lodash.forEach(logs, (line) => {
|
||||
if (versionCount <= -1) {
|
||||
return false
|
||||
}
|
||||
let versionRet = /^#\s*([0-9a-zA-Z\\.~\s]+?)\s*$/.exec(line.trim())
|
||||
if (versionRet && versionRet[1]) {
|
||||
let v = versionRet[1].trim()
|
||||
if (!currentVersion) {
|
||||
currentVersion = v
|
||||
} else {
|
||||
changelogs.push(temp)
|
||||
if (/0\s*$/.test(v) && versionCount > 0) {
|
||||
//versionCount = 0
|
||||
versionCount--
|
||||
} else {
|
||||
versionCount--
|
||||
}
|
||||
}
|
||||
temp = {
|
||||
version: v,
|
||||
logs: []
|
||||
}
|
||||
} else {
|
||||
if (!line.trim()) {
|
||||
return
|
||||
}
|
||||
if (/^\*/.test(line)) {
|
||||
lastLine = {
|
||||
title: getLine(line),
|
||||
logs: []
|
||||
}
|
||||
if(!temp.logs){
|
||||
temp = {
|
||||
version: line,
|
||||
logs: []
|
||||
}
|
||||
}
|
||||
temp.logs.push(lastLine)
|
||||
} else if (/^\s{2,}\*/.test(line)) {
|
||||
lastLine.logs.push(getLine(line))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error(e);
|
||||
// do nth
|
||||
}
|
||||
|
||||
try{
|
||||
if(fs.existsSync(README_path)){
|
||||
let README = fs.readFileSync(README_path, 'utf8') || ''
|
||||
let reg = /版本:(.*)/.exec(README)
|
||||
if(reg){
|
||||
currentVersion = reg[1]
|
||||
}
|
||||
}
|
||||
}catch(err){}
|
||||
|
||||
let Version = {
|
||||
get ver () {
|
||||
return currentVersion;
|
||||
},
|
||||
get yunzai(){
|
||||
return yunzai_ver;
|
||||
},
|
||||
get logs(){
|
||||
return changelogs;
|
||||
}
|
||||
}
|
||||
export default Version
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"sys": {
|
||||
"help": true,
|
||||
"scale": 100
|
||||
},
|
||||
"char": {
|
||||
"wife": false,
|
||||
"char": true
|
||||
},
|
||||
"wiki": {
|
||||
"abyss": true,
|
||||
"wiki": false,
|
||||
"stat": true
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
import { Data, Version, Plugin_Name} from '../index.js'
|
||||
import Cfg from '../Cfg.js'
|
||||
import fs from 'fs'
|
||||
import puppeteer from '../../../../lib/puppeteer/puppeteer.js'
|
||||
|
||||
const _path = process.cwd()
|
||||
|
||||
export default async function (path, params, cfg) {
|
||||
let [app, tpl] = path.split('/')
|
||||
let { e } = cfg
|
||||
let layoutPath = process.cwd() + `/plugins/${Plugin_Name}/resources/common/layout/`
|
||||
let resPath = `../../../../../plugins/${Plugin_Name}/resources/`
|
||||
Data.createDir(`data/html/${Plugin_Name}/${app}/${tpl}`, 'root')
|
||||
let data = {
|
||||
...params,
|
||||
_plugin: Plugin_Name,
|
||||
saveId: params.saveId || params.save_id || tpl,
|
||||
tplFile: `./plugins/${Plugin_Name}/resources/${app}/${tpl}.html`,
|
||||
pluResPath: resPath,
|
||||
_res_path: resPath,
|
||||
_layout_path: layoutPath,
|
||||
_tpl_path: process.cwd() + `/plugins/${Plugin_Name}/resources/common/tpl/`,
|
||||
defaultLayout: layoutPath + 'default.html',
|
||||
elemLayout: layoutPath + 'elem.html',
|
||||
pageGotoParams: {
|
||||
waitUntil: 'networkidle0'
|
||||
},
|
||||
sys: {
|
||||
scale: Cfg.scale(cfg.scale || 1),
|
||||
copyright: `Created By Yunzai-Bot<span class="version">${Version.yunzai}</span> & xiaofei-Plugin<span class="version">${Version.ver}</span>`
|
||||
},
|
||||
quality: 100
|
||||
}
|
||||
if (process.argv.includes('web-debug')) {
|
||||
// debug下保存当前页面的渲染数据,方便模板编写与调试
|
||||
// 由于只用于调试,开发者只关注自己当时开发的文件即可,暂不考虑app及plugin的命名冲突
|
||||
let saveDir = _path + '/data/ViewData/'
|
||||
if (!fs.existsSync(saveDir)) {
|
||||
fs.mkdirSync(saveDir)
|
||||
}
|
||||
let file = saveDir + tpl + '.json'
|
||||
data._app = app
|
||||
fs.writeFileSync(file, JSON.stringify(data))
|
||||
}
|
||||
let base64 = await puppeteer.screenshot(`${Plugin_Name}/${app}/${tpl}`, data)
|
||||
let ret = true
|
||||
if (base64) {
|
||||
ret = await e.reply(base64)
|
||||
}
|
||||
return cfg.retMsgId ? ret : true
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
const Path = process.cwd();
|
||||
const Plugin_Name = 'xiaofei-plugin'
|
||||
const Plugin_Path = `${Path}/plugins/${Plugin_Name}`;
|
||||
import Version from './Version.js'
|
||||
import Data from './Data.js'
|
||||
import Cfg from './Cfg.js'
|
||||
import Common from './Common.js'
|
||||
import Config from './Config.js'
|
||||
|
||||
export { Cfg, Common, Config, Data, Version, Path, Plugin_Name, Plugin_Path}
|
||||
@@ -1,87 +1,4 @@
|
||||
import plugin from '../../lib/plugins/plugin.js'
|
||||
import gsCfg from '../genshin/model/gsCfg.js'
|
||||
import { segment } from 'oicq'
|
||||
import fs from 'node:fs'
|
||||
import common from '../../lib/common/common.js'
|
||||
|
||||
export class curve extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
name: 'nga收益曲线',
|
||||
dsc: '收益曲线',
|
||||
event: 'message',
|
||||
priority: 500,
|
||||
rule: [
|
||||
{
|
||||
reg: '^#*(.*)收益曲线(帮助)?$',
|
||||
fnc: 'curve'
|
||||
},
|
||||
]
|
||||
})
|
||||
this.path = './resources/收益曲线'
|
||||
|
||||
}
|
||||
//初始化
|
||||
async init() {
|
||||
if (!fs.existsSync(this.path)) {
|
||||
fs.mkdirSync(this.path)
|
||||
}
|
||||
}
|
||||
|
||||
async curve() {
|
||||
let role = {}
|
||||
if (/#?收益曲线帮助/.test(this.e.msg)) role.name = "帮助"
|
||||
else role = gsCfg.getRole(this.e.msg, '收益曲线')
|
||||
|
||||
if (!role) return
|
||||
|
||||
|
||||
/** 主角特殊处理 */
|
||||
if (['10000005', '10000007', '20000000'].includes(String(role.roleId))) {
|
||||
if (!['风主', '岩主', '雷主', '草主'].includes(role.alias)) {
|
||||
await this.e.reply('请选择:风主收益曲线、岩主收益曲线、雷主收益曲线、草主收益曲线')
|
||||
return
|
||||
} else {
|
||||
role.name = role.alias
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!image[role.name]) return this.e.reply("暂时无该角色收益曲线~>_<")
|
||||
|
||||
this.imgPath = `${this.path}/${role.name}.png`
|
||||
|
||||
if (!fs.existsSync(this.imgPath)) {
|
||||
await this.getImg(role.name)
|
||||
}
|
||||
|
||||
|
||||
if (fs.existsSync(this.imgPath)) {
|
||||
await this.e.reply(segment.image(this.imgPath));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//下载图片
|
||||
async getImg(name) {
|
||||
logger.mark(`${this.e.logFnc} 下载${name}素材图`)
|
||||
|
||||
if (!await common.downFile(image[name], this.imgPath)) {
|
||||
return false
|
||||
}
|
||||
|
||||
logger.mark(`${this.e.logFnc} 下载${name}素材成功`)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const image = {
|
||||
{
|
||||
"帮助": "https://img.nga.178.com/attachments/mon_202208/21/i2Qjk1-j5voXxZ96T3cS1di-q9.png",
|
||||
|
||||
"烟绯": "https://img.nga.178.com/attachments/mon_202208/17/i2Q2q-gz71XxZ96T3cS1di-q9.png",
|
||||
17
config/noticecfg.json
Normal file
17
config/noticecfg.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"privateMessage": true,
|
||||
"groupMessage": false,
|
||||
"grouptemporaryMessage": true,
|
||||
"groupRecall": true,
|
||||
"PrivateRecall": true,
|
||||
"friendRequest": true,
|
||||
"groupInviteRequest": true,
|
||||
"groupAdminChange": true,
|
||||
"friendNumberChange": true,
|
||||
"groupNumberChange": true,
|
||||
"groupMemberNumberChange": false,
|
||||
"flashPhoto": true,
|
||||
"botBeenBanned": true,
|
||||
"notificationsAll": false,
|
||||
"deltime": 600
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
此目录为系统配置目录
|
||||
请勿修改此目录下的文件,否则可能导致工作不正常
|
||||
如需配置,可配置上级目录,复制对应_default.js 文件进行配置
|
||||
28
index.js
28
index.js
@@ -1,10 +1,13 @@
|
||||
import fs from 'node:fs'
|
||||
import common from '../../lib/common/common.js'
|
||||
|
||||
const files = fs.readdirSync('./plugins/suiyue/apps').filter(file => file.endsWith('.js'))
|
||||
const files = fs.readdirSync('./plugins/yenai-plugin/apps').filter(file => file.endsWith('.js'))
|
||||
|
||||
let ret = []
|
||||
|
||||
logger.info('-----------')
|
||||
logger.info('椰奶插件初始化~')
|
||||
logger.info('-----------')
|
||||
|
||||
files.forEach((file) => {
|
||||
ret.push(import(`./apps/${file}`))
|
||||
})
|
||||
@@ -20,23 +23,6 @@ for (let i in files) {
|
||||
logger.error(ret[i].reason)
|
||||
continue
|
||||
}
|
||||
|
||||
apps[name] = ret[i].value[name]
|
||||
apps[name] = ret[i].value[Object.keys(ret[i].value)[0]]
|
||||
}
|
||||
|
||||
logger.info('-----------')
|
||||
logger.info('加载碎月插件完成..[v1.0.0]')
|
||||
logger.info('-----------')
|
||||
|
||||
let restart = await redis.get(`Yunzai:suiyue:restart`);
|
||||
if (restart) {
|
||||
restart = JSON.parse(restart);
|
||||
if (restart.isGroup) {
|
||||
Bot.pickGroup(restart.id).sendMsg(`重启成功`);
|
||||
} else {
|
||||
common.relpyPrivate(restart.id, `重启成功`);
|
||||
}
|
||||
redis.del(`Yunzai:suiyue:restart`);
|
||||
}
|
||||
|
||||
export { apps }
|
||||
export { apps }
|
||||
|
||||
BIN
resources/curveimg/帮助.png
Normal file
BIN
resources/curveimg/帮助.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 MiB |
BIN
resources/curveimg/甘雨.png
Normal file
BIN
resources/curveimg/甘雨.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 MiB |
BIN
resources/curveimg/重云.png
Normal file
BIN
resources/curveimg/重云.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 MiB |
Reference in New Issue
Block a user