diff --git a/plugins/genshin/apps/gcLog.js b/plugins/genshin/apps/gcLog.js index c044ae0..dd6e6b3 100644 --- a/plugins/genshin/apps/gcLog.js +++ b/plugins/genshin/apps/gcLog.js @@ -32,7 +32,7 @@ export class gcLog extends plugin { fnc: 'logJson' }, { - reg: '^#*(原神|星铁)?(抽卡|抽奖|角色|武器|常驻|up|新手|光锥)池*(记录|祈愿|分析)$', + reg: '^#*(原神|星铁)?(全部)?(抽卡|抽奖|角色|武器|常驻|up|新手|光锥)池*(记录|祈愿|分析)$', fnc: 'getLog' }, { @@ -133,10 +133,16 @@ export class gcLog extends plugin { /** #抽卡记录 */ async getLog () { + this.e.isAll = !!(this.e.msg.includes('全部') && !this.e.isSr) let data = await new GachaLog(this.e).getLogData() if (!data) return - let url = this.srHead('gachaLog', data) - let img = await puppeteer.screenshot(url, data) + let name = 'gachaLog' + if (this.e.isAll) { + name = 'gachaAllLog' + } else { + name = this.srHead('gachaLog', data) + } + let img = await puppeteer.screenshot(name, data) if (img) await this.reply(img) } diff --git a/plugins/genshin/model/gachaLog.js b/plugins/genshin/model/gachaLog.js index bad215a..b263caf 100644 --- a/plugins/genshin/model/gachaLog.js +++ b/plugins/genshin/model/gachaLog.js @@ -6,7 +6,7 @@ import common from '../../../lib/common/common.js' import gsCfg from './gsCfg.js' export default class GachaLog extends base { - constructor(e) { + constructor (e) { super(e) this.model = 'gachaLog' @@ -35,7 +35,7 @@ export default class GachaLog extends base { } } - async logUrl() { + async logUrl () { let url = this.e.msg /** 处理url */ @@ -46,25 +46,22 @@ export default class GachaLog extends base { this.e.reply('链接发送成功,数据获取中... 请耐心等待') - /**制作合并消息 */ - let MakeMsg=[] - let tmpMsg='' + /** 制作合并消息 */ + let MakeMsg = [] + let tmpMsg = '' /** 按卡池更新记录 */ for (let i in this.pool) { this.type = this.pool[i].type this.typeName = this.pool[i].typeName let res = await this.updateLog() - if(res){ - tmpMsg+=`[${this.typeName}]记录获取成功,更新${res.num}条\n` + if (res) { + tmpMsg += `[${this.typeName}]记录获取成功,更新${res.num}条\n` } if (i <= 1) await common.sleep(500) } - //只去掉结尾的多余一个换行符 - tmpMsg=tmpMsg.replace(/(\n)$/, '') 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) - await this.e.reply(Msg) + MakeMsg.push(`\n抽卡记录更新完成,您还可回复\n【#${this?.e?.isSr ? '星铁光锥' : '武器'}记录】统计${this?.e?.isSr ? '星铁光锥' : '武器'}池数据\n【#${this?.e?.isSr ? '星铁' : ''}角色统计】按卡池统计数据\n【#导出记录】导出记录数据`) + await this.e.reply(MakeMsg) this.isLogUrl = true @@ -76,7 +73,7 @@ export default class GachaLog extends base { return data } - async logFile() { + async logFile () { let url = await this.downFile() if (!url) { if (this.e?.file?.name.includes('output')) { @@ -89,10 +86,10 @@ export default class GachaLog extends base { return this.logUrl() } - dealUrl(url) { + dealUrl (url) { // timestamp=1641338980〈=zh-cn 修复链接有奇怪符号 url = url.replace(/〈=/g, '&') - if (url.includes("getGachaLog?")) url = url.split('getGachaLog?')[1] + if (url.includes('getGachaLog?')) url = url.split('getGachaLog?')[1] // 处理参数 let arr = new URLSearchParams(url).entries() @@ -113,7 +110,7 @@ export default class GachaLog extends base { return params } - async downFile() { + async downFile () { this.creatFile() let textPath = `${this.path}output_log.txt` @@ -142,7 +139,7 @@ export default class GachaLog extends base { return url[0] } - async checkUrl(param) { + async checkUrl (param) { if (!param.region) { this.e.reply('链接参数错误:缺少region\n请复制完整链接') return false @@ -194,7 +191,7 @@ export default class GachaLog extends base { } } - async logApi(param) { + async logApi (param) { // 调用一次接口判断链接是否正确 let logUrl = 'https://hk4e-api.mihoyo.com/event/gacha_info/api/getGachaLog?' /** 国际服 */ @@ -202,7 +199,6 @@ export default class GachaLog extends base { logUrl = 'https://hk4e-api-os.mihoyo.com/event/gacha_info/api/getGachaLog?' } - let logParam = new URLSearchParams({ authkey_ver: 1, lang: 'zh-cn', // 只支持简体中文 @@ -238,7 +234,7 @@ export default class GachaLog extends base { } /** 更新抽卡记录 */ - async updateLog() { + async updateLog () { /** 获取authkey */ let authkey = await redis.get(`${this.urlKey}${this.uid}`) if (!authkey) return false @@ -257,7 +253,7 @@ export default class GachaLog extends base { let logJson = this.readJson() /** 第一次获取增加提示 */ - if (lodash.isEmpty(logJson.list) && this.type == 301) { + if (lodash.isEmpty(logJson.list) && this.type === 301) { await this.e.reply(`开始获取${this.typeName}记录,首次获取数据较多,请耐心等待...`) } @@ -281,7 +277,7 @@ export default class GachaLog extends base { } /** 递归获取所有数据 */ - async getAllLog(ids, authkey, page = 1, endId = 0) { + async getAllLog (ids, authkey, page = 1, endId = 0) { let res = await this.logApi({ gacha_type: this.type, page, @@ -325,7 +321,7 @@ export default class GachaLog extends base { } // 读取本地json - readJson() { + readJson () { let logJson = []; let ids = new Map() let file = `${this.path}/${this.uid}/${this.type}.json` if (fs.existsSync(file)) { @@ -341,7 +337,7 @@ export default class GachaLog extends base { return { list: logJson, ids } } - creatFile() { + creatFile () { if (!fs.existsSync(this.path)) { fs.mkdirSync(this.path) } @@ -352,7 +348,7 @@ export default class GachaLog extends base { } } - writeJson(data) { + writeJson (data) { this.creatFile() let file = `${this.path}${this.uid}/` @@ -361,31 +357,69 @@ export default class GachaLog extends base { } /** #抽卡记录 */ - async getLogData() { - /** 卡池 */ - this.getPool() - + async getLogData () { /** 判断uid */ await this.getUid() - if (!this.uid) { - // await this.e.reply('当前绑定uid暂无抽卡记录') return false } + if (this.e?.isAll) { + return await this.getAllGcLogData() + } else { + return await this.getGcLogData() + } + } - /** 更新记录 */ - if (!this.isLogUrl) await this.updateLog() - - /** 统计计算记录 */ - let data = this.analyse() - - /** 渲染数据 */ - data = this.randData(data) - + async getAllGcLogData () { + const poolList = ['角色', '武器', '常驻', '新手'] + const logData = [] + let fiveMaxNum = 0 + const originalMsg = this.e.msg + for (let i of poolList) { + this.e.msg = i + this.all = [] + let data = await this.getGcLogData() + if (!data || data.allNum === 0) { + continue + } + if (fiveMaxNum <= data.fiveLog.length) { + fiveMaxNum = data.fiveLog.length + } + data.max = i === '武器' ? 80 : 90 + logData.push(data) + } + if (logData.length === 0) { + this.e.reply('暂无抽卡记录\n#记录帮助,查看配置说明', false, { at: true }) + return true + } + for (let i of logData) { + let diffNum = fiveMaxNum - i.fiveLog.length + if (diffNum > 0) { + i.fiveLog = i.fiveLog.concat(new Array(diffNum).fill({ isUp: false, isNull: true })) + } + } + const data = { + ...logData[0], + data: logData + } + data.tplFile = './plugins/genshin/resources/html/gachaAllLog/gachaAllLog.html' + this.e.msg = originalMsg return data } - getPool() { + async getGcLogData () { + /** 卡池 */ + this.getPool() + /** 更新记录 */ + if (!this.isLogUrl) await this.updateLog() + /** 统计计算记录 */ + let data = this.analyse() + /** 渲染数据 */ + data = this.randData(data) + return data + } + + getPool () { let msg = this.e.msg.replace(/#|抽卡|记录|祈愿|分析|池|原神|星铁|崩坏星穹铁道|铁道/g, '') this.type = this.e.isSr ? 11 : 301 this.typeName = '角色' @@ -405,18 +439,18 @@ export default class GachaLog extends base { this.type = this.e.isSr ? 12 : 302 this.typeName = this.e.isSr ? '光锥' : '武器' break - case "光锥": + case '光锥': this.type = 12 this.typeName = '光锥' break - case "新手": + case '新手': this.type = this.e.isSr ? 2 : 100 this.typeName = '新手' break } } - async getUid() { + async getUid () { if (!fs.existsSync(this.path)) { this.e.reply('暂无抽卡记录\n#记录帮助,查看配置说明', false, { at: true }) return false @@ -428,8 +462,10 @@ export default class GachaLog extends base { this.e.reply('暂无抽卡记录\n#记录帮助,查看配置说明', false, { at: true }) return false } - - this.uid = await redis.get(this.uidKey) + this.uid = this?.e?.isSr ? this.e.user?._games?.sr?.uid : this.e.user?._games?.gs?.uid + if (!this.uid) { + this.uid = await redis.get(this.uidKey) + } /** 记录有绑定的uid */ if (this.uid && logs.includes(String(this.uid))) { @@ -464,7 +500,7 @@ export default class GachaLog extends base { } /** 统计计算记录 */ - analyse() { + analyse () { if (lodash.isEmpty(this.all)) { this.all = this.readJson().list } @@ -627,20 +663,20 @@ export default class GachaLog extends base { } } - checkIsUp() { + checkIsUp () { if (['莫娜', '七七', '迪卢克', '琴', '姬子', '杰帕德', '彦卿', '白露', '瓦尔特', '克拉拉', '布洛妮娅'].includes(this.role.name)) { return false } let role5join = { - '刻晴': { + 刻晴: { start: '2021-02-17 18:00:00', end: '2021-03-02 15:59:59' }, - '提纳里': { + 提纳里: { start: '2022-08-24 06:00:00', end: '2022-09-09 17:59:59' }, - '迪希雅': { + 迪希雅: { start: '2023-03-01 06:00:00', end: '2023-03-21 17:59:59' } @@ -660,7 +696,7 @@ export default class GachaLog extends base { } /** 渲染数据 */ - randData(data) { + randData (data) { let line = [] let weapon = this.e.isSr ? '光锥' : '武器' if ([301, 11].includes(this.type)) { @@ -739,7 +775,7 @@ export default class GachaLog extends base { } } - getServer() { + getServer () { let uid = this.uid switch (String(uid)[0]) { case '1': diff --git a/plugins/genshin/model/roleIndex.js b/plugins/genshin/model/roleIndex.js index df07b4a..02ecf9e 100644 --- a/plugins/genshin/model/roleIndex.js +++ b/plugins/genshin/model/roleIndex.js @@ -22,7 +22,8 @@ export default class RoleIndex extends base { 渊下宫: 5, 层岩巨渊: 6, 层岩地下: 7, - 须弥: 8 + 须弥: 8, + 枫丹: 9 } this.areaName = lodash.invert(this.area) @@ -133,21 +134,21 @@ export default class RoleIndex extends base { ] ] - // 尘歌壶 - let homesLevel = 0 - // let homesItem = 0 - if (resIndex.homes && resIndex.homes.length > 0) { - homesLevel = resIndex.homes[0].level - // homesItem = resIndex.homes[0].item_num - } + // // 尘歌壶 + // let homesLevel = 0 + // // let homesItem = 0 + // if (resIndex.homes && resIndex.homes.length > 0) { + // homesLevel = resIndex.homes[0].level + // // homesItem = resIndex.homes[0].item_num + // } let worldExplorations = lodash.keyBy(resIndex.world_explorations, 'id') let explor = [] let explor2 = [] - let expArr = ['须弥', '层岩巨渊', '渊下宫', '稻妻'] - let expArr2 = ['雪山', '璃月', '蒙德'] + let expArr = ['枫丹', '须弥', '层岩巨渊', '渊下宫'] + let expArr2 = ['稻妻', '雪山', '璃月', '蒙德'] for (let val of expArr) { let tmp = { lable: val, num: `${(worldExplorations[this.area[val]]?.exploration_percentage ?? 0) / 10}%` } @@ -159,7 +160,7 @@ export default class RoleIndex extends base { explor2.push(tmp) } - explor2.push({ lable: '家园等级', num: homesLevel }) + // explor2.push({ lable: '家园等级', num: homesLevel }) line.push(explor) line.push(explor2) @@ -349,6 +350,8 @@ export default class RoleIndex extends base { } explor2 = explor2.concat([ + { lable: '水神瞳', num: stats.hydroculus_number }, + { lable: '草神瞳', num: stats.dendroculus_number }, { lable: '雷神瞳', num: stats.electroculus_number }, { lable: '岩神瞳', num: stats.geoculus_number }, { lable: '风神瞳', num: stats.anemoculus_number } @@ -417,20 +420,30 @@ export default class RoleIndex extends base { { lable: '普通宝箱', num: stats.common_chest_number } ], [ + { lable: '水神瞳', num: stats.hydroculus_number }, { lable: '草神瞳', num: stats.dendroculus_number }, { lable: '雷神瞳', num: stats.electroculus_number }, - { lable: '岩神瞳', num: stats.geoculus_number }, + { lable: '岩神瞳', num: stats.geoculus_number } + ], + [ { lable: '风神瞳', num: stats.anemoculus_number } ] ] // 尘歌壶 if (res.homes && res.homes.length > 0) { - line.push([ + // line.push([ + // { lable: '家园等级', num: res.homes[0].level }, + // { lable: '最高仙力', num: res.homes[0].comfort_num }, + // { lable: '获得摆设', num: res.homes[0].item_num }, + // { lable: '历史访客', num: res.homes[0].visit_num } + // ]) + const anemoculus = { ...line[3][0] } + line[3] = [ + anemoculus, { lable: '家园等级', num: res.homes[0].level }, { lable: '最高仙力', num: res.homes[0].comfort_num }, - { lable: '获得摆设', num: res.homes[0].item_num }, - { lable: '历史访客', num: res.homes[0].visit_num } - ]) + { lable: '获得摆设', num: res.homes[0].item_num } + ] } res.world_explorations = lodash.orderBy(res.world_explorations, ['id'], ['desc']) @@ -451,7 +464,7 @@ export default class RoleIndex extends base { ] } - if (['蒙德', '璃月', '稻妻', '须弥'].includes(val.name)) { + if (['蒙德', '璃月', '稻妻', '须弥', '枫丹'].includes(val.name)) { tmp.line.push({ name: '声望', text: `${val.level}级` @@ -470,7 +483,7 @@ export default class RoleIndex extends base { } } - if (['雪山', '稻妻', '层岩巨渊', '须弥'].includes(val.name)) { + if (['雪山', '稻妻', '层岩巨渊', '须弥', '枫丹'].includes(val.name)) { if (val.offerings[0].name.includes('流明石')) { val.offerings[0].name = '流明石' } diff --git a/plugins/genshin/resources/html/gachaAllLog/gachaAllLog.css b/plugins/genshin/resources/html/gachaAllLog/gachaAllLog.css new file mode 100644 index 0000000..7e17245 --- /dev/null +++ b/plugins/genshin/resources/html/gachaAllLog/gachaAllLog.css @@ -0,0 +1,396 @@ +@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 { + font-size: 18px; + color: #1e1f20; + font-family: PingFangSC-Medium, PingFang SC, sans-serif; + transform: scale(1.5); + transform-origin: 0 0; + position: absolute; +} +.container { + width: 1500px; + display: flex; + flex-wrap: wrap; + justify-content: space-between; + padding: 20px 15px 10px 15px; + background-color: #f5f6fb; + height: 100%; /* 设置容器高度,这里假设容器的父元素有固定高度或是占满整个视口 */ +} +.info_box{ + width: 465px; + margin-right: 15px; + margin-left: 15px; + flex: 1; + align-items: center; + justify-content: center; +} + +.head_box { + border-radius: 15px; + font-family: tttgbnumber; + padding: 10px 20px; + position: relative; + box-shadow: 0 5px 10px 0 rgb(0 0 0 / 15%); +} + +.head_box .id_text { + font-size: 24px; +} + +.head_box .day_text { + font-size: 20px; +} + +.head_box .genshin_logo { + position: absolute; + top: 1px; + right: 15px; + width: 97px; +} + +.logo { + width: 100%; + font-size: 12px; + font-family: "tttgbnumber"; + text-align: center; + color: #7994a7; + position: relative; + padding-left: 10px; +} + + +.data_box { + border-radius: 15px; + margin-top: 20px; + margin-bottom: 20px; + padding: 20px 0px 5px 10px; + background: #fff; + box-shadow: 0 5px 10px 0 rgb(0 0 0 / 15%); + position: relative; +} + +.tab_lable { + position: absolute; + top: -10px; + left: -8px; + background: #d4b98c; + color: #fff; + font-size: 14px; + padding: 3px 10px; + border-radius: 15px 0px 15px 15px; + z-index: 20; +} + +.data_line { + display: flex; + justify-content: space-around; + margin-bottom: 14px; + padding-right: 10px; +} + +.data_line_item { + width: 100px; + text-align: center; + /*margin: 0 20px;*/ +} + +.num { + font-family: tttgbnumber; + font-size: 24px; +} + +.num .unit { + font-size: 12px; +} + +.data_box .lable { + font-size: 14px; + color: #7f858a; + line-height: 1; + margin-top: 3px; +} + +/*body {*/ +/* width: 510px;*/ +/*}*/ + +/*.container {*/ +/* width: 510px;*/ +/*}*/ + +.data_box { + margin-bottom: 10px; +} + +.info_box_border{ + border-radius: 15px; + /* margin-top: 20px; */ + margin-bottom: 20px; + padding: 6px 0px 5px 10px; + background: #fff; + box-shadow: 0 5px 10px 0 rgb(0 0 0 / 15%); + position: relative; +} + +.card_list { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; +} + +.card_list .item { + margin: 0px 10px 10px 10px; + border-radius: 7px; + box-shadow: 0 2px 6px 0 rgb(132 93 90 / 30%); + height: 90px; + position: relative; + overflow: hidden; + /*background: #e7e5d9;*/ +} +.card_list .item.isNull { + margin: 0px 10px 10px 10px; + border-radius: 7px; + height: 90px; + position: relative; + overflow: hidden; + box-shadow: none !important; + background: none !important; +} + +.card_list .item img { + width: 70px; + height: 70px; + border-radius: 7px 7px 20px 0; +} +.card_list .item.star5{ + width: 70px; +} + +.card_list .item.star5 img { + background-image: url(../../img/other/bg5.png); + width: 100%; + height: 70px; + /*filter: brightness(1.1);*/ + background-size: 100%; + background-repeat: no-repeat; +} + +.card_list .item.star4 img { + width: 100%; + height: 70px; + background-image: url(../../img/other/bg4.png); + background-size: 100%; + background-repeat: no-repeat; +} + +.card_list .item .num { + position: absolute; + top: 0px; + right: 0px; + z-index: 9; + font-size: 18px; + text-align: center; + color: #fff; + border-radius: 3px; + padding: 1px 5px; + border-radius: 3px; + background: rgb(0 0 0 / 50%); + font-family: "tttgbnumber"; +} + +.card_list .item .name, +.card_list .item .num_name { + position: absolute; + top: 71px; + left: 0px; + z-index: 9; + font-size: 12px; + text-align: center; + width: 100%; + height: 16px; + line-height: 18px; +} + +.card_list .item .num_name { + font-family: "tttgbnumber"; + font-size: 16px; +} + +.base_info { + position: relative; + padding-left: 10px; + margin: 5px 10px; +} + +.uid:before { + content: " "; + position: absolute; + width: 5px; + height: 24px; + border-radius: 1px; + left: 0; + top: 0; + background: #d3bc8d; +} + +.label_301 { + background-color: rgb(235 106 75); +} + +.label_302 { + background-color: #E69449; +} + +.label_200 { + background-color: #757CC8; +} + +.label { + color: #fff; + border-radius: 10px; + font-size: 12px; + padding: 2px 7px; + vertical-align: 2px; +} + +.ritem { + display: flex; + font-size: 12px; + margin-bottom: 5px; +} + +.info_role { + display: flex; + flex-wrap: wrap; + padding: 0 0px 5px 9px; +} + +.ritem .role { + width: 20px; + height: 20px; + background-color: #ffb285; + border-radius: 100%; +} + +.ritem .weapon_box { + overflow: hidden; + width: 20px; + height: 20px; + border-radius: 100%; +} + +.ritem .weapon { + width: 20px; + height: 20px; + background-color: #ffb285; + border-radius: 100%; + transform: scale(1.5); + -webkit-transform: scale(1.5); + +} + +.ritem .role_text { + margin: 2px 3px 0 2px; + display: flex; + align-items: baseline; +} + +.ritem .role_name { + width: 24px; + white-space: nowrap; + overflow: hidden; +} + +.ritem .role_num { + width: 24px; +} + +.line_box { + height: 32px; + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + font-size: 12px; + color: #7d7d7d; + padding-bottom: 5px; +} + +.line_box .line { + height: 2px; + flex-grow: 1; + background-color: #ebebeb; + margin: 0px 10px; +} + +.red { + color: #f21000; +} + +.orange { + color: #ff8d00; +} + +.green { + color: #12d88c; +} + +.blue { + color: #4169E1; +} + +.purple { + color: #7500ff; +} +.minimum{ + position: absolute; + top: 0px; + right: 0px; + z-index: 9; + font-size: 12px; + text-align: center; + color: #fff; + border-radius: 3px; + padding: 1px 3px; + background-color: rgb(0 0 0 / 80%); + font-family: "tttgbnumber"; +} +.hasMore{ + font-size: 12px; + margin: 6px 0; + color: #7f858a; +} + + +.gold { + background: #ffeb73; + color: #6f4b00; +} + +.good { + background: #168b2c; + color: #fff; +} + +.normal { + background: #6939b7; + color: #fff; +} + +.bad { + background: #9d3333; + color: #fff; +} diff --git a/plugins/genshin/resources/html/gachaAllLog/gachaAllLog.html b/plugins/genshin/resources/html/gachaAllLog/gachaAllLog.html new file mode 100644 index 0000000..e18bf92 --- /dev/null +++ b/plugins/genshin/resources/html/gachaAllLog/gachaAllLog.html @@ -0,0 +1,79 @@ + + + + + + + + + + {{@headStyle}} + + +
+ {{each data log}} +
+
+
+ ID: {{log.uid}} +
+

+ {{log.allNum}}抽 + {{log.typeName}}池 +

+ +
+
+
数据总览
+ {{each log.line val}} +
+ {{each val item}} +
+
{{item.num}}{{item.unit}}
+
{{item.lable}}
+
+ {{/each}} +
+ {{/each}} +
+ + 五星历史 {{firstTime}} ~ {{lastTime}} + +
+
+ {{each log.fiveLog val}} +
+ {{ if val.isUp && typeName == '角色' }} + UP + {{/if}} + {{ if val.isNull }} +
+
{{val.num}}
+ {{/if}} + {{ if !val.isNull }} + + +
{{val.num}}
+ {{/if}} +
+ {{/each}} +
+
+
+ {{/each}} + +
+ + +