This commit is contained in:
touchscale 2023-08-06 00:46:07 +08:00
commit 65ea249513
26 changed files with 1264 additions and 880 deletions

View File

@ -22,5 +22,7 @@ online_msg: true
# 上线推送通知的冷却时间 # 上线推送通知的冷却时间
online_msg_exp: 86400 online_msg_exp: 86400
# 签名API地址 # 签名API地址(如:http://127.0.0.1:8080/sign?key=114514)
sign_api_addr: sign_api_addr:
# 传入的QQ版本(如:8.9.63、8.9.68)
ver:

View File

@ -15,6 +15,7 @@ export default class Yunzai extends Client {
/** 加载icqq事件监听 */ /** 加载icqq事件监听 */
await ListenerLoader.load(bot) await ListenerLoader.load(bot)
await bot.login(cfg.qq, cfg.pwd) await bot.login(cfg.qq, cfg.pwd)
bot[bot.uin] = bot
return bot return bot
} }
} }

View File

@ -9,7 +9,7 @@ import path from 'node:path'
* @param user_id qq号 * @param user_id qq号
* @param msg 消息 * @param msg 消息
*/ */
async function relpyPrivate (userId, msg) { async function relpyPrivate(userId, msg) {
userId = Number(userId) userId = Number(userId)
let friend = Bot.fl.get(userId) let friend = Bot.fl.get(userId)
@ -25,7 +25,7 @@ async function relpyPrivate (userId, msg) {
* 休眠函数 * 休眠函数
* @param ms 毫秒 * @param ms 毫秒
*/ */
function sleep (ms) { function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms)) return new Promise((resolve) => setTimeout(resolve, ms))
} }
@ -34,7 +34,7 @@ function sleep (ms) {
* @param fileUrl 下载地址 * @param fileUrl 下载地址
* @param savePath 保存路径 * @param savePath 保存路径
*/ */
async function downFile (fileUrl, savePath, param = {}) { async function downFile(fileUrl, savePath, param = {}) {
try { try {
mkdirs(path.dirname(savePath)) mkdirs(path.dirname(savePath))
logger.debug(`[下载文件] ${fileUrl}`) logger.debug(`[下载文件] ${fileUrl}`)
@ -48,7 +48,7 @@ async function downFile (fileUrl, savePath, param = {}) {
} }
} }
function mkdirs (dirname) { function mkdirs(dirname) {
if (fs.existsSync(dirname)) { if (fs.existsSync(dirname)) {
return true return true
} else { } else {
@ -61,19 +61,20 @@ function mkdirs (dirname) {
/** /**
* 制作转发消息 * 制作转发消息
* @param e icqq消息e * @param e 消息事件
* @param msg 消息数组 * @param msg 消息数组
* @param dec 转发描述 * @param dec 转发描述
* @param msgsscr 转发信息是否为Bot * @param msgsscr 转发信息是否伪装
*/ */
async function makeForwardMsg (e, msg = [], dec = '', msgsscr = false) { async function makeForwardMsg(e, msg = [], dec = '', msgsscr = false) {
// 是频道直接返回 join if (!Array.isArray(msg)) msg = [msg]
if (e.isGuild) return msg.join('\n')
let name = msgsscr ? e.sender.card || e.user_id : Bot.nickname
let id = msgsscr ? e.user_id : Bot.uin
let name = msgsscr ? this.e.sender.card || this.e.user_id : Bot.nickname
let id = msgsscr ? this.e.user_id : Bot.uin
if (e.isGroup) { if (e.isGroup) {
let info = await e.bot.getGroupMemberInfo(e.group_id, e.bot.uin) let info = await e.bot.getGroupMemberInfo(e.group_id, id)
name = info.card || info.nickname
} }
let userInfo = { let userInfo = {
@ -82,29 +83,38 @@ async function makeForwardMsg (e, msg = [], dec = '', msgsscr = false) {
} }
let forwardMsg = [] let forwardMsg = []
msg.forEach(msg => { for (const message of msg){
if(!message) continue
forwardMsg.push({ forwardMsg.push({
...userInfo, ...userInfo,
message: msg message: message
})
}) })
}
/** 制作转发内容 */ /** 制作转发内容 */
if (e.isGroup) { if (e?.group?.makeForwardMsg) {
forwardMsg = await e.group.makeForwardMsg(forwardMsg) forwardMsg = await e.group.makeForwardMsg(forwardMsg)
} else if (e.friend) { } else if (e?.friend?.makeForwardMsg) {
forwardMsg = await e.friend.makeForwardMsg(forwardMsg) forwardMsg = await e.friend.makeForwardMsg(forwardMsg)
} else { } else {
return false return msg.join('\n')
} }
if (dec) { if (dec) {
/** 处理描述 */ /** 处理描述 */
if (typeof (forwardMsg.data) === 'object') {
let detail = forwardMsg.data?.meta?.detail
if (detail) {
detail.news = [{ text: dec }]
}
} else {
forwardMsg.data = forwardMsg.data forwardMsg.data = forwardMsg.data
.replace(/\n/g, '') .replace(/\n/g, '')
.replace(/<title color="#777777" size="26">(.+?)<\/title>/g, '___') .replace(/<title color="#777777" size="26">(.+?)<\/title>/g, '___')
.replace(/___+/, `<title color="#777777" size="26">${dec}</title>`) .replace(/___+/, `<title color="#777777" size="26">${dec}</title>`)
} }
}
return forwardMsg return forwardMsg
} }

View File

@ -21,7 +21,7 @@
"chalk": "^5.2.0", "chalk": "^5.2.0",
"chokidar": "^3.5.3", "chokidar": "^3.5.3",
"https-proxy-agent": "5.0.1", "https-proxy-agent": "5.0.1",
"icqq": "^0.4.11", "icqq": "^0.4.12",
"image-size": "^1.0.2", "image-size": "^1.0.2",
"inquirer": "^8.2.5", "inquirer": "^8.2.5",
"lodash": "^4.17.21", "lodash": "^4.17.21",

View File

@ -1,11 +1,12 @@
import plugin from '../../../lib/plugins/plugin.js' import plugin from '../../../lib/plugins/plugin.js'
import common from '../../../lib/common/common.js'
import fs from 'node:fs' import fs from 'node:fs'
import gsCfg from '../model/gsCfg.js' import gsCfg from '../model/gsCfg.js'
import YAML from 'yaml' import YAML from 'yaml'
import lodash from 'lodash' import lodash from 'lodash'
export class abbrSet extends plugin { export class abbrSet extends plugin {
constructor (e) { constructor(e) {
super({ super({
name: '别名设置', name: '别名设置',
dsc: '角色别名设置', dsc: '角色别名设置',
@ -13,24 +14,24 @@ export class abbrSet extends plugin {
priority: 600, priority: 600,
rule: [ rule: [
{ {
reg: '^#(设置|配置)(.*)(别名|昵称)$', reg: '^#(星铁)?(设置|配置)(.*)(别名|昵称)$',
fnc: 'abbr' fnc: 'abbr'
}, },
{ {
reg: '^#删除(别名|昵称)(.*)$', reg: '^#(星铁)?删除(别名|昵称)(.*)$',
fnc: 'delAbbr' fnc: 'delAbbr'
}, },
{ {
reg: '^#(.*)(别名|昵称)$', reg: '^#(星铁)?(.*)(别名|昵称)$',
fnc: 'abbrList' fnc: 'abbrList'
} }
] ]
}) })
this.isSr = false
this.file = './plugins/genshin/config/role.name.yaml' this.file = './plugins/genshin/config/role.name.yaml'
} }
async init () { async init() {
if (!fs.existsSync(this.file)) { if (!fs.existsSync(this.file)) {
fs.writeFileSync(this.file, `神里绫华: fs.writeFileSync(this.file, `神里绫华:
- 龟龟 - 龟龟
@ -38,17 +39,18 @@ export class abbrSet extends plugin {
} }
} }
async abbr () { async abbr() {
if (!await this.checkAuth()) return if (!await this.checkAuth()) return
let role = gsCfg.getRole(this.e.msg, '#|设置|配置|别名|昵称') let role = gsCfg.getRole(this.e.msg, '#|星铁|设置|配置|别名|昵称', this.e.isSr)
if (!role) return false if (!role) return false
this.e.role = role this.e.role = role
this.isSr = this.e.isSr
this.setContext('setAbbr') this.setContext('setAbbr')
await this.reply(`请发送${role.alias}别名,多个用空格隔开`) await this.reply(`请发送${role.alias}别名,多个用空格隔开`)
} }
async checkAuth () { async checkAuth() {
if (!this.e.isGroup && !this.e.isMaster) { if (!this.e.isGroup && !this.e.isMaster) {
await this.reply('禁止私聊设置角色别名') await this.reply('禁止私聊设置角色别名')
return false return false
@ -76,7 +78,7 @@ export class abbrSet extends plugin {
return true return true
} }
async setAbbr () { async setAbbr() {
if (!this.e.msg || this.e.at || this.e.img) { if (!this.e.msg || this.e.at || this.e.img) {
await this.reply('设置错误:请发送正确内容') await this.reply('设置错误:请发送正确内容')
return return
@ -96,10 +98,10 @@ export class abbrSet extends plugin {
let ret = [] let ret = []
for (let name of setName) { for (let name of setName) {
name = name.replace(/#|设置|配置|别名|昵称/g, '') name = name.replace(/#|星铁|设置|配置|别名|昵称/g, '')
if (!name) continue if (!name) continue
/** 重复添加 */ /** 重复添加 */
if (nameArr[role.name].includes(name) || gsCfg.roleNameToID(name)) { if (nameArr[role.name].includes(name) || gsCfg.roleNameToID(name, this.isSr)) {
continue continue
} }
@ -113,19 +115,18 @@ export class abbrSet extends plugin {
this.save(nameArr) this.save(nameArr)
gsCfg.nameID = false gsCfg[this.isSr ? 'sr_nameID' : 'nameID'] = false
await this.reply(`设置别名成功:${ret.join('、')}`) await this.reply(`设置别名成功:${ret.join('、')}`)
} }
save (data) { save(data) {
data = YAML.stringify(data) data = YAML.stringify(data)
fs.writeFileSync(this.file, data) fs.writeFileSync(this.file, data)
} }
async delAbbr () { async delAbbr() {
let role = gsCfg.getRole(this.e.msg, '#|删除|别名|昵称') let role = gsCfg.getRole(this.e.msg, '#|星铁|删除|别名|昵称', this.e.isSr)
if (!role) return false if (!role) return false
let nameArr = gsCfg.getConfig('role', 'name') let nameArr = gsCfg.getConfig('role', 'name')
@ -145,12 +146,12 @@ export class abbrSet extends plugin {
await this.reply(`设置${role.name}别名成功:${role.alias}`) await this.reply(`设置${role.name}别名成功:${role.alias}`)
} }
async abbrList () { async abbrList() {
let role = gsCfg.getRole(this.e.msg, '#|别名|昵称') let role = gsCfg.getRole(this.e.msg, '#|星铁|别名|昵称', this.e.isSr)
if (!role) return false if (!role) return false
let name = gsCfg.getdefSet('role', 'name')[role.roleId] let name = gsCfg.getdefSet('role', this.e.isSr ? 'sr_name' : 'name')[role.roleId]
let nameUser = gsCfg.getConfig('role', 'name')[role.name] ?? [] let nameUser = gsCfg.getConfig('role', 'name')[role.name] ?? []
let list = lodash.uniq([...name, ...nameUser]) let list = lodash.uniq([...name, ...nameUser])
@ -158,51 +159,13 @@ export class abbrSet extends plugin {
let msg = [] let msg = []
for (let i in list) { for (let i in list) {
let num = Number(i) + 1 let num = Number(i) + 1
msg.push(`${num}.${list[i]}\n`) msg.push(`${num}.${list[i]}`)
} }
let title = `${role.name}别名,${list.length}` let title = `${role.name}别名,${list.length}`
msg = await this.makeForwardMsg(this.e.bot.uin, title, msg) msg = await common.makeForwardMsg(this.e, [title, msg.join("\n")], title)
await this.e.reply(msg) await this.e.reply(msg)
} }
async makeForwardMsg (qq, title, msg) {
let nickname = this.e.bot.nickname
if (this.e.isGroup) {
let info = await this.e.bot.getGroupMemberInfo(this.e.group_id, qq)
nickname = info.card ?? info.nickname
}
let userInfo = {
user_id: this.e.bot.uin,
nickname
}
let forwardMsg = [
{
...userInfo,
message: title
},
{
...userInfo,
message: msg
}
]
/** 制作转发内容 */
if (this.e.isGroup) {
forwardMsg = await this.e.group.makeForwardMsg(forwardMsg)
} else {
forwardMsg = await this.e.friend.makeForwardMsg(forwardMsg)
}
/** 处理描述 */
forwardMsg.data = forwardMsg.data
.replace(/\n/g, '')
.replace(/<title color="#777777" size="26">(.+?)<\/title>/g, '___')
.replace(/___+/, `<title color="#777777" size="26">${title}</title>`)
return forwardMsg
}
} }

View File

@ -5,7 +5,7 @@ import puppeteer from '../../../lib/puppeteer/puppeteer.js'
import gsCfg from '../model/gsCfg.js' import gsCfg from '../model/gsCfg.js'
export class calculator extends plugin { export class calculator extends plugin {
constructor () { constructor() {
super({ super({
name: '养成计算', name: '养成计算',
dsc: '角色养成材料计算器', dsc: '角色养成材料计算器',
@ -13,11 +13,11 @@ export class calculator extends plugin {
priority: 700, priority: 700,
rule: [ rule: [
{ {
reg: '^#*(.*)(养成|计算)([0-9]|,|| )*$', reg: '^#*(星铁)?(.*)(养成|计算)([0-9]|,|| )*$',
fnc: 'Calculator' fnc: 'Calculator'
}, },
{ {
reg: '^#*角色(养成|计算|养成计算)$', reg: '^#*(星铁)?角色(养成|计算|养成计算)$',
fnc: 'calculatorHelp' fnc: 'calculatorHelp'
}, },
{ {
@ -30,20 +30,21 @@ export class calculator extends plugin {
}, },
] ]
}) })
this._path = process.cwd().replace(/\\/g, '/')
} }
async blueprintHelp (e) { async blueprintHelp(e) {
let msg = '#尘歌壶模数\n指令#尘歌壶模数\n示例#尘歌壶模数123456\n参数为模数id(10-15位数字)' let msg = '#尘歌壶模数\n指令#尘歌壶模数\n示例#尘歌壶模数123456\n参数为模数id(10-15位数字)'
await e.reply(msg) await e.reply(msg)
return true return true
} }
async calculatorHelp (e) { async calculatorHelp(e) {
let msg = '#角色养成计算\n指令#刻晴养成\n示例#刻晴养成81 90 9 9 9\n参数为角色、武器、技能等级' let msg = `角色养成计算\n指令:${e.isSr ? '*克拉拉养成\n示例*克拉拉养成75 80 6 9 9 9\n参数为角色、武器、普攻、战技、终结技、天赋' : '#刻晴养成\n示例#刻晴养成81 90 9 9 9\n参数为角色、武器、技能等级'}`
await e.reply(msg) await e.reply(msg)
return true return true
} }
async Blueprint(){ async Blueprint() {
let role = this.e.msg.replace(/#/,'').match(/\d+/g); let role = this.e.msg.replace(/#/, '').match(/\d+/g);
let data = await new Blueprint(this.e).get(role) let data = await new Blueprint(this.e).get(role)
if (!data) return if (!data) return
@ -52,8 +53,8 @@ export class calculator extends plugin {
if (img) await this.reply(img) if (img) await this.reply(img)
} }
/** #刻晴养成 */ /** #刻晴养成 */
async Calculator () { async Calculator() {
let role = gsCfg.getRole(this.e.msg, '#||养成|计算|[0-9]|,|| ') let role = gsCfg.getRole(this.e.msg, '#||星铁|养成|计算|[0-9]|,|| ', this.e.isSr)
if (!role) return false if (!role) return false
if ([10000005, 10000007, 20000000].includes(Number(role.roleId))) { if ([10000005, 10000007, 20000000].includes(Number(role.roleId))) {
@ -65,7 +66,18 @@ export class calculator extends plugin {
if (!data) return if (!data) return
/** 生成图片 */ /** 生成图片 */
let img = await puppeteer.screenshot('Calculator', data) let url = this.srHead('calculator', data)
let img = await puppeteer.screenshot(url, data)
if (img) await this.reply(img) if (img) await this.reply(img)
} }
srHead = (url, data) => {
let name = url
if (this.e.isSr) {
name = `StarRail/${url}`
data.pluResPath = `${this._path}/plugins/genshin/resources/StarRail/`
data.tplFile = `./plugins/genshin/resources/StarRail/html/${url}/${url}.html`
data.headStyle = `<style> .head_box { background: url(${this._path}/plugins/genshin/resources/StarRail/img/worldcard/星穹列车.png) #fff; background-position-x: -10px; background-repeat: no-repeat; background-size: 540px; background-position-y: -100px; </style>`
}
return name
}
} }

View File

@ -1,6 +1,5 @@
import plugin from '../../../lib/plugins/plugin.js' import plugin from '../../../lib/plugins/plugin.js'
import MysNews from '../model/mysNews.js' import MysNews from '../model/mysNews.js'
import MysSrNews from '../model/mysSrNews.js'
import fs from 'node:fs' import fs from 'node:fs'
import lodash from 'lodash' import lodash from 'lodash'
import gsCfg from '../model/gsCfg.js' import gsCfg from '../model/gsCfg.js'
@ -8,7 +7,7 @@ import YAML from 'yaml'
gsCfg.cpCfg('mys', 'pushNews') gsCfg.cpCfg('mys', 'pushNews')
export class mysNews extends plugin { export class mysNews extends plugin {
constructor (e) { constructor(e) {
super({ super({
name: '米游社公告', name: '米游社公告',
dsc: '#公告 #资讯 #活动', dsc: '#公告 #资讯 #活动',
@ -16,26 +15,13 @@ export class mysNews extends plugin {
priority: 700, priority: 700,
rule: [ rule: [
{ {
reg: '^(#*官方(公告|资讯|活动)|#*原神(公告|资讯|活动)|#公告|#资讯|#活动)[0-9]*$', reg: '^#*(官方|星铁|原神|崩坏三|崩三|绝区零|崩坏二|崩二|崩坏学园二|未定|未定事件簿)?(公告|资讯|活动)[0-9]*$',
fnc: 'news' fnc: 'news'
}, },
{ {
reg: '^(#米游社|#mys)(.*)', reg: '^(#米游社|#mys)(.*)',
fnc: 'mysSearch' fnc: 'mysSearch'
}, },
{
reg: '^(#*铁道(公告|资讯|活动)|#*星铁(公告|资讯|活动)|#星穹公告|#星穹资讯|#星穹活动)[0-9]*$',
fnc: 'srNews'
},
{
reg: '^#*(开启|关闭)(铁道|星铁|星穹)(公告|资讯)推送$',
fnc: 'srSetPush'
},
{
reg: '^#推送(铁道|星铁|星穹)(公告|资讯)$',
permission: 'master',
fnc: 'srMysNewsTask'
},
{ {
reg: '(.*)(bbs.mihoyo.com|miyoushe.com)/ys(.*)/article(.*)', reg: '(.*)(bbs.mihoyo.com|miyoushe.com)/ys(.*)/article(.*)',
fnc: 'mysUrl' fnc: 'mysUrl'
@ -45,85 +31,66 @@ export class mysNews extends plugin {
fnc: 'ysEstimate' fnc: 'ysEstimate'
}, },
{ {
reg: '^#*(开启|关闭)(公告|资讯)推送$', reg: '^#*(星铁|原神|崩坏三|崩三|绝区零|崩坏二|崩二|崩坏学园二|未定|未定事件簿)?(开启|关闭)(公告|资讯)推送$',
fnc: 'setPush' fnc: 'setPush'
}, },
{ {
reg: '^#推送(公告|资讯)$', reg: '^#(星铁|原神|崩坏三|崩三|绝区零|崩坏二|崩二|崩坏学园二|未定|未定事件簿)?推送(公告|资讯)$',
permission: 'master', permission: 'master',
fnc: 'mysNewsTask' fnc: 'mysNewsTask'
} }
] ]
}) })
this.file = './plugins/genshin/config/mys.pushNews.yaml' this.file = './plugins/genshin/config/mys.pushNews.yaml'
/** 定时任务 */ /** 定时任务 */
this.task = [ this.task = {
{
cron: gsCfg.getConfig('mys', 'pushNews').pushTime, cron: gsCfg.getConfig('mys', 'pushNews').pushTime,
name: '米游社公告推送任务', name: '米游社公告推送任务',
fnc: () => this.mysNewsTask(), fnc: () => this.mysNewsTask(),
log: false log: false
},
{
cron: gsCfg.getConfig('mys', 'pushNews').pushTime,
name: '崩坏星穹铁道公告推送任务',
fnc: () => this.srMysNewsTask(),
log: false
} }
]
} }
async init () { async init() {
if (fs.existsSync(this.file)) return if (fs.existsSync(this.file)) return
fs.copyFileSync('./plugins/genshin/defSet/mys/pushNews.yaml', this.file) fs.copyFileSync('./plugins/genshin/defSet/mys/pushNews.yaml', this.file)
} }
async news () { async news() {
let data = await new MysNews(this.e).getNews() let gids = this.gids()
let data = await new MysNews(this.e).getNews(gids)
if (!data) return if (!data) return
await this.reply(data) await this.reply(data)
} }
async srNews () { async mysNewsTask() {
let data = await new MysSrNews(this.e).getNews()
if (!data) return
await this.reply(data)
}
async mysNewsTask () {
let mysNews = new MysNews(this.e) let mysNews = new MysNews(this.e)
await mysNews.mysNewsTask() await mysNews.mysNewsTask()
} }
async srMysNewsTask () { async mysSearch() {
let mysNews = new MysSrNews(this.e)
await mysNews.mysNewsTask()
}
async mysSearch () {
if (/签到/g.test(this.e.msg)) return false if (/签到/g.test(this.e.msg)) return false
let data = await new MysNews(this.e).mysSearch() let data = await new MysNews(this.e).mysSearch()
if (!data) return if (!data) return
await this.reply(data) await this.reply(data)
} }
async mysUrl () { async mysUrl() {
let data = await new MysNews(this.e).mysUrl() let data = await new MysNews(this.e).mysUrl()
if (!data) return if (!data) return
await this.reply(data) await this.reply(data)
} }
async ysEstimate () { async ysEstimate() {
let data = await new MysNews(this.e).ysEstimate() let data = await new MysNews(this.e).ysEstimate()
if (!data) return if (!data) return
await this.reply(data) await this.reply(data)
} }
async srSetPush () { async setPush() {
if (!this.e.isGroup) { if (!this.e.isGroup) {
await this.reply('推送请在群聊中设置') await this.reply('推送请在群聊中设置')
return return
@ -134,25 +101,31 @@ export class mysNews extends plugin {
} }
let cfg = gsCfg.getConfig('mys', 'pushNews') let cfg = gsCfg.getConfig('mys', 'pushNews')
let gids = this.gids()
let type = 'srannounceGroup' let game = gids == 1 ? 'bbb' : gids == 2 ? 'gs' : gids == 3 ? 'bb' : gids == 4 ? 'wd' : gids == 6 ? 'sr' : 'zzz'
let type = `${game}announceGroup`
let typeName = '公告' let typeName = '公告'
if (this.e.msg.includes('资讯')) { if (this.e.msg.includes('资讯')) {
type = 'srinfoGroup' type = `${game}infoGroup`
typeName = '资讯' typeName = '资讯'
} }
let model let model
let msg = `崩坏星穹铁道${typeName}推送已` let name = await new MysNews(this.e).game(gids)
let msg = `${name}${typeName}推送已`
if (!Array.isArray(cfg[type][this.e.self_id]))
cfg[type][this.e.self_id] = []
if (this.e.msg.includes('开启')) { if (this.e.msg.includes('开启')) {
model = '开启' model = '开启'
cfg[type].push(this.e.group_id) cfg[type][this.e.self_id].push(this.e.group_id)
cfg[type] = lodash.uniq(cfg[type]) cfg[type][this.e.self_id] = lodash.uniq(cfg[type][this.e.self_id])
msg += `${model}\n如有最新${typeName}将自动推送至此` msg += `${model}\n如有最新${typeName}将自动推送至此`
} else { } else {
model = '关闭' model = '关闭'
msg += `${model}` msg += `${model}`
cfg[type] = lodash.difference(cfg[type], [this.e.group_id]) cfg[type][this.e.self_id] = lodash.difference(cfg[type][this.e.self_id], [this.e.group_id])
} }
let yaml = YAML.stringify(cfg) let yaml = YAML.stringify(cfg)
@ -162,42 +135,26 @@ export class mysNews extends plugin {
await this.reply(msg) await this.reply(msg)
} }
async setPush () { gids() {
if (!this.e.isGroup) { let msg = this.e.msg.replace(/[#公告资讯活动开启关闭推送]/g, '');
await this.reply('推送请在群聊中设置') switch (msg) {
return case '崩坏三':
case '崩三':
return 1
case '原神':
return 2
case '崩坏学园二':
case '崩坏二':
case '崩二':
return 3
case '未定事件簿':
case '未定':
return 4
case '星铁':
return 6
case '绝区零':
return 8
} }
if (!this.e.member?.is_admin && !this.e.isMaster) { return 2
await this.reply('暂无权限,只有管理员才能操作', true)
return true
}
let cfg = gsCfg.getConfig('mys', 'pushNews')
let type = 'announceGroup'
let typeName = '公告'
if (this.e.msg.includes('资讯')) {
type = 'infoGroup'
typeName = '资讯'
}
let model
let msg = `原神${typeName}推送已`
if (this.e.msg.includes('开启')) {
model = '开启'
cfg[type].push(this.e.group_id)
cfg[type] = lodash.uniq(cfg[type])
msg += `${model}\n如有最新${typeName}将自动推送至此`
} else {
model = '关闭'
msg += `${model}`
cfg[type] = lodash.difference(cfg[type], [this.e.group_id])
}
let yaml = YAML.stringify(cfg)
fs.writeFileSync(this.file, yaml, 'utf8')
logger.mark(`${this.e.logFnc} ${model}${typeName}推送:${this.e.group_id}`)
await this.reply(msg)
} }
} }

View File

@ -3,9 +3,9 @@
- 罗莎莉亚 - 罗莎莉亚
- 烟绯 - 烟绯
up5: up5:
- 珊瑚宫心海
up5_2:
- 流浪者 - 流浪者
up5_2:
- 珊瑚宫心海
weapon5: weapon5:
- 不灭月华 - 不灭月华
- 图莱杜拉的回忆 - 图莱杜拉的回忆
@ -15,7 +15,7 @@
- 钟剑 - 钟剑
- 匣里灭辰 - 匣里灭辰
- 西风猎弓 - 西风猎弓
endTime: "2023-08-15 18:00:00" endTime: "2023-08-11 18:00:00"
- up4: - up4:
- 米卡 - 米卡
- 雷泽 - 雷泽

View File

@ -1,18 +1,50 @@
# 米游社公共推送定时任务,修改需要重启 # 米游社公共推送定时任务,修改需要重启
pushTime: 0 0/5 * * * ? pushTime: 0 0/5 * * * ?
# 最多同时推送条数 # 最多同时推送条数
maxNum: 1 maxNum: 1
#公共推送群 # 包含关键字不推送
announceGroup: [] banWord:
gs: 冒险助力礼包|纪行|预下载|脚本外挂|集中反馈|已开奖|云·原神|魔神任务|传说任务|线下赛|晋级赛|战绩更新|海选赛|邀请赛|积分赛|战绩工具|交流平台|首日赛|线上赛|社区内容|个人专访|全民赛|决赛|总决赛|半决赛|淘汰赛|作品展示|同人|大别野
sr: 预下载|脚本外挂|集中反馈|已开奖|问题说明|意见反馈|账号封禁|工具|直播预告|获奖名单|大别野
wd: 大别野|已开奖
bb: 已开奖|大别野
bbb: 封禁名单|大别野|马克兔速报|预下载
zzz: 作品展示|已开奖|大别野
#资讯推送群 #原神公告推送群
infoGroup: [] gsannounceGroup: {}
#原神资讯推送群
gsinfoGroup: {}
#崩坏星穹铁道公告推送群 #崩坏星穹铁道公告推送群
srannounceGroup: [] srannounceGroup: {}
#崩坏星穹铁道资讯推送群 #崩坏星穹铁道资讯推送群
srinfoGroup: [] srinfoGroup: {}
#绝区零公告推送群
zzzannounceGroup: {}
#绝区零资讯推送群
zzzinfoGroup: {}
#未定事件簿公告推送群
wdannounceGroup: {}
#未定事件簿资讯推送群
wdinfoGroup: {}
#崩坏3公告推送群
bbbannounceGroup: {}
#崩坏3资讯推送群
bbbinfoGroup: {}
#崩坏学园2公告推送群
bbannounceGroup: {}
#崩坏学园2资讯推送群
bbinfoGroup: {}

View File

@ -1,13 +1,13 @@
- from: '2023-07-25 18:00:00' - from: '2023-07-25 18:00:00'
to: '2023-08-15 14:59:59' to: '2023-08-15 14:59:59'
five: five:
- 珊瑚宫心海
- 流浪者 - 流浪者
- 珊瑚宫心海
four: four:
- 珐露珊 - 珐露珊
- 罗莎莉亚 - 罗莎莉亚
- 烟绯 - 烟绯
name: 浮岳虹珠|余火变相 name: 余火变相|浮岳虹珠
- from: '2023-07-05 06:00:00' - from: '2023-07-05 06:00:00'
to: '2023-07-25 17:59:59' to: '2023-07-25 17:59:59'
five: five:

View File

@ -0,0 +1,149 @@
1001:
- 三月七
- 三月
- 看板娘
- 三七
- 三祁
- 纠缠之缘
- March7th
- 37
1002:
- 单恒
- 单垣
- 丹垣
- 丹桁
- 冷面小青龙
- DanHeng
- 丹恒
1003:
- 姬子
- 机子
- 寄子
- Himeko
1004:
- 瓦尔特
- 杨叔
- 老杨
- Welt
1005:
- 卡芙卡
1006:
- 银狼
- 音浪
- 银浪
- 隐狼
- 淫狼
- 骇兔
- 鸭子
- 小鸭
- 小鸭鸭
- yinlang
- YinLang
1008:
- 阿兰
- 阿兰
- Alan
- 阿郎
- 阿蓝
- Arlan
1009:
- 艾丝妲
- 爱思达
- 爱丝妲
- 爱思妲
- 爱丝达
- 艾思达
- 艾思妲
- 艾丝达
- 富婆
- Asta
1013:
- 黑塔
- 人偶
- 转圈圈
- Herta
1101:
- 布洛妮娅
- 布诺妮亚
- 布洛妮亚
- 布诺妮娅
- 布洛尼亚
- 鸭鸭
- 大鸭鸭
- Bronya
1102:
- 希儿
- 希尔
- Seele
1103:
- 希露瓦
- 希录瓦
- Serval
1104:
- 杰帕德
- 杰哥
- Gepard
1105:
- 娜塔莎
- 那塔莎
- 那塔沙
- 娜塔沙
- Natasha
- 渡鸦
1106:
- 佩拉
- 配拉
- 佩啦
- 冰砂糖
- Pela
1107:
- 克拉拉
- 可拉拉
- 史瓦罗
- Clara
1108:
- 桑博
- Sampo
1109:
- 虎克
- 胡克
- Hook
1201:
- 青雀
- 青却
- 卿雀
- Qingque
1202:
- 停云
- 停运
- 听云
- Tingyun
1203:
- 罗刹
1204:
- 景元
- JingYuan
1205:
-
1206:
- 素裳
- 李素裳
- Sushang
1207:
- 驭空
1209:
- 彦卿
- 言情
- 彦情
- 彦青
- 言卿
- 燕青
- Yanqing
1211:
- 白露
- 龙女
- 小龙女
- 白鹭
- 白鹿
- 白麓
- Bailu

View File

@ -18,7 +18,7 @@ export default class base {
* @param pluResPath 插件资源路径 * @param pluResPath 插件资源路径
*/ */
get screenData() { get screenData() {
let headImg = '优菈' let headImg = '珊瑚宫心海'
return { return {
saveId: this.userId, saveId: this.userId,

View File

@ -5,13 +5,13 @@ import lodash from 'lodash'
import gsCfg from './gsCfg.js' import gsCfg from './gsCfg.js'
export default class Calculator extends base { export default class Calculator extends base {
constructor (e) { constructor(e) {
super(e) super(e)
this.model = 'calculator' this.model = 'calculator'
this.checkMsg = '设置角色、武器、技能等级有误\n指令#刻晴养成\n示例#刻晴养成81 90 9 9 9\n参数为角色、武器、技能等级' this.checkMsg = `设置角色、武器、技能等级有误\n指令:${e.isSr ? '*克拉拉养成\n示例*克拉拉养成75 80 6 9 9 9\n参数为角色、武器、普攻、战技、终结技、天赋' : '#刻晴养成\n示例#刻晴养成81 90 9 9 9\n参数为角色、武器、技能等级'}`
} }
async get (role) { async get(role) {
this.role = role this.role = role
/** 获取绑定uid */ /** 获取绑定uid */
let uid = await MysInfo.getUid(this.e) let uid = await MysInfo.getUid(this.e)
@ -26,8 +26,18 @@ export default class Calculator extends base {
this.mysApi = new MysApi(uid, ck.ck, { log: true }) this.mysApi = new MysApi(uid, ck.ck, { log: true })
let seed_id = lodash.sample('abcdefghijklmnopqrstuvwxyz0123456789', 16).replace(/,/g, '')
let device_fp = await MysInfo.get(this.e, 'getFp', {
seed_id
})
this.headers = {
'x-rpc-device_fp': device_fp?.data?.device_fp
}
/** 获取角色数据 */ /** 获取角色数据 */
let character = await this.mysApi.getData('character') let character = await MysInfo.get(this.e, this.e.isSr ? 'avatarInfo' : 'character', {
headers: this.headers,
})
if (!character || character.retcode !== 0) return false if (!character || character.retcode !== 0) return false
character = character.data character = character.data
@ -35,7 +45,7 @@ export default class Calculator extends base {
await this.getSet() await this.getSet()
/** 获取计算角色 */ /** 获取计算角色 */
this.dataCharacter = character.avatars.find((item) => item.id == role.roleId) this.dataCharacter = character[this.e.isSr ? 'avatar_list' : 'avatars'].find((item) => item.id == role.roleId)
/** 获取计算参数 */ /** 获取计算参数 */
let body = await this.getBody() let body = await this.getBody()
@ -56,34 +66,35 @@ export default class Calculator extends base {
} }
} }
async getSet () { async getSet() {
let defSetSkill = '90,90,10,10,10'.split(',') let defSetSkill = this.e.isSr ? '80,80,6,10,10,10'.split(',') : '90,90,10,10,10'.split(',')
let set = this.e.msg.replace(/#||养成|计算/g, '').trim() let set = this.e.msg.replace(/#||星铁|养成|计算/g, '').trim()
set = set.replace(/| /g, ',') set = set.replace(/| /g, ',')
set = set.replace(this.role.alias, '') set = set.replace(this.role.alias, '')
let setSkill = [] let setSkill = []
let length = this.e.isSr ? 6 : 5
if (set) { if (set) {
setSkill = set.split(',') setSkill = set.split(',')
setSkill = lodash.compact(setSkill) setSkill = lodash.compact(setSkill)
for (let i = 0; i <= 4; i++) { for (let i = 0; i < length; i++) {
if (!setSkill[i]) setSkill[i] = defSetSkill[i] if (!setSkill[i]) setSkill[i] = defSetSkill[i]
} }
} else { } else {
setSkill = defSetSkill setSkill = defSetSkill
} }
if (setSkill.length != 5) { if (setSkill.length != length) {
let reMsg = this.checkMsg.replace(/刻晴/g, this.role.alias) let reMsg = this.checkMsg.replace(/刻晴|克拉拉/g, this.role.alias)
await this.e.reply(reMsg) await this.e.reply(reMsg)
return false return false
} }
/** 检查参数 */ /** 检查参数 */
let check = [90, 90, 10, 10, 10] let check = this.e.isSr ? [80, 80, 6, 10, 10, 10] : [90, 90, 10, 10, 10]
for (const key in check) { for (const key in check) {
if (check[key] < Number(setSkill[key])) { if (check[key] < Number(setSkill[key])) {
setSkill[key] = check[key] setSkill[key] = check[key]
@ -93,21 +104,37 @@ export default class Calculator extends base {
this.setSkill = setSkill this.setSkill = setSkill
} }
async getBody () { async getBody() {
// 技能 // 技能
let skillList = [] let skillList = []
if (this.dataCharacter) { if (this.dataCharacter) {
/** 角色存在获取技能数据 */ /** 角色存在获取技能数据 */
let detail = await this.mysApi.getData('detail', { avatar_id: this.role.roleId }) let data = this.e.isSr ? { avatar_id: this.role.roleId, tab_from: 'TabOwned' } : { avatar_id: this.role.roleId }
let detail = await MysInfo.get(this.e, 'detail', {
headers: this.headers,
...data
})
if (!detail || detail.retcode !== 0) return false if (!detail || detail.retcode !== 0) return false
skillList = detail.data.skill_list skillList = detail.data.skill_list || detail.data.skills
} else { } else {
/** 尚未拥有的角色 */ /** 尚未拥有的角色 */
if (this.e.isSr) {
let detail = await MysInfo.get(this.e, 'detail', {
headers: this.headers,
avatar_id: this.role.roleId,
tab_from: 'TabAll'
})
if (!detail || detail.retcode !== 0) return false
this.avatar = detail.data.avatar
skillList = detail.data.skills
} else {
skillList = await this.getSkillId(this.role.roleId) skillList = await this.getSkillId(this.role.roleId)
}
if (!skillList) { if (!skillList) {
this.e.reply('暂无角色数据,请稍后再试') this.e.reply('暂无角色数据,请稍后再试\n星铁角色养成请使用*开头')
return false return false
} }
@ -116,15 +143,36 @@ export default class Calculator extends base {
this.dataCharacter = { this.dataCharacter = {
level: 1, level: 1,
name: this.role.name, name: this.role.name,
icon: `${this.screenData.pluResPath}img/role/${this.role.name}.png`, icon: this.e.isSr ? this.avatar.icon_url : `${this.screenData.pluResPath}img/role/${this.role.name}.png`,
rarity: four.includes(Number(this.role.roleId)) ? 4 : 5 rarity: this.e.isSr ? this.avatar.rarity : four.includes(Number(this.role.roleId)) ? 4 : 5
} }
} }
skillList = skillList.filter((item) => item.max_level != 1)
/** 拼接计算参数 */ /** 拼接计算参数 */
let body = { let body
if (this.e.isSr) {
body = {
game: 'hkrpg',
avatar: {
item_id: Number(this.role.roleId),
cur_level: Number(this.dataCharacter.level),
target_level: Number(this.setSkill[0]),
},
skill_list: []
}
for (let data of skillList) {
let skill = {
item_id: data.point_id,
cur_level: data.cur_level,
target_level: data.target_level
}
if (Number(this.setSkill[0]) >= data.min_level_limit) body.skill_list.push(skill)
}
} else {
skillList = skillList.filter((item) => item.max_level != 1)
body = {
avatar_id: Number(this.role.roleId), avatar_id: Number(this.role.roleId),
avatar_level_current: Number(this.dataCharacter.level), avatar_level_current: Number(this.dataCharacter.level),
avatar_level_target: Number(this.setSkill[0]), avatar_level_target: Number(this.setSkill[0]),
@ -146,27 +194,45 @@ export default class Calculator extends base {
} }
] ]
} }
}
if (this.mysApi.getServer().startsWith('os')) { if (this.mysApi.getServer().startsWith('os')) {
body.lang = "zh-cn" body.lang = "zh-cn"
} }
if (this.e.isSr) {
if (this.dataCharacter.equip) {
body.equipment = {
item_id: Number(this.dataCharacter.equip.id),
cur_level: Number(this.dataCharacter.equip.level),
target_level: Number(this.setSkill[1])
}
}
} else {
if (this.dataCharacter.weapon) { if (this.dataCharacter.weapon) {
if (Number(this.dataCharacter.weapon.rarity) < 3) { if (Number(this.dataCharacter.weapon.rarity) < 3) {
this.setSkill[1] = 70 this.setSkill[1] = 70
} }
body.weapon = { body.weapon = {
id: Number(this.dataCharacter.weapon.id), id: Number(this.dataCharacter.weapon.id),
level_current: Number(this.dataCharacter.weapon.level), level_current: Number(this.dataCharacter.weapon.level),
level_target: Number(this.setSkill[1]) level_target: Number(this.setSkill[1])
} }
} }
}
skillList = skillList.filter((item) => item.max_level != 1)
this.skillList = skillList this.skillList = skillList
return body return body
} }
async getSkillId (roleId) { async getSkillId(roleId) {
let avatarSkill = await this.mysApi.getData('avatarSkill', { avatar_id: roleId }) let avatarSkill = await MysInfo.get(this.e, 'avatarSkill', {
headers: this.headers,
avatar_id: roleId
})
if (!avatarSkill || avatarSkill.retcode !== 0) return false if (!avatarSkill || avatarSkill.retcode !== 0) return false
avatarSkill = avatarSkill.data avatarSkill = avatarSkill.data
avatarSkill.list.forEach((item) => { avatarSkill.list.forEach((item) => {
@ -176,20 +242,20 @@ export default class Calculator extends base {
return avatarSkill.list return avatarSkill.list
} }
async computes (body) { async computes(body) {
let computes = await this.mysApi.getData('compute', body) let computes = await MysInfo.get(this.e, 'compute', body)
if (!computes || computes.retcode !== 0) return false if (!computes || computes.retcode !== 0) return false
computes = computes.data computes = computes.data
let formart = (num) => { let formart = (num) => {
return num > 10000 ? (num / 10000).toFixed(1) + ' w' : num return num > 10000 ? (num / 10000).toFixed(1) + ' w' : num
} }
if (this.e.isSr) delete computes.coin_id
for (let i in computes) { for (let i in computes) {
for (let j in computes[i]) { for (let j in computes[i]) {
computes[i][j].num = formart(computes[i][j].num) computes[i][j].num = formart(computes[i][j].num)
if (computes[i][j].name.includes('「')) { if (computes[i][j][this.e.isSr ? 'item_name' : 'name'].includes('「')) {
computes[i][j].isTalent = true computes[i][j].isTalent = true
} }
} }

View File

@ -64,11 +64,6 @@ export default class GachaLog extends base {
MakeMsg.push(tmpMsg) MakeMsg.push(tmpMsg)
MakeMsg.push(`抽卡记录更新完成,您还可回复\n【#${this?.e?.isSr?'星铁光锥':'武器'}记录】统计${this?.e?.isSr?'星铁光锥':'武器'}池数据\n【#${this?.e?.isSr?'星铁':''}角色统计】按卡池统计数据\n【#导出记录】导出记录数据`) MakeMsg.push(`抽卡记录更新完成,您还可回复\n【#${this?.e?.isSr?'星铁光锥':'武器'}记录】统计${this?.e?.isSr?'星铁光锥':'武器'}池数据\n【#${this?.e?.isSr?'星铁':''}角色统计】按卡池统计数据\n【#导出记录】导出记录数据`)
let Msg = await common.makeForwardMsg(this.e, MakeMsg, tmpMsg) let Msg = await common.makeForwardMsg(this.e, MakeMsg, tmpMsg)
Msg.data=Msg.data
.replace(/\n/g, '')
.replace(/<title color="#777777" size="26">(.+?)<\/title>/g, '___')
.replace(/___+/, `<title color="#777777" size="26">${tmpMsg}</title>`)
await this.e.reply(Msg) await this.e.reply(Msg)
this.isLogUrl = true this.isLogUrl = true

View File

@ -9,7 +9,8 @@ import MysUser from './mys/MysUser.js'
/** 配置文件 */ /** 配置文件 */
class GsCfg { class GsCfg {
constructor () { constructor() {
this.isSr = false
/** 默认设置 */ /** 默认设置 */
this.defSetPath = './plugins/genshin/defSet/' this.defSetPath = './plugins/genshin/defSet/'
this.defSet = {} this.defSet = {}
@ -24,7 +25,7 @@ class GsCfg {
this.ignore = ['mys.pubCk', 'gacha.set', 'bot.help', 'role.name'] this.ignore = ['mys.pubCk', 'gacha.set', 'bot.help', 'role.name']
} }
get element () { get element() {
return { ...this.getdefSet('element', 'role'), ...this.getdefSet('element', 'weapon') } return { ...this.getdefSet('element', 'role'), ...this.getdefSet('element', 'weapon') }
} }
@ -32,12 +33,12 @@ class GsCfg {
* @param app 功能 * @param app 功能
* @param name 配置文件名称 * @param name 配置文件名称
*/ */
getdefSet (app, name) { getdefSet(app, name) {
return this.getYaml(app, name, 'defSet') return this.getYaml(app, name, 'defSet')
} }
/** 用户配置 */ /** 用户配置 */
getConfig (app, name) { getConfig(app, name) {
if (this.ignore.includes(`${app}.${name}`)) { if (this.ignore.includes(`${app}.${name}`)) {
return this.getYaml(app, name, 'config') return this.getYaml(app, name, 'config')
} }
@ -51,7 +52,7 @@ class GsCfg {
* @param name 名称 * @param name 名称
* @param type 默认跑配置-defSet用户配置-config * @param type 默认跑配置-defSet用户配置-config
*/ */
getYaml (app, name, type) { getYaml(app, name, type) {
let file = this.getFilePath(app, name, type) let file = this.getFilePath(app, name, type)
let key = `${app}.${name}` let key = `${app}.${name}`
@ -71,13 +72,13 @@ class GsCfg {
return this[type][key] return this[type][key]
} }
getFilePath (app, name, type) { getFilePath(app, name, type) {
if (type == 'defSet') return `${this.defSetPath}${app}/${name}.yaml` if (type == 'defSet') return `${this.defSetPath}${app}/${name}.yaml`
else return `${this.configPath}${app}.${name}.yaml` else return `${this.configPath}${app}.${name}.yaml`
} }
/** 监听配置文件 */ /** 监听配置文件 */
watch (file, app, name, type = 'defSet') { watch(file, app, name, type = 'defSet') {
let key = `${app}.${name}` let key = `${app}.${name}`
if (this.watcher[type][key]) return if (this.watcher[type][key]) return
@ -95,7 +96,7 @@ class GsCfg {
} }
/** 读取所有用户绑定的ck */ /** 读取所有用户绑定的ck */
async getBingCk (game = 'gs') { async getBingCk(game = 'gs') {
let ck = {} let ck = {}
let ckQQ = {} let ckQQ = {}
let noteCk = {} let noteCk = {}
@ -121,20 +122,20 @@ class GsCfg {
} }
/** 获取qq号绑定ck */ /** 获取qq号绑定ck */
getBingCkSingle (userId) { getBingCkSingle(userId) {
console.log('gsCfg.getBingCkSingle() 即将废弃') console.log('gsCfg.getBingCkSingle() 即将废弃')
return {} return {}
} }
saveBingCk (userId, data) { saveBingCk(userId, data) {
console.log('gsCfg.saveBingCk() 即将废弃') console.log('gsCfg.saveBingCk() 即将废弃')
} }
/** /**
* 原神角色id转换角色名字 * 原神角色id转换角色名字
*/ */
roleIdToName (id) { roleIdToName(id) {
let name = this.getdefSet('role', 'name') let name = this.getdefSet('role', this.isSr ? 'sr_name' : 'name')
if (name[id]) { if (name[id]) {
return name[id][0] return name[id][0]
} }
@ -145,7 +146,7 @@ class GsCfg {
/** /**
* 原神武器id转换成武器名字 * 原神武器id转换成武器名字
*/ */
getWeaponDataByWeaponHash (hash) { getWeaponDataByWeaponHash(hash) {
let data = this.getdefSet('weapon', 'data') let data = this.getdefSet('weapon', 'data')
let weaponData = {} let weaponData = {}
weaponData.name = data.Name[hash] weaponData.name = data.Name[hash]
@ -155,20 +156,22 @@ class GsCfg {
} }
/** 原神角色别名转id */ /** 原神角色别名转id */
roleNameToID (keyword) { roleNameToID(keyword, isSr) {
if (isSr) this.isSr = isSr
if (!isNaN(keyword)) keyword = Number(keyword) if (!isNaN(keyword)) keyword = Number(keyword)
this.getAbbr() this.getAbbr()
let roelId = this.nameID.get(String(keyword)) let roelId = this[this.isSr ? 'sr_nameID' : 'nameID'].get(String(keyword))
return roelId || false return roelId || false
} }
/** 获取角色别名 */ /** 获取角色别名 */
getAbbr () { getAbbr() {
if (this.nameID) return if (this[this.isSr ? 'sr_nameID' : 'nameID']) return
this.nameID = new Map() this.nameID = new Map()
this.sr_nameID = new Map()
let nameArr = this.getdefSet('role', 'name') let nameArr = this.getdefSet('role', 'name')
let sr_nameArr = this.getdefSet('role', 'sr_name')
let nameArrUser = this.getConfig('role', 'name') let nameArrUser = this.getConfig('role', 'name')
let nameID = {} let nameID = {}
@ -180,6 +183,13 @@ class GsCfg {
} }
} }
for (let i in sr_nameArr) {
nameID[sr_nameArr[i][0]] = i
for (let abbr of sr_nameArr[i]) {
this.sr_nameID.set(String(abbr), i)
}
}
for (let i in nameArrUser) { for (let i in nameArrUser) {
for (let abbr of nameArrUser[i]) { for (let abbr of nameArrUser[i]) {
this.nameID.set(String(abbr), nameID[i]) this.nameID.set(String(abbr), nameID[i])
@ -188,8 +198,8 @@ class GsCfg {
} }
/** 返回所有别名,包括用户自定义的 */ /** 返回所有别名,包括用户自定义的 */
getAllAbbr () { getAllAbbr() {
let nameArr = this.getdefSet('role', 'name') let nameArr = this.getdefSet('role', this.isSr ? 'sr_name' : 'name')
let nameArrUser = this.getConfig('role', 'name') let nameArrUser = this.getConfig('role', 'name')
for (let i in nameArrUser) { for (let i in nameArrUser) {
@ -205,7 +215,7 @@ class GsCfg {
* @param name 名称 * @param name 名称
* @param isWeapon 是否武器 * @param isWeapon 是否武器
*/ */
shortName (name, isWeapon = false) { shortName(name, isWeapon = false) {
let other = {} let other = {}
if (isWeapon) { if (isWeapon) {
other = this.getdefSet('weapon', 'other') other = this.getdefSet('weapon', 'other')
@ -216,12 +226,12 @@ class GsCfg {
} }
/** 公共配置ck文件修改hook */ /** 公共配置ck文件修改hook */
async change_myspubCk () { async change_myspubCk() {
await MysInfo.initCache() await MysInfo.initCache()
await MysInfo.initPubCk() await MysInfo.initPubCk()
} }
getGachaSet (groupId = '') { getGachaSet(groupId = '') {
let config = this.getYaml('gacha', 'set', 'config') let config = this.getYaml('gacha', 'set', 'config')
let def = config.default let def = config.default
if (config[groupId]) { if (config[groupId]) {
@ -230,7 +240,7 @@ class GsCfg {
return def return def
} }
getMsgUid (msg) { getMsgUid(msg) {
let ret = /[1|2|5-9][0-9]{8}/g.exec(msg) let ret = /[1|2|5-9][0-9]{8}/g.exec(msg)
if (!ret) return false if (!ret) return false
return ret[0] return ret[0]
@ -245,12 +255,13 @@ class GsCfg {
* @return alias 当前别名 * @return alias 当前别名
* @return uid 游戏uid * @return uid 游戏uid
*/ */
getRole (msg, filterMsg = '') { getRole(msg, filterMsg = '', isSr = false) {
let alias = msg.replace(/#|老婆|老公|[1|2|5-9][0-9]{8}/g, '').trim() let alias = msg.replace(/#|老婆|老公|[1|2|5-9][0-9]{8}/g, '').trim()
if (filterMsg) { if (filterMsg) {
alias = alias.replace(new RegExp(filterMsg, 'g'), '').trim() alias = alias.replace(new RegExp(filterMsg, 'g'), '').trim()
} }
this.isSr = isSr
/** 判断是否命中别名 */ /** 判断是否命中别名 */
let roleId = this.roleNameToID(alias) let roleId = this.roleNameToID(alias)
if (!roleId) return false if (!roleId) return false
@ -265,7 +276,7 @@ class GsCfg {
} }
} }
cpCfg (app, name) { cpCfg(app, name) {
if (!fs.existsSync('./plugins/genshin/config')) { if (!fs.existsSync('./plugins/genshin/config')) {
fs.mkdirSync('./plugins/genshin/config') fs.mkdirSync('./plugins/genshin/config')
} }
@ -279,7 +290,7 @@ class GsCfg {
/** /**
* 根据角色名获取对应的元素类型 * 根据角色名获取对应的元素类型
*/ */
getElementByRoleName (roleName) { getElementByRoleName(roleName) {
let element = this.getdefSet('element', 'role') let element = this.getdefSet('element', 'role')
if (element[roleName]) { if (element[roleName]) {
return element[roleName] return element[roleName]
@ -289,7 +300,7 @@ class GsCfg {
/** /**
* 根据技能id获取对应的技能数据,角色名用于命座加成的技能等级 * 根据技能id获取对应的技能数据,角色名用于命座加成的技能等级
*/ */
getSkillDataByskillId (skillId, roleName) { getSkillDataByskillId(skillId, roleName) {
let skillMap = this.getdefSet('skill', 'data') let skillMap = this.getdefSet('skill', 'data')
let skillData = {} let skillData = {}
if (skillMap.Name[skillId]) { if (skillMap.Name[skillId]) {
@ -304,7 +315,7 @@ class GsCfg {
return skillData return skillData
} }
fightPropIdToName (propId) { fightPropIdToName(propId) {
let propMap = this.getdefSet('prop', 'prop') let propMap = this.getdefSet('prop', 'prop')
if (propMap[propId]) { if (propMap[propId]) {
return propMap[propId] return propMap[propId]
@ -312,7 +323,7 @@ class GsCfg {
return '' return ''
} }
getRoleTalentByTalentId (talentId) { getRoleTalentByTalentId(talentId) {
let talentMap = this.getdefSet('role', 'talent') let talentMap = this.getdefSet('role', 'talent')
let talent = {} let talent = {}
if (talentMap.Name[talentId]) { if (talentMap.Name[talentId]) {

View File

@ -173,6 +173,17 @@ export default class apiTool {
dailyNote: { dailyNote: {
url: `${hostRecord}game_record/app/hkrpg/api/note`, url: `${hostRecord}game_record/app/hkrpg/api/note`,
query: `role_id=${this.uid}&server=${this.server}` query: `role_id=${this.uid}&server=${this.server}`
},
/** 养成计算器 */
compute: {
url: `${host}event/rpgcalc/compute?`,
query:`game=hkrpg`,
body: data
},
/** 详情 */
detail: {
url: `${host}event/rpgcalc/avatar/detail`,
query: `game=hkrpg&lang=zh-cn&item_id=${data.avatar_id}&tab_from=${data.tab_from}&change_target_level=0&uid=${this.uid}&region=${this.server}`
} }
} }
} }

View File

@ -25,7 +25,7 @@ export default class MysInfo {
} }
// ck对应MysUser对象 // ck对应MysUser对象
this.ckUser = null this.ckUser = null
this.auth = ['dailyNote', 'bbs_sign_info', 'bbs_sign_home', 'bbs_sign', 'ys_ledger', 'compute', 'avatarSkill', 'detail', 'blueprint', 'UserGame', 'getFp', 'deckList', 'avatar_cardList', 'action_cardList'] this.auth = ['dailyNote', 'bbs_sign_info', 'bbs_sign_home', 'bbs_sign', 'ys_ledger', 'compute', 'avatarSkill', 'detail', 'blueprint', 'UserGame', 'deckList', 'avatar_cardList', 'action_cardList', 'avatarInfo']
} }
static async init(e, api) { static async init(e, api) {
@ -177,7 +177,7 @@ export default class MysInfo {
} }
for (let i in res) { for (let i in res) {
res[i] = await mysInfo.checkCode(res[i], res[i].api) res[i] = await mysInfo.checkCode(res[i], res[i].api, mysApi)
if (res[i]?.retcode === 0) continue if (res[i]?.retcode === 0) continue
@ -185,7 +185,7 @@ export default class MysInfo {
} }
} else { } else {
res = await mysApi.getData(api, data) res = await mysApi.getData(api, data)
res = await mysInfo.checkCode(res, api) res = await mysInfo.checkCode(res, api, mysApi)
} }
return res return res
@ -335,7 +335,7 @@ export default class MysInfo {
return this.ckUser?.ck return this.ckUser?.ck
} }
async checkCode(res, type) { async checkCode(res, type, mysApi = {}) {
if (!res) { if (!res) {
this.e.reply('米游社接口请求失败,暂时无法查询') this.e.reply('米游社接口请求失败,暂时无法查询')
return false return false

View File

@ -5,16 +5,15 @@ import puppeteer from '../../../lib/puppeteer/puppeteer.js'
import common from '../../../lib/common/common.js' import common from '../../../lib/common/common.js'
import gsCfg from '../model/gsCfg.js' import gsCfg from '../model/gsCfg.js'
const _path = process.cwd()
let emoticon let emoticon
export default class MysNews extends base { export default class MysNews extends base {
constructor (e) { constructor(e) {
super(e) super(e)
this.model = 'mysNews' this.model = 'mysNews'
} }
async getNews () { async getNews(gid) {
let type = 1 let type = 1
let typeName = '公告' let typeName = '公告'
if (this.e.msg.includes('资讯')) { if (this.e.msg.includes('资讯')) {
@ -26,7 +25,7 @@ export default class MysNews extends base {
typeName = '活动' typeName = '活动'
} }
const res = await this.postData('getNewsList', { gids: 2, page_size: 20, type }) const res = await this.postData('getNewsList', { gids: gid, page_size: 20, type })
if (!res) return if (!res) return
const data = res.data.list const data = res.data.list
@ -34,7 +33,7 @@ export default class MysNews extends base {
return true return true
} }
const page = this.e.msg.replace(/#||官方|原神|公告|资讯|活动/g, '').trim() || 1 const page = this.e.msg.replace(/#||官方|星铁|原神|崩坏三|崩三|绝区零|崩坏二|崩二|崩坏学园二|未定|未定事件簿|公告|资讯|活动/g, '').trim() || 1
if (page > data.length) { if (page > data.length) {
await this.e.reply('目前只查前20条最新的公告请输入1-20之间的整数。') await this.e.reply('目前只查前20条最新的公告请输入1-20之间的整数。')
return true return true
@ -42,22 +41,22 @@ export default class MysNews extends base {
const postId = data[page - 1].post.post_id const postId = data[page - 1].post.post_id
const param = await this.newsDetail(postId) const param = await this.newsDetail(postId, gid)
const img = await this.render(param) const img = await this.render(param)
let game = this.game()
return await this.replyMsg(img, `原神${typeName}${param.data.post.subject}`) return this.replyMsg(img, `${game}${typeName}${param.data.post.subject}`)
} }
async render (param) { render(param) {
return await puppeteer.screenshots(this.model, param) return puppeteer.screenshots(this.model, param)
} }
async newsDetail (postId) { async newsDetail(postId, gid) {
const res = await this.postData('getPostFull', { gids: 2, read: 1, post_id: postId }) const res = await this.postData('getPostFull', { gids: gid, read: 1, post_id: postId })
if (!res) return if (!res) return
const data = await this.detalData(res.data.post) const data = await this.detalData(res.data.post, gid)
return { return {
...this.screenData, ...this.screenData,
@ -67,15 +66,15 @@ export default class MysNews extends base {
} }
} }
postApi (type, data) { postApi(type, data) {
let host = 'https://bbs-api-static.mihoyo.com/' let host = 'https://bbs-api.miyoushe.com/'
let param = [] let param = []
lodash.forEach(data, (v, i) => param.push(`${i}=${v}`)) lodash.forEach(data, (v, i) => param.push(`${i}=${v}`))
param = param.join('&') param = param.join('&')
switch (type) { switch (type) {
// 搜索 // 搜索
case 'searchPosts': case 'searchPosts':
host = 'https://bbs-api.mihoyo.com/post/wapi/searchPosts?' host = 'https://bbs-api.miyoushe.com/post/wapi/searchPosts?'
break break
// 帖子详情 // 帖子详情
case 'getPostFull': case 'getPostFull':
@ -92,10 +91,10 @@ export default class MysNews extends base {
return host + param return host + param
} }
async postData (type, data) { async postData(type, data) {
const url = this.postApi(type, data) const url = this.postApi(type, data)
const headers = { const headers = {
Referer: 'https://bbs.mihoyo.com/', Referer: 'https://www.miyoushe.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36' 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
} }
let response let response
@ -114,7 +113,7 @@ export default class MysNews extends base {
return res return res
} }
async detalData (data) { async detalData(data, gid) {
let json let json
try { try {
json = JSON.parse(data.post.content) json = JSON.parse(data.post.content)
@ -134,7 +133,7 @@ export default class MysNews extends base {
} }
if (!emoticon) { if (!emoticon) {
emoticon = await this.mysEmoticon() emoticon = await this.mysEmoticon(gid)
} }
data.post.content = data.post.content.replace(/_\([^)]*\)/g, function (t, e) { data.post.content = data.post.content.replace(/_\([^)]*\)/g, function (t, e) {
@ -161,10 +160,10 @@ export default class MysNews extends base {
return data return data
} }
async mysEmoticon () { async mysEmoticon(gid) {
const emp = new Map() const emp = new Map()
const res = await this.postData('emoticon', { gids: 2 }) const res = await this.postData('emoticon', { gids: gid })
if (res.retcode != 0) { if (res.retcode != 0) {
return emp return emp
@ -181,7 +180,7 @@ export default class MysNews extends base {
return emp return emp
} }
async mysSearch () { async mysSearch() {
let msg = this.e.msg let msg = this.e.msg
msg = msg.replace(/#|米游社|mys/g, '') msg = msg.replace(/#|米游社|mys/g, '')
@ -211,10 +210,10 @@ export default class MysNews extends base {
const img = await this.render(param) const img = await this.render(param)
return await this.replyMsg(img, `${param.data.post.subject}`) return this.replyMsg(img, `${param.data.post.subject}`)
} }
async mysUrl () { async mysUrl() {
let msg = this.e.msg let msg = this.e.msg
let postId = /[0-9]+/g.exec(msg)[0] let postId = /[0-9]+/g.exec(msg)[0]
@ -224,10 +223,10 @@ export default class MysNews extends base {
const img = await this.render(param) const img = await this.render(param)
return await this.replyMsg(img, `${param.data.post.subject}`) return this.replyMsg(img, `${param.data.post.subject}`)
} }
async ysEstimate () { async ysEstimate() {
let msg = '版本原石盘点' let msg = '版本原石盘点'
let res = await this.postData('searchPosts', { gids: 2, size: 20, keyword: msg }) let res = await this.postData('searchPosts', { gids: 2, size: 20, keyword: msg })
if (res?.data?.posts.length <= 0) { if (res?.data?.posts.length <= 0) {
@ -255,86 +254,85 @@ export default class MysNews extends base {
img.push(segment.image(param.data.post.images[0] + '?x-oss-process=image//resize,s_600/quality,q_80/auto-orient,0/interlace,1/format,jpg')) img.push(segment.image(param.data.post.images[0] + '?x-oss-process=image//resize,s_600/quality,q_80/auto-orient,0/interlace,1/format,jpg'))
} }
return await this.replyMsg(img, `${param.data.post.subject}`) return this.replyMsg(img, `${param.data.post.subject}`)
} }
async replyMsg (img, titile) { replyMsg(img, title = '') {
if (!img || img.length <= 0) return false if (!img || img.length <= 0) return false
if (img.length == 1) { if (img.length == 1) {
return img[0] if (title) img.unshift(title)
return img
} else { } else {
let msg = [titile, ...img] return common.makeForwardMsg(this.e, img, title)
return await common.makeForwardMsg(this.e, msg, titile).catch((err) => {
logger.error(err)
})
} }
} }
async mysNewsTask (type = 1) { async mysNewsTask() {
let cfg = gsCfg.getConfig('mys', 'pushNews') let cfg = gsCfg.getConfig('mys', 'pushNews')
// 推送2小时内的公告资讯 // 推送2小时内的公告资讯
let interval = 7200 let interval = 7200
// 最多同时推送两条 // 最多同时推送两条
this.maxNum = cfg.maxNum this.maxNum = cfg.maxNum
// 包含关键字不推送
let banWord = /冒险助力礼包|纪行|预下载|脚本外挂|集中反馈|已开奖|云·原神|魔神任务|传说任务说明/g
let anno = await this.postData('getNewsList', { gids: 2, page_size: 10, type: 1 }) for (let gid of [1, 2, 3, 4, 6, 8]) {
let info = await this.postData('getNewsList', { gids: 2, page_size: 10, type: 3 }) let type = gid == 1 ? 'bbb' : gid == 2 ? 'gs' : gid == 3 ? 'bb' : gid == 4 ? 'wd' : gid == 6 ? 'sr' : 'zzz'
let news = [] let news = []
if (!lodash.isEmpty(cfg[`${type}announceGroup`])) {
let anno = await this.postData('getNewsList', { gids: gid, page_size: 10, type: 1 })
if (anno) anno.data.list.forEach(v => { news.push({ ...v, typeName: '公告', post_id: v.post.post_id }) }) if (anno) anno.data.list.forEach(v => { news.push({ ...v, typeName: '公告', post_id: v.post.post_id }) })
}
if (!lodash.isEmpty(cfg[`${type}infoGroup`])) {
let info = await this.postData('getNewsList', { gids: gid, page_size: 10, type: 3 })
if (info) info.data.list.forEach(v => { news.push({ ...v, typeName: '资讯', post_id: v.post.post_id }) }) if (info) info.data.list.forEach(v => { news.push({ ...v, typeName: '资讯', post_id: v.post.post_id }) })
if (news.length <= 0) return }
if (news.length <= 0) continue
news = lodash.orderBy(news, ['post_id'], ['asc']) news = lodash.orderBy(news, ['post_id'], ['asc'])
let now = Date.now() / 1000 let now = Date.now() / 1000
this.key = 'Yz:genshin:mys:newPush:' this.key = `Yz:${type}:mys:newPush:`
this.e.isGroup = true this.e.isGroup = true
this.pushGroup = [] this.pushGroup = []
for (let val of news) { for (let val of news) {
if (Number(now - val.post.created_at) > interval) { if (Number(now - val.post.created_at) > interval)
continue continue
} if (cfg.banWord[type] && new RegExp(cfg.banWord[type]).test(val.post.subject))
if (new RegExp(banWord).test(val.post.subject)) {
continue continue
} if (val.typeName == '公告')
if (val.typeName == '公告') { for (let botId in cfg[`${type}announceGroup`])
for (let groupId of cfg.announceGroup) { for (let groupId of cfg[`${type}announceGroup`][botId])
await this.sendNews(groupId, val.typeName, val.post.post_id) await this.sendNews(botId, groupId, val.typeName, val.post.post_id, gid)
} if (val.typeName == '资讯')
} for (let botId in cfg[`${type}infoGroup`])
if (val.typeName == '资讯') { for (let groupId of cfg[`${type}infoGroup`][botId])
for (let groupId of cfg.infoGroup) { await this.sendNews(botId, groupId, val.typeName, val.post.post_id, gid)
await this.sendNews(groupId, val.typeName, val.post.post_id)
}
} }
} }
} }
async sendNews (groupId, typeName, postId) { async sendNews(botId, groupId, typeName, postId, gid) {
if (!this.pushGroup[groupId]) this.pushGroup[groupId] = 0 if (!this.pushGroup[groupId]) this.pushGroup[groupId] = 0
if (this.pushGroup[groupId] >= this.maxNum) return if (this.pushGroup[groupId] >= this.maxNum) return
let sended = await redis.get(`${this.key}${groupId}:${postId}`) let sended = await redis.get(`${this.key}${botId}:${groupId}:${postId}`)
if (sended) return if (sended) return
// TODO: 暂时处理,后续待更好的解决方案 定时任务无法获取e.bot let game = this.game(gid)
this.e.bot = Bot
// 判断是否存在群关系 // 判断是否存在群关系
if (!this.e.bot.gl.get(Number(groupId))) { this.e.group = Bot[botId]?.pickGroup(groupId)
logger.mark(`[米游社${typeName}推送] 群${groupId}未关联`) if (!this.e.group) {
logger.mark(`[米游社${game}${typeName}推送] 群${botId}:${groupId}未关联`)
return return
} }
if (!this[postId]) { if (!this[postId]) {
const param = await this.newsDetail(postId) const param = await this.newsDetail(postId, gid)
logger.mark(`[米游社${typeName}推送] ${param.data.post.subject}`) logger.mark(`[米游社${game}${typeName}推送] ${param.data.post.subject}`)
this[postId] = { this[postId] = {
img: await this.render(param), img: await this.render(param),
@ -343,20 +341,28 @@ export default class MysNews extends base {
} }
this.pushGroup[groupId]++ this.pushGroup[groupId]++
this.e.group = this.e.bot.pickGroup(Number(groupId)) await redis.set(`${this.key}${botId}:${groupId}:${postId}`, '1', { EX: 3600 * 10 })
this.e.group_id = Number(groupId) // 随机延迟10-90秒
let tmp = await this.replyMsg(this[postId].img, `原神${typeName}推送:${this[postId].title}`) await common.sleep(lodash.random(10000, 90000))
const msg = await this.replyMsg(this[postId].img, `${game}${typeName}推送:${this[postId].title}`)
await common.sleep(1000) return this.e.group.sendMsg(msg)
if (!tmp) return
if (tmp?.type != 'xml') {
tmp = [`原神${typeName}推送\n`, tmp]
} }
await redis.set(`${this.key}${groupId}:${postId}`, '1', { EX: 3600 * 10 }) game(gid) {
// 随机延迟10-90秒 switch (gid) {
await common.sleep(lodash.random(10, 90) * 1000) case 1:
await this.e.group.sendMsg(tmp) return '崩坏三'
case 2:
return '原神'
case 3:
return '崩坏二'
case 4:
return '未定事件簿'
case 6:
return '崩坏星穹铁道'
case 8:
return '绝区零'
}
return ''
} }
} }

View File

@ -1,284 +0,0 @@
import base from './base.js'
import fetch from 'node-fetch'
import lodash from 'lodash'
import puppeteer from '../../../lib/puppeteer/puppeteer.js'
import common from '../../../lib/common/common.js'
import gsCfg from '../model/gsCfg.js'
let emoticon
export default class MysSrNews extends base {
constructor (e) {
super(e)
this.model = 'mysNews'
}
async getNews () {
let type = 1
let typeName = '公告'
if (this.e.msg.includes('资讯')) {
type = '3'
typeName = '资讯'
}
if (this.e.msg.includes('活动')) {
type = '2'
typeName = '活动'
}
const res = await this.postData('getNewsList', { gids: 6, page_size: 20, type })
if (!res) return
const data = res.data.list
if (data.length == 0) {
return true
}
const page = this.e.msg.replace(/#||星铁|星穹|铁道|公告|资讯|活动/g, '').trim() || 1
if (page > data.length) {
await this.e.reply('目前只查前20条最新的公告请输入1-20之间的整数。')
return true
}
const postId = data[page - 1].post.post_id
const param = await this.newsDetail(postId)
const img = await this.render(param)
return await this.replyMsg(img, `崩坏星穹铁道${typeName}${param.data.post.subject}`)
}
async render (param) {
return await puppeteer.screenshots(this.model, param)
}
async newsDetail (postId) {
const res = await this.postData('getPostFull', { gids: 6, read: 1, post_id: postId })
if (!res) return
const data = await this.detalData(res.data.post)
return {
...this.screenData,
saveId: postId,
dataConent: data.post.content,
data
}
}
postApi (type, data) {
let host = 'https://bbs-api-static.mihoyo.com/'
let param = []
lodash.forEach(data, (v, i) => param.push(`${i}=${v}`))
param = param.join('&')
switch (type) {
// 搜索
case 'searchPosts':
host = 'https://bbs-api.mihoyo.com/post/wapi/searchPosts?'
break
// 帖子详情
case 'getPostFull':
host += 'post/wapi/getPostFull?'
break
// 公告列表
case 'getNewsList':
host += 'post/wapi/getNewsList?'
break
case 'emoticon':
host += 'misc/api/emoticon_set?'
break
}
return host + param
}
async postData (type, data) {
const url = this.postApi(type, data)
const headers = {
Referer: 'https://bbs.mihoyo.com/',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
}
let response
try {
response = await fetch(url, { method: 'get', headers })
} catch (error) {
logger.error(error.toString())
return false
}
if (!response.ok) {
logger.error(`[米游社接口错误][${type}] ${response.status} ${response.statusText}`)
return false
}
const res = await response.json()
return res
}
async detalData (data) {
let json
try {
json = JSON.parse(data.post.content)
} catch (error) {
}
if (typeof json == 'object') {
if (json.imgs && json.imgs.length > 0) {
for (const val of json.imgs) {
data.post.content = ` <div class="ql-image-box"><img src="${val}?x-oss-process=image//resize,s_600/quality,q_80/auto-orient,0/interlace,1/format,png"></div>`
}
}
} else {
for (const img of data.post.images) {
data.post.content = data.post.content.replace(img, img + '?x-oss-process=image//resize,s_600/quality,q_80/auto-orient,0/interlace,1/format,jpg')
}
if (!emoticon) {
emoticon = await this.mysEmoticon()
}
data.post.content = data.post.content.replace(/_\([^)]*\)/g, function (t, e) {
t = t.replace(/_\(|\)/g, '')
if (emoticon.has(t)) {
return `<img class="emoticon-image" src="${emoticon.get(t)}"/>`
} else {
return ''
}
})
const arrEntities = { lt: '<', gt: '>', nbsp: ' ', amp: '&', quot: '"' }
data.post.content = data.post.content.replace(/&(lt|gt|nbsp|amp|quot);/ig, function (all, t) {
return arrEntities[t]
})
}
data.post.created_time = new Date(data.post.created_at * 1000).toLocaleString()
for (const i in data.stat) {
data.stat[i] = data.stat[i] > 10000 ? (data.stat[i] / 10000).toFixed(2) + '万' : data.stat[i]
}
return data
}
async mysEmoticon () {
const emp = new Map()
const res = await this.postData('emoticon', { gids: 6 })
if (res.retcode != 0) {
return emp
}
for (const val of res.data.list) {
if (!val.icon) continue
for (const list of val.list) {
if (!list.icon) continue
emp.set(list.name, list.icon)
}
}
return emp
}
async replyMsg (img, titile) {
if (!img || img.length <= 0) return false
if (img.length == 1) {
return img[0]
} else {
let msg = [titile, ...img]
return await common.makeForwardMsg(this.e, msg, titile).catch((err) => {
logger.error(err)
})
}
}
async mysNewsTask (type = 1) {
let cfg = gsCfg.getConfig('mys', 'pushNews')
// 推送2小时内的公告资讯
let interval = 7200
// 最多同时推送两条
this.maxNum = cfg.maxNum
// 包含关键字不推送
let banWord = /冒险助力礼包|纪行|预下载|脚本外挂|集中反馈|已开奖|云·原神|魔神任务|传说任务说明/g
let anno = await this.postData('getNewsList', { gids: 6, page_size: 10, type: 1 })
let info = await this.postData('getNewsList', { gids: 6, page_size: 10, type: 3 })
let news = []
if (anno) anno.data.list.forEach(v => { news.push({ ...v, typeName: '公告', post_id: v.post.post_id }) })
if (info) info.data.list.forEach(v => { news.push({ ...v, typeName: '资讯', post_id: v.post.post_id }) })
if (news.length <= 0) return
news = lodash.orderBy(news, ['post_id'], ['asc'])
let now = Date.now() / 1000
this.key = 'Yz:genshin:mys:newPush:'
this.e.isGroup = true
this.pushGroup = []
for (let val of news) {
if (Number(now - val.post.created_at) > interval) {
continue
}
if (new RegExp(banWord).test(val.post.subject)) {
continue
}
if (val.typeName == '公告') {
for (let groupId of cfg.srannounceGroup) {
await this.sendNews(groupId, val.typeName, val.post.post_id)
}
}
if (val.typeName == '资讯') {
for (let groupId of cfg.srinfoGroup) {
await this.sendNews(groupId, val.typeName, val.post.post_id)
}
}
}
}
async sendNews (groupId, typeName, postId) {
if (!this.pushGroup[groupId]) this.pushGroup[groupId] = 0
if (this.pushGroup[groupId] >= this.maxNum) return
let sended = await redis.get(`${this.key}${groupId}:${postId}`)
if (sended) return
// TODO: 暂时处理,后续待更好的解决方案 定时任务无法获取e.bot
this.e.bot = Bot
// 判断是否存在群关系
if (!this.e.bot.gl.get(Number(groupId))) {
logger.mark(`[崩坏星穹铁道${typeName}推送] 群${groupId}未关联`)
return
}
if (!this[postId]) {
const param = await this.newsDetail(postId)
logger.mark(`[崩坏星穹铁道${typeName}推送] ${param.data.post.subject}`)
this[postId] = {
img: await this.render(param),
title: param.data.post.subject
}
}
this.pushGroup[groupId]++
this.e.group = Bot.pickGroup(Number(groupId))
this.e.group_id = Number(groupId)
let tmp = await this.replyMsg(this[postId].img, `崩坏星穹铁道${typeName}推送:${this[postId].title}`)
await common.sleep(1000)
if (!tmp) return
if (tmp?.type != 'xml') {
tmp = [`崩坏星穹铁道${typeName}推送\n`, tmp]
}
redis.set(`${this.key}${groupId}:${postId}`, '1', { EX: 3600 * 10 })
// 随机延迟10-90秒
await common.sleep(lodash.random(10, 90) * 1000)
await this.e.group.sendMsg(tmp)
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,135 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<link rel="shortcut icon" href="#" />
<link rel="stylesheet" type="text/css" href="{{pluResPath}}html/calculator/calculator.css" />
</head>
<body>
<div class="container" id="container">
<div class="info_box">
<div class="uidRight">
<span>UID : {{uid}}</span>
</div>
<div class="topLeft">
<span>角色养成计算</span>
</div>
</div>
<div class="head_box">
<div class="item">
<div class="role_box">
{{ if dataCharacter.rank>0}}
<span class="life life{{dataCharacter.rank}}">
{{dataCharacter.rank}}命</span>
{{/if}}
<div class="bg{{dataCharacter.rarity}}">
<img class="role_img" src="{{dataCharacter.icon}}" onerror="whenError(this)" />
</div>
</div>
<div class="role_name">
{{dataCharacter.name}}
<div class="role_LV">Lv.{{dataCharacter.level}} <span class="jt"></span> Lv.{{setSkill[0]}}</div>
</div>
{{ if dataCharacter.equip}}
<div class="weapon_box">
<div class="weapon_bg{{dataCharacter.equip.rarity}}">
<img class="weapon_img" src="{{dataCharacter.equip.icon}}" onerror="whenError(this)" />
</div>
</div>
<div class="weapon_name">
{{dataCharacter.equip.name}}
<div class="weapon_LV">Lv.{{dataCharacter.equip.level}} <span class="jt"></span>
Lv.{{setSkill[1]}}
</div>
</div>
{{/if}}
</div>
{{each skillList skill i}}
<div class="skill">
<div class="skillimg">
<img class="skillimgC" src="{{skill.item_url}}" />
</div>
<div class="skillname">
{{ if skill.anchor=="Point01"}}普通攻击{{else if skill.anchor=="Point02"}}战技{{else if skill.anchor=="Point03"}}终结技{{else}}天赋{{/if}}
<div class="skillLv">Lv.{{skill.max_level}}</div>
</div>
<div class="skillRight">
<div class="skillNow"> {{skill.cur_level}} </div>
<div class="skillJt"><span class="jt"></span></div>
<div class="skillNow"> {{setSkill[i+2]}} </div>
</div>
</div>
{{/each}}
</div>
{{if computes.avatar_consume.length + computes.skill_consume.length + computes.equipment_consume.length > 0}}
<div class="data_box">
{{if computes.avatar_consume.length > 0}}
<div class="role_top">
<div class="role_top_name">{{dataCharacter.name}}</div>
<div class="role_top_LV">Lv.{{dataCharacter.level}} <span class="jt"></span> Lv.{{setSkill[0]}}</div>
</div>
<div class="role_separate_line">角色消耗</div>
<div class="cailiao_box">
{{each computes.avatar_consume avatar_consume}}
<div
class="cailiao_item {{if computes.avatar_consume.length>2 && avatar_consume.item_name == `信用点`}}long{{/if}}">
<div class="cailiao_img">
<img class="cailiao_item_img" src="{{avatar_consume.item_url}}" />
</div>
<div class="cailiao_item_title">{{avatar_consume.item_name}} x {{avatar_consume.num}}</div>
</div>
{{/each}}
</div>
{{/if}}
{{if computes.skill_consume.length > 0}}
<div class="role_separate_line">行迹消耗</div>
<div class="cailiao_box">
{{each computes.skill_consume skill_consume}}
<div class="cailiao_item {{if skill_consume.item_name == `信用点`}}long{{/if}}">
<div class="cailiao_img">
<img class="cailiao_item_img" src="{{skill_consume.item_url}}" />
</div>
<div class="cailiao_item_title {{if skill_consume.isTalent}}isTalent{{/if}}">
{{skill_consume.item_name}} x {{skill_consume.num}}</div>
</div>
{{/each}}
</div>
{{/if}}
{{if computes.equipment_consume.length > 0}}
<div class="role_top">
<div class="role_top_name">{{dataCharacter.equip.name}}</div>
<div class="role_top_LV">Lv.{{dataCharacter.equip.level}} <span class="jt"></span>
Lv.{{setSkill[1]}}</div>
</div>
<div class="role_separate"></div>
<div class="cailiao_box">
{{each computes.equipment_consume equipment_consume}}
<div class="cailiao_item">
<div class="cailiao_img">
<img class="cailiao_item_img" src="{{equipment_consume.item_url}}" />
</div>
<div class="cailiao_item_title">{{equipment_consume.item_name}} x {{equipment_consume.num}}</div>
</div>
{{/each}}
</div>
{{/if}}
</div>
{{else}}
<div class="data_box">
<div class="biye">毕业了,下一位 </div>
</div>
{{/if}}
</div>
</body>
<script type="text/javascript"></script>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

View File

@ -1,10 +1,11 @@
import plugin from '../../lib/plugins/plugin.js' import plugin from '../../lib/plugins/plugin.js'
import common from '../../lib/common/common.js'
import fs from 'node:fs' import fs from 'node:fs'
import lodash from 'lodash' import lodash from 'lodash'
import moment from 'moment' import moment from 'moment'
export class sendLog extends plugin { export class sendLog extends plugin {
constructor () { constructor() {
super({ super({
name: '发送日志', name: '发送日志',
dsc: '发送最近100条运行日志', dsc: '发送最近100条运行日志',
@ -25,7 +26,7 @@ export class sendLog extends plugin {
this.errFile = './logs/error.log' this.errFile = './logs/error.log'
} }
async sendLog () { async sendLog() {
let lineNum = this.e.msg.match(/\d+/g) let lineNum = this.e.msg.match(/\d+/g)
if (lineNum) { if (lineNum) {
this.lineNum = lineNum[0] this.lineNum = lineNum[0]
@ -48,13 +49,14 @@ export class sendLog extends plugin {
this.reply(`暂无相关日志:${type}`) this.reply(`暂无相关日志:${type}`)
return return
} }
let title = `最近${log.length}${type}日志`
let forwardMsg = await this.makeForwardMsg(`最近${log.length}${type}日志`, log) let forwardMsg = await common.makeForwardMsg(this.e, [title, log.join("")], title)
await this.reply(forwardMsg) await this.reply(forwardMsg)
} }
getLog (logFile) { getLog(logFile) {
let log = fs.readFileSync(logFile, { encoding: 'utf-8' }) let log = fs.readFileSync(logFile, { encoding: 'utf-8' })
log = log.split('\n') log = log.split('\n')
@ -78,42 +80,4 @@ export class sendLog extends plugin {
return tmp return tmp
} }
async makeForwardMsg (title, msg) {
let nickname = this.e.bot.nickname
if (this.e.isGroup) {
let info = await this.e.bot.getGroupMemberInfo(this.e.group_id, this.e.bot.uin)
nickname = info.card ?? info.nickname
}
let userInfo = {
user_id: this.e.bot.uin,
nickname
}
let forwardMsg = [
{
...userInfo,
message: title
},
{
...userInfo,
message: msg
}
]
/** 制作转发内容 */
if (this.e.isGroup) {
forwardMsg = await this.e.group.makeForwardMsg(forwardMsg)
} else {
forwardMsg = await this.e.friend.makeForwardMsg(forwardMsg)
}
/** 处理描述 */
forwardMsg.data = forwardMsg.data
.replace(/\n/g, '')
.replace(/<title color="#777777" size="26">(.+?)<\/title>/g, '___')
.replace(/___+/, `<title color="#777777" size="26">${title}</title>`)
return forwardMsg
}
} }

View File

@ -11,7 +11,7 @@ const { exec, execSync } = require('child_process')
let uping = false let uping = false
export class update extends plugin { export class update extends plugin {
constructor () { constructor() {
super({ super({
name: '更新', name: '更新',
dsc: '#更新 #强制更新', dsc: '#更新 #强制更新',
@ -37,7 +37,7 @@ export class update extends plugin {
this.typeName = 'Miao-Yunzai' this.typeName = 'Miao-Yunzai'
} }
async update () { async update() {
if (!this.e.isMaster) return false if (!this.e.isMaster) return false
if (uping) { if (uping) {
await this.reply('已有命令更新中..请勿重复操作') await this.reply('已有命令更新中..请勿重复操作')
@ -64,7 +64,7 @@ export class update extends plugin {
} }
} }
async checkGit () { async checkGit() {
let ret = await execSync('git --version', { encoding: 'utf-8' }) let ret = await execSync('git --version', { encoding: 'utf-8' })
if (!ret || !ret.includes('git version')) { if (!ret || !ret.includes('git version')) {
await this.reply('请先安装git') await this.reply('请先安装git')
@ -74,21 +74,19 @@ export class update extends plugin {
return true return true
} }
getPlugin (plugin = '') { getPlugin(plugin = '') {
if (!plugin) { if (!plugin) {
plugin = this.e.msg.replace(/#|更新|强制/g, '') plugin = this.e.msg.replace(/#|更新|强制/g, '')
if (!plugin) return '' if (!plugin) return ''
} }
let path = `./plugins/${plugin}/.git` if (!fs.existsSync(`plugins/${plugin}/.git`)) return false
if (!fs.existsSync(path)) return false
this.typeName = plugin this.typeName = plugin
return plugin return plugin
} }
async execSync (cmd) { async execSync(cmd) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
exec(cmd, { windowsHide: true }, (error, stdout, stderr) => { exec(cmd, { windowsHide: true }, (error, stdout, stderr) => {
resolve({ error, stdout, stderr }) resolve({ error, stdout, stderr })
@ -96,7 +94,7 @@ export class update extends plugin {
}) })
} }
async runUpdate (plugin = '') { async runUpdate(plugin = '') {
this.isNowUp = false this.isNowUp = false
let cm = 'git pull --no-rebase' let cm = 'git pull --no-rebase'
@ -104,17 +102,15 @@ export class update extends plugin {
let type = '更新' let type = '更新'
if (this.e.msg.includes('强制')) { if (this.e.msg.includes('强制')) {
type = '强制更新' type = '强制更新'
cm = `git fetch --all && git reset --hard && ${cm}` cm = `git reset --hard && git pull --rebase --allow-unrelated-histories`
} }
if (plugin) { if (plugin) {
if (this.e.msg.includes('强制')) { if (type == '强制更新')
type = '强制更新' cm = `cd "plugins/${plugin}" && git reset --hard && git pull --rebase --allow-unrelated-histories`
cm = `git -C ./plugins/${plugin}/ fetch --all && git -C ./plugins/${plugin}/ reset --hard && git -C ./plugins/${plugin}/ pull` else
}else{ cm = `cd "plugins/${plugin}" && git pull --no-rebase`
cm = `git -C ./plugins/${plugin}/ pull --no-rebase`
} }
}
this.oldCommitId = await this.getcommitId(plugin) this.oldCommitId = await this.getcommitId(plugin)
@ -147,10 +143,10 @@ export class update extends plugin {
return true return true
} }
async getcommitId (plugin = '') { async getcommitId(plugin = '') {
let cm = 'git rev-parse --short HEAD' let cm = 'git rev-parse --short HEAD'
if (plugin) { if (plugin) {
cm = `git -C ./plugins/${plugin}/ rev-parse --short HEAD` cm = `cd "plugins/${plugin}" && git rev-parse --short HEAD`
} }
let commitId = await execSync(cm, { encoding: 'utf-8' }) let commitId = await execSync(cm, { encoding: 'utf-8' })
@ -159,10 +155,10 @@ export class update extends plugin {
return commitId return commitId
} }
async getTime (plugin = '') { async getTime(plugin = '') {
let cm = 'git log -1 --oneline --pretty=format:"%cd" --date=format:"%m-%d %H:%M"' let cm = 'git log -1 --pretty=format:"%cd" --date=format:"%F %T"'
if (plugin) { if (plugin) {
cm = `cd ./plugins/${plugin}/ && git log -1 --oneline --pretty=format:"%cd" --date=format:"%m-%d %H:%M"` cm = `cd "plugins/${plugin}" && git log -1 --pretty=format:"%cd" --date=format:"%F %T"`
} }
let time = '' let time = ''
@ -177,7 +173,7 @@ export class update extends plugin {
return time return time
} }
async gitErr (err, stdout) { async gitErr(err, stdout) {
let msg = '更新失败!' let msg = '更新失败!'
let errMsg = err.toString() let errMsg = err.toString()
stdout = stdout.toString() stdout = stdout.toString()
@ -207,7 +203,7 @@ export class update extends plugin {
await this.reply([errMsg, stdout]) await this.reply([errMsg, stdout])
} }
async updateAll () { async updateAll() {
let dirs = fs.readdirSync('./plugins/') let dirs = fs.readdirSync('./plugins/')
await this.runUpdate() await this.runUpdate()
@ -225,14 +221,14 @@ export class update extends plugin {
} }
} }
restart () { restart() {
new Restart(this.e).restart() new Restart(this.e).restart()
} }
async getLog (plugin = '') { async getLog(plugin = '') {
let cm = 'git log -20 --oneline --pretty=format:"%h||[%cd] %s" --date=format:"%m-%d %H:%M"' let cm = 'git log -20 --pretty=format:"%h||[%cd] %s" --date=format:"%F %T"'
if (plugin) { if (plugin) {
cm = `cd ./plugins/${plugin}/ && ${cm}` cm = `cd "plugins/${plugin}" && ${cm}`
} }
let logAll let logAll
@ -259,59 +255,14 @@ export class update extends plugin {
if (log.length <= 0) return '' if (log.length <= 0) return ''
let end = '' let title = `${plugin || 'Miao-Yunzai'}更新日志,共${line}`
log = await this.makeForwardMsg(`${plugin || 'Miao-Yunzai'}更新日志,共${line}`, log, end) log = await common.makeForwardMsg(this.e, [title, log], title)
return log return log
} }
async makeForwardMsg (title, msg, end) { async updateLog() {
let nickname = this.e.bot.nickname
if (this.e.isGroup) {
let info = await this.e.bot.getGroupMemberInfo(this.e.group_id, this.e.bot.uin)
nickname = info.card ?? info.nickname
}
let userInfo = {
user_id: this.e.bot.uin,
nickname
}
let forwardMsg = [
{
...userInfo,
message: title
},
{
...userInfo,
message: msg
}
]
if (end) {
forwardMsg.push({
...userInfo,
message: end
})
}
/** 制作转发内容 */
if (this.e.isGroup) {
forwardMsg = await this.e.group.makeForwardMsg(forwardMsg)
} else {
forwardMsg = await this.e.friend.makeForwardMsg(forwardMsg)
}
/** 处理描述 */
forwardMsg.data = forwardMsg.data
.replace(/\n/g, '')
.replace(/<title color="#777777" size="26">(.+?)<\/title>/g, '___')
.replace(/___+/, `<title color="#777777" size="26">${title}</title>`)
return forwardMsg
}
async updateLog () {
let log = await this.getLog() let log = await this.getLog()
await this.reply(log) await this.reply(log)
} }

View File

@ -1,9 +1,8 @@
import cfg from '../../lib/config/config.js' import cfg from '../../lib/config/config.js'
import plugin from '../../lib/plugins/plugin.js' import plugin from '../../lib/plugins/plugin.js'
import common from '../../lib/common/common.js'
import fs from 'node:fs' import fs from 'node:fs'
import lodash from 'lodash' import lodash from 'lodash'
import { segment } from 'icqq'
import { pipeline } from 'stream' import { pipeline } from 'stream'
import { promisify } from 'util' import { promisify } from 'util'
import fetch from 'node-fetch' import fetch from 'node-fetch'
@ -12,7 +11,7 @@ import moment from 'moment'
let textArr = {} let textArr = {}
export class add extends plugin { export class add extends plugin {
constructor () { constructor() {
super({ super({
name: '添加表情', name: '添加表情',
dsc: '添加表情,文字等', dsc: '添加表情,文字等',
@ -45,7 +44,7 @@ export class add extends plugin {
this.isGlobal = false this.isGlobal = false
} }
async init () { async init() {
if (!fs.existsSync(this.path)) { if (!fs.existsSync(this.path)) {
fs.mkdirSync(this.path) fs.mkdirSync(this.path)
} }
@ -54,7 +53,7 @@ export class add extends plugin {
} }
} }
async accept () { async accept() {
/** 处理消息 */ /** 处理消息 */
if (this.e.atBot && this.e.msg && this.e?.msg.includes('添加') && !this.e?.msg.includes('#')) { if (this.e.atBot && this.e.msg && this.e?.msg.includes('添加') && !this.e?.msg.includes('#')) {
this.e.msg = '#' + this.e.msg this.e.msg = '#' + this.e.msg
@ -62,12 +61,12 @@ export class add extends plugin {
} }
/** 群号key */ /** 群号key */
get grpKey () { get grpKey() {
return `Yz:group_id:${this.e.user_id}` return `Yz:group_id:${this.e.user_id}`
} }
/** #添加 */ /** #添加 */
async add () { async add() {
this.isGlobal = this.e?.msg.includes("全局"); this.isGlobal = this.e?.msg.includes("全局");
await this.getGroupId() await this.getGroupId()
@ -95,8 +94,7 @@ export class add extends plugin {
} }
/** 获取群号 */ /** 获取群号 */
async getGroupId () { async getGroupId() {
/** 添加全局表情存入到机器人qq文件中 */ /** 添加全局表情存入到机器人qq文件中 */
if (this.isGlobal) { if (this.isGlobal) {
this.group_id = this.e.bot.uin; this.group_id = this.e.bot.uin;
@ -119,7 +117,7 @@ export class add extends plugin {
return false return false
} }
checkAuth () { checkAuth() {
if (this.e.isMaster) return true if (this.e.isMaster) return true
let groupCfg = cfg.getGroup(this.group_id) let groupCfg = cfg.getGroup(this.group_id)
@ -148,7 +146,7 @@ export class add extends plugin {
return true return true
} }
checkKeyWord () { checkKeyWord() {
if (this.e.img && this.e.img.length > 1) { if (this.e.img && this.e.img.length > 1) {
this.e.reply('添加错误:只能发送一个表情当关键词') this.e.reply('添加错误:只能发送一个表情当关键词')
return false return false
@ -171,7 +169,7 @@ export class add extends plugin {
} }
/** 单独添加 */ /** 单独添加 */
async singleAdd () { async singleAdd() {
if (this.e.message.length != 2) return false if (this.e.message.length != 2) return false
let msg = lodash.keyBy(this.e.message, 'type') let msg = lodash.keyBy(this.e.message, 'type')
if (!this.e.msg || !msg.image) return false if (!this.e.msg || !msg.image) return false
@ -194,7 +192,7 @@ export class add extends plugin {
} }
/** 获取添加关键词 */ /** 获取添加关键词 */
getKeyWord () { getKeyWord() {
this.e.isGlobal = this.e.msg.includes("全局"); this.e.isGlobal = this.e.msg.includes("全局");
this.keyWord = this.e.toString() this.keyWord = this.e.toString()
@ -214,7 +212,7 @@ export class add extends plugin {
} }
/** 过滤别名 */ /** 过滤别名 */
trimAlias (msg) { trimAlias(msg) {
let groupCfg = cfg.getGroup(this.group_id) let groupCfg = cfg.getGroup(this.group_id)
let alias = groupCfg.botAlias let alias = groupCfg.botAlias
if (!Array.isArray(alias)) { if (!Array.isArray(alias)) {
@ -230,7 +228,7 @@ export class add extends plugin {
} }
/** 添加内容 */ /** 添加内容 */
async addContext () { async addContext() {
this.isGlobal = this.e.isGlobal || this.getContext()?.addContext?.isGlobal; this.isGlobal = this.e.isGlobal || this.getContext()?.addContext?.isGlobal;
await this.getGroupId() await this.getGroupId()
/** 关键词 */ /** 关键词 */
@ -287,7 +285,7 @@ export class add extends plugin {
} }
/** 添加成功回复消息 */ /** 添加成功回复消息 */
getRetMsg () { getRetMsg() {
let retMsg = this.getContext() let retMsg = this.getContext()
let msg = '' let msg = ''
if (retMsg?.addContext?.message) { if (retMsg?.addContext?.message) {
@ -316,7 +314,7 @@ export class add extends plugin {
return lodash.compact(msg) return lodash.compact(msg)
} }
saveJson () { saveJson() {
let obj = {} let obj = {}
for (let [k, v] of textArr[this.group_id]) { for (let [k, v] of textArr[this.group_id]) {
obj[k] = v obj[k] = v
@ -337,7 +335,7 @@ export class add extends plugin {
); );
} }
async saveImg (url, keyWord) { async saveImg(url, keyWord) {
let groupCfg = cfg.getGroup(this.group_id) let groupCfg = cfg.getGroup(this.group_id)
let savePath = `${this.facePath}${this.group_id}/` let savePath = `${this.facePath}${this.group_id}/`
@ -375,7 +373,7 @@ export class add extends plugin {
return savePath return savePath
} }
async getText () { async getText() {
if (!this.e.message) return false if (!this.e.message) return false
this.isGlobal = false this.isGlobal = false
@ -446,7 +444,7 @@ export class add extends plugin {
return true return true
} }
expiredMsg (keyWord, num) { expiredMsg(keyWord, num) {
logger.mark(`[发送表情]${this.e.logText} ${keyWord} 表情已过期失效`) logger.mark(`[发送表情]${this.e.logText} ${keyWord} 表情已过期失效`)
let arr = textArr[this.group_id].get(keyWord) let arr = textArr[this.group_id].get(keyWord)
@ -462,7 +460,7 @@ export class add extends plugin {
} }
/** 初始化已添加内容 */ /** 初始化已添加内容 */
initTextArr () { initTextArr() {
if (textArr[this.group_id]) return if (textArr[this.group_id]) return
textArr[this.group_id] = new Map() textArr[this.group_id] = new Map()
@ -568,7 +566,7 @@ export class add extends plugin {
} }
} }
async del () { async del() {
this.isGlobal = this.e?.msg.includes("全局"); this.isGlobal = this.e?.msg.includes("全局");
await this.getGroupId() await this.getGroupId()
if (!this.group_id) return false if (!this.group_id) return false
@ -652,14 +650,14 @@ export class add extends plugin {
img = item[0] img = item[0]
} }
if (img.local) { if (img.local) {
fs.unlink(img.local, () => {}) fs.unlink(img.local, () => { })
} }
}) })
this.saveJson() this.saveJson()
} }
async list () { async list() {
this.isGlobal = this.e?.msg.includes("全局"); this.isGlobal = this.e?.msg.includes("全局");
let page = 1 let page = 1
@ -727,9 +725,8 @@ export class add extends plugin {
num++ num++
} }
let end = ''
if (type == 'list' && count > 100) { if (type == 'list' && count > 100) {
end = `更多内容请翻页查看\n如:#表情列表${Number(page) + 1}` msg.push(`更多内容请翻页查看\n如:#表情列表${Number(page) + 1}`)
} }
let title = `表情列表,第${page}页,共${count}` let title = `表情列表,第${page}页,共${count}`
@ -737,63 +734,19 @@ export class add extends plugin {
title = `表情${search}${count}` title = `表情${search}${count}`
} }
let forwardMsg = await this.makeForwardMsg(this.e.bot.uin, title, msg, end) let forwardMsg = await common.makeForwardMsg(this.e, [title, msg], title)
this.e.reply(forwardMsg) this.e.reply(forwardMsg)
} }
async makeForwardMsg (qq, title, msg, end = '') {
let nickname = this.e.bot.nickname
if (this.e.isGroup) {
let info = await this.e.bot.getGroupMemberInfo(this.e.group_id, qq)
nickname = info.card ?? info.nickname
}
let userInfo = {
user_id: this.e.bot.uin,
nickname
}
let forwardMsg = [
{
...userInfo,
message: title
}
]
let msgArr = lodash.chunk(msg, 40)
msgArr.forEach(v => {
v[v.length - 1] = lodash.trim(v[v.length - 1], '\n')
forwardMsg.push({ ...userInfo, message: v })
})
if (end) {
forwardMsg.push({ ...userInfo, message: end })
}
/** 制作转发内容 */
if (this.e.isGroup) {
forwardMsg = await this.e.group.makeForwardMsg(forwardMsg)
} else {
forwardMsg = await this.e.friend.makeForwardMsg(forwardMsg)
}
/** 处理描述 */
forwardMsg.data = forwardMsg.data
.replace(/\n/g, '')
.replace(/<title color="#777777" size="26">(.+?)<\/title>/g, '___')
.replace(/___+/, `<title color="#777777" size="26">${title}</title>`)
return forwardMsg
}
/** 分页 */ /** 分页 */
pagination (pageNo, pageSize, array) { pagination(pageNo, pageSize, array) {
let offset = (pageNo - 1) * pageSize let offset = (pageNo - 1) * pageSize
return offset + pageSize >= array.length ? array.slice(offset, array.length) : array.slice(offset, offset + pageSize) return offset + pageSize >= array.length ? array.slice(offset, array.length) : array.slice(offset, offset + pageSize)
} }
/** 关键词转换成可发送消息 */ /** 关键词转换成可发送消息 */
async keyWordTran (msg) { async keyWordTran(msg) {
/** 图片 */ /** 图片 */
if (msg.includes('{image')) { if (msg.includes('{image')) {
let tmp = msg.split('{image') let tmp = msg.split('{image')