diff --git a/CHANGELOG.md b/CHANGELOG.md index a03a3e70..72ea0fdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,16 @@ -# 2.3.2 +# 2.3.3 Dev + +* 初步增加`#抽卡分析``#抽卡统计`,样式与功能尚未完全稳定 + +# 2.3.1~2.3.2 * 面板服务增加国内专属面板服务 MiniGG-API * 由小灰灰大佬**@MiniGrayGay**与Enka官方合作部署 * 国内节点,免费开放,请求速度会比Enka更快 -* `#喵喵设置`中可区分国服、B服、外服分别设置面板服务器,具体参见喵喵设置 - -# 2.3.1 - * MiaoApi面板服务更新 * 使用新版接口获取面板,大幅提高响应速度 * 使用statsIds存储圣遗物数据,能够更精确的计算角色属性 +* `#喵喵设置`中可区分国服、B服、外服分别设置面板服务器,具体参见喵喵设置 * `#面板`、`#角色`等页面使用Q版头像(@QuAn_、Misaaa),可在#喵喵设置 中关闭 * 部分已知问题调整或优化 * 圣遗物、天赋更新策略及更新逻辑优化 diff --git a/apps/gacha.js b/apps/gacha.js new file mode 100644 index 00000000..c0390264 --- /dev/null +++ b/apps/gacha.js @@ -0,0 +1,21 @@ +import { App } from '../components/index.js' +import Gacha from './gacha/Gacha.js' + +let app = App.init({ + id: 'gacha', + name: '抽卡统计' +}) +app.reg({ + detail: { + name: '抽卡记录', + fn: Gacha.detail, + rule: /^#*(抽卡|抽奖|角色|武器|常驻|up)池*(记录|祈愿|分析)$/ + }, + stat: { + name: '抽卡统计', + fn: Gacha.stat, + rule: /^#*(抽卡|抽奖|角色|武器|常驻|up|版本)池*统计$/ + } +}) + +export default app diff --git a/apps/gacha/Gacha.js b/apps/gacha/Gacha.js new file mode 100644 index 00000000..6ea0f2a7 --- /dev/null +++ b/apps/gacha/Gacha.js @@ -0,0 +1,68 @@ +import { Common } from '../../components/index.js' +import { getTargetUid } from '../profile/ProfileCommon.js' +import GachaData from './GachaData.js' +import { Character, Player } from '../../models/index.js' + +let Gacha = { + async detail (e) { + let msg = e.msg.replace(/#|抽卡|记录|祈愿|分析|池/g, '') + let type = 301 + switch (msg) { + case 'up': + case '抽卡': + case '角色': + case '抽奖': + type = 301 + break + case '常驻': + type = 200 + break + case '武器': + type = 302 + break + } + let uid = e.uid || await getTargetUid(e) + let qq = e.user_id + if (!uid || !qq) { + return false + } + + let gacha = GachaData.analyse(e.user_id, uid, type) + await Common.render('gacha/gacha-detail', { + save_id: uid, + uid, + gacha, + face: Gacha.getFace(uid) + }, { e, scale: 1.1, retMsgId: true }) + }, + async stat (e) { + let uid = e.uid || await getTargetUid(e) + let qq = e.user_id + if (!uid || !qq) { + return false + } + let gacha = GachaData.stat(e.user_id, uid) + await Common.render('gacha/gacha-stat', { + save_id: uid, + uid, + gacha, + face: Gacha.getFace(uid) + }, { e, scale: 1.1, retMsgId: true }) + }, + + getFace (uid) { + let player = Player.create(uid) + + let faceChar = Character.get(player.face || '100000003') + let imgs = faceChar.imgs + return { + banner: imgs?.banner, + face: imgs?.face, + qFace: imgs?.qFace, + name: player.name || `#${uid}`, + sign: player.sign, + level: player.level + } + } +} +export default Gacha diff --git a/apps/gacha/GachaData.js b/apps/gacha/GachaData.js new file mode 100644 index 00000000..8052af36 --- /dev/null +++ b/apps/gacha/GachaData.js @@ -0,0 +1,371 @@ +import lodash from 'lodash' +import { Data } from '../../components/index.js' +import { Character, Weapon } from '../../models/index.js' +import { poolName, poolDetail } from '../../resources/meta/info/index.js' +import moment from 'moment' + +let poolVersion = [] +lodash.forEach(poolDetail, (ds) => { + poolVersion.push({ + ...ds, + start: new Date(ds.from), + end: new Date(ds.to) + }) +}) +let last = poolVersion[poolVersion.length - 1] +// 为未知卡池做兼容 +poolVersion.push({ + version: '?', + half: '?', + from: last.to, + to: '2025-12-31 23:59:59', + start: last.end, + end: new Date('2025-12-31 23:59:59') +}) + +let GachaData = { + readJSON (qq, uid, type) { + let logJson = [] + // 获取本地数据 进行数据合并 + logJson = Data.readJSON(`/data/gachaJSON/${qq}/${uid}/${type}.json`, 'root') + let itemMap = {} + let nameMap = {} + let items = [] + let ids = {} + lodash.forEach(logJson, (ds) => { + if (!nameMap[ds.name]) { + if (ds.item_type === '武器') { + let weapon = Weapon.get(ds.name) + nameMap[ds.name] = weapon.id + itemMap[weapon.id] = { + type: 'weapon', + count: 0, + ...weapon.getData('star,name,abbr,img') + } + } else if (ds.item_type === '角色') { + let char = Character.get(ds.name) + nameMap[ds.name] = char.id + itemMap[char.id] = { + type: 'char', + count: 0, + ...char.getData('star,name,abbr,img:face') + } + } + } + let id = nameMap[ds.name] + if (!id || !itemMap[id] || ids[ds.id]) { + return true + } + ids[ds.id] = true + items.push({ + id, + logId: ds.id, + time: new Date(ds.time) + }) + }) + items = items.sort((a, b) => b.time - a.time) + return { items, itemMap } + }, + // 卡池分析 + analyse (qq, uid, type) { + let logData = GachaData.readJSON(qq, uid, type) + let fiveLog = [] + let fourLog = [] + let fiveNum = 0 + let fourNum = 0 + let fiveLogNum = 0 + let fourLogNum = 0 + let noFiveNum = 0 + let noFourNum = 0 + let wai = 0 // 歪 + let weaponNum = 0 + let weaponFourNum = 0 + let bigNum = 0 + let allNum = 0 + + let itemMap = logData.itemMap + lodash.forEach(logData.items, (item) => { + allNum++ + let ds = itemMap[item.id] + let { star, type } = ds + ds.count++ + if (star === 4) { + fourNum++ + if (noFourNum === 0) { + noFourNum = fourLogNum + } + fourLogNum = 0 + if (fourLog[ds.name]) { + fourLog[ds.name]++ + } else { + fourLog[ds.name] = 1 + } + if (type === 'weapon') { + weaponFourNum++ + } + } + fourLogNum++ + + if (star === 5) { + fiveNum++ + if (fiveLog.length > 0) { + fiveLog[fiveLog.length - 1].count = fiveLogNum + } else { + noFiveNum = fiveLogNum + } + fiveLogNum = 0 + let isUp = false + // 歪了多少个 + if (type === 'char') { + if (GachaData.checkIsUp(item, ds)) { + isUp = true + } else { + wai++ + } + } else { + weaponNum++ + } + + fiveLog.push({ + id: item.id, + isUp, + date: moment(item.time).format('MM-DD') + }) + } + fiveLogNum++ + }) + + if (fiveLog.length > 0) { + fiveLog[fiveLog.length - 1].count = fiveLogNum + } else { + // 没有五星 + noFiveNum = allNum + } + + // 四星最多 + let fourItem = lodash.filter(lodash.values(itemMap), (ds) => ds.star === 4) + fourItem.push({ name: '无', count: 0 }) + fourItem = fourItem.sort((a, b) => b.count - a.count) + + // 平均5星 + let fiveAvg = 0 + let fourAvg = 0 + if (fiveNum > 0) { + fiveAvg = ((allNum - noFiveNum) / fiveNum).toFixed(2) + } + // 平均四星 + if (fourNum > 0) { + fourAvg = ((allNum - noFourNum) / fourNum).toFixed(2) + } + + // 有效抽卡 + let isvalidNum = 0 + if (fiveNum > 0 && fiveNum > wai) { + if (fiveLog.length > 0 && !fiveLog[0].isUp) { + isvalidNum = (allNum - noFiveNum - fiveLog[0].count) / (fiveNum - wai) + } else { + isvalidNum = (allNum - noFiveNum) / (fiveNum - wai) + } + isvalidNum = isvalidNum.toFixed(2) + } + + let upYs = isvalidNum * 160 + if (upYs >= 10000) { + upYs = (upYs / 10000).toFixed(2) + 'w' + } else { + upYs = upYs.toFixed(0) + } + + // 小保底不歪概率 + let noWaiRate = 0 + if (fiveNum > 0) { + noWaiRate = (fiveNum - bigNum - wai) / (fiveNum - bigNum) + noWaiRate = (noWaiRate * 100).toFixed(1) + } + + return { + stat: { + allNum, + noFiveNum, + noFourNum, + fiveNum, + fourNum, + fiveAvg, + fourAvg, + wai, + isvalidNum, + weaponNum, + weaponFourNum, + upYs + }, + maxFour: fourItem[0], + fiveLog, + noWaiRate, + items: itemMap + } + }, + + // 卡池统计 + stat (qq, uid, type) { + let charData = GachaData.readJSON(qq, uid, 301) + let weaponData = GachaData.readJSON(qq, uid, 302) + + let items = charData.items.concat(weaponData.items || []) + items = items.sort((a, b) => b.time - a.time) + let itemMap = lodash.extend({}, charData.itemMap, weaponData.itemMap) + + let versionData = [] + let currVersion + + let getCurr = function () { + if (currVersion && !lodash.isEmpty(currVersion)) { + let cv = currVersion + let temp = { + version: cv.version, + half: cv.half, + from: moment(new Date(cv.from)).format('YY-MM-DD'), + to: moment(new Date(cv.to)).format('YY-MM-DD'), + upIds: {} + } + let upName = {} + let items = [] + let poolNames = [] + lodash.forEach(cv.char5, (name) => { + upName[name] = true + let char = Character.get(name) + poolNames.push(char.abbr) + }) + lodash.forEach(cv.weapon5, (name) => { + upName[name] = true + }) + let w5Num = 0 + let w5UpNum = 0 + let c5Num = 0 + let c5UpNum = 0 + let c4Num = 0 + let w4Num = 0 + let w3Num = 0 + lodash.forEach(cv.items, (num, id) => { + let item = itemMap[id] + let isUp = upName[item.name] + let star = item.star + if (isUp) { + temp.upIds[id] = item.name + } + items.push({ id, num, star: item.star, isUp: temp.upIds[id] ? 1 : 0 }) + if (item.type === 'char') { + if (star === 5) { + c5Num += num + isUp && (c5UpNum += num) + } else { + c4Num += num + } + } + if (item.type === 'weapon') { + if (star === 5) { + w5Num += num + isUp && (w5UpNum += num) + } else { + star === 4 ? (w4Num += num) : (w3Num += num) + } + } + }) + temp.name = poolNames.join(' / ') + temp.items = lodash.sortBy(items, ['star', 'num', 'isUp']).reverse() + temp.stats = { + w5Num, + w5UpNum, + c5Num, + c5UpNum, + c4Num, + w4Num, + w3Num, + upNum: w5UpNum + c5UpNum, + star5Num: w5Num + c5Num, + star4Num: w4Num + c4Num, + totalNum: w5Num + w4Num + w3Num + c5Num + c4Num + } + return temp + } + } + + lodash.forEach(items, (ds) => { + if (!currVersion || ds.time < currVersion.start) { + if (currVersion) { + versionData.push(getCurr()) + } + let v = GachaData.getVersion(ds.time) + if (!v) { + console.log('no v') + return true + } + currVersion = { + ...v, + items: {} + } + } + if (!currVersion.items[ds.id]) { + currVersion.items[ds.id] = 1 + } else { + currVersion.items[ds.id]++ + } + }) + versionData.push(getCurr()) + + return { + versionData, + itemMap + } + }, + + getVersion (time) { + for (let ds of poolVersion) { + if (time > ds.start && time < ds.end) { + return ds + } + } + return false + }, + + getItem (ds) { + if (ds.item_type === '武器') { + let weapon = Weapon.get(ds.name) + return { + type: 'weapon', + count: 0, + ...weapon.getData('id,star,name,abbr,img') + } + } else if (ds.item_type === '角色') { + let char = Character.get(ds.name) + return { + type: 'char', + count: 0, + ...char.getData('id,star,name,abbr,face') + } + } + }, + + // 检查角色是否是Up角色 + checkIsUp (ds, item) { + if (['莫娜', '七七', '迪卢克', '琴'].includes(item.name)) { + return false + } + + let time = ds.time + + if (item.name === '刻晴') { + let start = new Date('2021-02-17 18:00:00').getTime() + let end = new Date('2021-03-02 15:59:59').getTime() + return !(time < start || time > end) + } + + if (item.name === '提纳里') { + let start = new Date('2022-08-24 06:00:00').getTime() + let end = new Date('2022-09-09 17:59:59').getTime() + return !(time < start || time > end) + } + return true + } + +} +export default GachaData diff --git a/apps/index.js b/apps/index.js index 5907b526..eb972f4a 100644 --- a/apps/index.js +++ b/apps/index.js @@ -5,6 +5,7 @@ import wiki from './wiki.js' import poke from './poke.js' import help from './help.js' import admin from './admin.js' +import gacha from './gacha.js' export const characterApp = character.v2App() export const profileApp = profile.v2App() @@ -13,8 +14,9 @@ export const helpApp = help.v2App() export const statApp = stat.v2App() export const wikiApp = wiki.v2App() export const pokeApp = poke.v2App() +export const gachaApp = gacha.v2App() -let apps = { character, poke, profile, stat, wiki, admin, help } +let apps = { character, poke, profile, stat, wiki, gacha, admin, help } let rule = {} // v2 let rules = {} // v3 for (let key in apps) { diff --git a/components/Common.js b/components/Common.js index f4a55a50..93a42496 100644 --- a/components/Common.js +++ b/components/Common.js @@ -10,6 +10,10 @@ const Common = { return new Promise((resolve) => setTimeout(resolve, ms)) }, + async downFile () { + console.log('down file') + }, + async getNoteQQUids (e) { let ret = {} if (Version.isV3) { diff --git a/models/ProfileReq.js b/models/ProfileReq.js index 8a581d66..0601414e 100644 --- a/models/ProfileReq.js +++ b/models/ProfileReq.js @@ -78,7 +78,7 @@ export default class ProfileReq extends Base { if (self._isReq) { this.msg(`开始获取uid:${uid}的数据,可能会需要一定时间~`) } - }, 3000) + }, 2000) // 发起请求 this.log(`${logger.yellow('开始请求数据')},面板服务:${serv.name}...`) const startTime = new Date() * 1 diff --git a/models/Weapon.js b/models/Weapon.js index 6c75e85a..db73285d 100644 --- a/models/Weapon.js +++ b/models/Weapon.js @@ -14,6 +14,7 @@ class Weapon extends Base { if (cache) { return cache } + this.id = meta.id this.name = meta.name this.meta = meta this.type = meta.type diff --git a/resources/gacha/gacha-detail.css b/resources/gacha/gacha-detail.css new file mode 100644 index 00000000..6d6dab6f --- /dev/null +++ b/resources/gacha/gacha-detail.css @@ -0,0 +1,117 @@ +.avatar-cont { + background: rgba(0, 0, 0, 0.1); +} +.gacha-list .gacha-item { + height: 38px; + display: flex; +} +.gacha-list .gacha-item .date { + width: 97px; + line-height: 38px; + padding-left: 5px; + background: rgba(0, 0, 0, 0.8); + display: flex; +} +.gacha-list .gacha-item .date .dot { + width: 23.75px; + height: 38px; + background: url('./imgs/date-icon.webp') center -100%; + background-size: 100% auto; +} +.gacha-list .gacha-item .date .dot.first { + background-position: center 0; +} +.gacha-list .gacha-item .date .dot.last { + background-position: center -128px; +} +.gacha-list .gacha-item .date .txt { + text-align: center; +} +.gacha-list .gacha-item.no-date .date .dot { + background-position: center -71.25px; +} +.gacha-list .gacha-item.no-date .date .dot.last { + background-position: center -95px; +} +.gacha-list .gacha-item.no-date .date .txt { + opacity: 0; +} +.gacha-list .gacha-item.has-date { + margin-top: 5px; +} +.gacha-list .gacha-item .name { + width: 90px; + text-align: right; + line-height: 38px; + padding-right: 5px; +} +.gacha-list .gacha-item.wai .name { + color: #aaa; +} +.gacha-list .gacha-item.wai .name, +.gacha-list .gacha-item.wai .icon, +.gacha-list .gacha-item.wai .process { + background-color: rgba(85, 85, 85, 0.8); +} +.gacha-list .gacha-item.up .name { + background: rgba(0, 0, 0, 0.5); + color: #ffd484; +} +.gacha-list .gacha-item.up .process, +.gacha-list .gacha-item.up .icon { + background-color: rgba(0, 0, 0, 0.5); +} +.gacha-list .icon { + width: 32px; + height: 38px; +} +.gacha-list .icon .icon-bg { + width: 32px; + height: 32px; + margin: 3px 0; + border-radius: 5px; +} +.gacha-list .icon .icon-bg.star5 { + background: url('../common/item/bg5.png') 100% 100% no-repeat; +} +.gacha-list .icon span { + display: block; + width: 32px; + height: 32px; + background-size: auto 100%; + background-position: center; + background-repeat: no-repeat; +} +.gacha-list .process { + width: 490px; + padding-right: 15px; +} +.gacha-list .process .bar { + background: green; + border-radius: 0 5px 5px 0; + height: 26px; + line-height: 26px; + margin: 6px 0; + padding-left: 5px; +} +.gacha-list .process .bar.gold { + background: #ffeb73; + color: #6f4b00; + min-width: 18px; +} +.gacha-list .process .bar.good { + background: #6939b7; + color: #fff; +} +.gacha-list .process .bar.normal { + background: #168b2c; + color: #fff; +} +.gacha-list .process .bar.bad { + background: #9d3333; + color: #fff; +} +.avatar-card .name { + text-align: center; +} +/*# sourceMappingURL=gacha-detail.css.map */ \ No newline at end of file diff --git a/resources/gacha/gacha-detail.html b/resources/gacha/gacha-detail.html new file mode 100644 index 00000000..7d595f91 --- /dev/null +++ b/resources/gacha/gacha-detail.html @@ -0,0 +1,70 @@ +{{extend elemLayout}} + +{{block 'css'}} + + + + +{{/block}} + +{{ set statMap = { allNum:'抽卡总数', fiveNum:'金卡数', fiveAvg:'平均出金' } }} + +{{block 'main'}} +
+
+
+ +
+ + {{if gacha && gacha.stat }} + {{set stat = gacha.stat }} +
+ {{each statMap title key}} + {{if stat[key] }} +
+ {{stat[key]}} + {{title}} +
+ {{/if}} + {{/each}} +
+ {{/if}} +
+ +
+
+ {{each gacha.fiveLog ds idx}} + {{set item = gacha.items[ds.id]}} + {{set max = item.type === 'weapon'?80:90}} + {{set hasDate = (idx===0 || idx ===gacha.items.length-1 || (idx>0 && gacha.fiveLog[idx-1].date !== ds.date)) }} +
+
+
+
{{ds.date}}
+
+
{{item.abbr}}
+
+
+ +
+
+
+ {{set count = ds.count}} +
{{count}} +
+
+
+ {{/each}} +
+
+
+{{/block}} \ No newline at end of file diff --git a/resources/gacha/gacha-detail.less b/resources/gacha/gacha-detail.less new file mode 100644 index 00000000..073c4e3d --- /dev/null +++ b/resources/gacha/gacha-detail.less @@ -0,0 +1,165 @@ +.avatar-cont { + background: rgba(0, 0, 0, .1); +} + +.gacha-list { + @size: 32px; + @padding: 3px; + @height: @size + @padding * 2; + + .gacha-item { + height: @height; + display: flex; + + .date { + width: @size + 65px; + line-height: @height; + padding-left: 5px; + background: rgba(0, 0, 0, .8); + display: flex; + + .dot { + width: @height * 0.625; + height: @height; + background: url('./imgs/date-icon.webp') center -100%; + background-size: 100% auto; + + &.first { + background-position: center 0; + } + + &.last { + background-position: center @size * -4 + } + } + + .txt { + text-align: center; + } + } + + &.no-date { + .date { + .dot { + background-position: center @height * 0.625 * -3; + + &.last { + background-position: center @height * 0.625 * -4 + } + } + + .txt { + opacity: 0; + } + } + } + + &.has-date { + margin-top: 5px; + } + + .name { + width: 90px; + text-align: right; + line-height: @height; + padding-right: 5px; + } + + + &.wai { + + .name { + color: #aaa; + } + + .name, .icon, .process { + background-color: rgba(85, 85, 85, 0.8); + } + } + + &.up { + .name { + background: rgba(0, 0, 0, .5); + color: rgb(255, 212, 132); + } + + .process, .icon { + background-color: rgba(0, 0, 0, .5); + } + } + } + + + .icon { + width: @size; + height: @height; + + .icon-bg { + width: @size; + height: @size; + margin: @padding 0; + border-radius: 5px; + &.star5 { + background: url('../common/item/bg5.png') 100% 100% no-repeat; + } + } + + + + span { + display: block; + width: @size; + height: @size; + background-size: auto 100%; + background-position: center; + background-repeat: no-repeat; + } + } + + .process { + width: 490px; + padding-right: 15px; + @pd: 3px; + + .bar { + background: green; + border-radius: 0 5px 5px 0; + height: @size - @pd * 2; + line-height: @size - @pd * 2; + margin: @padding + @pd 0; + padding-left: 5px; + + &.gold { + background: #ffeb73; + color: #6f4b00; + min-width: 18px; + } + + &.good { + background: #6939b7; + color: #fff; + } + + &.normal { + background: #168b2c; + color: #fff; + } + + &.bad { + background: #9d3333; + color: #fff; + } + } + + + } + + +} + + +.avatar-card { + .name { + text-align: center; + } +} diff --git a/resources/gacha/gacha-stat.css b/resources/gacha/gacha-stat.css new file mode 100644 index 00000000..fe8cec74 --- /dev/null +++ b/resources/gacha/gacha-stat.css @@ -0,0 +1,117 @@ +.cont-title { + padding: 0; + background: rgba(0, 0, 0, 0.6); +} +.gacha-pool { + display: flex; + text-align: center; +} +.gacha-pool > div { + padding: 10px; + height: 56px; +} +.gacha-pool .line { + padding-right: 15px; + position: relative; +} +.gacha-pool .line:after { + content: ""; + display: block; + width: 1px; + height: 15px; + position: absolute; + top: 12px; + right: 7px; + background: #d3bc8e; +} +.gacha-pool .version { + text-align: center; + background: rgba(0, 0, 0, 0.8); + padding: 10px 0; + display: flex; + border-right: 1px solid rgba(255, 255, 255, 0.3); +} +.gacha-pool .version-name { + width: 100px; + line-height: 36px; + font-size: 20px; + font-weight: bold; + text-align: right; +} +.gacha-pool .pool-name { + width: 125px; + text-align: left; +} +.gacha-pool .pool-name .name { + height: 22px; + line-height: 22px; +} +.gacha-pool .pool-name .time { + font-size: 12px; + line-height: 14px; + height: 14px; + color: #888; +} +.gacha-pool .stat-info { + display: flex; + padding: 8px 20px 0; +} +.gacha-pool .stat-info .info { + min-width: 60px; + padding: 0 20px 0 10px; +} +.gacha-pool .stat-info .info .num { + height: 25px; + line-height: 25px; + font-size: 20px; + text-shadow: 0 0 2px #000; +} +.gacha-pool .stat-info .info .title { + font-size: 12px; + line-height: 14px; + height: 14px; + color: #888; +} +.gacha-pool .stat-info .info:last-child:after { + display: none; +} +.gacha-stat { + display: flex; + flex-wrap: wrap; + align-items: flex-start; + background: rgba(0, 0, 0, 0.5); + padding: 5px 8px; +} +.gacha-stat .gacha-item { + text-align: center; +} +.gacha-stat .gacha-item .item-card { + width: 69px; +} +.gacha-stat .item-life { + top: initial; + left: initial; + right: 0; + bottom: 0; + border-radius: 5px 0 0 0; + font-size: 16px; + padding: 0 6px; + min-width: 20px; + height: 22px; + line-height: 22px; + text-align: center; +} +.gacha-stat .item-life.life5 { + background: #ffeb73; + color: #6f4b00; + box-shadow: 0 0 3px 0 #6f4b00; +} +.gacha-stat .item-life.life1 { + background: #333; + color: #fff; +} +.gacha-stat .item-name { + font-size: 15px; + line-height: 24px; +} +/*# sourceMappingURL=gacha-stat.css.map */ \ No newline at end of file diff --git a/resources/gacha/gacha-stat.html b/resources/gacha/gacha-stat.html new file mode 100644 index 00000000..4a0e68c3 --- /dev/null +++ b/resources/gacha/gacha-stat.html @@ -0,0 +1,88 @@ +{{extend elemLayout}} + +{{block 'css'}} + + + + + +{{/block}} + +{{ set statMap = { allNum:'抽卡总数', fiveNum:'金卡数', fiveAvg:'平均出金' } }} + +{{block 'main'}} +
+
+
+ +
+ + {{if gacha && gacha.stat }} + {{set stat = gacha.stat }} +
+ {{each statMap title key}} + {{if stat[key] }} +
+ {{stat[key]}} + {{title}} +
+ {{/if}} + {{/each}} +
+ {{/if}} +
+ {{each gacha.versionData vData}} + {{set stats = vData.stats}} +
+
+
+
+
+ {{vData.version}}{{vData.half}} +
+
+
{{vData.name}}
+
{{vData.from}}~{{vData.to}}
+
+
+
+ {{set keyMap = {totalNum:'总抽卡',star5Num:'金卡',upNum:'UP金卡', c4Num:'紫角色', w4Num:'紫武器'} }} + {{each keyMap title key}} + {{if stats[key] > 0}} +
+
{{stats[key]}}
+
{{title}}
+
+ {{/if}} + {{/each}} +
+
+
+
+ {{each vData.items ds}} + {{set item = gacha.itemMap[ds.id]}} + {{if item.star === 4 || item.star === 5}} +
+
+
+
+
{{ds.num}}
+
+
{{item.name.length >4 ? item.abbr : item.name}}
+
+
+ {{/if}} + {{/each}} +
+
+ {{/each}} +
+{{/block}} \ No newline at end of file diff --git a/resources/gacha/gacha-stat.less b/resources/gacha/gacha-stat.less new file mode 100644 index 00000000..bb776f93 --- /dev/null +++ b/resources/gacha/gacha-stat.less @@ -0,0 +1,138 @@ +.cont-title { + padding: 0; + background: rgba(0, 0, 0, .6); +} + +.gacha-pool { + display: flex; + text-align: center; + + & > div { + padding: 10px; + height: 56px; + } + + .line { + padding-right: 15px; + position: relative; + + &:after { + content: ""; + display: block; + width: 1px; + height: 15px; + position: absolute; + top: 12px; + right: 7px; + background: #d3bc8e; + } + } + + .version { + text-align: center; + background: rgba(0, 0, 0, .8); + padding: 10px 0; + display: flex; + border-right: 1px solid rgba(255, 255, 255, .3); + } + + .version-name { + width: 100px; + line-height: 36px; + font-size: 20px; + font-weight: bold; + text-align: right; + } + + .pool-name { + width: 125px; + text-align: left; + + .name { + height: 22px; + line-height: 22px; + } + + .time { + font-size: 12px; + line-height: 14px; + height: 14px; + color: #888; + } + } + + .stat-info { + display: flex; + padding: 8px 20px 0; + + .info { + min-width: 60px; + padding: 0 20px 0 10px; + + .num { + height: 25px; + line-height: 25px; + font-size: 20px; + text-shadow: 0 0 2px #000; + } + + .title { + font-size: 12px; + line-height: 14px; + height: 14px; + color: #888; + } + + &:last-child:after { + display: none; + } + } + } +} + +.gacha-stat { + display: flex; + flex-wrap: wrap; + align-items: flex-start; + background: rgba(0, 0, 0, .5); + padding: 5px 8px; + + .gacha-item { + text-align: center; + + .item-card { + width: 69px; + } + } + + .item-life { + top: initial; + left: initial; + right: 0; + bottom: 0; + border-radius: 5px 0 0 0; + font-size: 16px; + padding: 0 6px; + min-width: 20px; + height: 22px; + line-height: 22px; + text-align: center; + + &.life5 { + background: #ffeb73; + color: #6f4b00; + box-shadow: 0 0 3px 0 #6f4b00; + } + + &.life1 { + background: #333; + color: #fff; + } + } + + .item-name { + font-size: 15px; + line-height: 24px; + } +} + diff --git a/resources/gacha/imgs/date-icon.webp b/resources/gacha/imgs/date-icon.webp new file mode 100644 index 00000000..63a036fd Binary files /dev/null and b/resources/gacha/imgs/date-icon.webp differ diff --git a/resources/meta/info/index.js b/resources/meta/info/index.js index 10730715..2a6ea3c4 100644 --- a/resources/meta/info/index.js +++ b/resources/meta/info/index.js @@ -1,4 +1,6 @@ -// 报箱数统计 +export * from './pool.js' + +// 宝箱数统计 export const chestInfo = { common: { title: '普通宝箱', diff --git a/resources/meta/info/pool.js b/resources/meta/info/pool.js new file mode 100644 index 00000000..419bb87d --- /dev/null +++ b/resources/meta/info/pool.js @@ -0,0 +1,461 @@ +export const poolName = { + 温迪: '杯装之诗', + 可莉: '闪焰的驻足', + 达达利亚: '暂别冬都', + 钟离: '陵薮市朝', + 阿贝多: '深秘之息', + 甘雨: '浮生孰来', + 魈: '烟火之邀', + 刻晴: '鱼龙灯昼', + 胡桃: '赤团开时', + 优菈: '浪涌之瞬', + 枫原万叶: '叶落风随', + 神里绫华: '白鹭之庭', + 宵宫: '焰色天河', + 雷电将军: '影寂天下人', + 珊瑚宫心海: '浮岳虹珠', + 荒泷一斗: '鬼门斗宴', + 申鹤: '出尘入世', + 八重神子: '华紫樱绯', + 神里绫人: '苍流踏花', + 夜兰: '素霓伣天', + 提纳里: '巡御蘙荟', + 赛诺: '雳裁冥昭', + 妮露: '翩舞歈莲', + 纳西妲: '月草的赐慧', + 流浪者: '余火变相', + 艾尔海森: '敕诫枢谋' +} + +export const poolDetail = [ + { + version: '1.0', + half: '上半', + from: '2020-09-28 06:00:00', + to: '2020-10-18 17:59:59', + char5: ['温迪'], + char4: ['芭芭拉', '菲谢尔', '香菱'], + weapon5: ['风鹰剑', '阿莫斯之弓'], + weapon4: ['笛剑', '流浪乐章', '钟剑', '绝弦', '西风长枪'] + }, + { + version: '1.0', + half: '下半', + from: '2020-10-20 18:00:00', + to: '2020-11-10 14:59:59', + char5: ['可莉'], + char4: ['行秋', '诺艾尔', '砂糖'], + weapon5: ['四风原典', '狼的末路'], + weapon4: ['祭礼剑', '祭礼残章', '祭礼大剑', '祭礼弓', '匣里灭辰'] + }, + { + version: '1.1', + half: '上半', + from: '2020-11-11 06:00:00', + to: '2020-12-01 15:59:59', + char5: ['达达利亚'], + char4: ['迪奥娜', '北斗', '凝光'], + weapon5: ['尘世之锁', '天空之翼'], + weapon4: ['笛剑', '昭心', '雨裁', '弓藏', '西风长枪'] + }, + { + version: '1.1', + half: '下半', + from: '2020-12-01 18:00:00', + to: '2020-12-22 14:59:59', + char5: ['钟离'], + char4: ['辛焱', '雷泽', '重云'], + weapon5: ['无工之剑', '贯虹之槊'], + weapon4: ['匣里龙吟', '西风秘典', '钟剑', '西风猎弓', '匣里灭辰'] + }, + { + version: '1.2', + half: '上半', + from: '2020-12-23 06:00:00', + to: '2021-01-12 15:59:59', + char5: ['阿贝多'], + char4: ['菲谢尔', '砂糖', '班尼特'], + weapon5: ['斫峰之刃', '天空之卷'], + weapon4: ['西风剑', '祭礼残章', '西风大剑', '绝弦', '西风长枪'] + }, + { + version: '1.2', + half: '下半', + from: '2021-01-12 18:00:00', + to: '2021-02-02 14:59:59', + char5: ['甘雨'], + char4: ['香菱', '行秋', '诺艾尔'], + weapon5: ['天空之傲', '阿莫斯之弓'], + weapon4: ['祭礼剑', '昭心', '钟剑', '西风猎弓', '匣里灭辰'] + }, + { + version: '1.3', + half: '上半', + from: '2021-02-03 06:00:00', + to: '2021-02-23 15:59:59', + char5: ['魈'], + char4: ['迪奥娜', '北斗', '辛焱'], + weapon5: ['磐岩结绿', '和璞鸢'], + weapon4: ['笛剑', '昭心', '祭礼大剑', '弓藏', '西风长枪'] + }, + { + version: '1.3', + half: '中场', + from: '2021-02-17 18:00:00', + to: '2021-03-02 15:59:59', + char5: ['刻晴'], + char4: ['凝光', '班尼特', '芭芭拉'], + weapon5: [], + weapon4: [] + }, + { + version: '1.3', + half: '下半', + from: '2021-03-02 18:00:00', + to: '2021-03-16 14:59:59', + char5: ['胡桃'], + char4: ['行秋', '香菱', '重云'], + weapon5: ['狼的末路', '护摩之杖'], + weapon4: ['匣里龙吟', '流浪乐章', '千岩古剑', '祭礼弓', '千岩长枪'] + }, + { + version: '1.4', + half: '上半', + from: '2021-03-17 06:00:00', + to: '2021-04-06 15:59:59', + char5: ['温迪'], + char4: ['砂糖', '雷泽', '诺艾尔'], + weapon5: ['天空之刃', '终末嗟叹之诗'], + weapon4: ['暗巷闪光', '暗巷的酒与诗', '西风大剑', '西风猎弓', '匣里灭辰'] + }, + { + version: '1.4', + half: '下半', + from: '2021-04-06 18:00:00', + to: '2021-04-27 14:59:59', + char5: ['达达利亚'], + char4: ['罗莎莉亚', '芭芭拉', '菲谢尔'], + weapon5: ['四风原典', '天空之翼'], + weapon4: ['西风剑', '西风秘典', '祭礼大剑', '暗巷猎手', '西风长枪'] + }, + { + version: '1.5', + half: '上半', + from: '2021-04-28 06:00:00', + to: '2021-05-18 17:59:59', + char5: ['钟离'], + char4: ['烟绯', '诺艾尔', '迪奥娜'], + weapon5: ['斫峰之刃', '尘世之锁'], + weapon4: ['笛剑', '昭心', '千岩古剑', '祭礼弓', '千岩长枪'] + }, + { + version: '1.5', + half: '下半', + from: '2021-05-18 18:00:00', + to: '2021-06-08 14:59:59', + char5: ['优菈'], + char4: ['辛焱', '行秋', '北斗'], + weapon5: ['风鹰剑', '松籁响起之时'], + weapon4: ['祭礼剑', '祭礼残章', '雨裁', '弓藏', '匣里灭辰'] + }, + { + version: '1.6', + half: '上半', + from: '2021-06-09 06:00:00', + to: '2021-06-29 17:59:59', + char5: ['可莉'], + char4: ['芭芭拉', '砂糖', '菲谢尔'], + weapon5: ['四风原典', '天空之傲'], + weapon4: ['匣里龙吟', '流浪乐章', '钟剑', '幽夜华尔兹', '西风长枪'] + }, + { + version: '1.6', + half: '下半', + from: '2021-06-29 18:00:00', + to: '2021-07-20 14:59:59', + char5: ['枫原万叶'], + char4: ['罗莎莉亚', '班尼特', '雷泽'], + weapon5: ['苍古自由之誓', '天空之卷'], + weapon4: ['暗巷闪光', '暗巷的酒与诗', '西风大剑', '暗巷猎手', '匣里灭辰'] + }, + { + version: '2.0', + half: '上半', + from: '2021-07-21 06:00:00', + to: '2021-08-10 17:59:59', + char5: ['神里绫华'], + char4: ['凝光', '重云', '烟绯'], + weapon5: ['雾切之回光', '天空之脊'], + weapon4: ['西风剑', '西风秘典', '祭礼大剑', '绝弦', '西风长枪'] + }, + { + version: '2.0', + half: '下半', + from: '2021-08-10 18:00:00', + to: '2021-08-31 14:59:59', + char5: ['宵宫'], + char4: ['早柚', '迪奥娜', '辛焱'], + weapon5: ['天空之刃', '飞雷之弦振'], + weapon4: ['祭礼剑', '祭礼残章', '雨裁', '西风猎弓', '匣里灭辰'] + }, + { + version: '2.1', + half: '上半', + from: '2021-09-01 06:00:00', + to: '2021-09-21 17:59:59', + char5: ['雷电将军'], + char4: ['九条裟罗', '香菱', '砂糖'], + weapon5: ['无工之剑', '薙草之稻光'], + weapon4: ['匣里龙吟', '流浪乐章', '钟剑', '祭礼弓', '西风长枪'] + }, + { + version: '2.1', + half: '下半', + from: '2021-09-21 18:00:00', + to: '2021-10-12 14:59:59', + char5: ['珊瑚宫心海'], + char4: ['罗莎莉亚', '北斗', '行秋'], + weapon5: ['磐岩结绿', '不灭月华'], + weapon4: ['笛剑', '西风秘典', '西风大剑', '绝弦', '匣里灭辰'] + }, + { + version: '2.2', + half: '上半', + from: '2021-10-13 06:00:00', + to: '2021-11-02 17:59:59', + char5: ['达达利亚'], + char4: ['凝光', '重云', '烟绯'], + weapon5: ['尘世之锁', '冬极白星'], + weapon4: ['西风剑', '昭心', '恶王丸', '弓藏', '西风长枪'] + }, + { + version: '2.2', + half: '下半', + from: '2021-11-02 18:00:00', + to: '2021-11-23 14:59:59', + char5: ['胡桃'], + char4: ['托马', '迪奥娜', '早柚'], + weapon5: ['终末嗟叹之诗', '护摩之杖'], + weapon4: ['祭礼剑', '流浪乐章', '雨裁', '曚云之月', '断浪长鳍'] + }, + { + version: '2.3', + half: '上半', + from: '2021-11-24 06:00:00', + to: '2021-12-14 17:59:59', + char5: ['阿贝多', '优菈'], + char4: ['班尼特', '诺艾尔', '罗莎莉亚'], + weapon5: ['苍古自由之誓', '松籁响起之时'], + weapon4: ['匣里龙吟', '暗巷的酒与诗', '祭礼大剑', '暗巷猎手', '匣里灭辰'] + }, + { + version: '2.3', + half: '下半', + from: '2021-12-14 18:00:00', + to: '2022-01-04 14:59:59', + char5: ['荒泷一斗'], + char4: ['五郎', '芭芭拉', '香菱'], + weapon5: ['赤角石溃杵', '天空之翼'], + weapon4: ['暗巷闪光', '祭礼残章', '钟剑', '幽夜华尔兹', '西风长枪'] + }, + { + version: '2.4', + half: '上半', + from: '2022-01-05 06:00:00', + to: '2022-01-25 17:59:59', + char5: ['申鹤', '魈'], + char4: ['云堇', '凝光', '重云'], + weapon5: ['息灾', '和璞鸢'], + weapon4: ['笛剑', '流浪乐章', '西风大剑', '西风猎弓', '千岩长枪'] + }, + { + version: '2.4', + half: '下半', + from: '2022-01-25 18:00:00', + to: '2022-02-15 14:59:59', + char5: ['钟离', '甘雨'], + char4: ['行秋', '北斗', '烟绯'], + weapon5: ['阿莫斯之弓', '贯虹之槊'], + weapon4: ['西风剑', '西风秘典', '千岩古剑', '祭礼弓', '匣里灭辰'] + }, + { + version: '2.5', + half: '上半', + from: '2022-02-16 06:00:00', + to: '2022-03-08 17:59:59', + char5: ['八重神子'], + char4: ['托马', '菲谢尔', '迪奥娜'], + weapon5: ['磐岩结绿', '神乐之真意'], + weapon4: ['祭礼剑', '昭心', '雨裁', '绝弦', '断浪长鳍'] + }, + { + version: '2.5', + half: '下半', + from: '2022-03-08 18:00:00', + to: '2022-03-29 14:59:59', + char5: ['雷电将军', '珊瑚宫心海'], + char4: ['班尼特', '辛焱', '九条裟罗'], + weapon5: ['不灭月华', '薙草之稻光'], + weapon4: ['匣里龙吟', '恶王丸', '祭礼残章', '曚云之月', '西风长枪'] + }, + { + version: '2.6', + half: '上半', + from: '2022-03-30 06:00:00', + to: '2022-04-19 17:59:59', + char5: ['神里绫人', '温迪'], + char4: ['砂糖', '香菱', '云堇'], + weapon5: ['波乱月白经津', '终末嗟叹之诗'], + weapon4: ['笛剑', '流浪乐章', '祭礼大剑', '弓藏', '匣里灭辰'] + }, + { + version: '2.6', + half: '下半', + from: '2022-04-19 18:00:00', + to: '2022-05-31 05:59:59', + char5: ['神里绫华'], + char4: ['早柚', '雷泽', '罗莎莉亚'], + weapon5: ['雾切之回光', '无工之剑'], + weapon4: ['西风剑', '西风秘典', '钟剑', '西风猎弓', '西风长枪'] + }, + { + version: '2.7', + half: '上半', + from: '2022-05-31 06:00:00', + to: '2022-06-21 17:59:59', + char5: ['夜兰', '魈'], + char4: ['诺艾尔', '芭芭拉', '烟绯'], + weapon5: ['若水', '和璞鸢'], + weapon4: ['祭礼剑', '昭心', '西风大剑', '祭礼弓', '千岩长枪'] + }, + { + version: '2.7', + half: '下半', + from: '2022-06-21 18:00:00', + to: '2022-07-12 14:59:59', + char5: ['荒泷一斗'], + char4: ['五郎', '久岐忍', '重云'], + weapon5: ['尘世之锁', '赤角石溃杵'], + weapon4: ['匣里龙吟', '祭礼残章', '千岩古剑', '绝弦', '匣里灭辰'] + }, + { + version: '2.8', + half: '上半', + from: '2022-07-13 06:00:00', + to: '2022-08-02 17:59:59', + char5: ['枫原万叶', '可莉'], + char4: ['鹿野院平藏', '托马', '凝光'], + weapon5: ['苍古自由之誓', '四风原典'], + weapon4: ['暗巷闪光', '流浪乐章', '雨裁', '幽夜华尔兹', '西风长枪'] + }, + { + version: '2.8', + half: '下半', + from: '2022-08-02 18:00:00', + to: '2022-08-23 14:59:59', + char5: ['宵宫'], + char4: ['云堇', '辛焱', '班尼特'], + weapon5: ['斫峰之刃', '飞雷之弦振'], + weapon4: ['笛剑', '暗巷的酒与诗', '祭礼大剑', '暗巷猎手', '匣里灭辰'] + }, + { + version: '3.0', + half: '上半', + from: '2022-08-24 06:00:00', + to: '2022-09-09 17:59:59', + char5: ['提纳里', '钟离'], + char4: ['柯莱', '迪奥娜', '菲谢尔'], + weapon5: ['猎人之径', '贯虹之槊'], + weapon4: ['西风剑', '西风秘典', '钟剑', '绝弦', '西风长枪'] + }, + { + version: '3.0', + half: '下半', + from: '2022-09-09 18:00:00', + to: '2022-09-27 14:59:59', + char5: ['甘雨', '珊瑚宫心海'], + char4: ['多莉', '砂糖', '行秋'], + weapon5: ['不灭月华', '阿莫斯之弓'], + weapon4: ['祭礼剑', '昭心', '西风大剑', '弓藏', '匣里灭辰'] + }, + { + version: '3.1', + half: '上半', + from: '2022-09-28 06:00:00', + to: '2022-10-14 17:59:59', + char5: ['赛诺', '温迪'], + char4: ['坎蒂丝', '久岐忍', '早柚'], + weapon5: ['终末嗟叹之诗', '赤沙之杖'], + weapon4: ['匣里龙吟', '祭礼残章', '玛海菈的水色', '西风猎弓', '西风长枪'] + }, + { + version: '3.1', + half: '下半', + from: '2022-10-14 18:00:00', + to: '2022-11-01 14:59:59', + char5: ['妮露', '阿贝多'], + char4: ['北斗', '芭芭拉', '香菱'], + weapon5: ['圣显之钥', '磐岩结绿'], + weapon4: ['西福斯的月光', '流浪的晚星', '雨裁', '祭礼弓', '匣里灭辰'] + }, + { + version: '3.2', + half: '上半', + from: '2022-11-02 06:00:00', + to: '2022-11-18 17:59:59', + char5: ['纳西妲', '宵宫'], + char4: ['雷泽', '诺艾尔', '班尼特'], + weapon5: ['千夜浮梦', '飞雷之弦振'], + weapon4: ['笛剑', '流浪乐章', '祭礼大剑', '弓藏', '西风长枪'] + }, + { + version: '3.2', + half: '下半', + from: '2022-11-18 18:00:00', + to: '2022-12-06 14:59:59', + char5: ['八重神子', '达达利亚'], + char4: ['莱依拉', '托马', '鹿野院平藏'], + weapon5: ['神乐之真意', '冬极白星'], + weapon4: ['西风剑', '西风秘典', '钟剑', '绝弦', '匣里灭辰'] + }, + { + version: '3.3', + half: '上半', + from: '2022-12-07 06:00:00', + to: '2022-12-27 17:59:59', + char5: ['流浪者', '荒泷一斗'], + char4: ['珐露珊', '五郎', '烟绯'], + weapon5: ['图莱杜拉的回忆', '赤角石溃杵'], + weapon4: ['祭礼剑', '昭心', '西风大剑', '西风猎弓', '断浪长鳍'] + }, + { + version: '3.3', + half: '下半', + from: '2022-12-27 18:00:00', + to: '2023-01-17 14:59:59', + char5: ['雷电将军', '神里绫人'], + char4: ['罗莎莉亚', '早柚', '九条裟罗'], + weapon5: ['波乱月白经津', '薙草之稻光'], + weapon4: ['匣里龙吟', '祭礼残章', '恶王丸', '曚云之月', '西风长枪'] + }, + { + version: '3.4', + half: '上半', + from: '2023-01-18 06:00:00', + to: '2023-02-07 17:59:59', + char5: ['艾尔海森', '魈'], + char4: ['瑶瑶', '云堇', '辛焱'], + weapon5: ['裁叶萃光', '和璞鸢'], + weapon4: ['笛剑', '流浪乐章', '雨裁', '祭礼弓', '千岩长枪'] + }, + { + version: '3.4', + half: '下半', + from: '2023-02-07 18:00:00', + to: '2023-02-28 14:59:59', + char5: ['胡桃', '夜兰'], + char4: ['行秋', '凝光', '北斗'], + weapon5: ['若水', '护摩之杖'], + weapon4: ['西风剑', '西风秘典', '千岩古剑', '弓藏', '匣里灭辰'] + } +] diff --git a/resources/meta/weapon/index.js b/resources/meta/weapon/index.js index 52d7100f..9ca2a6cb 100644 --- a/resources/meta/weapon/index.js +++ b/resources/meta/weapon/index.js @@ -26,6 +26,8 @@ const attr = function (key, start, _step) { } } +let ids = {} + for (let type in weaponType) { // calc let typeCalc = await Data.importDefault(`resources/meta/weapon/${type}/calc.js`) @@ -35,7 +37,13 @@ for (let type in weaponType) { // data let typeData = await Data.readJSON(`resources/meta/weapon/${type}/data.json`) lodash.forEach(typeData, (ds) => { + let id = ds.id.replace('n', '') * 1 + if (ids[id]) { + console.log(ds.id, id) + } + ids[id] = true data[ds.name] = { + id, name: ds.name, type, star: ds.star diff --git a/resources/meta/weapon/meta.js b/resources/meta/weapon/meta.js index 2704f4bf..d238dc0f 100644 --- a/resources/meta/weapon/meta.js +++ b/resources/meta/weapon/meta.js @@ -8,16 +8,16 @@ export const weaponType = { export const abbr = { 磐岩结绿: '绿剑', - 赤角石溃杵: '赤角', - 终末嗟叹之诗: '终末', - 松籁响起之时: '松籁', - 苍古自由之誓: '苍古', + 赤角石溃杵: '赤角石', + 终末嗟叹之诗: '终末之诗', + 松籁响起之时: '松籁之时', + 苍古自由之誓: '苍古之誓', 阿莫斯之弓: '阿莫斯', 雾切之回光: '雾切', 飞雷之弦振: '飞雷', 薙草之稻光: '薙刀', 神乐之真意: '神乐铃', - 波乱月白经津: '波乱', + 波乱月白经津: '波乱刀', 笼钓瓶一心: '妖刀', 幽夜华尔兹: '幽夜弓', 雪葬的星银: '雪葬星银', @@ -27,8 +27,8 @@ export const abbr = { 桂木斩长正: '桂木刀', 证誓之明瞳: '证誓明瞳', 嘟嘟可故事集: '嘟嘟可', - 辰砂之纺锤: '辰砂', - 讨龙英杰谭: '讨龙', + 辰砂之纺锤: '辰砂纺锤', + 讨龙英杰谭: '讨龙书', 神射手之誓: '神射手', '「渔获」': '渔获', 暗巷的酒与诗: '暗巷书', @@ -40,7 +40,8 @@ export const abbr = { 异世界行记: '异世行记', 西福斯的月光: '西福斯', 玛海菈的水色: '玛海菈', - 图莱杜拉的回忆: '铃铛' + 图莱杜拉的回忆: '图莱杜拉', + 流浪的晚星: '流浪晚星' } export const alias = {