diff --git a/config/default_config/bot.yaml b/config/default_config/bot.yaml index 919080f..0e0fc3c 100644 --- a/config/default_config/bot.yaml +++ b/config/default_config/bot.yaml @@ -22,5 +22,7 @@ online_msg: true # 上线推送通知的冷却时间 online_msg_exp: 86400 -# 签名API地址 +# 签名API地址(如:http://127.0.0.1:8080/sign?key=114514) sign_api_addr: +# 传入的QQ版本(如:8.9.63、8.9.68) +ver: \ No newline at end of file diff --git a/lib/bot.js b/lib/bot.js index f23da06..4dbb3f6 100644 --- a/lib/bot.js +++ b/lib/bot.js @@ -15,6 +15,7 @@ export default class Yunzai extends Client { /** 加载icqq事件监听 */ await ListenerLoader.load(bot) await bot.login(cfg.qq, cfg.pwd) + bot[bot.uin] = bot return bot } } diff --git a/lib/common/common.js b/lib/common/common.js index 84a8a17..6de7879 100644 --- a/lib/common/common.js +++ b/lib/common/common.js @@ -9,7 +9,7 @@ import path from 'node:path' * @param user_id qq号 * @param msg 消息 */ -async function relpyPrivate (userId, msg) { +async function relpyPrivate(userId, msg) { userId = Number(userId) let friend = Bot.fl.get(userId) @@ -25,7 +25,7 @@ async function relpyPrivate (userId, msg) { * 休眠函数 * @param ms 毫秒 */ -function sleep (ms) { +function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)) } @@ -34,7 +34,7 @@ function sleep (ms) { * @param fileUrl 下载地址 * @param savePath 保存路径 */ -async function downFile (fileUrl, savePath, param = {}) { +async function downFile(fileUrl, savePath, param = {}) { try { mkdirs(path.dirname(savePath)) logger.debug(`[下载文件] ${fileUrl}`) @@ -48,7 +48,7 @@ async function downFile (fileUrl, savePath, param = {}) { } } -function mkdirs (dirname) { +function mkdirs(dirname) { if (fs.existsSync(dirname)) { return true } else { @@ -61,19 +61,20 @@ function mkdirs (dirname) { /** * 制作转发消息 - * @param e icqq消息e + * @param e 消息事件 * @param msg 消息数组 * @param dec 转发描述 - * @param msgsscr 转发信息是否为Bot + * @param msgsscr 转发信息是否伪装 */ -async function makeForwardMsg (e, msg = [], dec = '', msgsscr = false) { - // 是频道直接返回 join - if (e.isGuild) return msg.join('\n') +async function makeForwardMsg(e, msg = [], dec = '', msgsscr = false) { + if (!Array.isArray(msg)) msg = [msg] + + 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) { - 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 = { @@ -82,28 +83,37 @@ async function makeForwardMsg (e, msg = [], dec = '', msgsscr = false) { } let forwardMsg = [] - msg.forEach(msg => { + for (const message of msg){ + if(!message) continue forwardMsg.push({ ...userInfo, - message: msg + message: message }) - }) + } + /** 制作转发内容 */ - if (e.isGroup) { + if (e?.group?.makeForwardMsg) { forwardMsg = await e.group.makeForwardMsg(forwardMsg) - } else if (e.friend) { + } else if (e?.friend?.makeForwardMsg) { forwardMsg = await e.friend.makeForwardMsg(forwardMsg) } else { - return false + return msg.join('\n') } if (dec) { /** 处理描述 */ - forwardMsg.data = forwardMsg.data - .replace(/\n/g, '') - .replace(/(.+?)<\/title>/g, '___') - .replace(/___+/, `<title color="#777777" size="26">${dec}`) + if (typeof (forwardMsg.data) === 'object') { + let detail = forwardMsg.data?.meta?.detail + if (detail) { + detail.news = [{ text: dec }] + } + } else { + forwardMsg.data = forwardMsg.data + .replace(/\n/g, '') + .replace(/(.+?)<\/title>/g, '___') + .replace(/___+/, `<title color="#777777" size="26">${dec}`) + } } return forwardMsg diff --git a/package.json b/package.json index 4ff66c2..4faa8dc 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "chalk": "^5.2.0", "chokidar": "^3.5.3", "https-proxy-agent": "5.0.1", - "icqq": "^0.4.11", + "icqq": "^0.4.12", "image-size": "^1.0.2", "inquirer": "^8.2.5", "lodash": "^4.17.21", diff --git a/plugins/genshin/apps/abbrSet.js b/plugins/genshin/apps/abbrSet.js index 3063eb2..48c1569 100644 --- a/plugins/genshin/apps/abbrSet.js +++ b/plugins/genshin/apps/abbrSet.js @@ -1,11 +1,12 @@ import plugin from '../../../lib/plugins/plugin.js' +import common from '../../../lib/common/common.js' import fs from 'node:fs' import gsCfg from '../model/gsCfg.js' import YAML from 'yaml' import lodash from 'lodash' export class abbrSet extends plugin { - constructor (e) { + constructor(e) { super({ name: '别名设置', dsc: '角色别名设置', @@ -13,24 +14,24 @@ export class abbrSet extends plugin { priority: 600, rule: [ { - reg: '^#(设置|配置)(.*)(别名|昵称)$', + reg: '^#(星铁)?(设置|配置)(.*)(别名|昵称)$', fnc: 'abbr' }, { - reg: '^#删除(别名|昵称)(.*)$', + reg: '^#(星铁)?删除(别名|昵称)(.*)$', fnc: 'delAbbr' }, { - reg: '^#(.*)(别名|昵称)$', + reg: '^#(星铁)?(.*)(别名|昵称)$', fnc: 'abbrList' } ] }) - + this.isSr = false this.file = './plugins/genshin/config/role.name.yaml' } - async init () { + async init() { if (!fs.existsSync(this.file)) { fs.writeFileSync(this.file, `神里绫华: - 龟龟 @@ -38,17 +39,18 @@ export class abbrSet extends plugin { } } - async abbr () { + async abbr() { 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 this.e.role = role + this.isSr = this.e.isSr this.setContext('setAbbr') await this.reply(`请发送${role.alias}别名,多个用空格隔开`) } - async checkAuth () { + async checkAuth() { if (!this.e.isGroup && !this.e.isMaster) { await this.reply('禁止私聊设置角色别名') return false @@ -76,7 +78,7 @@ export class abbrSet extends plugin { return true } - async setAbbr () { + async setAbbr() { if (!this.e.msg || this.e.at || this.e.img) { await this.reply('设置错误:请发送正确内容') return @@ -96,10 +98,10 @@ export class abbrSet extends plugin { let ret = [] for (let name of setName) { - name = name.replace(/#|设置|配置|别名|昵称/g, '') + name = name.replace(/#|星铁|设置|配置|别名|昵称/g, '') if (!name) continue /** 重复添加 */ - if (nameArr[role.name].includes(name) || gsCfg.roleNameToID(name)) { + if (nameArr[role.name].includes(name) || gsCfg.roleNameToID(name, this.isSr)) { continue } @@ -113,19 +115,18 @@ export class abbrSet extends plugin { this.save(nameArr) - gsCfg.nameID = false + gsCfg[this.isSr ? 'sr_nameID' : 'nameID'] = false await this.reply(`设置别名成功:${ret.join('、')}`) } - save (data) { + save(data) { data = YAML.stringify(data) fs.writeFileSync(this.file, data) } - async delAbbr () { - let role = gsCfg.getRole(this.e.msg, '#|删除|别名|昵称') - + async delAbbr() { + let role = gsCfg.getRole(this.e.msg, '#|星铁|删除|别名|昵称', this.e.isSr) if (!role) return false let nameArr = gsCfg.getConfig('role', 'name') @@ -145,12 +146,12 @@ export class abbrSet extends plugin { await this.reply(`设置${role.name}别名成功:${role.alias}`) } - async abbrList () { - let role = gsCfg.getRole(this.e.msg, '#|别名|昵称') + async abbrList() { + let role = gsCfg.getRole(this.e.msg, '#|星铁|别名|昵称', this.e.isSr) 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 list = lodash.uniq([...name, ...nameUser]) @@ -158,51 +159,13 @@ export class abbrSet extends plugin { let msg = [] for (let i in list) { let num = Number(i) + 1 - msg.push(`${num}.${list[i]}\n`) + msg.push(`${num}.${list[i]}`) } 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) } - - 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>/g, '___') - .replace(/___+/, `<title color="#777777" size="26">${title}`) - - return forwardMsg - } } diff --git a/plugins/genshin/apps/calculator.js b/plugins/genshin/apps/calculator.js index 75e6614..9766fee 100644 --- a/plugins/genshin/apps/calculator.js +++ b/plugins/genshin/apps/calculator.js @@ -5,7 +5,7 @@ import puppeteer from '../../../lib/puppeteer/puppeteer.js' import gsCfg from '../model/gsCfg.js' export class calculator extends plugin { - constructor () { + constructor() { super({ name: '养成计算', dsc: '角色养成材料计算器', @@ -13,47 +13,48 @@ export class calculator extends plugin { priority: 700, rule: [ { - reg: '^#*(.*)(养成|计算)([0-9]|,|,| )*$', + reg: '^#*(星铁)?(.*)(养成|计算)([0-9]|,|,| )*$', fnc: 'Calculator' }, { - reg: '^#*角色(养成|计算|养成计算)$', + reg: '^#*(星铁)?角色(养成|计算|养成计算)$', fnc: 'calculatorHelp' }, - { - reg: '^#*尘歌壶模数(养成|计算|养成计算)$', - fnc: 'blueprintHelp' - }, - { - reg: '^#*尘歌壶(模数|养成|养成计算)(\\d{10,15})$', - fnc: 'Blueprint' - }, + { + reg: '^#*尘歌壶模数(养成|计算|养成计算)$', + fnc: 'blueprintHelp' + }, + { + reg: '^#*尘歌壶(模数|养成|养成计算)(\\d{10,15})$', + fnc: 'Blueprint' + }, ] }) + this._path = process.cwd().replace(/\\/g, '/') } - async blueprintHelp (e) { + async blueprintHelp(e) { let msg = '#尘歌壶模数\n指令:#尘歌壶模数\n示例:#尘歌壶模数123456\n参数为模数id(10-15位数字)' await e.reply(msg) return true } - - async calculatorHelp (e) { - let msg = '#角色养成计算\n指令:#刻晴养成\n示例:#刻晴养成81 90 9 9 9\n参数为角色、武器、技能等级' + + async calculatorHelp(e) { + let msg = `角色养成计算\n指令:${e.isSr ? '*克拉拉养成\n示例:*克拉拉养成75 80 6 9 9 9\n参数为角色、武器、普攻、战技、终结技、天赋' : '#刻晴养成\n示例:#刻晴养成81 90 9 9 9\n参数为角色、武器、技能等级'}` await e.reply(msg) return true } - async Blueprint(){ - let role = this.e.msg.replace(/#/,'').match(/\d+/g); - let data = await new Blueprint(this.e).get(role) - if (!data) return - - /** 生成图片 */ - let img = await puppeteer.screenshot('Blueprint', data) - if (img) await this.reply(img) + async Blueprint() { + let role = this.e.msg.replace(/#/, '').match(/\d+/g); + let data = await new Blueprint(this.e).get(role) + if (!data) return + + /** 生成图片 */ + let img = await puppeteer.screenshot('Blueprint', data) + if (img) await this.reply(img) } /** #刻晴养成 */ - async Calculator () { - let role = gsCfg.getRole(this.e.msg, '#|#|养成|计算|[0-9]|,|,| ') + async Calculator() { + let role = gsCfg.getRole(this.e.msg, '#|#|星铁|养成|计算|[0-9]|,|,| ', this.e.isSr) if (!role) return false if ([10000005, 10000007, 20000000].includes(Number(role.roleId))) { @@ -65,7 +66,18 @@ export class calculator extends plugin { 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) } + 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 = `` + } + return name + } } diff --git a/plugins/genshin/apps/mysNews.js b/plugins/genshin/apps/mysNews.js index 3401fc3..7c5eb19 100644 --- a/plugins/genshin/apps/mysNews.js +++ b/plugins/genshin/apps/mysNews.js @@ -1,6 +1,5 @@ import plugin from '../../../lib/plugins/plugin.js' import MysNews from '../model/mysNews.js' -import MysSrNews from '../model/mysSrNews.js' import fs from 'node:fs' import lodash from 'lodash' import gsCfg from '../model/gsCfg.js' @@ -8,7 +7,7 @@ import YAML from 'yaml' gsCfg.cpCfg('mys', 'pushNews') export class mysNews extends plugin { - constructor (e) { + constructor(e) { super({ name: '米游社公告', dsc: '#公告 #资讯 #活动', @@ -16,26 +15,13 @@ export class mysNews extends plugin { priority: 700, rule: [ { - reg: '^(#*官方(公告|资讯|活动)|#*原神(公告|资讯|活动)|#公告|#资讯|#活动)[0-9]*$', + reg: '^#*(官方|星铁|原神|崩坏三|崩三|绝区零|崩坏二|崩二|崩坏学园二|未定|未定事件簿)?(公告|资讯|活动)[0-9]*$', fnc: 'news' }, { reg: '^(#米游社|#mys)(.*)', fnc: 'mysSearch' }, - { - reg: '^(#*铁道(公告|资讯|活动)|#*星铁(公告|资讯|活动)|#星穹公告|#星穹资讯|#星穹活动)[0-9]*$', - fnc: 'srNews' - }, - { - reg: '^#*(开启|关闭)(铁道|星铁|星穹)(公告|资讯)推送$', - fnc: 'srSetPush' - }, - { - reg: '^#推送(铁道|星铁|星穹)(公告|资讯)$', - permission: 'master', - fnc: 'srMysNewsTask' - }, { reg: '(.*)(bbs.mihoyo.com|miyoushe.com)/ys(.*)/article(.*)', fnc: 'mysUrl' @@ -45,85 +31,66 @@ export class mysNews extends plugin { fnc: 'ysEstimate' }, { - reg: '^#*(开启|关闭)(公告|资讯)推送$', + reg: '^#*(星铁|原神|崩坏三|崩三|绝区零|崩坏二|崩二|崩坏学园二|未定|未定事件簿)?(开启|关闭)(公告|资讯)推送$', fnc: 'setPush' }, { - reg: '^#推送(公告|资讯)$', + reg: '^#(星铁|原神|崩坏三|崩三|绝区零|崩坏二|崩二|崩坏学园二|未定|未定事件簿)?推送(公告|资讯)$', permission: 'master', fnc: 'mysNewsTask' } - ] }) this.file = './plugins/genshin/config/mys.pushNews.yaml' /** 定时任务 */ - this.task = [ - { - cron: gsCfg.getConfig('mys', 'pushNews').pushTime, - name: '米游社公告推送任务', - fnc: () => this.mysNewsTask(), - log: false - }, - { - cron: gsCfg.getConfig('mys', 'pushNews').pushTime, - name: '崩坏星穹铁道公告推送任务', - fnc: () => this.srMysNewsTask(), - log: false - } - ] + this.task = { + cron: gsCfg.getConfig('mys', 'pushNews').pushTime, + name: '米游社公告推送任务', + fnc: () => this.mysNewsTask(), + log: false + } } - async init () { + async init() { if (fs.existsSync(this.file)) return fs.copyFileSync('./plugins/genshin/defSet/mys/pushNews.yaml', this.file) } - async news () { - let data = await new MysNews(this.e).getNews() + async news() { + let gids = this.gids() + let data = await new MysNews(this.e).getNews(gids) if (!data) return await this.reply(data) } - async srNews () { - let data = await new MysSrNews(this.e).getNews() - if (!data) return - await this.reply(data) - } - - async mysNewsTask () { + async mysNewsTask() { let mysNews = new MysNews(this.e) await mysNews.mysNewsTask() } - async srMysNewsTask () { - let mysNews = new MysSrNews(this.e) - await mysNews.mysNewsTask() - } - - async mysSearch () { + async mysSearch() { if (/签到/g.test(this.e.msg)) return false let data = await new MysNews(this.e).mysSearch() if (!data) return await this.reply(data) } - async mysUrl () { + async mysUrl() { let data = await new MysNews(this.e).mysUrl() if (!data) return await this.reply(data) } - async ysEstimate () { + async ysEstimate() { let data = await new MysNews(this.e).ysEstimate() if (!data) return await this.reply(data) } - async srSetPush () { + async setPush() { if (!this.e.isGroup) { await this.reply('推送请在群聊中设置') return @@ -134,25 +101,31 @@ export class mysNews extends plugin { } 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 = '公告' if (this.e.msg.includes('资讯')) { - type = 'srinfoGroup' + type = `${game}infoGroup` typeName = '资讯' } 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('开启')) { model = '开启' - cfg[type].push(this.e.group_id) - cfg[type] = lodash.uniq(cfg[type]) + cfg[type][this.e.self_id].push(this.e.group_id) + cfg[type][this.e.self_id] = lodash.uniq(cfg[type][this.e.self_id]) msg += `${model}\n如有最新${typeName}将自动推送至此` } else { 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) @@ -162,42 +135,26 @@ export class mysNews extends plugin { await this.reply(msg) } - async setPush () { - if (!this.e.isGroup) { - await this.reply('推送请在群聊中设置') - return + gids() { + let msg = this.e.msg.replace(/[#公告资讯活动开启关闭推送]/g, ''); + switch (msg) { + 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) { - 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) + return 2 } } diff --git a/plugins/genshin/defSet/gacha/pool.yaml b/plugins/genshin/defSet/gacha/pool.yaml index 711b339..35059c3 100644 --- a/plugins/genshin/defSet/gacha/pool.yaml +++ b/plugins/genshin/defSet/gacha/pool.yaml @@ -3,9 +3,9 @@ - 罗莎莉亚 - 烟绯 up5: - - 珊瑚宫心海 - up5_2: - 流浪者 + up5_2: + - 珊瑚宫心海 weapon5: - 不灭月华 - 图莱杜拉的回忆 @@ -15,7 +15,7 @@ - 钟剑 - 匣里灭辰 - 西风猎弓 - endTime: "2023-08-15 18:00:00" + endTime: "2023-08-11 18:00:00" - up4: - 米卡 - 雷泽 diff --git a/plugins/genshin/defSet/mys/pushNews.yaml b/plugins/genshin/defSet/mys/pushNews.yaml index 6cca109..2435a78 100644 --- a/plugins/genshin/defSet/mys/pushNews.yaml +++ b/plugins/genshin/defSet/mys/pushNews.yaml @@ -1,18 +1,50 @@ - # 米游社公共推送定时任务,修改需要重启 pushTime: 0 0/5 * * * ? # 最多同时推送条数 maxNum: 1 -#公共推送群 -announceGroup: [] +# 包含关键字不推送 +banWord: + gs: 冒险助力礼包|纪行|预下载|脚本外挂|集中反馈|已开奖|云·原神|魔神任务|传说任务|线下赛|晋级赛|战绩更新|海选赛|邀请赛|积分赛|战绩工具|交流平台|首日赛|线上赛|社区内容|个人专访|全民赛|决赛|总决赛|半决赛|淘汰赛|作品展示|同人|大别野 + sr: 预下载|脚本外挂|集中反馈|已开奖|问题说明|意见反馈|账号封禁|工具|直播预告|获奖名单|大别野 + wd: 大别野|已开奖 + bb: 已开奖|大别野 + bbb: 封禁名单|大别野|马克兔速报|预下载 + zzz: 作品展示|已开奖|大别野 -#资讯推送群 -infoGroup: [] +#原神公告推送群 +gsannounceGroup: {} + +#原神资讯推送群 +gsinfoGroup: {} #崩坏星穹铁道公告推送群 -srannounceGroup: [] +srannounceGroup: {} #崩坏星穹铁道资讯推送群 -srinfoGroup: [] \ No newline at end of file +srinfoGroup: {} + +#绝区零公告推送群 +zzzannounceGroup: {} + +#绝区零资讯推送群 +zzzinfoGroup: {} + +#未定事件簿公告推送群 +wdannounceGroup: {} + +#未定事件簿资讯推送群 +wdinfoGroup: {} + +#崩坏3公告推送群 +bbbannounceGroup: {} + +#崩坏3资讯推送群 +bbbinfoGroup: {} + +#崩坏学园2公告推送群 +bbannounceGroup: {} + +#崩坏学园2资讯推送群 +bbinfoGroup: {} \ No newline at end of file diff --git a/plugins/genshin/defSet/pool/301.yaml b/plugins/genshin/defSet/pool/301.yaml index 0bd6954..6837ef0 100644 --- a/plugins/genshin/defSet/pool/301.yaml +++ b/plugins/genshin/defSet/pool/301.yaml @@ -1,13 +1,13 @@ - from: '2023-07-25 18:00:00' to: '2023-08-15 14:59:59' five: - - 珊瑚宫心海 - 流浪者 + - 珊瑚宫心海 four: - 珐露珊 - 罗莎莉亚 - 烟绯 - name: 浮岳虹珠|余火变相 + name: 余火变相|浮岳虹珠 - from: '2023-07-05 06:00:00' to: '2023-07-25 17:59:59' five: diff --git a/plugins/genshin/defSet/role/sr_name.yaml b/plugins/genshin/defSet/role/sr_name.yaml new file mode 100644 index 0000000..7c2f0fd --- /dev/null +++ b/plugins/genshin/defSet/role/sr_name.yaml @@ -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 \ No newline at end of file diff --git a/plugins/genshin/model/base.js b/plugins/genshin/model/base.js index a0df52a..868a9ed 100644 --- a/plugins/genshin/model/base.js +++ b/plugins/genshin/model/base.js @@ -18,7 +18,7 @@ export default class base { * @param pluResPath 插件资源路径 */ get screenData() { - let headImg = '优菈' + let headImg = '珊瑚宫心海' return { saveId: this.userId, diff --git a/plugins/genshin/model/calculator.js b/plugins/genshin/model/calculator.js index ea5a1dc..fdf4c87 100644 --- a/plugins/genshin/model/calculator.js +++ b/plugins/genshin/model/calculator.js @@ -5,13 +5,13 @@ import lodash from 'lodash' import gsCfg from './gsCfg.js' export default class Calculator extends base { - constructor (e) { + constructor(e) { super(e) 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 /** 获取绑定uid */ 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 }) + 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 character = character.data @@ -35,7 +45,7 @@ export default class Calculator extends base { 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() @@ -56,34 +66,35 @@ export default class Calculator extends base { } } - async getSet () { - let defSetSkill = '90,90,10,10,10'.split(',') + async getSet() { + 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(this.role.alias, '') let setSkill = [] + let length = this.e.isSr ? 6 : 5 if (set) { setSkill = set.split(',') 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] } } else { setSkill = defSetSkill } - if (setSkill.length != 5) { - let reMsg = this.checkMsg.replace(/刻晴/g, this.role.alias) + if (setSkill.length != length) { + let reMsg = this.checkMsg.replace(/刻晴|克拉拉/g, this.role.alias) await this.e.reply(reMsg) 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) { if (check[key] < Number(setSkill[key])) { setSkill[key] = check[key] @@ -93,21 +104,37 @@ export default class Calculator extends base { this.setSkill = setSkill } - async getBody () { + async getBody() { // 技能 let skillList = [] 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 - skillList = detail.data.skill_list + skillList = detail.data.skill_list || detail.data.skills } else { /** 尚未拥有的角色 */ - skillList = await this.getSkillId(this.role.roleId) + 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) + } if (!skillList) { - this.e.reply('暂无角色数据,请稍后再试') + this.e.reply('暂无角色数据,请稍后再试\n星铁角色养成请使用*开头') return false } @@ -116,57 +143,96 @@ export default class Calculator extends base { this.dataCharacter = { level: 1, name: this.role.name, - icon: `${this.screenData.pluResPath}img/role/${this.role.name}.png`, - rarity: four.includes(Number(this.role.roleId)) ? 4 : 5 + icon: this.e.isSr ? this.avatar.icon_url : `${this.screenData.pluResPath}img/role/${this.role.name}.png`, + 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 = { - avatar_id: Number(this.role.roleId), - avatar_level_current: Number(this.dataCharacter.level), - avatar_level_target: Number(this.setSkill[0]), - skill_list: [ - { - id: Number(skillList[0].group_id), - level_current: Number(skillList[0].level_current), - level_target: Number(this.setSkill[2]) + 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]), }, - { - id: Number(skillList[1].group_id), - level_current: Number(skillList[1].level_current), - level_target: Number(this.setSkill[3]) - }, - { - id: Number(skillList[2].group_id), - level_current: Number(skillList[2].level_current), - level_target: Number(this.setSkill[4]) + 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_level_current: Number(this.dataCharacter.level), + avatar_level_target: Number(this.setSkill[0]), + skill_list: [ + { + id: Number(skillList[0].group_id), + level_current: Number(skillList[0].level_current), + level_target: Number(this.setSkill[2]) + }, + { + id: Number(skillList[1].group_id), + level_current: Number(skillList[1].level_current), + level_target: Number(this.setSkill[3]) + }, + { + id: Number(skillList[2].group_id), + level_current: Number(skillList[2].level_current), + level_target: Number(this.setSkill[4]) + } + ] + } } if (this.mysApi.getServer().startsWith('os')) { body.lang = "zh-cn" } - if (this.dataCharacter.weapon) { - if (Number(this.dataCharacter.weapon.rarity) < 3) { - this.setSkill[1] = 70 + 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]) + } } - body.weapon = { - id: Number(this.dataCharacter.weapon.id), - level_current: Number(this.dataCharacter.weapon.level), - level_target: Number(this.setSkill[1]) + } else { + if (this.dataCharacter.weapon) { + if (Number(this.dataCharacter.weapon.rarity) < 3) { + this.setSkill[1] = 70 + } + + body.weapon = { + id: Number(this.dataCharacter.weapon.id), + level_current: Number(this.dataCharacter.weapon.level), + level_target: Number(this.setSkill[1]) + } + } } + + skillList = skillList.filter((item) => item.max_level != 1) this.skillList = skillList return body } - async getSkillId (roleId) { - let avatarSkill = await this.mysApi.getData('avatarSkill', { avatar_id: roleId }) + async getSkillId(roleId) { + let avatarSkill = await MysInfo.get(this.e, 'avatarSkill', { + headers: this.headers, + avatar_id: roleId + }) if (!avatarSkill || avatarSkill.retcode !== 0) return false avatarSkill = avatarSkill.data avatarSkill.list.forEach((item) => { @@ -176,20 +242,20 @@ export default class Calculator extends base { return avatarSkill.list } - async computes (body) { - let computes = await this.mysApi.getData('compute', body) + async computes(body) { + let computes = await MysInfo.get(this.e, 'compute', body) if (!computes || computes.retcode !== 0) return false computes = computes.data let formart = (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 j in computes[i]) { 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 } } diff --git a/plugins/genshin/model/gachaLog.js b/plugins/genshin/model/gachaLog.js index 443126c..bad215a 100644 --- a/plugins/genshin/model/gachaLog.js +++ b/plugins/genshin/model/gachaLog.js @@ -64,11 +64,6 @@ export default class GachaLog extends base { MakeMsg.push(tmpMsg) MakeMsg.push(`抽卡记录更新完成,您还可回复\n【#${this?.e?.isSr?'星铁光锥':'武器'}记录】统计${this?.e?.isSr?'星铁光锥':'武器'}池数据\n【#${this?.e?.isSr?'星铁':''}角色统计】按卡池统计数据\n【#导出记录】导出记录数据`) let Msg = await common.makeForwardMsg(this.e, MakeMsg, tmpMsg) - Msg.data=Msg.data - .replace(/\n/g, '') - .replace(/(.+?)<\/title>/g, '___') - .replace(/___+/, `<title color="#777777" size="26">${tmpMsg}`) - await this.e.reply(Msg) this.isLogUrl = true diff --git a/plugins/genshin/model/gsCfg.js b/plugins/genshin/model/gsCfg.js index 36d70c8..facd6d7 100644 --- a/plugins/genshin/model/gsCfg.js +++ b/plugins/genshin/model/gsCfg.js @@ -9,7 +9,8 @@ import MysUser from './mys/MysUser.js' /** 配置文件 */ class GsCfg { - constructor () { + constructor() { + this.isSr = false /** 默认设置 */ this.defSetPath = './plugins/genshin/defSet/' this.defSet = {} @@ -24,7 +25,7 @@ class GsCfg { this.ignore = ['mys.pubCk', 'gacha.set', 'bot.help', 'role.name'] } - get element () { + get element() { return { ...this.getdefSet('element', 'role'), ...this.getdefSet('element', 'weapon') } } @@ -32,12 +33,12 @@ class GsCfg { * @param app 功能 * @param name 配置文件名称 */ - getdefSet (app, name) { + getdefSet(app, name) { return this.getYaml(app, name, 'defSet') } /** 用户配置 */ - getConfig (app, name) { + getConfig(app, name) { if (this.ignore.includes(`${app}.${name}`)) { return this.getYaml(app, name, 'config') } @@ -51,7 +52,7 @@ class GsCfg { * @param name 名称 * @param type 默认跑配置-defSet,用户配置-config */ - getYaml (app, name, type) { + getYaml(app, name, type) { let file = this.getFilePath(app, name, type) let key = `${app}.${name}` @@ -71,13 +72,13 @@ class GsCfg { return this[type][key] } - getFilePath (app, name, type) { + getFilePath(app, name, type) { if (type == 'defSet') return `${this.defSetPath}${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}` if (this.watcher[type][key]) return @@ -95,7 +96,7 @@ class GsCfg { } /** 读取所有用户绑定的ck */ - async getBingCk (game = 'gs') { + async getBingCk(game = 'gs') { let ck = {} let ckQQ = {} let noteCk = {} @@ -121,20 +122,20 @@ class GsCfg { } /** 获取qq号绑定ck */ - getBingCkSingle (userId) { + getBingCkSingle(userId) { console.log('gsCfg.getBingCkSingle() 即将废弃') return {} } - saveBingCk (userId, data) { + saveBingCk(userId, data) { console.log('gsCfg.saveBingCk() 即将废弃') } /** * 原神角色id转换角色名字 */ - roleIdToName (id) { - let name = this.getdefSet('role', 'name') + roleIdToName(id) { + let name = this.getdefSet('role', this.isSr ? 'sr_name' : 'name') if (name[id]) { return name[id][0] } @@ -145,7 +146,7 @@ class GsCfg { /** * 原神武器id转换成武器名字 */ - getWeaponDataByWeaponHash (hash) { + getWeaponDataByWeaponHash(hash) { let data = this.getdefSet('weapon', 'data') let weaponData = {} weaponData.name = data.Name[hash] @@ -155,20 +156,22 @@ class GsCfg { } /** 原神角色别名转id */ - roleNameToID (keyword) { + roleNameToID(keyword, isSr) { + if (isSr) this.isSr = isSr if (!isNaN(keyword)) keyword = Number(keyword) this.getAbbr() - let roelId = this.nameID.get(String(keyword)) + let roelId = this[this.isSr ? 'sr_nameID' : 'nameID'].get(String(keyword)) return roelId || false } /** 获取角色别名 */ - getAbbr () { - if (this.nameID) return + getAbbr() { + if (this[this.isSr ? 'sr_nameID' : 'nameID']) return this.nameID = new Map() - + this.sr_nameID = new Map() let nameArr = this.getdefSet('role', 'name') + let sr_nameArr = this.getdefSet('role', 'sr_name') let nameArrUser = this.getConfig('role', 'name') 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 abbr of nameArrUser[i]) { this.nameID.set(String(abbr), nameID[i]) @@ -188,8 +198,8 @@ class GsCfg { } /** 返回所有别名,包括用户自定义的 */ - getAllAbbr () { - let nameArr = this.getdefSet('role', 'name') + getAllAbbr() { + let nameArr = this.getdefSet('role', this.isSr ? 'sr_name' : 'name') let nameArrUser = this.getConfig('role', 'name') for (let i in nameArrUser) { @@ -205,7 +215,7 @@ class GsCfg { * @param name 名称 * @param isWeapon 是否武器 */ - shortName (name, isWeapon = false) { + shortName(name, isWeapon = false) { let other = {} if (isWeapon) { other = this.getdefSet('weapon', 'other') @@ -216,12 +226,12 @@ class GsCfg { } /** 公共配置ck文件修改hook */ - async change_myspubCk () { + async change_myspubCk() { await MysInfo.initCache() await MysInfo.initPubCk() } - getGachaSet (groupId = '') { + getGachaSet(groupId = '') { let config = this.getYaml('gacha', 'set', 'config') let def = config.default if (config[groupId]) { @@ -230,7 +240,7 @@ class GsCfg { return def } - getMsgUid (msg) { + getMsgUid(msg) { let ret = /[1|2|5-9][0-9]{8}/g.exec(msg) if (!ret) return false return ret[0] @@ -245,12 +255,13 @@ class GsCfg { * @return alias 当前别名 * @return uid 游戏uid */ - getRole (msg, filterMsg = '') { + getRole(msg, filterMsg = '', isSr = false) { let alias = msg.replace(/#|老婆|老公|[1|2|5-9][0-9]{8}/g, '').trim() if (filterMsg) { alias = alias.replace(new RegExp(filterMsg, 'g'), '').trim() } + this.isSr = isSr /** 判断是否命中别名 */ let roleId = this.roleNameToID(alias) if (!roleId) return false @@ -265,7 +276,7 @@ class GsCfg { } } - cpCfg (app, name) { + cpCfg(app, name) { if (!fs.existsSync('./plugins/genshin/config')) { fs.mkdirSync('./plugins/genshin/config') } @@ -279,7 +290,7 @@ class GsCfg { /** * 根据角色名获取对应的元素类型 */ - getElementByRoleName (roleName) { + getElementByRoleName(roleName) { let element = this.getdefSet('element', 'role') if (element[roleName]) { return element[roleName] @@ -289,7 +300,7 @@ class GsCfg { /** * 根据技能id获取对应的技能数据,角色名用于命座加成的技能等级 */ - getSkillDataByskillId (skillId, roleName) { + getSkillDataByskillId(skillId, roleName) { let skillMap = this.getdefSet('skill', 'data') let skillData = {} if (skillMap.Name[skillId]) { @@ -304,7 +315,7 @@ class GsCfg { return skillData } - fightPropIdToName (propId) { + fightPropIdToName(propId) { let propMap = this.getdefSet('prop', 'prop') if (propMap[propId]) { return propMap[propId] @@ -312,7 +323,7 @@ class GsCfg { return '' } - getRoleTalentByTalentId (talentId) { + getRoleTalentByTalentId(talentId) { let talentMap = this.getdefSet('role', 'talent') let talent = {} if (talentMap.Name[talentId]) { diff --git a/plugins/genshin/model/mys/apiTool.js b/plugins/genshin/model/mys/apiTool.js index 9150d5f..036e770 100644 --- a/plugins/genshin/model/mys/apiTool.js +++ b/plugins/genshin/model/mys/apiTool.js @@ -173,6 +173,17 @@ export default class apiTool { dailyNote: { url: `${hostRecord}game_record/app/hkrpg/api/note`, 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}®ion=${this.server}` } } } diff --git a/plugins/genshin/model/mys/mysInfo.js b/plugins/genshin/model/mys/mysInfo.js index 36a909e..31bb030 100644 --- a/plugins/genshin/model/mys/mysInfo.js +++ b/plugins/genshin/model/mys/mysInfo.js @@ -25,7 +25,7 @@ export default class MysInfo { } // ck对应MysUser对象 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) { @@ -177,7 +177,7 @@ export default class MysInfo { } 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 @@ -185,7 +185,7 @@ export default class MysInfo { } } else { res = await mysApi.getData(api, data) - res = await mysInfo.checkCode(res, api) + res = await mysInfo.checkCode(res, api, mysApi) } return res @@ -335,7 +335,7 @@ export default class MysInfo { return this.ckUser?.ck } - async checkCode(res, type) { + async checkCode(res, type, mysApi = {}) { if (!res) { this.e.reply('米游社接口请求失败,暂时无法查询') return false diff --git a/plugins/genshin/model/mysNews.js b/plugins/genshin/model/mysNews.js index 7a5cd58..96132c6 100644 --- a/plugins/genshin/model/mysNews.js +++ b/plugins/genshin/model/mysNews.js @@ -5,16 +5,15 @@ import puppeteer from '../../../lib/puppeteer/puppeteer.js' import common from '../../../lib/common/common.js' import gsCfg from '../model/gsCfg.js' -const _path = process.cwd() let emoticon export default class MysNews extends base { - constructor (e) { + constructor(e) { super(e) this.model = 'mysNews' } - async getNews () { + async getNews(gid) { let type = 1 let typeName = '公告' if (this.e.msg.includes('资讯')) { @@ -26,7 +25,7 @@ export default class MysNews extends base { 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 const data = res.data.list @@ -34,7 +33,7 @@ export default class MysNews extends base { return true } - const page = this.e.msg.replace(/#|#|官方|原神|公告|资讯|活动/g, '').trim() || 1 + const page = this.e.msg.replace(/#|#|官方|星铁|原神|崩坏三|崩三|绝区零|崩坏二|崩二|崩坏学园二|未定|未定事件簿|公告|资讯|活动/g, '').trim() || 1 if (page > data.length) { await this.e.reply('目前只查前20条最新的公告,请输入1-20之间的整数。') return true @@ -42,22 +41,22 @@ export default class MysNews extends base { 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) - - return await this.replyMsg(img, `原神${typeName}:${param.data.post.subject}`) + let game = this.game() + return this.replyMsg(img, `${game}${typeName}:${param.data.post.subject}`) } - async render (param) { - return await puppeteer.screenshots(this.model, param) + render(param) { + return puppeteer.screenshots(this.model, param) } - async newsDetail (postId) { - const res = await this.postData('getPostFull', { gids: 2, read: 1, post_id: postId }) + async newsDetail(postId, gid) { + const res = await this.postData('getPostFull', { gids: gid, read: 1, post_id: postId }) if (!res) return - const data = await this.detalData(res.data.post) + const data = await this.detalData(res.data.post, gid) return { ...this.screenData, @@ -67,15 +66,15 @@ export default class MysNews extends base { } } - postApi (type, data) { - let host = 'https://bbs-api-static.mihoyo.com/' + postApi(type, data) { + let host = 'https://bbs-api.miyoushe.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?' + host = 'https://bbs-api.miyoushe.com/post/wapi/searchPosts?' break // 帖子详情 case 'getPostFull': @@ -92,10 +91,10 @@ export default class MysNews extends base { return host + param } - async postData (type, data) { + async postData(type, data) { const url = this.postApi(type, data) 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' } let response @@ -114,7 +113,7 @@ export default class MysNews extends base { return res } - async detalData (data) { + async detalData(data, gid) { let json try { json = JSON.parse(data.post.content) @@ -134,7 +133,7 @@ export default class MysNews extends base { } if (!emoticon) { - emoticon = await this.mysEmoticon() + emoticon = await this.mysEmoticon(gid) } data.post.content = data.post.content.replace(/_\([^)]*\)/g, function (t, e) { @@ -161,10 +160,10 @@ export default class MysNews extends base { return data } - async mysEmoticon () { + async mysEmoticon(gid) { const emp = new Map() - const res = await this.postData('emoticon', { gids: 2 }) + const res = await this.postData('emoticon', { gids: gid }) if (res.retcode != 0) { return emp @@ -181,7 +180,7 @@ export default class MysNews extends base { return emp } - async mysSearch () { + async mysSearch() { let msg = this.e.msg msg = msg.replace(/#|米游社|mys/g, '') @@ -211,10 +210,10 @@ export default class MysNews extends base { 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 postId = /[0-9]+/g.exec(msg)[0] @@ -224,10 +223,10 @@ export default class MysNews extends base { 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 res = await this.postData('searchPosts', { gids: 2, size: 20, keyword: msg }) 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')) } - 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.length == 1) { - return img[0] + if (title) img.unshift(title) + return img } else { - let msg = [titile, ...img] - return await common.makeForwardMsg(this.e, msg, titile).catch((err) => { - logger.error(err) - }) + return common.makeForwardMsg(this.e, img, title) } } - async mysNewsTask (type = 1) { + async mysNewsTask() { let cfg = gsCfg.getConfig('mys', 'pushNews') // 推送2小时内的公告资讯 let interval = 7200 // 最多同时推送两条 this.maxNum = cfg.maxNum - // 包含关键字不推送 - let banWord = /冒险助力礼包|纪行|预下载|脚本外挂|集中反馈|已开奖|云·原神|魔神任务|传说任务说明/g - let anno = await this.postData('getNewsList', { gids: 2, page_size: 10, type: 1 }) - let info = await this.postData('getNewsList', { gids: 2, page_size: 10, type: 3 }) + for (let gid of [1, 2, 3, 4, 6, 8]) { + let type = gid == 1 ? 'bbb' : gid == 2 ? 'gs' : gid == 3 ? 'bb' : gid == 4 ? 'wd' : gid == 6 ? 'sr' : 'zzz' - 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 + 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 (new RegExp(banWord).test(val.post.subject)) { - continue + 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 (val.typeName == '公告') { - for (let groupId of cfg.announceGroup) { - await this.sendNews(groupId, val.typeName, val.post.post_id) - } - } - if (val.typeName == '资讯') { - for (let groupId of cfg.infoGroup) { - await this.sendNews(groupId, val.typeName, val.post.post_id) - } + + if (news.length <= 0) continue + + news = lodash.orderBy(news, ['post_id'], ['asc']) + + let now = Date.now() / 1000 + + this.key = `Yz:${type}:mys:newPush:` + this.e.isGroup = true + this.pushGroup = [] + for (let val of news) { + if (Number(now - val.post.created_at) > interval) + continue + if (cfg.banWord[type] && new RegExp(cfg.banWord[type]).test(val.post.subject)) + continue + if (val.typeName == '公告') + for (let botId in cfg[`${type}announceGroup`]) + for (let groupId of cfg[`${type}announceGroup`][botId]) + await this.sendNews(botId, groupId, val.typeName, val.post.post_id, gid) + if (val.typeName == '资讯') + for (let botId in cfg[`${type}infoGroup`]) + for (let groupId of cfg[`${type}infoGroup`][botId]) + await this.sendNews(botId, groupId, val.typeName, val.post.post_id, gid) } } } - 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.maxNum) return - let sended = await redis.get(`${this.key}${groupId}:${postId}`) + let sended = await redis.get(`${this.key}${botId}:${groupId}:${postId}`) if (sended) return - // TODO: 暂时处理,后续待更好的解决方案 (定时任务无法获取e.bot) - this.e.bot = Bot - + let game = this.game(gid) // 判断是否存在群关系 - if (!this.e.bot.gl.get(Number(groupId))) { - logger.mark(`[米游社${typeName}推送] 群${groupId}未关联`) + this.e.group = Bot[botId]?.pickGroup(groupId) + if (!this.e.group) { + logger.mark(`[米游社${game}${typeName}推送] 群${botId}:${groupId}未关联`) return } 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] = { img: await this.render(param), @@ -343,20 +341,28 @@ export default class MysNews extends base { } this.pushGroup[groupId]++ - this.e.group = this.e.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] - } - - await redis.set(`${this.key}${groupId}:${postId}`, '1', { EX: 3600 * 10 }) + await redis.set(`${this.key}${botId}:${groupId}:${postId}`, '1', { EX: 3600 * 10 }) // 随机延迟10-90秒 - await common.sleep(lodash.random(10, 90) * 1000) - await this.e.group.sendMsg(tmp) + await common.sleep(lodash.random(10000, 90000)) + const msg = await this.replyMsg(this[postId].img, `${game}${typeName}推送:${this[postId].title}`) + return this.e.group.sendMsg(msg) } -} + + game(gid) { + switch (gid) { + case 1: + return '崩坏三' + case 2: + return '原神' + case 3: + return '崩坏二' + case 4: + return '未定事件簿' + case 6: + return '崩坏星穹铁道' + case 8: + return '绝区零' + } + return '' + } +} \ No newline at end of file diff --git a/plugins/genshin/model/mysSrNews.js b/plugins/genshin/model/mysSrNews.js deleted file mode 100644 index 2a2093b..0000000 --- a/plugins/genshin/model/mysSrNews.js +++ /dev/null @@ -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 = `
` - } - } - } 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 `` - } 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) - } -} diff --git a/plugins/genshin/resources/StarRail/html/calculator/calculator.css b/plugins/genshin/resources/StarRail/html/calculator/calculator.css new file mode 100644 index 0000000..d1ae9f9 --- /dev/null +++ b/plugins/genshin/resources/StarRail/html/calculator/calculator.css @@ -0,0 +1,450 @@ +@font-face { + font-family: "tttgbnumber"; + src: url("../../../../../../resources/font/tttgbnumber.ttf"); + font-weight: normal; + font-style: normal; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; + user-select: none; +} + +body { + transform: scale(1.48); + transform-origin: 0 0; +} + +.container { + width: 550px; + padding: 10px 15px 15px 15px; + background-color: #fff; + position: relative; +} + +.info_box { + position: relative; + height: 40px; + margin-top: 10px; + margin-bottom: 15px; +} + +.head_box { + /* padding: 10px; */ + /* border-radius: 15px; */ + font-family: tttgbnumber; + /* box-shadow: 0 5px 10px 0 rgb(0 0 0 / 15%); */ +} + +.data_box { + padding: 5px 10px 5px 10px; + margin-top: 10px; + /* box-shadow: 0 5px 10px 0 rgb(0 0 0 / 15%); */ + border-radius: 5px; + font-family: tttgbnumber; + background-color: #f2eee6; + border: 1px solid #d9d3c7; +} + +.uidRight { + position: absolute; + top: 5px; + right: 0px; + font-size: 20px; + text-align: center; + color: #fff; + padding: 3px 6px; + border-radius: 7px; + font-family: "tttgbnumber"; + background-color: #a57f72; + box-shadow: 0 3px 6px 0 rgb(132 93 90 / 40%); +} + +.topLeft { + position: absolute; + top: 5px; + left: 0px; + z-index: 9; + font-size: 20px; + text-align: center; + color: #fff; + padding: 3px 6px; + border-radius: 7px; + font-family: "tttgbnumber"; + background-color: #a57f72; + box-shadow: 0 3px 6px 0 rgb(132 93 90 / 40%); +} + +.item { + margin: 10px 0px 10px 0px; + border-radius: 5px; + background: #e9e5dc; + display: flex; + /* box-shadow: 0 5px 10px 0 rgb(0 0 0 / 15%); */ + border: 1px solid #d9d3c7; +} + +.role_box { + margin: 10px 0px 10px 10px; + height: 112px; + width: 95px; + background: #e9e5dc; + border-radius: 7px; + overflow: hidden; + position: relative; +} + +.role_img { + width: 100%; + height: 100%; +} + +.role_name { + margin-top: 20px; + margin-left: 10px; + width: 125px; + color: #91837a; + font-weight: bold; + font-size: 24px; + line-height: 30px; + letter-spacing: 1px; + white-space: nowrap; +} + +.role_LV { + margin-top: 10px; + width: 120px; + height: 40px; + line-height: 30px; + white-space: nowrap; + font-size: 16px; +} + +.weapon_box { + margin: 10px 0px 10px 20px; + height: 95px; + width: 95px; + background: #e9e5dc; + border-radius: 7px; + overflow: hidden; +} + +.weapon_img { + width: 100%; + height: 100%; +} + +.weapon_name { + margin-top: 20px; + margin-left: 10px; + width: 120px; + color: #91837a; + font-weight: bold; + font-size: 24px; + line-height: 30px; + letter-spacing: 1px; + white-space: nowrap; +} + +.weapon_LV { + margin-top: 10px; + width: 120px; + height: 40px; + font-size: 16px; + line-height: 30px; + white-space: nowrap; +} + +.weapon_bg5 { + background-image: url(../../../img/other/bg5.png); + width: 100%; + height: 95px; + background-size: 100%; + background-repeat: no-repeat; +} + +.weapon_bg4 { + width: 100%; + height: 95px; + background-image: url(../../../img/other/bg4.png); + background-size: 100%; + background-repeat: no-repeat; +} + +.weapon_bg3 { + width: 100%; + height: 95px; + background-image: url(../../../img/other/bg3.png); + background-size: 100%; + background-repeat: no-repeat; +} + +.weapon_bg2 { + width: 100%; + height: 95px; + background-image: url(../../../img/other/bg3.png); + background-size: 100%; + background-repeat: no-repeat; +} + +.weapon_bg1 { + width: 100%; + height: 95px; + background-image: url(../../../img/other/bg3.png); + background-size: 100%; + background-repeat: no-repeat; +} + +.bg105 { + background-image: url(../../../img/other/bg105.png); + width: 100%; + height: 95px; + background-size: 100%; + background-repeat: no-repeat; +} + +.bg5 { + background-image: url(../../../img/other/bg5.png); + width: 100%; + height: 112px; + /*filter: brightness(1.1);*/ + background-size: 100%; + background-repeat: no-repeat; +} + +.bg4 { + width: 100%; + height: 112px; + background-image: url(../../../img/other/bg4.png); + background-size: 100%; + background-repeat: no-repeat; +} + +.skill { + margin: 5px 0px 0px 0px; + background: #f1eee5; + display: flex; + border-radius: 7px; + padding: 1px 0 1px 0; + /* box-shadow: 0 5px 10px 0 rgb(0 0 0 / 15%); */ + padding-left: 20px; + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAq4AAACACAMAAAD9GBtbAAABaFBMVEVHcEyqqqrbkpK0lpaAgID/qqq5oqL///9VVVW2kpKqVVWZmZm/gICqmZnMzMyqqqqSkpKZZmbu59vayKzZx67k1sPbwqrYxq3s5NnZyKzZx62zmZm5oovMmZnx7eSAgIC5i4vVqqq/n5+qqqqqgIC7mZnMmZnbybDEsbGxnZ2qlZXXxa3VxK3OtaXXxq2/v7+7qqrbtpLjqqrGqqqqjo7x7OTXxazv6eHYxazq4dXg08Hq4tbXx6/o4dbf0r7n3tOvn5+llpa7qpmkkpK2pKTWw6uxiYnv6eD/gICdiYnVw6ry7ubv6uLw7OTZx63x7eXy7eXw6+Pt6ODx7OTv6+Pu6eHx6+Pu6ODu6eDv6eHv6uHw6uLt59/Xxavx7OPYxqzx7eTXxKzZxqzWw6rYxavWw6vYxKzWxavs59/w6+Lw7OPXxazv6+LXw6vWxKzYxa3XxKvVw6rXxKrWxqzt6N/WxKru6uLWxKscG7OjAAAAS3RSTlMAAwcRAgMLAQMHAwUEDwUGBwXtU+voFYLiz/IKCwXzBAsGCAkGDwruDQ0M61ofhgQPBwkJCfPy89Dj6e7u7unjEBEPDg7RDfMCDfMtJH2VAAAUGElEQVQYGe3B34sk2ZXY8e8999zIiO6uavWMZqTR7HiXxXgNZt8MRi8G/+1+EBiMwcbgXS/axaPRr9FsqzK7OyPinnuuIzKzqrKqqwWqKr3dzyfQNI/Wi3PfpNwwFsMcKWoRmGADpctgDDNEoBCZuLWhdOGr7+ev3vzu9/yse/Xuw++/6P1bAwJN82i9OPdJ5pptMIgsilpkURQmZVP5jH8NU6wcTJxsOAjTy+pfTenXfKn8mtXX/wyBpnm0F/sN903KtWiRgwAWgdLtXybmMG1qDAGq7CuLiaMNpfyb/8fgldJJ9f/wNn74PSd/9UsCiy+DhP9I0/y5Xm8mzm0yEDkpvOXgTSx+BbyWNG02sP3ij3L5vbyKu5jfcuaN82YHxmZCIE3avZIt/A/5UP+Br/85AJ+HELu/p2n+bIpzrTMInCnOkYaKgUgIhhKrS6kozIhxpp8r/dj/9DsJFTNUnczl9nsJV+Ef8QCf//j7n9M0jyNcEwJ3FAfUQMFQtFBAiVmkVBdCLNW4JZp5/eHFVcr0FOsM72Y2I4u34Y//+HXkS97/nKZ5pMC1z8bAHbWCKuILpNZYSYVUxRyowdzcuaFdrM6mvr/QzTx8uMCjlFiDpejw+sP+CxNC+DlN8ziqfJooYDgKSIdDgSlm7WJQ4R6dpwwV2O0wrlKeXMFELHHBF5+HUZBI0zyOqHNjxz3BFdMQ1QCdsRCJyiS1YM49OiuXQLrYAaXrpo4hT967YWm3ieEnr5WQaJrH6YwbYoF7OoNRFUzNBDGNpUYq0dUxzqlIzMCOoxSo5CHtpw0zFnb08a8j/+ULmuZxvHJNCNznOFAdd9wlxhxCYCGhYJxTl2wX9BMHXcK1pGCmVsTpoqb6V/9TaJpHExEOOgmBh7mqq4JidAYxRjCMc+qaYSeBgyFBBELXxYGsG8zqhiulaR7NQJ2FBR6iGCsdwVh0M9DFWYxzSo39jksqQyFSJIBHQLaXsbBPaqOUjdI0fynBWMxdZ6zU8A63Ut25Qz2NI9S6o0DhWkHYwsth/3qrNmWlaZ7uzR95QHTBEBDFwMBHRYpzz7wZWexYzF2CwOod7FnEjFcR+Y3SNH8pMx1gOIhirIyP9b7pthwMBQjck5iGn/j7qDTNUzgPiayCzaIG3Szixqf0nq84Ggpd4qRwdJmlK/Iv/Y9QmuYZ1MA5Z2WozGB0Zp2OPEzJXIQatgyUxFElboGBPYOL7HhJmRCa5imE1Q9vKnfYCsxFAXPCrDxIcQiVylBKIiw4GhgKDIIHBv/GQGiaZ/AD5yLXTB2MDjbKg4IDlUVJXQichO1QugII7/bbgf2v5AqlaZ5ADeEjzo1Z3TDvJjo1PqZFY74gbLkjvKNA3DPwfihR3ie3H09K0zyFmgv3BIwbIpiadRgfS1k9jhfsYNhDDSxky2IosL+EbVdAgxtvUZrmCYyHGAcK1pmjhvGgLCFnAovScSRbFkNhsYWhROpWjIXQNE8k3BEjJwYYHaqAmfER7QpQKwyQuDUUYAaGEtlPYspCaZonMmFRCayiY6w6c2NhHYoZD5orXAZnKIkAJVIzMHAyFNCAYSyEpnkq6TpcOTHjYEY+7wQ8uCsPU+0vqBlIBCC9gwSUPRBhKMAO50homiebgVkrd73hrbGK7soDVD2PXEjcAYGDErZD17GI+0sKKdYgypHQNE9lMnNLOereciATyVR5gL/gAuqOoXCyf8eNbQe+n8SMI6VpnszUua8zToSymUSNj11dwpaBwrUBCtAR9wMF6LNxTWia5yCdceAcGTemWDbu3Kda+1q3DKVErpVSIqs9pRBnm4wbQtM8gSonRgBixDjjyVkV7ZR7dGYkQOFAFhC5NpAivQk3NkrTPJ44ByYEVm7csSmbSSSnEnE1zumsMe04KPCOg31HgZQjkNP7JMaR8qMiNM2jSQfKSoisjPvKxlmUiXtcX5Qdi0hKKXIys8iUriSkFwMU7cX9dRKa5vGME8NYKXc4UDYpARu854xqngZWBQicdKziHCHHXIxVL9Om1ulzoWkeT7lmbyoL6VS55mnDoixiLJvNLNxSSFxyXySS2AMpghvQu+dXI8P8d0rTPAf9XmuAQnSubSisUmZRUMGMa5kdi6GwysOeo0JmleM+iBo6Vw1lAP1vQtM8iXFgoBwYNwpHiVXCuaFzz+XlBdciq2EoAyeJIGao1JcFkVL6nwpN83gzwjWzykpZfC4sItdKgT4xu3LkjNTKKiUWERhKoQARiL7vDNTpckqQEi+VpnkCMe4pKCZvuSOxGHv46nfurMRfTyXugBRYFE5SJu7pYJ9A8arCwuHdj4SmeQLjjBJYVOFhY89v5o6V6uaSFKArrGS/5w6V3kZwfVUgZ2IsP/qvQtM8E7PorJxPGMk69wrqc/m2+JYBcgXZci3DHmbzqWOh5W9ZzfOLLULTPBczYo2x8LGcM4vEC51dsW6T+xxgD+RattyKMwyw11FVK+WXkFL+8gWgNM2zMRQc42MZEvD6imSgbBgvtpzsuZEyDKUM9BnrfSjJQyV/+Y6F0DRPoZxRDESVj1xAZnEFCRdmxovAtYGDoUAGCrCfgDkDkZy/fMdKaZqnMO4pEPjI+Nkuf+CkM52vOEkE4iVbbgwleaqvvlfjYkoe4ct3HAhN8wTKOcO8Egx35673mRuubIAKDBCgbLecy2lb32KiFonAO46EpnkC5x7xyCf1PaQMPpceEaAkkHd77in9DEgGKreEpnm0rkMU5YwJf0pPBmPlzoFwbR9ZlAJ5FANFuUNomsczEe5STJRPGnuidgK8ZsfRlvviJqmy2HGH0DSPZgQF44wZsyifMF6MYAXNELhvKBxEdpixElavOFKa5gmqGfcYcwcdGIWPpakjAL7j05IJYKk3CdwSmubR3DFuKIgo4KbdPM86RVaJhUPfk0oPhfKiTzsYuo6MX3IjsSoaO1ZmhVJr9wNHQtM8gXFHJ64oKrN0zNzIObOKPqIVrsYdD8nEGeJuMgMMmzOBKh84EJrmKZQbBhYETM1w62DiJGeuRWMWLi752D7Cnhj5G1aKfDUkCjeEpnk0Ee5ygipmdGBAjECGlIARGJk6CFCBwkq4NhRmVt+JAZb41kKJQHrFSmiaRzPDuMdYmHWCiEwcpfQZMAIJg7Hn1nbLjciqGgfZJL7rZhY/fHj1CpSmeT5dYaVm4AjCjZRZJFRsM3IQC4tX8I6juGexJxhHRgrgEeIP5a8RmubZqHFgLFQ48z6zyiwmxpHFfp4hz5U7Er1wzWSMLnNBIvxnoWmeTwBcWZiJ4IkYI5lzBonIrVw52bMofTXlRM0MkBhI9iuhaZ6NA6FzQBUTB3KeIrcSoJwMw8C5PVxy6QWMEzMRex9zpTL+Vmia52UszDDrWAkr5+BrkzBvOCmFj5Q9xjmztI95ztn+k9A0z0Yqiw5QBQMmd4iZPgM943dqUDKFReFBXylnzMTT/t/OMfKd0jTPxpTFzMLFGXViw8GOg4SYkOk3zif9xgXBuGbo5v/2ez7bCk3zfJwTExYmkksBMkcvwOF1n5xFjBwEzmRQxaUXbtjoNYRhUJrm+XSFE2NlqvOmsEiZE2chDuyhY1G5sb3MxIlKTkhnOouxMoNffqs0zbNRC0BnhhoHRjdtCouUOVAcMokzA2nLUUk2dTMD+xSLOC7CwlhF/q7SNI8j0TknAQiuiAESQsVJc6osoiszwUItAmliFVm4hvJiYjWEYEpBVHXvMVF6QiifjbHjxz8WmubxnDucVSi4shABzLopRo4yEHhA5MQzoBfJkw+DVmXMOW/+UAW//CelaZ6LsgoQQgWEA6Or86ZAGkkxEwO3ZobCrUt/Ryrx638BStwP8DJHFpd1x36vNM0zUQIQ3UCj48aRAdOmcPE+7h2IhYddskhi9t1LL4Uy7IdSIoshw+V8KTTN81AC18w74UjBEKbIe0BdbGJ1ybnqrLaFFzOeA3Ge59IVKAsppXSj/kppmufhwi1TxUARFDOlK8QCiCmrHDkYCpAhsciDcBWAUugihZPMkdA0z0IkcMZwUNRYmWDkl5y75L4swq1SuE9omucgUDk3s/D5c9QAMyxyx5bVPnIm+yVHiQcITfMXoSLinf4gs7IwYRp7LviUS4j8CSn1P1Wa5lkVYjDANBRm6Yq4GmDqGd6yeHHVc2NPxyJzWWYelliFdy+FpvkLqeLiRogICxPL/AnOp4VAKK8/E5rmOTi3hJVwFIJ3ysIxnIMR50yMkXsy52qlxvKt0jTPQlw4cRTMMPUO3HA1wHtcTOEDjP3ucstRZA9DTlzrghTOZBapjr8VmuYJlGvGtYiKSHRDhXk2MFMWc6k4H9nvgT05s6ivO6wQuS8DQtM8XufcEI6iG6XYjxzBZxG064Kj4LUarjxo5ugKNDsfyyA0zTNxDgoK1d+y6gAxQ1g5b8A4SJWHBAgs4rzgHqFpnkI5UDAppbKoteJiiMAFb7SwUAPcf8AdXgMxv+ZGt+BgiwfYs+coztwSmuYpXFkZYCJeOTEQ0B9kJ9wShBtXfKwAX83pQgYO4p6ZG0LTPBcz0VqJkWvSVayq4qYsTHhQXBDjHCM930LIrCKryDWlaR5v5i7DETwWFi4WqHNnThU3VsYifoCx5/UV1/bAsIc9lGjdvFdW+4HFfuBEaZpHc+EONUO9xMKBWgUp6o5xZlIWhQt23NpzkHOErBzsWe05+NnXQtM8ngvOLQNMagFhYUAIAcG4JZ2yYVWEj73uKd98s99z0nHjO6VpnsC4R42VYoi6lEo1Mc4YvhEY+w/JLwJb7nKS/S4wsOdg5sbXQtM8J1O8xsLKjAqIcYdSMjDGhITKrYHFblMqExqHYeAepWmelyHOjJopsxgfmTFNGfiQU4qXW85cbnF0ht0gThc5sw1K0zwrA3XAwZRPSWSIEajc2EOFXV/ppsstMFA4SsCrb5SmeW5zh4o5GA8RV0jksQf3zeWWWztgDJ+/DTOLPSeDAy9+pTTNc/NZ3BHnYdaHAumn37K6uuSevrx1rd98CxcsAjVsWfzxn5SmeQphJcY5d3XE+ZRCP+bf8rDXV72Jdb+lZwf0LPoNLq++UZrmKVxYuILD599zYuCcU4wjNSMBKbPqwyWVsOXkwhkDXkqkhE1hfH1F4gr+pvxaaZonEWfhIPBWMQ7UUM4pGAcGXoDcAyP9NJJeOEeXAWeVFStdVk8fEpAudt/97N8pTfMkhnAUoHo/A2KmeGfc0FK5YWJjhhIZYex7blUjcmCAYTpz8Lbj3f9WmubR1FDMhYMaCGISqCgQEeNAsVmjcUsz8OKKWxc7FpeVlToHBsbJSI5C0zyai5qBCwulVkIIEA5w48gMdTNuRItAfsGiZzFlubgEtrsIr/mpKEeqnKgyCU3zeJ0rC3NgdudT1DFu1e4VKUGi7zmayv7igpV4+jaqcmDGiRkITfMUzkrp+BPUMc6Y/RAhZ844AlxI/iADZeYhStM8iRqfIIpxIG6AggJmQEdm8c239CPQA3EaYddHri4vZ1OMjyhN8yTGp5ToHHRmoCg3TCdl8QOM3OgpyYEKm0n4mNI0z0YtcMaNI2ehbqyiAgYp85GIQBIoanxMaZpnMwvnRI2FIq4G0s0KyOygXcg8wCXhE+TUmXGf0DTPxzlXaqegboYRmOeu1ipFFMxqBPJniUUP4ziy8mli0UdXPiI0zfPpKncUAeGglK6zWnFwBeaJxS4lViOJc5sRlPuEpnkK4a5auUvBUBbFwAsRQTGIXBtH7rnqozvKXULTPN6McYcqlXMqLIwj5XOZQ1AWXWH1gqPMOHIyjj0j9MZdStM8gTjnZkAqgRt1FuMk4Lz1jmKO2ryhQM4vcuZkhJ6DkX5M3Cc0zaN1nBi33DlTxQDloIqqzBA6DMklXQA5cV/Pos+uqpwTmubRZjEOlDsq18yNhYGUWjGZlQImYGoZYoRNShwkGFn1MI7fGBjnhKZ5NDcFRcWZuaXceOOgvSqY405R11prEAXrbEcp8DKlxCoD44rVt+qqnBOa5vHUOOg4N3MtcuCugDlQxdW14orRscq7nFPijp5FVucOoWkezwDDOz7lLcpCUQXEazVmmTVEhxGLnKQF51JioZwTmuYJVEGYZ+6qHFQzDGZMlIWJL8TcKJ2ippxkUpKUErcuAENRbghN82iqmErHfU6tLJSDTrFZFTABMVYzmPkUOcoQU0ovOBhHGDdkdce4Edn94Sc0zaO4uzqFj9SaKlQ3Fk4sEMUAqRTUxaUGZxGAKFKJLHLMnDihEJFkHP2vX+2UOtM0j6Q4wi3n2iwBF45MTV36EQx1THXWmYX386Zw7kUP/CuLnDYvdzCrcTAHFHea5nHEQYwzwjUtiLFS660rwa03A0NxmDtjMUNk2nCSYARSZpE/GxMZxVgVQaj1FzTNo4ggxjl34T5jxH4kwBtVwGGGwkKdaZqEO3JO3Eg6qyrwi1qJvB+++IdvaJpH6EyMezxWViWAc+I+1iA5V1w9UgHBwYmVz0ePUt09cuBE0VVnUDTiBr/44sMfCMDnIcTu72maP5c4J2rcUOfIuaUuIc4qZiAdbrEaK9VZgEThJHEtQ+p3xm+/LbX+AAr88GUIFmmaP1v88R84qJEb9TNndRW5VcOlpAnEryC/SU55y6q+SmTg9Y5riZMMpIsP9t+D1N8DgaZ5tA0TsGFVIMIEbCCwqEyc2QStdPl9jBNsgsyRxcQmhgiEMHEycbJh8e//z9f5t0wsAk3zNBsooCwswgQbCEBl4txmfgkpv4+RRYkcTGh58dkVhMDEmQnYsOrsQzexiDTNk2ygqAgrKYIWilKEReGcIh+yxZdfXFWZVJiKUqSQ+OmbOgGhcEYLFGVRkmZn8f8BKlZ8bJPrhHsAAAAASUVORK5CYII=) no-repeat; + background-size: 102% 107%; + background-repeat: no-repeat; + background-attachment: fixed; + /*关键*/ + background-position: center; + overflow: hidden; + border: 1px solid #d9d3c7; +} + +.skillimg { + margin: 5px; + width: 60px; + height: 60px; + background-image: url(skillbg.png); + background-size: 100%; +} + +.skillimgC { + width: 55px; + height: 55px; + margin: 2px 0px 0px 2px; +} + +.skillname { + margin: 10px; + width: 250px; + height: 20px; + line-height: 20px; + color: #91837a; + font-weight: bold; + letter-spacing: 1px; + font-size: 18px; +} + +.skillLv { + margin-top: 8px; + width: 250px; + height: 20px; + line-height: 20px; +} + +.skillRight { + margin-top: 20px; + width: 140px; + height: 40px; + line-height: 40px; + display: flex; +} + +.skillJt { + line-height: 32px; + font-weight: bold; + color: #91837a; +} + +.skillNow { + border-style: solid; + border-width: 1px; + border-color: #d9d3c7; + border-radius: 7px; + width: 50px; + height: 30px; + line-height: 30px; + text-align: center; + color: #91837a; + font-weight: bold; + font-size: 20px; + background-color: #f7f5f0; +} + +.role_top { + margin: 10px 0 20px 0; + padding: 10px; + /* box-shadow: 0 5px 10px 0 rgb(0 0 0 / 10%); */ + border-radius: 3px; + font-family: tttgbnumber; + background: linear-gradient(1turn, hsla(25, 23%, 67%, 0.4), hsla(25, 23%, 67%, 0.2)); + display: flex; + color: #8c7770; + font-weight: bold; + font-size: 20px; + letter-spacing: 1px; +} + +.role_top .role_top_name { + width: 50%; +} + +.role_top .role_top_LV { + width: 50%; + text-align: right; +} + +.role_separate_line { + text-align: center; + color: #bfa399; + height: 24px; + line-height: 24px; + font-size: 18px; + margin: 10px 0 20px 0; + background: url(data:image/png;base64,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) no-repeat; + background-position: 50%; + background-size: 100% auto; + font-weight: bold; +} + +.cailiao_box { + display: flex; + flex-direction: row; + justify-content: space-between; + flex-wrap: wrap; + color: #91837a; + font-weight: bold; + margin-bottom: 20px; + padding: 0px 10px; + width: 100%; +} + +.cailiao_item { + width: 230px; + display: flex; + align-items: center; + margin-bottom: 10px; +} + +.long { + width: 100%; +} + +.isTalent { + margin-left: -10px; +} + +.cailiao_img { + width: 50px; + height: 50px; + margin-right: 10px; + background-position: 50%; + background-repeat: no-repeat; + background-size: contain; + text-align: center; + border-radius: 3px; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAEXElEQVRYhc2ZO2tUQRTHz5l73WQlGhHETlDEQhALG20kxEJLW2trv4SIYCOCHyTYWSh2CmIR7CwsbK1CFNxsdufIvM887mN3bx4Lm53XPfObM/8zM3eCRAQ7r5/fQIRXALANAOeBfxABEXUBogAUJi+wMmkhQrmodL5SZbq8AqwECNtGVJVpq8sqWya0PfessiPQtAeBAIQTOZvuTg8mz+48evwN3715cVPK+WcA2IT0k8JqwyXYkPewFkAIC2fLXVpY8GAjDEzZAnTgqMGJ4N9kf2+rlnL+UsEqT8v5PGOOnA3KUF4aF4eMbm+LeML4AFlzZtQ5yKbrMyO4fPU6bFy4OB6Nz74VAPBA1bXBKoN6pBiXmhnwGDks+p5NiX4EGTiyQVl7ttyBz2eH8PvXTwO/vn67BoCNlT0a/fA892iDV5E9FT0TepgdHupfgWKt7g/LO+sCLUM0grJRIfARBue4AWTAQ+i0FdQCpaCQeDW0iXlq13Dp6W8LqAIEZF5sAuXtQ32tlg4oBtTx6rQRNHFizdfats5z0DLEMjqN+sNyPQGpP1C7hfm06DSVmZcYOQ/7bTQHLRkI/Q+h0x6g7oeMl2uzHeLAOl0woDLQMBj3hIJVu3Ht9vFBdMoHF4H302kJ1Nsk0t8a3WnpSHTK46I0/YnEsrbIeK2HReLhok47Dig56HI6zWYtihXS39od606DTtvsaw9LaYNOnVHZA+2gbBY6QRbTaWafQZPTsDtQe2snqNOyHG29lCBN0FVew8et08ZBFRwltYel2em0LE6BTtvqwa8SzMNdOiqDDqfTNkcQSSBp12H9UsmmIvdqt04jkF46XcwRClZB1wpWBd7R6LRnQDWChjbew14SS+u0axnsr9Oo/0Re5IPO3RVg26iXCSju1VUDFqwk7Drsd7pEe5kOC4aG1GnpiOtPa14SaknTV0iFhl3T3wjK2/bXabO8jIcBpNk4BNvpVtLpoueOzlljNsjudMK9cZwCnRZB7R8ZDj/JxnGCOs37YAmS9gBvrzjT6Y81PbBOi6CFAfnmbONA/xK6nE7bd8hkMD2nP662qwRI+05n72QXDpjeO+CCoOns2aReJXzQIQ+64QOKWW3VaQk0rBJOEv6dbnWdpoelHDQfXGjeAGo/5iUUnCQaAi41dsQ6LYG6MgoeRnv4aZv+49FpBJvUU7SsRReCK+q0CArMIYuB+pyJOethFC2gw+i0EzTpJ+3beNhcaE9B4KgejWCu/pfQufAH2OL0FwMqzjfpNM+yVtrDtC9ms9muKr505RrUozXmoeBJjLTs/nNk23gAHrgIoRqbYdE5JQwpOIoNQAgXdB/w+6f398bnNj+iwLGfSgrDInK/tlCSvUmUfjF3917qcKLLeZ6X6XR41qeVbVWnuyrUmavWPSC6K25tPfwy+bu/PZtOvxLJg0ZYfRx1sKoDc9cVwdntMwXVg/KwKh2AFKgftH4ug/1DQDsK9v6Tpz/+A+D9r7rzum/YAAAAAElFTkSuQmCC); +} + +.cailiao_item_img { + width: 50px; + height: 50px; + /* margin-right: 10px; */ +} + +.cailiao_item_title { + line-height: 30px; + font-size: 18px; + vertical-align: middle; + white-space: nowrap; +} + +.biye { + text-align: center; + font-family: "tttgbnumber"; + line-height: 30px; + color: #91837a; +} + +.logo { + font-size: 14px; + font-family: "tttgbnumber"; + text-align: center; + color: #7994a7; +} + +.jt { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAQCAYAAABtPJ3XAAAC4klEQVRIS9VWTWsTURS9b4oiBPozIiKI1l2hBanUNHThokip0NJUKJrRHxBoOxGSmoL/IaWxKUnrvuDGzLiTbtWI0K0TN4Uijc27R+Yj85FMmml3zSabnHfPPffccyPomn2ExfeXric7Ix3l9vij71fhr+9tJ0f4hjK+sHAl/MdiMclEylwuNxQvmkZjDUCeWQoAtTOlrY5NpltxiRvVD2sMmWfJgphriiR1MpOJjT8oba7BxQviGkRbfZbbHIgXzS+NE5Y8CmYCmJhhCoJ6d2q6Hoe0Ua2cMPMoW3j7DZgA1KnlF7Hw+1uFE0iMgiWBQQw2BUid33gbibcUhl0MTsFA4Xqng+xY+mK19WoFIZz7BgH1f0o7m868uVDtg1LBqe+QdThIJgLX2+fIZjbDaoum8RnMcNXxCVuPEMhksPpgZnagWvruDgD4jYabNiWgzqy+GojfLxVgkbUU7uMBNsGkLhbeefhIhT2V3UYYKI99PVoRmsa9NtGrO55CtiUChLuKAVRO/f4TiQ8p3LWl7J04yse3EiuaprFPuOfHXdLdrkkg9XD26WEUYYekMyW/WfZHzExCiNTMy9d9+D7ClpcDE+u+pwCpxdL7wxBhT5HwWB1PDSRsedgfZz9hyy4yBmG3aWvxAwp3RWAglQkRthPC3fSQUiAilO+nj1aEiLJE9NLZiWMXBhFQfnIJS3gku3wI5eObvZboSQl3c1sgZIctnTOZgCX8t1oClJ0eunRuSnjR6IjHzC0CZUNL98No2LHk57CXp/FibUBKxI21YEoEow2Mevuco2KtccrMCT+HYbKEem863uHQq5VTMCfCh6OjTi2vxjocB6XiKbNMBMiaDKk+3yhEH46fRmNdMudthYlqZ3/P1GHHIpgUxm5lncF5O7eJa8r55U7z/lZxHdKqLwmEmhh2mq3i3/RPSev7zsTjZpxz3Bdt29s2fmJp6Ur4vaJm4+dz2lC8/W/tOn3+A23CzD4pjl20AAAAAElFTkSuQmCC) 50% / cover no-repeat; + width: 20px; + height: 8px; + display: inline-block; + margin: 0 5px 2px 5px; +} + +.role_box .life { + position: absolute; + top: 0px; + right: 0px; + z-index: 9; + font-size: 16px; + text-align: center; + color: #fff; + border-radius: 2px; + padding: 1px 5px; + border-radius: 3px; + font-family: "tttgbnumber"; +} + +.life1 { + background-color: #62a8ea; +} + +.life2 { + background-color: #62a8ea; +} + +.life3 { + background-color: #45b97c; +} + +.life4 { + background-color: #45b97c; +} + +.life5 { + background-color: #ff5722; +} + +.life6 { + background-color: #ff5722; +} \ No newline at end of file diff --git a/plugins/genshin/resources/StarRail/html/calculator/calculator.html b/plugins/genshin/resources/StarRail/html/calculator/calculator.html new file mode 100644 index 0000000..aefc4ce --- /dev/null +++ b/plugins/genshin/resources/StarRail/html/calculator/calculator.html @@ -0,0 +1,135 @@ + + + + + + + + + + +
+
+
+ UID : {{uid}} +
+
+ 角色养成计算 +
+
+
+
+
+ {{ if dataCharacter.rank>0}} + + {{dataCharacter.rank}}命 + {{/if}} +
+ +
+ +
+
+ {{dataCharacter.name}} +
Lv.{{dataCharacter.level}} Lv.{{setSkill[0]}}
+
+ {{ if dataCharacter.equip}} +
+
+ +
+ +
+
+ {{dataCharacter.equip.name}} +
Lv.{{dataCharacter.equip.level}} + Lv.{{setSkill[1]}} +
+
+ {{/if}} +
+ + {{each skillList skill i}} +
+
+ +
+
+ {{ if skill.anchor=="Point01"}}普通攻击{{else if skill.anchor=="Point02"}}战技{{else if skill.anchor=="Point03"}}终结技{{else}}天赋{{/if}} +
Lv.{{skill.max_level}}
+
+
+
{{skill.cur_level}}
+
+
{{setSkill[i+2]}}
+
+
+ {{/each}} + +
+ {{if computes.avatar_consume.length + computes.skill_consume.length + computes.equipment_consume.length > 0}} +
+ {{if computes.avatar_consume.length > 0}} +
+
{{dataCharacter.name}}
+
Lv.{{dataCharacter.level}} Lv.{{setSkill[0]}}
+
+
角色消耗
+
+ {{each computes.avatar_consume avatar_consume}} +
+
+ +
+
{{avatar_consume.item_name}} x {{avatar_consume.num}}
+
+ {{/each}} +
+ {{/if}} + + {{if computes.skill_consume.length > 0}} +
行迹消耗
+
+ {{each computes.skill_consume skill_consume}} +
+
+ +
+
+ {{skill_consume.item_name}} x {{skill_consume.num}}
+
+ {{/each}} +
+ {{/if}} + + {{if computes.equipment_consume.length > 0}} +
+
{{dataCharacter.equip.name}}
+
Lv.{{dataCharacter.equip.level}} + Lv.{{setSkill[1]}}
+
+
+
+ {{each computes.equipment_consume equipment_consume}} +
+
+ +
+
{{equipment_consume.item_name}} x {{equipment_consume.num}}
+
+ {{/each}} +
+ {{/if}} + +
+ {{else}} +
+
毕业了,下一位 !
+
+ {{/if}} +
+ + + + \ No newline at end of file diff --git a/plugins/genshin/resources/StarRail/html/calculator/skillbg.png b/plugins/genshin/resources/StarRail/html/calculator/skillbg.png new file mode 100644 index 0000000..06523c2 Binary files /dev/null and b/plugins/genshin/resources/StarRail/html/calculator/skillbg.png differ diff --git a/plugins/genshin/resources/img/namecard/珊瑚宫心海.png b/plugins/genshin/resources/img/namecard/珊瑚宫心海.png new file mode 100644 index 0000000..4516884 Binary files /dev/null and b/plugins/genshin/resources/img/namecard/珊瑚宫心海.png differ diff --git a/plugins/other/sendLog.js b/plugins/other/sendLog.js index 03ea644..6fbd113 100644 --- a/plugins/other/sendLog.js +++ b/plugins/other/sendLog.js @@ -1,10 +1,11 @@ import plugin from '../../lib/plugins/plugin.js' +import common from '../../lib/common/common.js' import fs from 'node:fs' import lodash from 'lodash' import moment from 'moment' export class sendLog extends plugin { - constructor () { + constructor() { super({ name: '发送日志', dsc: '发送最近100条运行日志', @@ -25,7 +26,7 @@ export class sendLog extends plugin { this.errFile = './logs/error.log' } - async sendLog () { + async sendLog() { let lineNum = this.e.msg.match(/\d+/g) if (lineNum) { this.lineNum = lineNum[0] @@ -48,13 +49,14 @@ export class sendLog extends plugin { this.reply(`暂无相关日志:${type}`) 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) } - getLog (logFile) { + getLog(logFile) { let log = fs.readFileSync(logFile, { encoding: 'utf-8' }) log = log.split('\n') @@ -78,42 +80,4 @@ export class sendLog extends plugin { 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>/g, '___') - .replace(/___+/, `<title color="#777777" size="26">${title}`) - - return forwardMsg - } } diff --git a/plugins/other/update.js b/plugins/other/update.js index 5c42e26..ed434a4 100644 --- a/plugins/other/update.js +++ b/plugins/other/update.js @@ -11,7 +11,7 @@ const { exec, execSync } = require('child_process') let uping = false export class update extends plugin { - constructor () { + constructor() { super({ name: '更新', dsc: '#更新 #强制更新', @@ -37,7 +37,7 @@ export class update extends plugin { this.typeName = 'Miao-Yunzai' } - async update () { + async update() { if (!this.e.isMaster) return false if (uping) { 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' }) if (!ret || !ret.includes('git version')) { await this.reply('请先安装git') @@ -74,21 +74,19 @@ export class update extends plugin { return true } - getPlugin (plugin = '') { + getPlugin(plugin = '') { if (!plugin) { plugin = this.e.msg.replace(/#|更新|强制/g, '') if (!plugin) return '' } - let path = `./plugins/${plugin}/.git` - - if (!fs.existsSync(path)) return false + if (!fs.existsSync(`plugins/${plugin}/.git`)) return false this.typeName = plugin return plugin } - async execSync (cmd) { + async execSync(cmd) { return new Promise((resolve, reject) => { exec(cmd, { windowsHide: true }, (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 let cm = 'git pull --no-rebase' @@ -104,17 +102,15 @@ export class update extends plugin { let type = '更新' if (this.e.msg.includes('强制')) { type = '强制更新' - cm = `git fetch --all && git reset --hard && ${cm}` + cm = `git reset --hard && git pull --rebase --allow-unrelated-histories` } if (plugin) { - if (this.e.msg.includes('强制')) { - type = '强制更新' - cm = `git -C ./plugins/${plugin}/ fetch --all && git -C ./plugins/${plugin}/ reset --hard && git -C ./plugins/${plugin}/ pull` - }else{ - cm = `git -C ./plugins/${plugin}/ pull --no-rebase` - } -} + if (type == '强制更新') + cm = `cd "plugins/${plugin}" && git reset --hard && git pull --rebase --allow-unrelated-histories` + else + cm = `cd "plugins/${plugin}" && git pull --no-rebase` + } this.oldCommitId = await this.getcommitId(plugin) @@ -147,10 +143,10 @@ export class update extends plugin { return true } - async getcommitId (plugin = '') { + async getcommitId(plugin = '') { let cm = 'git rev-parse --short HEAD' 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' }) @@ -159,10 +155,10 @@ export class update extends plugin { return commitId } - async getTime (plugin = '') { - let cm = 'git log -1 --oneline --pretty=format:"%cd" --date=format:"%m-%d %H:%M"' + async getTime(plugin = '') { + let cm = 'git log -1 --pretty=format:"%cd" --date=format:"%F %T"' 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 = '' @@ -177,7 +173,7 @@ export class update extends plugin { return time } - async gitErr (err, stdout) { + async gitErr(err, stdout) { let msg = '更新失败!' let errMsg = err.toString() stdout = stdout.toString() @@ -207,7 +203,7 @@ export class update extends plugin { await this.reply([errMsg, stdout]) } - async updateAll () { + async updateAll() { let dirs = fs.readdirSync('./plugins/') await this.runUpdate() @@ -225,14 +221,14 @@ export class update extends plugin { } } - restart () { + restart() { new Restart(this.e).restart() } - async getLog (plugin = '') { - let cm = 'git log -20 --oneline --pretty=format:"%h||[%cd] %s" --date=format:"%m-%d %H:%M"' + async getLog(plugin = '') { + let cm = 'git log -20 --pretty=format:"%h||[%cd] %s" --date=format:"%F %T"' if (plugin) { - cm = `cd ./plugins/${plugin}/ && ${cm}` + cm = `cd "plugins/${plugin}" && ${cm}` } let logAll @@ -259,59 +255,14 @@ export class update extends plugin { 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 } - async makeForwardMsg (title, msg, end) { - 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>/g, '___') - .replace(/___+/, `<title color="#777777" size="26">${title}`) - - return forwardMsg - } - - async updateLog () { + async updateLog() { let log = await this.getLog() await this.reply(log) } diff --git a/plugins/system/add.js b/plugins/system/add.js index 6bb0ce6..9568688 100644 --- a/plugins/system/add.js +++ b/plugins/system/add.js @@ -1,9 +1,8 @@ - import cfg from '../../lib/config/config.js' import plugin from '../../lib/plugins/plugin.js' +import common from '../../lib/common/common.js' import fs from 'node:fs' import lodash from 'lodash' -import { segment } from 'icqq' import { pipeline } from 'stream' import { promisify } from 'util' import fetch from 'node-fetch' @@ -12,7 +11,7 @@ import moment from 'moment' let textArr = {} export class add extends plugin { - constructor () { + constructor() { super({ name: '添加表情', dsc: '添加表情,文字等', @@ -45,7 +44,7 @@ export class add extends plugin { this.isGlobal = false } - async init () { + async init() { if (!fs.existsSync(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('#')) { this.e.msg = '#' + this.e.msg @@ -62,12 +61,12 @@ export class add extends plugin { } /** 群号key */ - get grpKey () { + get grpKey() { return `Yz:group_id:${this.e.user_id}` } /** #添加 */ - async add () { + async add() { this.isGlobal = this.e?.msg.includes("全局"); await this.getGroupId() @@ -95,14 +94,13 @@ export class add extends plugin { } /** 获取群号 */ - async getGroupId () { - + async getGroupId() { /** 添加全局表情,存入到机器人qq文件中 */ if (this.isGlobal) { this.group_id = this.e.bot.uin; return this.e.bot.uin; } - + if (this.e.isGroup) { this.group_id = this.e.group_id redis.setEx(this.grpKey, 3600 * 24 * 30, String(this.group_id)) @@ -119,7 +117,7 @@ export class add extends plugin { return false } - checkAuth () { + checkAuth() { if (this.e.isMaster) return true let groupCfg = cfg.getGroup(this.group_id) @@ -148,7 +146,7 @@ export class add extends plugin { return true } - checkKeyWord () { + checkKeyWord() { if (this.e.img && this.e.img.length > 1) { this.e.reply('添加错误:只能发送一个表情当关键词') return false @@ -171,7 +169,7 @@ export class add extends plugin { } /** 单独添加 */ - async singleAdd () { + async singleAdd() { if (this.e.message.length != 2) return false let msg = lodash.keyBy(this.e.message, 'type') 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.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 alias = groupCfg.botAlias 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; await this.getGroupId() /** 关键词 */ @@ -287,7 +285,7 @@ export class add extends plugin { } /** 添加成功回复消息 */ - getRetMsg () { + getRetMsg() { let retMsg = this.getContext() let msg = '' if (retMsg?.addContext?.message) { @@ -316,7 +314,7 @@ export class add extends plugin { return lodash.compact(msg) } - saveJson () { + saveJson() { let obj = {} for (let [k, v] of textArr[this.group_id]) { obj[k] = v @@ -324,7 +322,7 @@ export class add extends plugin { fs.writeFileSync(`${this.path}${this.group_id}.json`, JSON.stringify(obj, '', '\t')) } - + saveGlobalJson() { let obj = {}; for (let [k, v] of textArr[this.e.bot.uin]) { @@ -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 savePath = `${this.facePath}${this.group_id}/` @@ -375,9 +373,9 @@ export class add extends plugin { return savePath } - async getText () { + async getText() { if (!this.e.message) return false - + this.isGlobal = false await this.getGroupId() @@ -385,7 +383,7 @@ export class add extends plugin { if (!this.group_id) return false this.initTextArr() - + this.initGlobalTextArr() let keyWord = this.e.toString() @@ -410,7 +408,7 @@ export class add extends plugin { if (lodash.isEmpty(msg) && lodash.isEmpty(globalMsg)) return false msg = [...msg, ...globalMsg] - + if (num >= 0 && num < msg.length) { msg = msg[num] } else { @@ -446,7 +444,7 @@ export class add extends plugin { return true } - expiredMsg (keyWord, num) { + expiredMsg(keyWord, num) { logger.mark(`[发送表情]${this.e.logText} ${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 textArr[this.group_id] = new Map() @@ -510,7 +508,7 @@ export class add extends plugin { fs.mkdirSync(facePath) } } - + /** 初始化全局已添加内容 */ initGlobalTextArr() { if (textArr[this.e.bot.uin]) return; @@ -568,7 +566,7 @@ export class add extends plugin { } } - async del () { + async del() { this.isGlobal = this.e?.msg.includes("全局"); await this.getGroupId() if (!this.group_id) return false @@ -652,14 +650,14 @@ export class add extends plugin { img = item[0] } if (img.local) { - fs.unlink(img.local, () => {}) + fs.unlink(img.local, () => { }) } }) this.saveJson() } - async list () { + async list() { this.isGlobal = this.e?.msg.includes("全局"); let page = 1 @@ -727,9 +725,8 @@ export class add extends plugin { num++ } - let end = '' if (type == 'list' && count > 100) { - end = `更多内容请翻页查看\n如:#表情列表${Number(page) + 1}` + msg.push(`更多内容请翻页查看\n如:#表情列表${Number(page) + 1}`) } let title = `表情列表,第${page}页,共${count}条` @@ -737,63 +734,19 @@ export class add extends plugin { 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) } - 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>/g, '___') - .replace(/___+/, `<title color="#777777" size="26">${title}`) - - return forwardMsg - } - /** 分页 */ - pagination (pageNo, pageSize, array) { + pagination(pageNo, pageSize, array) { let offset = (pageNo - 1) * 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')) { let tmp = msg.split('{image') @@ -825,4 +778,4 @@ export class add extends plugin { return msg } -} +} \ No newline at end of file