mirror of
https://github.com/yoimiya-kokomi/miao-plugin.git
synced 2024-11-21 22:48:13 +00:00
更新鹮穿之喙的数据
This commit is contained in:
parent
c06233e86a
commit
d74098b6df
@ -24,7 +24,7 @@ app.reg({
|
||||
desc: '【#统计】 #深渊出场率 #深渊12层出场率'
|
||||
},
|
||||
abyssTeam: {
|
||||
rule: /#深渊(组队|配队)/,
|
||||
rule: /^#深渊(组队|配队)/,
|
||||
fn: AbyssTeam,
|
||||
describe: '【#角色】 #深渊组队'
|
||||
},
|
||||
|
@ -30,6 +30,7 @@ export const idsMap = {
|
||||
303155515: '离簇不归',
|
||||
310247243: '神乐之真意',
|
||||
313300315: '原木刀',
|
||||
316078811: '鹮穿之喙',
|
||||
334242634: '申鹤',
|
||||
339931171: '乘胜追击',
|
||||
342097547: '辰砂之纺锤',
|
||||
@ -67,6 +68,7 @@ export const idsMap = {
|
||||
646032090: '鹿野院平藏',
|
||||
646100491: '千岩诀·同心',
|
||||
650049651: '风花之颂',
|
||||
650438131: '秘智之眸的青睐',
|
||||
655825874: '云堇',
|
||||
656120259: '神射手之誓',
|
||||
680510411: '白影剑',
|
||||
@ -144,6 +146,7 @@ export const idsMap = {
|
||||
1437658243: '螭骨剑',
|
||||
1438974835: '逆飞的流星',
|
||||
1455107995: '四风原典',
|
||||
1456643042: '绮良良',
|
||||
1468367538: '迪奥娜',
|
||||
1470442731: '风信之锋',
|
||||
1479961579: '铁影阔剑',
|
||||
|
@ -8,8 +8,8 @@ export const usefulAttr = {
|
||||
布洛妮娅: { hp: 0, atk: 75, def: 0, speed: 100, cpct: 75, cdmg: 100, stance: 0, heal: 0, recharge: 100, effPct: 0, effDef: 0, dmg: 100 },
|
||||
杰帕德: { hp: 50, atk: 0, def: 100, speed: 100, cpct: 0, cdmg: 0, stance: 0, heal: 0, recharge: 100, effPct: 50, effDef: 50, dmg: 0 },
|
||||
姬子: { hp: 0, atk: 75, def: 0, speed: 75, cpct: 100, cdmg: 100, stance: 50, heal: 0, recharge: 50, effPct: 0, effDef: 0, dmg: 100 },
|
||||
瓦尔特: { hp: 0, atk: 75, def: 0, speed: 100, cpct: 100, cdmg: 100, stance: 0, heal: 0, recharge: 50, effPct: 0, effDef: 0, dmg: 100 },
|
||||
彦卿: { hp: 0, atk: 75, def: 0, speed: 75, cpct: 100, cdmg: 100, stance: 0, heal: 0, recharge: 75, effPct: 100, effDef: 0, dmg: 100 },
|
||||
瓦尔特: { hp: 0, atk: 75, def: 0, speed: 75, cpct: 100, cdmg: 100, stance: 0, heal: 0, recharge: 50, effPct: 100, effDef: 0, dmg: 100 },
|
||||
彦卿: { hp: 0, atk: 75, def: 0, speed: 75, cpct: 100, cdmg: 100, stance: 0, heal: 0, recharge: 75, effPct: 0, effDef: 0, dmg: 100 },
|
||||
白露: { hp: 100, atk: 0, def: 50, speed: 75, cpct: 0, cdmg: 0, stance: 0, heal: 100, recharge: 100, effPct: 0, effDef: 50, dmg: 0 },
|
||||
克拉拉: { hp: 0, atk: 75, def: 0, speed: 75, cpct: 100, cdmg: 100, stance: 0, heal: 0, recharge: 50, effPct: 0, effDef: 0, dmg: 100 },
|
||||
三月七: { hp: 50, atk: 0, def: 100, speed: 100, cpct: 0, cdmg: 0, stance: 0, heal: 0, recharge: 100, effPct: 50, effDef: 50, dmg: 0 },
|
||||
|
@ -218,6 +218,13 @@ export default function (step, staticStep) {
|
||||
dmg: ({ refine }) => step(12)[refine],
|
||||
a2Plus: ({ attr, calc, refine }) => calc(attr.mastery) * step(160)[refine] / 100
|
||||
}
|
||||
},
|
||||
|
||||
鹮穿之喙: {
|
||||
title: '重击命中敌人2层提高元素精通[mastery]点',
|
||||
data: {
|
||||
mastery: step(80)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -163,5 +163,10 @@
|
||||
"id": 15511,
|
||||
"name": "猎人之径",
|
||||
"star": 5
|
||||
},
|
||||
"鹮穿之喙": {
|
||||
"id": 15419,
|
||||
"name": "鹮穿之喙",
|
||||
"star": 4
|
||||
}
|
||||
}
|
BIN
resources/meta/weapon/bow/鹮穿之喙/awaken.webp
Normal file
BIN
resources/meta/weapon/bow/鹮穿之喙/awaken.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
59
resources/meta/weapon/bow/鹮穿之喙/data.json
Normal file
59
resources/meta/weapon/bow/鹮穿之喙/data.json
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"id": 15419,
|
||||
"name": "鹮穿之喙",
|
||||
"affixTitle": "秘智之眸的青睐",
|
||||
"star": 4,
|
||||
"desc": "以故事中的描述铸就的黄金之弓。若将它作为寻常武具使用,也可视为让纸上故事的一角在纸外的世界得到显现了吧。",
|
||||
"attr": {
|
||||
"atk": {
|
||||
"1": 43.73,
|
||||
"20": 118.57,
|
||||
"40": 225.99,
|
||||
"50": 293.36,
|
||||
"60": 360.9,
|
||||
"70": 428.69,
|
||||
"80": 496.72,
|
||||
"90": 564.78,
|
||||
"20+": 144.47,
|
||||
"40+": 251.99,
|
||||
"50+": 319.26,
|
||||
"60+": 386.8,
|
||||
"70+": 454.69,
|
||||
"80+": 522.62
|
||||
},
|
||||
"bonusKey": "atkPct",
|
||||
"bonusData": {
|
||||
"1": 6,
|
||||
"20": 10.6,
|
||||
"40": 15.45,
|
||||
"50": 17.87,
|
||||
"60": 20.3,
|
||||
"70": 22.72,
|
||||
"80": 25.14,
|
||||
"90": 27.56,
|
||||
"20+": 10.6,
|
||||
"40+": 15.45,
|
||||
"50+": 17.87,
|
||||
"60+": 20.3,
|
||||
"70+": 22.72,
|
||||
"80+": 25.14
|
||||
}
|
||||
},
|
||||
"materials": {
|
||||
"weapon": "谧林涓露的金符",
|
||||
"monster": "漫游者的盛放之花",
|
||||
"normal": "织金红绸"
|
||||
},
|
||||
"affixData": {
|
||||
"text": "重击命中敌人后的6秒内,角色元素精通提升$[0]点。该效果至多叠加2层,每0.5秒至多触发一次。",
|
||||
"datas": {
|
||||
"0": [
|
||||
"40",
|
||||
"50",
|
||||
"60",
|
||||
"70",
|
||||
"80"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
BIN
resources/meta/weapon/bow/鹮穿之喙/gacha.webp
Normal file
BIN
resources/meta/weapon/bow/鹮穿之喙/gacha.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
BIN
resources/meta/weapon/bow/鹮穿之喙/icon.webp
Normal file
BIN
resources/meta/weapon/bow/鹮穿之喙/icon.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
111
tools/ambr.js
111
tools/ambr.js
@ -1,111 +0,0 @@
|
||||
import fs from 'fs'
|
||||
import lodash from 'lodash'
|
||||
import fetch from 'node-fetch'
|
||||
import ImgDownloader from './sprider/ImgDown.js'
|
||||
import CharData from './sprider/CharDataAmber.js'
|
||||
import { Data } from '#miao'
|
||||
|
||||
|
||||
|
||||
const _path = process.cwd()
|
||||
const _root = _path + '/plugins/miao-plugin/'
|
||||
const _mRoot = _root + 'resources/meta/material/'
|
||||
|
||||
let mData = {}
|
||||
if (fs.existsSync(_mRoot + 'data.json')) {
|
||||
mData = JSON.parse(fs.readFileSync(_mRoot + 'data.json', 'utf8'))
|
||||
}
|
||||
|
||||
const tElems = ['anemo', 'geo', 'electro', 'dendro']
|
||||
|
||||
let getCharData = async function (id, key, name = '', _id = id) {
|
||||
let url = `https://api.ambr.top/v2/chs/avatar/100000${id}`
|
||||
console.log('req: ' + url)
|
||||
let req = await fetch(url)
|
||||
let reqData = await req.json()
|
||||
reqData = reqData.data
|
||||
console.log(reqData.id)
|
||||
let data = CharData.getBasic(reqData)
|
||||
name = name || data.name
|
||||
let imgs = new ImgDownloader(name)
|
||||
let attr = CharData.getDetailAttr(reqData)
|
||||
data.baseAttr = {}
|
||||
data.growAttr = {}
|
||||
let talentId
|
||||
let talentKey
|
||||
let detail = CharData.getDetail(reqData)
|
||||
let { talent, cons } = detail
|
||||
data.talentKey = talentKey || lodash.invert(lodash.mapValues(talent, (t) => t.id))
|
||||
data.talentId = talentId
|
||||
data.talentCons = CharData.getConsTalent(talent, cons)
|
||||
return {
|
||||
data,
|
||||
details: [detail],
|
||||
imgs
|
||||
}
|
||||
}
|
||||
|
||||
function checkName (name) {
|
||||
let charPath = `resources/meta/character/${name}/`
|
||||
Data.createDir(charPath, 'miao')
|
||||
if (name === '旅行者') {
|
||||
for (let idx in tElems) {
|
||||
Data.createDir(`${charPath}${tElems[idx]}/icons`, 'miao')
|
||||
}
|
||||
} else {
|
||||
Data.createDir(`${charPath}/icons`, 'miao')
|
||||
}
|
||||
Data.createDir(`${charPath}/imgs`, 'miao')
|
||||
let data = Data.readJSON(`${charPath}/data.json`, 'miao')
|
||||
return data.ver * 1 > 1
|
||||
}
|
||||
|
||||
async function saveCharData (id) {
|
||||
|
||||
let { data, details, imgs } = await getCharData(id)
|
||||
let name = data.name
|
||||
|
||||
if (!name) {
|
||||
console.log(`角色名不存在${id}:${name}`)
|
||||
return
|
||||
}
|
||||
|
||||
Data.createDir(`resources/meta/character/${name}/`, 'miao')
|
||||
|
||||
let charPath = `${_path}/plugins/miao-plugin/resources/meta/character/${name}/`
|
||||
fs.writeFileSync(`${charPath}data.json`, JSON.stringify(data, '', 2))
|
||||
if (details.length === 1) {
|
||||
fs.writeFileSync(`${charPath}detail.json`, JSON.stringify(details[0], '', 2))
|
||||
} else if (data.id === 20000000) {
|
||||
for (let idx in details) {
|
||||
let detail = details[idx]
|
||||
fs.writeFileSync(`${charPath}/${detail.elem}/detail.json`, JSON.stringify(detail, '', 2))
|
||||
}
|
||||
}
|
||||
|
||||
console.log(data.name + '数据下载完成')
|
||||
if (![10000005, 10000007].includes(data.id)) {
|
||||
await imgs.download()
|
||||
console.log(data.name + '图像全部下载完成')
|
||||
}
|
||||
}
|
||||
|
||||
async function down (name = '', force = false) {
|
||||
if (name === '') {
|
||||
name = lodash.keys(charData).join(',')
|
||||
}
|
||||
let names = name.split(',')
|
||||
for (let id in charData) {
|
||||
let ds = charData[id]
|
||||
if (!names.includes(id) && !names.includes(ds.key) && !names.includes(ds.name)) {
|
||||
continue
|
||||
}
|
||||
await saveCharData(id)
|
||||
}
|
||||
fs.writeFileSync(`${_mRoot}data.json`, JSON.stringify(mData, '', 2))
|
||||
}
|
||||
|
||||
const charData = {
|
||||
61: '绮良良'
|
||||
}
|
||||
await down('61', true)
|
@ -1,141 +0,0 @@
|
||||
import fs from 'fs'
|
||||
import cheerio from 'cheerio'
|
||||
import fetch from 'node-fetch'
|
||||
import { Data } from '#miao'
|
||||
import lodash from 'lodash'
|
||||
import request from 'request'
|
||||
import HttpsProxyAgent from 'https-proxy-agent'
|
||||
|
||||
let agent = new HttpsProxyAgent('http://localhost:4780')
|
||||
|
||||
const artiIdx = {
|
||||
Flower: 1,
|
||||
Plume: 2,
|
||||
Sands: 3,
|
||||
Goblet: 4,
|
||||
Circlet: 5
|
||||
}
|
||||
|
||||
async function getSets (id) {
|
||||
const url = `https://genshin.honeyhunterworld.com/i_${id}/?lang=CHS`
|
||||
let req = await fetch(url, { agent })
|
||||
let txt = await req.text()
|
||||
let sTxt = /sortable_data.push\((\[\[.*?\]\])[\n\s]*\)/.exec(txt)
|
||||
let ret = {}
|
||||
|
||||
if (sTxt && sTxt[1]) {
|
||||
// eslint-disable-next-line no-eval
|
||||
let arrs = eval(sTxt[1])
|
||||
lodash.forEach(arrs, (ds) => {
|
||||
let $ = cheerio.load(ds.join(''))
|
||||
let a = $('a:eq(1)')
|
||||
let idRet = /i_(.+)\//.exec(a.attr('href'))
|
||||
let nRet = /^(\w+)\s/.exec($('a:last').text())
|
||||
if (nRet && idRet) {
|
||||
ret[artiIdx[nRet[1]]] = {
|
||||
id: idRet[1],
|
||||
name: a.text()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
async function down (sets = '') {
|
||||
const url = 'https://genshin.honeyhunterworld.com/fam_art_set/?lang=CHS'
|
||||
let req = await fetch(url, { agent })
|
||||
let txt = await req.text()
|
||||
if (sets) {
|
||||
sets = sets.split(',')
|
||||
}
|
||||
|
||||
let ret = Data.readJSON('resources/meta/artifact/data.json', 'miao')
|
||||
|
||||
let sTxt = /sortable_data.push\((\[\[.*?\]\])\)/.exec(txt)
|
||||
if (sTxt && sTxt[1]) {
|
||||
// eslint-disable-next-line no-eval
|
||||
let txt = sTxt[1]
|
||||
txt = txt.replace(/<script>.+<\/script>/g, '')
|
||||
let tmp
|
||||
try {
|
||||
tmp = eval(txt)
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
lodash.forEach(tmp, (ds) => {
|
||||
let na = cheerio.load(ds[0])('a:last')
|
||||
let idRet = /i_(\w+)\//.exec(na.attr('href'))
|
||||
if (idRet && idRet[1]) {
|
||||
let effect = {}
|
||||
let $ = cheerio.load(`<div>${ds[2]}</div>`)
|
||||
|
||||
$('span').each(function () {
|
||||
let setRet = /(\d)-Piece:\s*(.*)。?$/.exec($(this).text())
|
||||
if (setRet && setRet[1]) {
|
||||
effect[setRet[1]] = setRet[2]
|
||||
}
|
||||
})
|
||||
if (idRet[1]) {
|
||||
let id = idRet[1]
|
||||
ret[id] = ret[id] || {
|
||||
id,
|
||||
name: na.find('img').attr('alt'),
|
||||
sets: {},
|
||||
effect
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
let imgs = []
|
||||
for (let idx in ret) {
|
||||
let ds = ret[idx]
|
||||
if (sets) {
|
||||
if (!sets.includes(ds.name)) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
ds.sets = await getSets(ds.id)
|
||||
console.log(`arti ${ds.id}:${ds.name} Done`)
|
||||
Data.createDir(`resources/meta/artifact/imgs/${ds.name}`, 'miao')
|
||||
|
||||
lodash.forEach(ds.sets, (s, idx) => {
|
||||
imgs.push({
|
||||
url: `img/i_${s.id}.webp`,
|
||||
file: `${ds.name}/${idx}.webp`
|
||||
})
|
||||
})
|
||||
}
|
||||
Data.createDir('resources/meta/artifact', 'miao')
|
||||
Data.writeJSON('resources/meta/artifact/data.json', ret, 'miao')
|
||||
|
||||
const _path = process.cwd()
|
||||
const _root = _path + '/plugins/miao-plugin/'
|
||||
const _aRoot = _root + 'resources/meta/artifact/imgs/'
|
||||
await Data.asyncPool(5, imgs, async function (ds) {
|
||||
if (fs.existsSync(`${_aRoot}/${ds.file}`)) {
|
||||
// console.log(`已存在,跳过 ${ds.file}`)
|
||||
return true
|
||||
}
|
||||
|
||||
try {
|
||||
let stream = fs.createWriteStream(`${_aRoot}/${ds.file}.tmp`)
|
||||
await request('https://genshin.honeyhunterworld.com/' + ds.url).pipe(stream)
|
||||
return new Promise((resolve) => {
|
||||
stream.on('finish', () => {
|
||||
fs.rename(`${_aRoot}/${ds.file}.tmp`, `${_aRoot}/${ds.file}`, () => {
|
||||
console.log(`图像下载成功: ${ds.file}`)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(`图像下载失败: ${ds.file}`)
|
||||
console.log(e)
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
await down('水仙之梦,花海甘露之光')
|
@ -1,295 +0,0 @@
|
||||
import cheerio from 'cheerio'
|
||||
import lodash from 'lodash'
|
||||
import fetch from 'node-fetch'
|
||||
import ImgDownloader from './sprider/ImgDown.js'
|
||||
import CharData from './sprider/CharData.js'
|
||||
import { Data } from '#miao'
|
||||
import HttpsProxyAgent from 'https-proxy-agent'
|
||||
|
||||
let agent = new HttpsProxyAgent('http://localhost:4780')
|
||||
|
||||
let mData = Data.readJSON('/resources/meta/material/data.json', 'miao')
|
||||
let tId = Data.readJSON('/tools/meta/talent.json', 'miao')
|
||||
|
||||
const tElems = ['anemo', 'geo', 'electro', 'dendro']
|
||||
|
||||
let getCharData = async function (id, key, name = '', _id = id) {
|
||||
let idNum = (id < 10 ? '0' : '') + (id < 100 ? '0' : '') + id
|
||||
let url = `https://genshin.honeyhunterworld.com/${key}_${idNum}/?lang=CHS`
|
||||
console.log('req: ' + url)
|
||||
let req = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.20',
|
||||
referer: 'https://genshin.honeyhunterworld.com/fam_chars/?lang=CHS',
|
||||
'sec-ch-ua': '"Microsoft Edge";v = "105", " Not;A Brand";v = "99", "Chromium";v = "105"',
|
||||
'sec-ch-ua-mobile': '?0',
|
||||
'sec-ch-ua-platform': 'Windows',
|
||||
'sec-fetch-dest': 'document',
|
||||
'sec-fetch-mode': 'navigate',
|
||||
'sec-fetch-site': 'none',
|
||||
'sec-fetch-user': '?1',
|
||||
'upgrade-insecure-requests': 1
|
||||
},
|
||||
agent
|
||||
})
|
||||
let txt = await req.text()
|
||||
const $ = cheerio.load(txt)
|
||||
let sTxt = /sortable_data.push\((.*)\)/.exec(txt)
|
||||
if (sTxt && sTxt[1]) {
|
||||
// eslint-disable-next-line no-eval
|
||||
|
||||
let tmp
|
||||
try {
|
||||
tmp = eval(sTxt[1])
|
||||
} catch (e) {
|
||||
tmp = {}
|
||||
}
|
||||
for (let idx in tmp) {
|
||||
let t = tmp[idx].join('')
|
||||
if (/Namecard/.test(t)) {
|
||||
let r = /\/i_([n\d]+)\/\?/.exec(t)
|
||||
if (r && r[1]) {
|
||||
$._nid = r[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let data = CharData.getBasic($, id, name, _id)
|
||||
name = name || data.name
|
||||
let imgs = new ImgDownloader(name)
|
||||
$.imgs = imgs
|
||||
let attr = CharData.getDetailAttr($)
|
||||
|
||||
let ld = attr.details['90']
|
||||
data.baseAttr = {
|
||||
hp: ld[0] * 1,
|
||||
atk: ld[1] * 1,
|
||||
def: ld[2] * 1
|
||||
}
|
||||
data.growAttr = {
|
||||
key: attr.keys[3],
|
||||
value: ld[3]
|
||||
}
|
||||
|
||||
let details = []
|
||||
let metas = []
|
||||
let talentElem = {}
|
||||
let talentId
|
||||
let talentKey
|
||||
if (data.elem === 'multi') {
|
||||
talentKey = {}
|
||||
talentId = {}
|
||||
for (let idx in tElems) {
|
||||
let detail = CharData.getDetail({ $, id, name, setIdx: idx * 1 + 1, elem: tElems[idx] })
|
||||
detail.attr = attr
|
||||
detail.elem = tElems[idx]
|
||||
details.push(detail)
|
||||
const te = {
|
||||
anemo: 4,
|
||||
geo: 6,
|
||||
electro: 7,
|
||||
dendro: 8
|
||||
}
|
||||
let cid = `1000000${id}-${id}0${te[tElems[idx]]}`
|
||||
lodash.forEach(tId[cid].talentId || {}, (v, k) => {
|
||||
talentId[k] = v
|
||||
})
|
||||
lodash.forEach(detail.talent, (ds, k) => {
|
||||
talentKey[ds.id] = k
|
||||
if (k === 'e' || k === 'q') {
|
||||
talentElem[ds.id] = tElems[idx]
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
let detail = CharData.getDetail({ $, id, name })
|
||||
details.push(detail)
|
||||
talentId = tId[(10000000 + id * 1)]?.talentId || {}
|
||||
}
|
||||
let detail = details[0]
|
||||
let { talent, cons } = detail
|
||||
talentKey = talentKey || lodash.invert(lodash.mapValues(talent, (t) => t.id))
|
||||
data.talentId = {}
|
||||
let talentKeyId = {}
|
||||
lodash.forEach(talentId, (tid, id) => {
|
||||
data.talentId[id] = talentKey[tid]
|
||||
talentKeyId[tid] = id
|
||||
})
|
||||
if (data.elem === 'multi') {
|
||||
data.talentElem = {}
|
||||
lodash.forEach(talentElem, (elem, tid) => {
|
||||
data.talentElem[talentKeyId[tid]] = elem
|
||||
})
|
||||
}
|
||||
data.talentCons = CharData.getConsTalent(talent, cons)
|
||||
data.materials = CharData.getMaterials($, mData)
|
||||
CharData.getImgs($)
|
||||
return {
|
||||
data,
|
||||
details,
|
||||
metas,
|
||||
imgs
|
||||
}
|
||||
}
|
||||
|
||||
function checkName (name) {
|
||||
let charPath = `resources/meta/character/${name}/`
|
||||
Data.createDir(charPath, 'miao')
|
||||
if (name === '旅行者') {
|
||||
for (let idx in tElems) {
|
||||
Data.createDir(`${charPath}${tElems[idx]}/icons`, 'miao')
|
||||
}
|
||||
} else {
|
||||
Data.createDir(`${charPath}/icons`, 'miao')
|
||||
}
|
||||
Data.createDir(`${charPath}/imgs`, 'miao')
|
||||
let data = Data.readJSON(`${charPath}/data.json`, 'miao')
|
||||
return data.ver * 1 > 1
|
||||
}
|
||||
|
||||
async function saveCharData (id, key, name = '', force = false, _id = id) {
|
||||
if (!id || !key) {
|
||||
return
|
||||
}
|
||||
if (name && checkName(name) && !force) {
|
||||
return
|
||||
}
|
||||
let { data, details, imgs } = await getCharData(id, key, name, _id)
|
||||
name = name || data.name
|
||||
|
||||
if (!name) {
|
||||
console.log(`角色名不存在${id}:${key}`)
|
||||
return
|
||||
}
|
||||
if (checkName(name) && !force) {
|
||||
return
|
||||
}
|
||||
if (eta[name]) {
|
||||
data.eta = new Date(`${eta[name]} 10:00:00`) * 1
|
||||
}
|
||||
let charPath = `/resources/meta/character/${name}/`
|
||||
Data.writeJSON({ path: charPath, name: 'data.json', data, rn: true, root: 'miao' })
|
||||
if (details.length === 1) {
|
||||
Data.writeJSON({ path: charPath, name: 'detail.json', data: details[0], rn: true, root: 'miao' })
|
||||
} else if (data.id === 20000000) {
|
||||
for (let idx in details) {
|
||||
let detail = details[idx]
|
||||
Data.writeJSON({ path: `${charPath}/${detail.elem}`, name: 'detail.json', data: detail, rn: true, root: 'miao' })
|
||||
}
|
||||
}
|
||||
|
||||
console.log(data.name + '数据下载完成')
|
||||
if (![10000005, 10000007].includes(data.id)) {
|
||||
await imgs.download()
|
||||
console.log(data.name + '图像全部下载完成')
|
||||
}
|
||||
}
|
||||
|
||||
async function down (name = '', force = false) {
|
||||
if (name === '') {
|
||||
name = lodash.keys(charData).join(',')
|
||||
}
|
||||
let names = name.split(',')
|
||||
for (let id in charData) {
|
||||
let ds = charData[id]
|
||||
if (typeof (ds) === 'string') {
|
||||
ds = ds.split(',')
|
||||
ds = { key: ds[0], name: ds[1] }
|
||||
}
|
||||
|
||||
if (!names.includes(id) && !names.includes(ds.key) && !names.includes(ds.name)) {
|
||||
continue
|
||||
}
|
||||
await saveCharData(ds.id || id, ds.key, ds.name, force, id)
|
||||
}
|
||||
Data.writeJSON({ name: '/resources/meta/material/data.json', data: mData, rn: true, root: 'miao' })
|
||||
}
|
||||
|
||||
const charData = {
|
||||
2: 'ayaka,神里绫华',
|
||||
3: 'qin,琴',
|
||||
4: { key: 'playergirl', name: '旅行者', id: 7 },
|
||||
5: 'playerboy,空',
|
||||
6: 'lisa,丽莎',
|
||||
7: 'playergirl,荧',
|
||||
14: 'barbara,芭芭拉',
|
||||
15: 'kaeya,凯亚',
|
||||
16: 'diluc,迪卢克',
|
||||
20: 'razor,雷泽',
|
||||
21: 'ambor,安柏',
|
||||
22: 'venti,温迪',
|
||||
23: 'xiangling,香菱',
|
||||
24: 'beidou,北斗',
|
||||
25: 'xingqiu,行秋',
|
||||
26: 'xiao,魈',
|
||||
27: 'ningguang,凝光',
|
||||
29: 'klee,可莉',
|
||||
30: 'zhongli,钟离',
|
||||
31: 'fischl,菲谢尔',
|
||||
32: 'bennett,班尼特',
|
||||
33: 'tartaglia,达达利亚',
|
||||
34: 'noel,诺艾尔',
|
||||
35: 'qiqi,七七',
|
||||
36: 'chongyun,重云',
|
||||
37: 'ganyu,甘雨',
|
||||
38: 'albedo,阿贝多',
|
||||
39: 'diona,迪奥娜',
|
||||
41: 'mona,莫娜',
|
||||
42: 'keqing,刻晴',
|
||||
43: 'sucrose,砂糖',
|
||||
44: 'xinyan,辛焱',
|
||||
45: 'rosaria,罗莎莉亚',
|
||||
46: 'hutao,胡桃',
|
||||
47: 'kazuha,枫原万叶',
|
||||
48: 'feiyan,烟绯',
|
||||
49: 'yoimiya,宵宫',
|
||||
50: 'tohma,托马',
|
||||
51: 'eula,优菈',
|
||||
52: 'shougun,雷电将军',
|
||||
53: 'sayu,早柚',
|
||||
54: 'kokomi,珊瑚宫心海',
|
||||
55: 'gorou,五郎',
|
||||
56: 'sara,九条裟罗',
|
||||
57: 'itto,荒泷一斗',
|
||||
58: 'yae,八重神子',
|
||||
59: 'heizo,鹿野院平藏',
|
||||
60: 'yelan,夜兰',
|
||||
61: 'momoka,绮良良',
|
||||
62: 'aloy,埃洛伊',
|
||||
63: 'shenhe,申鹤',
|
||||
64: 'yunjin,云堇',
|
||||
65: 'shinobu,久岐忍',
|
||||
66: 'ayato,神里绫人',
|
||||
67: 'collei,柯莱',
|
||||
68: 'dori,多莉',
|
||||
69: 'tighnari,提纳里',
|
||||
70: 'nilou,妮露',
|
||||
71: 'cyno,赛诺',
|
||||
72: 'candace,坎蒂丝',
|
||||
73: 'nahida,纳西妲',
|
||||
74: 'layla,莱依拉',
|
||||
75: 'wanderer,流浪者',
|
||||
76: 'faruzan,珐露珊',
|
||||
77: 'yaoyao,瑶瑶',
|
||||
78: 'alhatham,艾尔海森',
|
||||
79: 'dehya,迪希雅',
|
||||
80: 'mika,米卡',
|
||||
81: 'kaveh,卡维',
|
||||
82: 'baizhuer,白术'
|
||||
}
|
||||
let eta = {
|
||||
妮露: '2022-10-14',
|
||||
纳西妲: '2022-11-02',
|
||||
莱依拉: '2022-11-02',
|
||||
流浪者: '2022-12-07',
|
||||
珐露珊: '2022-12-07',
|
||||
瑶瑶: '2023-01-18',
|
||||
艾尔海森: '2023-01-18',
|
||||
迪希雅: '2023-03-01',
|
||||
米卡: '2023-03-21',
|
||||
卡维: '2023-05-02',
|
||||
白术: '2023-05-02',
|
||||
绮良良: '2023-05-24'
|
||||
}
|
||||
await down('卡维,白术,绮良良', true)
|
@ -1,20 +0,0 @@
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { Data } from '#miao'
|
||||
import { ProfileDmg } from '#miao.models'
|
||||
import { ProfileWeapon } from '../apps/profile/ProfileWeapon.js'
|
||||
|
||||
export async function calcDmg (inputData, enemyLv = 86) {
|
||||
let dmg = new ProfileDmg(inputData)
|
||||
let ret = await dmg.calcData({ enemyLv })
|
||||
if (ret === false) {
|
||||
return {}
|
||||
} else {
|
||||
ret = Data.getData(ret, 'ret,msg,enemyName')
|
||||
ret.enemyLevel = enemyLv
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
export async function calcWeapon (inputData, enemyLv = 86) {
|
||||
return await ProfileWeapon.calc(inputData)
|
||||
}
|
@ -1,834 +0,0 @@
|
||||
{
|
||||
"10000002": {
|
||||
"name": "神里绫华",
|
||||
"talentId": {
|
||||
"10018": 232,
|
||||
"10019": 239,
|
||||
"10024": 231
|
||||
},
|
||||
"talentKey": {
|
||||
"10018": "e",
|
||||
"10019": "q",
|
||||
"10024": "a"
|
||||
}
|
||||
},
|
||||
"10000003": {
|
||||
"name": "琴",
|
||||
"talentId": {
|
||||
"10031": 331,
|
||||
"10033": 332,
|
||||
"10034": 339
|
||||
},
|
||||
"talentKey": {
|
||||
"10031": "a",
|
||||
"10033": "e",
|
||||
"10034": "q"
|
||||
}
|
||||
},
|
||||
"10000006": {
|
||||
"name": "丽莎",
|
||||
"talentId": {
|
||||
"10060": 431,
|
||||
"10061": 432,
|
||||
"10062": 439
|
||||
},
|
||||
"talentKey": {
|
||||
"10060": "a",
|
||||
"10061": "e",
|
||||
"10062": "q"
|
||||
}
|
||||
},
|
||||
"10000014": {
|
||||
"name": "芭芭拉",
|
||||
"talentId": {
|
||||
"10070": 1431,
|
||||
"10071": 1432,
|
||||
"10072": 1439
|
||||
},
|
||||
"talentKey": {
|
||||
"10070": "a",
|
||||
"10071": "e",
|
||||
"10072": "q"
|
||||
}
|
||||
},
|
||||
"10000015": {
|
||||
"name": "凯亚",
|
||||
"talentId": {
|
||||
"10073": 1531,
|
||||
"10074": 1532,
|
||||
"10075": 1539
|
||||
},
|
||||
"talentKey": {
|
||||
"10073": "a",
|
||||
"10074": "e",
|
||||
"10075": "q"
|
||||
}
|
||||
},
|
||||
"10000016": {
|
||||
"name": "迪卢克",
|
||||
"talentId": {
|
||||
"10160": 1631,
|
||||
"10161": 1632,
|
||||
"10165": 1639
|
||||
},
|
||||
"talentKey": {
|
||||
"10160": "a",
|
||||
"10161": "e",
|
||||
"10165": "q"
|
||||
}
|
||||
},
|
||||
"10000020": {
|
||||
"name": "雷泽",
|
||||
"talentId": {
|
||||
"10201": 2031,
|
||||
"10202": 2032,
|
||||
"10203": 2039
|
||||
},
|
||||
"talentKey": {
|
||||
"10201": "a",
|
||||
"10202": "e",
|
||||
"10203": "q"
|
||||
}
|
||||
},
|
||||
"10000021": {
|
||||
"name": "安柏",
|
||||
"talentId": {
|
||||
"10017": 2139,
|
||||
"10032": 2132,
|
||||
"10041": 2131
|
||||
},
|
||||
"talentKey": {
|
||||
"10017": "q",
|
||||
"10032": "e",
|
||||
"10041": "a"
|
||||
}
|
||||
},
|
||||
"10000022": {
|
||||
"name": "温迪",
|
||||
"talentId": {
|
||||
"10221": 2231,
|
||||
"10224": 2232,
|
||||
"10225": 2239
|
||||
},
|
||||
"talentKey": {
|
||||
"10221": "a",
|
||||
"10224": "e",
|
||||
"10225": "q"
|
||||
}
|
||||
},
|
||||
"10000023": {
|
||||
"name": "香菱",
|
||||
"talentId": {
|
||||
"10231": 2331,
|
||||
"10232": 2332,
|
||||
"10235": 2339
|
||||
},
|
||||
"talentKey": {
|
||||
"10231": "a",
|
||||
"10232": "e",
|
||||
"10235": "q"
|
||||
}
|
||||
},
|
||||
"10000024": {
|
||||
"name": "北斗",
|
||||
"talentId": {
|
||||
"10241": 2431,
|
||||
"10242": 2432,
|
||||
"10245": 2439
|
||||
},
|
||||
"talentKey": {
|
||||
"10241": "a",
|
||||
"10242": "e",
|
||||
"10245": "q"
|
||||
}
|
||||
},
|
||||
"10000025": {
|
||||
"name": "行秋",
|
||||
"talentId": {
|
||||
"10381": 2531,
|
||||
"10382": 2532,
|
||||
"10385": 2539
|
||||
},
|
||||
"talentKey": {
|
||||
"10381": "a",
|
||||
"10382": "e",
|
||||
"10385": "q"
|
||||
}
|
||||
},
|
||||
"10000026": {
|
||||
"name": "魈",
|
||||
"talentId": {
|
||||
"10261": 2631,
|
||||
"10262": 2632,
|
||||
"10265": 2639
|
||||
},
|
||||
"talentKey": {
|
||||
"10261": "a",
|
||||
"10262": "e",
|
||||
"10265": "q"
|
||||
}
|
||||
},
|
||||
"10000027": {
|
||||
"name": "凝光",
|
||||
"talentId": {
|
||||
"10271": 2731,
|
||||
"10272": 2732,
|
||||
"10274": 2739
|
||||
},
|
||||
"talentKey": {
|
||||
"10271": "a",
|
||||
"10272": "e",
|
||||
"10274": "q"
|
||||
}
|
||||
},
|
||||
"10000029": {
|
||||
"name": "可莉",
|
||||
"talentId": {
|
||||
"10291": 2931,
|
||||
"10292": 2932,
|
||||
"10295": 2939
|
||||
},
|
||||
"talentKey": {
|
||||
"10291": "a",
|
||||
"10292": "e",
|
||||
"10295": "q"
|
||||
}
|
||||
},
|
||||
"10000030": {
|
||||
"name": "钟离",
|
||||
"talentId": {
|
||||
"10301": 3031,
|
||||
"10302": 3032,
|
||||
"10303": 3039
|
||||
},
|
||||
"talentKey": {
|
||||
"10301": "a",
|
||||
"10302": "e",
|
||||
"10303": "q"
|
||||
}
|
||||
},
|
||||
"10000031": {
|
||||
"name": "菲谢尔",
|
||||
"talentId": {
|
||||
"10311": 3131,
|
||||
"10312": 3132,
|
||||
"10313": 3139
|
||||
},
|
||||
"talentKey": {
|
||||
"10311": "a",
|
||||
"10312": "e",
|
||||
"10313": "q"
|
||||
}
|
||||
},
|
||||
"10000032": {
|
||||
"name": "班尼特",
|
||||
"talentId": {
|
||||
"10321": 3231,
|
||||
"10322": 3232,
|
||||
"10323": 3239
|
||||
},
|
||||
"talentKey": {
|
||||
"10321": "a",
|
||||
"10322": "e",
|
||||
"10323": "q"
|
||||
}
|
||||
},
|
||||
"10000033": {
|
||||
"name": "达达利亚",
|
||||
"talentId": {
|
||||
"10331": 3331,
|
||||
"10332": 3332,
|
||||
"10333": 3339
|
||||
},
|
||||
"talentKey": {
|
||||
"10331": "a",
|
||||
"10332": "e",
|
||||
"10333": "q"
|
||||
}
|
||||
},
|
||||
"10000034": {
|
||||
"name": "诺艾尔",
|
||||
"talentId": {
|
||||
"10341": 3431,
|
||||
"10342": 3432,
|
||||
"10343": 3439
|
||||
},
|
||||
"talentKey": {
|
||||
"10341": "a",
|
||||
"10342": "e",
|
||||
"10343": "q"
|
||||
}
|
||||
},
|
||||
"10000035": {
|
||||
"name": "七七",
|
||||
"talentId": {
|
||||
"10351": 3531,
|
||||
"10352": 3532,
|
||||
"10353": 3539
|
||||
},
|
||||
"talentKey": {
|
||||
"10351": "a",
|
||||
"10352": "e",
|
||||
"10353": "q"
|
||||
}
|
||||
},
|
||||
"10000036": {
|
||||
"name": "重云",
|
||||
"talentId": {
|
||||
"10401": 3631,
|
||||
"10402": 3632,
|
||||
"10403": 3639
|
||||
},
|
||||
"talentKey": {
|
||||
"10401": "a",
|
||||
"10402": "e",
|
||||
"10403": "q"
|
||||
}
|
||||
},
|
||||
"10000037": {
|
||||
"name": "甘雨",
|
||||
"talentId": {
|
||||
"10371": 3731,
|
||||
"10372": 3732,
|
||||
"10373": 3739
|
||||
},
|
||||
"talentKey": {
|
||||
"10371": "a",
|
||||
"10372": "e",
|
||||
"10373": "q"
|
||||
}
|
||||
},
|
||||
"10000038": {
|
||||
"name": "阿贝多",
|
||||
"talentId": {
|
||||
"10386": 3831,
|
||||
"10387": 3832,
|
||||
"10388": 3839
|
||||
},
|
||||
"talentKey": {
|
||||
"10386": "a",
|
||||
"10387": "e",
|
||||
"10388": "q"
|
||||
}
|
||||
},
|
||||
"10000039": {
|
||||
"name": "迪奥娜",
|
||||
"talentId": {
|
||||
"10391": 3931,
|
||||
"10392": 3932,
|
||||
"10395": 3939
|
||||
},
|
||||
"talentKey": {
|
||||
"10391": "a",
|
||||
"10392": "e",
|
||||
"10395": "q"
|
||||
}
|
||||
},
|
||||
"10000041": {
|
||||
"name": "莫娜",
|
||||
"talentId": {
|
||||
"10411": 4131,
|
||||
"10412": 4132,
|
||||
"10415": 4139
|
||||
},
|
||||
"talentKey": {
|
||||
"10411": "a",
|
||||
"10412": "e",
|
||||
"10415": "q"
|
||||
}
|
||||
},
|
||||
"10000042": {
|
||||
"name": "刻晴",
|
||||
"talentId": {
|
||||
"10421": 4231,
|
||||
"10422": 4232,
|
||||
"10425": 4239
|
||||
},
|
||||
"talentKey": {
|
||||
"10421": "a",
|
||||
"10422": "e",
|
||||
"10425": "q"
|
||||
}
|
||||
},
|
||||
"10000043": {
|
||||
"name": "砂糖",
|
||||
"talentId": {
|
||||
"10431": 4331,
|
||||
"10432": 4332,
|
||||
"10435": 4339
|
||||
},
|
||||
"talentKey": {
|
||||
"10431": "a",
|
||||
"10432": "e",
|
||||
"10435": "q"
|
||||
}
|
||||
},
|
||||
"10000044": {
|
||||
"name": "辛焱",
|
||||
"talentId": {
|
||||
"10441": 4431,
|
||||
"10442": 4432,
|
||||
"10443": 4439
|
||||
},
|
||||
"talentKey": {
|
||||
"10441": "a",
|
||||
"10442": "e",
|
||||
"10443": "q"
|
||||
}
|
||||
},
|
||||
"10000045": {
|
||||
"name": "罗莎莉亚",
|
||||
"talentId": {
|
||||
"10451": 4531,
|
||||
"10452": 4532,
|
||||
"10453": 4539
|
||||
},
|
||||
"talentKey": {
|
||||
"10451": "a",
|
||||
"10452": "e",
|
||||
"10453": "q"
|
||||
}
|
||||
},
|
||||
"10000046": {
|
||||
"name": "胡桃",
|
||||
"talentId": {
|
||||
"10461": 4631,
|
||||
"10462": 4632,
|
||||
"10463": 4639
|
||||
},
|
||||
"talentKey": {
|
||||
"10461": "a",
|
||||
"10462": "e",
|
||||
"10463": "q"
|
||||
}
|
||||
},
|
||||
"10000047": {
|
||||
"name": "枫原万叶",
|
||||
"talentId": {
|
||||
"10471": 4731,
|
||||
"10472": 4732,
|
||||
"10475": 4739
|
||||
},
|
||||
"talentKey": {
|
||||
"10471": "a",
|
||||
"10472": "e",
|
||||
"10475": "q"
|
||||
}
|
||||
},
|
||||
"10000048": {
|
||||
"name": "烟绯",
|
||||
"talentId": {
|
||||
"10481": 4831,
|
||||
"10482": 4832,
|
||||
"10485": 4839
|
||||
},
|
||||
"talentKey": {
|
||||
"10481": "a",
|
||||
"10482": "e",
|
||||
"10485": "q"
|
||||
}
|
||||
},
|
||||
"10000049": {
|
||||
"name": "宵宫",
|
||||
"talentId": {
|
||||
"10491": 4931,
|
||||
"10492": 4932,
|
||||
"10495": 4939
|
||||
},
|
||||
"talentKey": {
|
||||
"10491": "a",
|
||||
"10492": "e",
|
||||
"10495": "q"
|
||||
}
|
||||
},
|
||||
"10000050": {
|
||||
"name": "托马",
|
||||
"talentId": {
|
||||
"10501": 5031,
|
||||
"10502": 5032,
|
||||
"10505": 5039
|
||||
},
|
||||
"talentKey": {
|
||||
"10501": "a",
|
||||
"10502": "e",
|
||||
"10505": "q"
|
||||
}
|
||||
},
|
||||
"10000051": {
|
||||
"name": "优菈",
|
||||
"talentId": {
|
||||
"10511": 5131,
|
||||
"10512": 5132,
|
||||
"10515": 5139
|
||||
},
|
||||
"talentKey": {
|
||||
"10511": "a",
|
||||
"10512": "e",
|
||||
"10515": "q"
|
||||
}
|
||||
},
|
||||
"10000052": {
|
||||
"name": "雷电将军",
|
||||
"talentId": {
|
||||
"10521": 5231,
|
||||
"10522": 5232,
|
||||
"10525": 5239
|
||||
},
|
||||
"talentKey": {
|
||||
"10521": "a",
|
||||
"10522": "e",
|
||||
"10525": "q"
|
||||
}
|
||||
},
|
||||
"10000053": {
|
||||
"name": "早柚",
|
||||
"talentId": {
|
||||
"10531": 5331,
|
||||
"10532": 5332,
|
||||
"10535": 5339
|
||||
},
|
||||
"talentKey": {
|
||||
"10531": "a",
|
||||
"10532": "e",
|
||||
"10535": "q"
|
||||
}
|
||||
},
|
||||
"10000054": {
|
||||
"name": "珊瑚宫心海",
|
||||
"talentId": {
|
||||
"10541": 5431,
|
||||
"10542": 5432,
|
||||
"10545": 5439
|
||||
},
|
||||
"talentKey": {
|
||||
"10541": "a",
|
||||
"10542": "e",
|
||||
"10545": "q"
|
||||
}
|
||||
},
|
||||
"10000055": {
|
||||
"name": "五郎",
|
||||
"talentId": {
|
||||
"10551": 5531,
|
||||
"10552": 5532,
|
||||
"10555": 5539
|
||||
},
|
||||
"talentKey": {
|
||||
"10551": "a",
|
||||
"10552": "e",
|
||||
"10555": "q"
|
||||
}
|
||||
},
|
||||
"10000056": {
|
||||
"name": "九条裟罗",
|
||||
"talentId": {
|
||||
"10561": 5631,
|
||||
"10562": 5632,
|
||||
"10565": 5639
|
||||
},
|
||||
"talentKey": {
|
||||
"10561": "a",
|
||||
"10562": "e",
|
||||
"10565": "q"
|
||||
}
|
||||
},
|
||||
"10000057": {
|
||||
"name": "荒泷一斗",
|
||||
"talentId": {
|
||||
"10571": 5731,
|
||||
"10572": 5732,
|
||||
"10575": 5739
|
||||
},
|
||||
"talentKey": {
|
||||
"10571": "a",
|
||||
"10572": "e",
|
||||
"10575": "q"
|
||||
}
|
||||
},
|
||||
"10000058": {
|
||||
"name": "八重神子",
|
||||
"talentId": {
|
||||
"10581": 5831,
|
||||
"10582": 5832,
|
||||
"10585": 5839
|
||||
},
|
||||
"talentKey": {
|
||||
"10581": "a",
|
||||
"10582": "e",
|
||||
"10585": "q"
|
||||
}
|
||||
},
|
||||
"10000059": {
|
||||
"name": "鹿野院平藏",
|
||||
"talentId": {
|
||||
"10591": 5931,
|
||||
"10592": 5932,
|
||||
"10595": 5939
|
||||
},
|
||||
"talentKey": {
|
||||
"10591": "a",
|
||||
"10592": "e",
|
||||
"10595": "q"
|
||||
}
|
||||
},
|
||||
"10000060": {
|
||||
"name": "夜兰",
|
||||
"talentId": {
|
||||
"10606": 6031,
|
||||
"10607": 6032,
|
||||
"10610": 6039
|
||||
},
|
||||
"talentKey": {
|
||||
"10606": "a",
|
||||
"10607": "e",
|
||||
"10610": "q"
|
||||
}
|
||||
},
|
||||
"10000062": {
|
||||
"name": "埃洛伊",
|
||||
"talentId": {
|
||||
"10621": 6231,
|
||||
"10622": 6232,
|
||||
"10625": 6239
|
||||
},
|
||||
"talentKey": {
|
||||
"10621": "a",
|
||||
"10622": "e",
|
||||
"10625": "q"
|
||||
}
|
||||
},
|
||||
"10000063": {
|
||||
"name": "申鹤",
|
||||
"talentId": {
|
||||
"10631": 6331,
|
||||
"10632": 6332,
|
||||
"10635": 6339
|
||||
},
|
||||
"talentKey": {
|
||||
"10631": "a",
|
||||
"10632": "e",
|
||||
"10635": "q"
|
||||
}
|
||||
},
|
||||
"10000064": {
|
||||
"name": "云堇",
|
||||
"talentId": {
|
||||
"10641": 6431,
|
||||
"10642": 6432,
|
||||
"10643": 6439
|
||||
},
|
||||
"talentKey": {
|
||||
"10641": "a",
|
||||
"10642": "e",
|
||||
"10643": "q"
|
||||
}
|
||||
},
|
||||
"10000065": {
|
||||
"name": "久岐忍",
|
||||
"talentId": {
|
||||
"10651": 6531,
|
||||
"10652": 6532,
|
||||
"10655": 6539
|
||||
},
|
||||
"talentKey": {
|
||||
"10651": "a",
|
||||
"10652": "e",
|
||||
"10655": "q"
|
||||
}
|
||||
},
|
||||
"10000066": {
|
||||
"name": "神里绫人",
|
||||
"talentId": {
|
||||
"10661": 6631,
|
||||
"10662": 6632,
|
||||
"10665": 6639
|
||||
},
|
||||
"talentKey": {
|
||||
"10661": "a",
|
||||
"10662": "e",
|
||||
"10665": "q"
|
||||
}
|
||||
},
|
||||
"10000067": {
|
||||
"name": "柯莱",
|
||||
"talentId": {
|
||||
"10671": 6731,
|
||||
"10672": 6732,
|
||||
"10675": 6739
|
||||
},
|
||||
"talentKey": {
|
||||
"10671": "a",
|
||||
"10672": "e",
|
||||
"10675": "q"
|
||||
}
|
||||
},
|
||||
"10000068": {
|
||||
"name": "多莉",
|
||||
"talentId": {
|
||||
"10681": 6831,
|
||||
"10682": 6832,
|
||||
"10685": 6839
|
||||
},
|
||||
"talentKey": {
|
||||
"10681": "a",
|
||||
"10682": "e",
|
||||
"10685": "q"
|
||||
}
|
||||
},
|
||||
"10000069": {
|
||||
"name": "提纳里",
|
||||
"talentId": {
|
||||
"10691": 6931,
|
||||
"10692": 6932,
|
||||
"10695": 6939
|
||||
},
|
||||
"talentKey": {
|
||||
"10691": "a",
|
||||
"10692": "e",
|
||||
"10695": "q"
|
||||
}
|
||||
},
|
||||
"10000070": {
|
||||
"name": "妮露",
|
||||
"talentId": {
|
||||
"10701": 7031,
|
||||
"10702": 7032,
|
||||
"10705": 7039
|
||||
},
|
||||
"talentKey": {
|
||||
"10701": "a",
|
||||
"10702": "e",
|
||||
"10705": "q"
|
||||
}
|
||||
},
|
||||
"10000071": {
|
||||
"name": "赛诺",
|
||||
"talentId": {
|
||||
"10711": 7131,
|
||||
"10712": 7132,
|
||||
"10715": 7139
|
||||
},
|
||||
"talentKey": {
|
||||
"10711": "a",
|
||||
"10712": "e",
|
||||
"10715": "q"
|
||||
}
|
||||
},
|
||||
"10000072": {
|
||||
"name": "坎蒂丝",
|
||||
"talentId": {
|
||||
"10721": 7231,
|
||||
"10722": 7232,
|
||||
"10725": 7239
|
||||
},
|
||||
"talentKey": {
|
||||
"10721": "a",
|
||||
"10722": "e",
|
||||
"10725": "q"
|
||||
}
|
||||
},
|
||||
"10000073": {
|
||||
"name": "纳西妲",
|
||||
"talentId": {
|
||||
"10731": 7331,
|
||||
"10732": 7332,
|
||||
"10735": 7339
|
||||
},
|
||||
"talentKey": {
|
||||
"10731": "a",
|
||||
"10732": "e",
|
||||
"10735": "q"
|
||||
}
|
||||
},
|
||||
"10000074": {
|
||||
"name": "莱依拉",
|
||||
"talentId": {
|
||||
"10741": 7431,
|
||||
"10742": 7432,
|
||||
"10745": 7439
|
||||
},
|
||||
"talentKey": {
|
||||
"10741": "a",
|
||||
"10742": "e",
|
||||
"10745": "q"
|
||||
}
|
||||
},
|
||||
"10000075": {
|
||||
"name": "流浪者",
|
||||
"talentId": {
|
||||
"10751": 7531,
|
||||
"10752": 7532,
|
||||
"10755": 7539
|
||||
},
|
||||
"talentKey": {
|
||||
"10751": "a",
|
||||
"10752": "e",
|
||||
"10755": "q"
|
||||
}
|
||||
},
|
||||
"10000076": {
|
||||
"name": "珐露珊",
|
||||
"talentId": {
|
||||
"10761": 7631,
|
||||
"10762": 7632,
|
||||
"10765": 7639
|
||||
},
|
||||
"talentKey": {
|
||||
"10761": "a",
|
||||
"10762": "e",
|
||||
"10765": "q"
|
||||
}
|
||||
},
|
||||
"10000077": {
|
||||
"name": "瑶瑶",
|
||||
"talentId": {
|
||||
"10771": 7731,
|
||||
"10772": 7732,
|
||||
"10775": 7739
|
||||
},
|
||||
"talentKey": {
|
||||
"10771": "a",
|
||||
"10772": "e",
|
||||
"10775": "q"
|
||||
}
|
||||
},
|
||||
"10000078": {
|
||||
"name": "艾尔海森",
|
||||
"talentId": {
|
||||
"10781": 7831,
|
||||
"10782": 7832,
|
||||
"10785": 7839
|
||||
},
|
||||
"talentKey": {
|
||||
"10781": "a",
|
||||
"10782": "e",
|
||||
"10785": "q"
|
||||
}
|
||||
},
|
||||
"10000079": {
|
||||
"name": "迪希雅",
|
||||
"talentId": {
|
||||
"10791": 7931,
|
||||
"10792": 7932,
|
||||
"10795": 7939
|
||||
},
|
||||
"talentKey": {
|
||||
"10791": "a",
|
||||
"10792": "e",
|
||||
"10795": "q"
|
||||
}
|
||||
},
|
||||
"10000080": {
|
||||
"name": "米卡",
|
||||
"talentId": {
|
||||
"10801": 8031,
|
||||
"10802": 8032,
|
||||
"10805": 8039
|
||||
},
|
||||
"talentKey": {
|
||||
"10801": "a",
|
||||
"10802": "e",
|
||||
"10805": "q"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,422 +0,0 @@
|
||||
import abbr from './abbr.js'
|
||||
import lodash from 'lodash'
|
||||
import fixData from './fixData.js'
|
||||
|
||||
let costumes = {
|
||||
琴: [200301],
|
||||
芭芭拉: [201401],
|
||||
刻晴: [204201],
|
||||
凝光: [202701],
|
||||
迪卢克: [201601],
|
||||
菲谢尔: [203101],
|
||||
神里绫华: [200201],
|
||||
丽莎: [200601]
|
||||
}
|
||||
|
||||
const CharData = {
|
||||
getBasic ($, id, name = '', _id = id) {
|
||||
let ret = {}
|
||||
console.log(id, _id)
|
||||
let fix = fixData[_id || id] || {}
|
||||
ret.id = fix.id || 10000000 + id * 1
|
||||
let basic = $('.genshin_table.main_table')
|
||||
let title = function (title) {
|
||||
return basic.find(`td:contains('${title}'):last`).next('td').text().trim()
|
||||
}
|
||||
ret.name = name || title('Name')
|
||||
ret.abbr = abbr[ret.name] || ret.name
|
||||
ret.title = fix.title || title('Title')
|
||||
ret.star = basic.find('td:contains(\'Rarity\')').next('td').find('.cur_icon').length
|
||||
ret.elem = title('Element').toLowerCase()
|
||||
ret.allegiance = title('Occupation')
|
||||
ret.weapon = title('Weapon').toLowerCase()
|
||||
ret.birth = title('Month of Birth') + '-' + title('Day of Birth')
|
||||
ret.astro = title('Constellation')
|
||||
ret.desc = title('Description')
|
||||
ret.cncv = fix.cncv || title('Chinese')
|
||||
ret.jpcv = fix.jpcv || title('Japanese')
|
||||
ret.costume = costumes[ret.name] || false
|
||||
ret.ver = 1
|
||||
return ret
|
||||
},
|
||||
|
||||
getDetailAttr ($) {
|
||||
// 采集属性信息
|
||||
let stat = $('.genshin_table.stat_table:first')
|
||||
let attrs = []
|
||||
let colIdxs = {}
|
||||
const titleMap = {
|
||||
HP: 'hpBase',
|
||||
Atk: 'atkBase',
|
||||
Def: 'defBase'
|
||||
}
|
||||
const bonusMap = {
|
||||
Atk: 'atkPct',
|
||||
HP: 'hpPct',
|
||||
Def: 'defPct',
|
||||
CritDMG: 'cdmg',
|
||||
CritRate: 'cpct',
|
||||
ER: 'recharge',
|
||||
EM: 'mastery',
|
||||
Geo: 'dmg',
|
||||
Hydro: 'dmg',
|
||||
Anemo: 'dmg',
|
||||
Dendro: 'dmg',
|
||||
Pyro: 'dmg',
|
||||
Cryo: 'dmg',
|
||||
Elec: 'dmg',
|
||||
Heal: 'heal',
|
||||
Phys: 'phy'
|
||||
}
|
||||
stat.find('tr:first td:lt(8)').each(function (i) {
|
||||
let title = $(this).text()
|
||||
let titleRet = /^Bonuse?\s(\w+)%*$/.exec(title)
|
||||
if (titleRet && titleRet[1]) {
|
||||
attrs.push(bonusMap[titleRet[1]] || titleRet[1])
|
||||
colIdxs[i] = true
|
||||
} else if (titleMap[title]) {
|
||||
attrs.push(titleMap[title])
|
||||
colIdxs[i] = true
|
||||
}
|
||||
})
|
||||
let lvs = []
|
||||
let lvStat = {}
|
||||
stat.find('tr:gt(0)').each(function (i) {
|
||||
let tr = $(this)
|
||||
let lvl = tr.find('td:first').text()
|
||||
lvs.push(lvl)
|
||||
let data = []
|
||||
tr.find('td:lt(8)').each(function (i) {
|
||||
if (!colIdxs[i]) {
|
||||
return
|
||||
}
|
||||
data.push((lodash.trim($(this).text(), '%') * 1) || 0)
|
||||
})
|
||||
lvStat[lvl] = data
|
||||
})
|
||||
return {
|
||||
keys: attrs,
|
||||
details: lvStat
|
||||
}
|
||||
},
|
||||
|
||||
getDetail ({ $, id, name, setIdx = '', elem = '' }) {
|
||||
let cont = setIdx ? $(`#skillset_${setIdx}`) : $('#char_skills')
|
||||
cont.imgs = $.imgs
|
||||
let iconPath = elem ? `${elem}/icons` : 'icons'
|
||||
let talent = CharData.getTalents($, cont, name, iconPath)
|
||||
let talentData = CharData.getTalentData(talent)
|
||||
let passive = CharData.getPassive($, cont, name, iconPath)
|
||||
let cons = CharData.getCons($, cont, iconPath)
|
||||
let attr = CharData.getDetailAttr($)
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
talent,
|
||||
talentData,
|
||||
cons,
|
||||
passive,
|
||||
attr
|
||||
}
|
||||
},
|
||||
|
||||
// 获取正文
|
||||
getDesc (dt) {
|
||||
dt = dt || ''
|
||||
dt = dt.replace(/<color=[^>]*>/g, '')
|
||||
dt = dt.replace(/<\/color=[^>]*>/g, '')
|
||||
dt = dt.replace(/<span class=[^>]*>/g, '<strong>')
|
||||
dt = dt.replace(/<\/span>/g, '</strong>')
|
||||
dt = dt.split('<br>')
|
||||
let desc = []
|
||||
let isEmpty = true
|
||||
lodash.forEach(dt, (txt, i) => {
|
||||
txt = lodash.trim(txt)
|
||||
if (!txt) {
|
||||
isEmpty = true
|
||||
return
|
||||
} else if (txt.length < 15 && isEmpty) {
|
||||
txt = `<h3>${txt}</h3>`
|
||||
}
|
||||
desc.push(txt)
|
||||
isEmpty = false
|
||||
})
|
||||
return desc
|
||||
},
|
||||
|
||||
// 获取单个天赋数据
|
||||
getTalent ($, cont, imgKey, eq, onlyLv1 = false) {
|
||||
let info = cont.find(`.genshin_table.skill_table:eq(${eq})`)
|
||||
|
||||
let name = info.find('tr:first td:eq(1)').text()
|
||||
let icon = info.find('tr:first td:first img').attr('src')
|
||||
let idRet = /s_(\d+)01.webp/.exec(icon)
|
||||
let id = 0
|
||||
if (idRet && idRet[1]) {
|
||||
id = idRet[1] * 1
|
||||
}
|
||||
if (onlyLv1) {
|
||||
$.imgs.add(imgKey, icon)
|
||||
}
|
||||
// 说明
|
||||
let desc = CharData.getDesc(info.find('tr:eq(1) td').html())
|
||||
|
||||
// detail
|
||||
let detail = cont.find(`.genshin_table.skill_dmg_table:eq(${eq})`)
|
||||
let lvs = []
|
||||
let details = []
|
||||
detail.find('tr:first td').each(function (i) {
|
||||
if (onlyLv1 && i > 1) {
|
||||
return false
|
||||
}
|
||||
if (i > 0) {
|
||||
lvs.push($(this).text())
|
||||
}
|
||||
})
|
||||
detail.find('tr:gt(0)').each(function () {
|
||||
let name = $(this).find('td:eq(0)').text()
|
||||
let values = []
|
||||
let values2 = []
|
||||
let isSame = true
|
||||
let unit = ''
|
||||
$(this).find('td:gt(0)').each(function (i) {
|
||||
if (onlyLv1 && i > 0) {
|
||||
return false
|
||||
}
|
||||
let val = lodash.trim($(this).text())
|
||||
let v = val.replace(/(生命值上限|最大生命值)/, 'HP')
|
||||
v = v.replace(/(防御力)/, '防御')
|
||||
v = v.replace('元素精通', '精通')
|
||||
v = v.replace('攻击力', '攻击')
|
||||
values.push(v)
|
||||
if (i > 0 && values[0] !== val) {
|
||||
isSame = false
|
||||
}
|
||||
let ur = /^(.*)(生命值上限|防御力|最大生命值|攻击力|生命值上限 \/ 层|当前生命值| \/ 层)(\s*\*\s*\d)?$/.exec(val)
|
||||
if (ur && ur[1] && ur[2]) {
|
||||
values2.push(ur[1] + (ur[3] || ''))
|
||||
unit = ur[2]
|
||||
} else {
|
||||
ur = /^(每点元素能量|每个猫爪|每朵|每个|[12]名角色)(.*)$/.exec(val)
|
||||
if (ur && ur[1] && ur[2]) {
|
||||
values2.push(ur[2])
|
||||
unit = ur[1]
|
||||
} else {
|
||||
ur = /^(每层)(.*)(攻击力?)$/.exec(val)
|
||||
if (ur && ur[1] && ur[2] && ur[3]) {
|
||||
values2.push(ur[2])
|
||||
unit = ur[1] + ' ' + ur[3]
|
||||
} else {
|
||||
unit = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
let detail = {
|
||||
name,
|
||||
unit,
|
||||
isSame,
|
||||
values: unit ? values2 : values
|
||||
}
|
||||
if (unit === '1名角色') {
|
||||
detail.name2 = name.replace(':', '1')
|
||||
} else if (unit === '2名角色') {
|
||||
detail.name2 = name.replace(':', '2')
|
||||
}
|
||||
|
||||
details.push(detail)
|
||||
})
|
||||
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
desc,
|
||||
tables: details
|
||||
}
|
||||
},
|
||||
|
||||
// 获取天赋
|
||||
getTalents ($, cont, name, iconPath) {
|
||||
return {
|
||||
a: CharData.getTalent($, cont, `${iconPath}/talent-a`, 0),
|
||||
e: CharData.getTalent($, cont, `${iconPath}/talent-e`, 1),
|
||||
q: CharData.getTalent($, cont, `${iconPath}/talent-q`, name === '莫娜' || name === '神里绫华' ? 3 : 2)
|
||||
}
|
||||
},
|
||||
|
||||
// 获取被动天赋
|
||||
getPassive ($, cont, name, iconPath) {
|
||||
let tables = cont.find('span.delim h3:contains("Passive Skills")').parent().nextUntil('span.delim')
|
||||
let ret = []
|
||||
tables.each(function () {
|
||||
let ds = {}
|
||||
$.imgs.add(`${iconPath}/passive-${ret.length}`, $(this).find('img').attr('src'))
|
||||
ds.name = $(this).find('tr:first td:eq(1)').text()
|
||||
ds.desc = CharData.getDesc($(this).find('tr:eq(1) td:first').html())
|
||||
ret.push(ds)
|
||||
})
|
||||
if (name === '莫娜' || name === '神里绫华') {
|
||||
ret.push(CharData.getTalent($, cont, `${iconPath}/passive-${ret.length}`, 2, true))
|
||||
}
|
||||
return ret
|
||||
},
|
||||
|
||||
// 获取命座数据
|
||||
getCons ($, cont, iconPath) {
|
||||
let tables = cont.find('span.delim h3:contains("Constellations")').parent().nextAll('.skill_table')
|
||||
let ret = {}
|
||||
tables.each(function (idx) {
|
||||
let ds = {}
|
||||
$.imgs.add(`${iconPath}/cons-${idx + 1}`, $(this).find('img').attr('src'))
|
||||
ds.name = $(this).find('tr:first td:eq(1)').text()
|
||||
ds.desc = CharData.getDesc($(this).find('tr:eq(1) td:first').html())
|
||||
ret[idx + 1] = ds
|
||||
})
|
||||
return ret
|
||||
},
|
||||
|
||||
// 获取角色图片素材
|
||||
getImgs ($) {
|
||||
let urls = {}
|
||||
$('#char_gallery a>span.gallery_cont_span').each(function () {
|
||||
urls[$(this).text()] = $(this).parent().attr('href')
|
||||
})
|
||||
let img = function (title, key) {
|
||||
if (urls[title]) {
|
||||
$.imgs.add(key, urls[title])
|
||||
}
|
||||
}
|
||||
img('Icon', 'imgs/face')
|
||||
img('Side Icon', 'imgs/side')
|
||||
img('Gacha Card', 'imgs/gacha')
|
||||
img('Gacha Splash', 'imgs/splash')
|
||||
if ($._nid) {
|
||||
$.imgs.add('imgs/banner', `img/i_${$._nid}_back.webp`)
|
||||
$.imgs.add('imgs/card', `img/i_${$._nid}_profile.webp`)
|
||||
}
|
||||
},
|
||||
|
||||
// 获取命座加成天赋
|
||||
getConsTalent (talent, cons) {
|
||||
if (!talent || !cons) {
|
||||
return { e: 3, q: 5 }
|
||||
}
|
||||
let e = talent.e.name
|
||||
let q = talent.q.name
|
||||
let c3 = (cons['3']?.desc || []).join('')
|
||||
let c5 = (cons['5']?.desc || []).join('')
|
||||
return {
|
||||
e: c3.includes(e) ? 3 : 5,
|
||||
q: c5.includes(q) ? 5 : 3
|
||||
}
|
||||
},
|
||||
|
||||
// 获取素材
|
||||
getMaterials ($, mData) {
|
||||
let basic = $('.genshin_table.main_table')
|
||||
let ret = {}
|
||||
lodash.forEach([{
|
||||
title: 'Character Ascension Materials',
|
||||
keys: 'gem,gem,gem,gem,boss,specialty,normal,normal,normal',
|
||||
group: { gem: 3, normal: 8 }
|
||||
}, {
|
||||
title: 'Skill Ascension Materials',
|
||||
keys: 'talent,talent,talent,weekly',
|
||||
group: { talent: 2 }
|
||||
}], ({ title, keys, group }) => {
|
||||
let imgs = basic.find(`td:contains('${title}')`).next('td').find('a')
|
||||
keys = keys.split(',')
|
||||
let temp = {}
|
||||
imgs.each(function (idx) {
|
||||
let key = keys[idx]
|
||||
if (key) {
|
||||
let a = $(this)
|
||||
let img = $(this).find('img')
|
||||
let name = img.attr('alt')
|
||||
let idRet = /i_([n\d]+)\//.exec(a.attr('href')) || []
|
||||
let starRet = /rar_bg_(\d)/.exec(a.find('>div').attr('class'))
|
||||
let id = idRet[1] || 0
|
||||
id = id[0] === 'n' ? id : id * 1
|
||||
let star = starRet[1] * 1 || 0
|
||||
if (id) {
|
||||
$.imgs.add2(name, key, `img/i_${id}.webp`)
|
||||
} else {
|
||||
console.log('fail', a.attr('href'))
|
||||
}
|
||||
ret[key] = name
|
||||
let ds = {
|
||||
id,
|
||||
name,
|
||||
type: key,
|
||||
star
|
||||
}
|
||||
if (group[key]) {
|
||||
temp[name] = ds
|
||||
if (group[key] === idx) {
|
||||
mData[name] = {
|
||||
id,
|
||||
name,
|
||||
type: key,
|
||||
star,
|
||||
items: temp
|
||||
}
|
||||
temp = {}
|
||||
}
|
||||
} else {
|
||||
mData[name] = ds
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
return ret
|
||||
},
|
||||
getTalentData (talentData) {
|
||||
let ret = {}
|
||||
lodash.forEach(['a', 'e', 'q'], (key) => {
|
||||
let map = {}
|
||||
lodash.forEach(talentData[key].tables, (tr) => {
|
||||
if (tr.isSame) {
|
||||
return true
|
||||
}
|
||||
|
||||
lodash.forEach(tr.values, (val) => {
|
||||
// eslint-disable-next-line no-control-regex
|
||||
val = val.replace(/[^\x00-\xff]/g, '').trim()
|
||||
val = val.replace(/[a-zA-Z]/g, '').trim()
|
||||
let valArr = []
|
||||
let valArr2 = []
|
||||
lodash.forEach(val.split('/'), (v, idx) => {
|
||||
let valNum = 0
|
||||
lodash.forEach(v.split('+'), (v) => {
|
||||
v = v.split('*')
|
||||
let v1 = v[0].replace('%', '').trim()
|
||||
valNum += v1 * (v[1] || 1)
|
||||
valArr2.push(v1 * 1)
|
||||
if (v[1]) {
|
||||
valArr2.push(v[1] * 1)
|
||||
}
|
||||
})
|
||||
valArr.push(valNum)
|
||||
})
|
||||
|
||||
let name = tr.name2 || tr.name
|
||||
map[name] = map[name] || []
|
||||
if (isNaN(valArr[0])) {
|
||||
map[name].push(false)
|
||||
} else if (valArr.length === 1) {
|
||||
map[name].push(valArr[0])
|
||||
} else {
|
||||
map[name].push(valArr)
|
||||
}
|
||||
if (valArr2.length > 1) {
|
||||
map[name + '2'] = map[name + '2'] || []
|
||||
map[name + '2'].push(valArr2)
|
||||
}
|
||||
})
|
||||
})
|
||||
ret[key] = map
|
||||
})
|
||||
return ret
|
||||
}
|
||||
}
|
||||
export default CharData
|
@ -1,259 +0,0 @@
|
||||
import abbr from './abbr.js'
|
||||
import lodash from 'lodash'
|
||||
import { Data } from '#miao'
|
||||
|
||||
let costumes = {
|
||||
琴: [200301], // 琴
|
||||
芭芭拉: [201401], // 芭芭拉
|
||||
刻晴: [204201], // 刻晴
|
||||
凝光: [202701], // 凝光
|
||||
迪卢克: [201601], // 迪卢克
|
||||
菲谢尔: [203101], // 菲谢尔
|
||||
}
|
||||
const fixData = {
|
||||
4: {
|
||||
id: 20000000,
|
||||
title: '异界的旅人',
|
||||
cncv: '宴宁/鹿喑',
|
||||
jpcv: '悠木碧/堀江瞬'
|
||||
},
|
||||
5: {
|
||||
title: '异界的旅人'
|
||||
},
|
||||
7: {
|
||||
title: '异界的旅人'
|
||||
}
|
||||
}
|
||||
|
||||
const elemMap = { Water: 'hydro', Grass: 'dendro', Ice: 'cryo', Fire: 'pyro', Stone: 'geo' }
|
||||
const weaponMap = { pole: 'polearm', sword_one_hand: 'sword' }
|
||||
|
||||
const CharData = {
|
||||
getBasic (ds) {
|
||||
let fe = ds.fetter || {}
|
||||
let w = Data.regRet(/WEAPON_(.*)$/, ds.weaponType, 1).toLowerCase()
|
||||
let ret = {
|
||||
id: ds.id,
|
||||
name: ds.name,
|
||||
abbr: abbr[ds.name] || ds.name,
|
||||
title: fe.title || '',
|
||||
star: ds.rank,
|
||||
elem: elemMap[ds.element] || ds.element,
|
||||
allegiance: fe.native || '',
|
||||
weapon: weaponMap[w] || w,
|
||||
birth: ds.birthday.join('-'),
|
||||
astro: fe.constellation || '',
|
||||
desc: fe.detail || '',
|
||||
cncv: fe.cv?.CHS || '',
|
||||
jpcv: fe.cv?.JP || '',
|
||||
costume: costumes[ds.name] || false,
|
||||
source: 'amber',
|
||||
ver: 1
|
||||
}
|
||||
ret.title = ret.title === '???' ? '' : ret.title
|
||||
ret.desc = ret.desc === '???' ? '测试角色' : ret.title
|
||||
return ret
|
||||
},
|
||||
|
||||
getDetailAttr (ds) {
|
||||
return {
|
||||
details: { 90: {} }
|
||||
}
|
||||
},
|
||||
|
||||
getDetail (ds) {
|
||||
let id = ds.id
|
||||
let name = ds.name
|
||||
|
||||
let talent = CharData.getTalents(ds)
|
||||
let passive = CharData.getPassive(ds)
|
||||
let cons = CharData.getCons(ds)
|
||||
let attr = CharData.getDetailAttr(ds)
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
talent,
|
||||
cons,
|
||||
passive,
|
||||
attr
|
||||
}
|
||||
},
|
||||
|
||||
// 获取正文
|
||||
getDesc (dt) {
|
||||
dt = dt || ''
|
||||
dt = dt.replace(/<color=[^>]*>/g, '')
|
||||
dt = dt.replace(/<\/color(=?[^>])*>/g, '')
|
||||
dt = dt.replace(/<span class=[^>]*>/g, '<strong>')
|
||||
dt = dt.replace(/<\/span>/g, '</strong>')
|
||||
dt = dt.split('\\n')
|
||||
let desc = []
|
||||
let isEmpty = true
|
||||
lodash.forEach(dt, (txt, i) => {
|
||||
txt = lodash.trim(txt)
|
||||
if (!txt) {
|
||||
isEmpty = true
|
||||
return
|
||||
} else if (txt.length < 15 && isEmpty) {
|
||||
txt = `<h3>${txt}</h3>`
|
||||
}
|
||||
desc.push(txt)
|
||||
isEmpty = false
|
||||
})
|
||||
return desc
|
||||
},
|
||||
|
||||
// 获取单个天赋数据
|
||||
getTalent (ds) {
|
||||
|
||||
let name = ds.name
|
||||
let icon = ds.icon
|
||||
|
||||
// 说明
|
||||
let desc = CharData.getDesc(ds.description)
|
||||
|
||||
let ret = {}
|
||||
let titles = []
|
||||
let details = []
|
||||
|
||||
let formater = {
|
||||
F1P: (t) => (t * 100).toFixed(2) * 1 + '%',
|
||||
P: (t) => (t * 100).toFixed(2) * 1 + '%',
|
||||
F1: (t) => t.toFixed(1) * 1,
|
||||
F2: (t) => t.toFixed(2) * 1,
|
||||
I: (t) => parseInt(t)
|
||||
}
|
||||
|
||||
lodash.forEach(ds.promote, function (ds) {
|
||||
lodash.forEach(ds.description, (txt, idx) => {
|
||||
if (!txt) {
|
||||
return
|
||||
}
|
||||
let [title, tpl] = txt.split('|')
|
||||
if (!ret[title]) {
|
||||
ret[title] = []
|
||||
titles.push(title)
|
||||
}
|
||||
|
||||
let value = []
|
||||
if (tpl) {
|
||||
lodash.forEach(tpl.split('}'), (txt) => {
|
||||
if (txt.trim()) {
|
||||
let txtRet = /(.*){param(\d+):(F1P|F1|F2|I|P)/.exec(txt)
|
||||
if (txtRet) {
|
||||
let pIdx = txtRet[2] - 1
|
||||
let val = formater[txtRet[3]](ds.params[pIdx])
|
||||
value.push(txtRet[1] + val)
|
||||
} else {
|
||||
value.push(txt)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
ret[title].push(value.join(''))
|
||||
})
|
||||
})
|
||||
|
||||
lodash.forEach(titles, (name) => {
|
||||
let values = []
|
||||
let values2 = []
|
||||
let isSame = true
|
||||
let unit = ''
|
||||
|
||||
lodash.forEach(ret[name], (val, i) => {
|
||||
let v = val.replace(/(生命值上限|最大生命值)/, 'HP')
|
||||
v = v.replace('/', ' / ').replace('+', ' + ').replace('*', ' * ')
|
||||
v = v.replace(/(防御力)/, '防御')
|
||||
values.push(v)
|
||||
if (i > 0 && values[0] !== val) {
|
||||
isSame = false
|
||||
}
|
||||
let ur = /^(.*)(生命值上限|防御力|最大生命值|攻击力|生命值上限 \/ 层|当前生命值| \/ 层)(\s*\*\s*\d)?$/.exec(val)
|
||||
if (ur && ur[1] && ur[2]) {
|
||||
values2.push(ur[1] + (ur[3] || ''))
|
||||
unit = ur[2]
|
||||
} else {
|
||||
ur = /^(每点元素能量|每个猫爪|每朵|每个)(.*)$/.exec(val)
|
||||
if (ur && ur[1] && ur[2]) {
|
||||
values2.push(ur[2])
|
||||
unit = ur[1]
|
||||
} else {
|
||||
ur = /^(每层)(.*)(攻击力)$/.exec(val)
|
||||
if (ur && ur[1] && ur[2] && ur[3]) {
|
||||
values2.push(ur[2])
|
||||
unit = ur[1] + ' ' + ur[3]
|
||||
} else {
|
||||
unit = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
details.push({
|
||||
name,
|
||||
unit,
|
||||
isSame,
|
||||
values: unit ? values2 : values
|
||||
})
|
||||
})
|
||||
|
||||
return {
|
||||
name,
|
||||
desc,
|
||||
tables: details
|
||||
}
|
||||
},
|
||||
|
||||
// 获取天赋
|
||||
getTalents (ds) {
|
||||
return {
|
||||
a: CharData.getTalent(ds.talent[0]),
|
||||
e: CharData.getTalent(ds.talent[1]),
|
||||
q: CharData.getTalent(ds.talent[3])
|
||||
}
|
||||
},
|
||||
|
||||
// 获取被动天赋
|
||||
getPassive (ds) {
|
||||
let ret = []
|
||||
|
||||
for (let idx in ds.talent) {
|
||||
if (idx < 4) {
|
||||
continue
|
||||
}
|
||||
let tmp = ds.talent[idx]
|
||||
ret.push({
|
||||
name: tmp.name,
|
||||
desc: CharData.getDesc(tmp.description)
|
||||
})
|
||||
}
|
||||
return ret
|
||||
},
|
||||
|
||||
// 获取命座数据
|
||||
getCons (ds) {
|
||||
let ret = {}
|
||||
lodash.forEach(ds.constellation, (tmp, idx) => {
|
||||
ret[idx * 1 + 1] = {
|
||||
name: tmp.name,
|
||||
desc: CharData.getDesc(tmp.description)
|
||||
}
|
||||
})
|
||||
return ret;
|
||||
},
|
||||
|
||||
// 获取命座加成天赋
|
||||
getConsTalent (talent, cons) {
|
||||
if (!talent || !cons) {
|
||||
return { e: 3, q: 5 }
|
||||
}
|
||||
let e = talent.e.name
|
||||
let q = talent.q.name
|
||||
let c3 = (cons['3']?.desc || []).join('')
|
||||
let c5 = (cons['5']?.desc || []).join('')
|
||||
return {
|
||||
e: c3.includes(e) ? 3 : 5,
|
||||
q: c5.includes(q) ? 5 : 3
|
||||
}
|
||||
}
|
||||
}
|
||||
export default CharData
|
@ -1,56 +0,0 @@
|
||||
import lodash from 'lodash'
|
||||
|
||||
const CharMeta = {
|
||||
getMeta ({ $, id, name, setIdx = '', elem = '', detail = {}, attr }) {
|
||||
return {
|
||||
talent: CharMeta.getTalentMeta(detail.talent)
|
||||
}
|
||||
},
|
||||
|
||||
getTalentMeta (talentData) {
|
||||
let ret = {}
|
||||
lodash.forEach(['a', 'e', 'q'], (key) => {
|
||||
let map = {}
|
||||
lodash.forEach(talentData[key].tables, (tr) => {
|
||||
if (tr.isSame) {
|
||||
return true
|
||||
}
|
||||
|
||||
lodash.forEach(tr.values, (val) => {
|
||||
// eslint-disable-next-line no-control-regex
|
||||
val = val.replace(/[^\x00-\xff]/g, '').trim()
|
||||
val = val.replace(/[a-zA-Z]/g, '').trim()
|
||||
let valArr = []
|
||||
let valArr2 = []
|
||||
lodash.forEach(val.split('/'), (v, idx) => {
|
||||
let valNum = 0
|
||||
lodash.forEach(v.split('+'), (v) => {
|
||||
v = v.split('*')
|
||||
let v1 = v[0].replace('%', '').trim()
|
||||
valNum += v1 * (v[1] || 1)
|
||||
valArr2.push(v1 * 1)
|
||||
})
|
||||
valArr.push(valNum)
|
||||
})
|
||||
|
||||
let name = tr.name2 || tr.name
|
||||
map[name] = map[name] || []
|
||||
if (isNaN(valArr[0])) {
|
||||
map[name].push(false)
|
||||
} else if (valArr.length === 1) {
|
||||
map[name].push(valArr[0])
|
||||
} else {
|
||||
map[name].push(valArr)
|
||||
}
|
||||
if (valArr2.length > 1) {
|
||||
map[name + '2'] = map[name + '2'] || []
|
||||
map[name + '2'].push(valArr2)
|
||||
}
|
||||
})
|
||||
})
|
||||
ret[key] = map
|
||||
})
|
||||
return ret
|
||||
}
|
||||
}
|
||||
export default CharMeta
|
@ -1,59 +0,0 @@
|
||||
import fs from 'fs'
|
||||
import request from 'request'
|
||||
import { Data } from '#miao'
|
||||
import HttpsProxyAgent from 'https-proxy-agent'
|
||||
|
||||
let agent = new HttpsProxyAgent('http://localhost:4780')
|
||||
request.defaults({
|
||||
agent
|
||||
})
|
||||
|
||||
const _path = process.cwd()
|
||||
const _root = _path + '/plugins/miao-plugin/'
|
||||
const _cRoot = _root + 'resources/meta/character/'
|
||||
|
||||
export default class ImgDown {
|
||||
constructor (name) {
|
||||
this.name = name
|
||||
this.imgs = []
|
||||
}
|
||||
|
||||
add (key, url) {
|
||||
this.imgs.push({
|
||||
url,
|
||||
file: `${this.name}/${key}.webp`
|
||||
})
|
||||
}
|
||||
|
||||
add2 (name, type, url) {
|
||||
this.imgs.push({
|
||||
url,
|
||||
file: `../material/${type}/${name}.webp`
|
||||
})
|
||||
}
|
||||
|
||||
async _down (ds) {
|
||||
if (fs.existsSync(`${_cRoot}/${ds.file}`)) {
|
||||
// console.log(`已存在,跳过 ${ds.file}`)
|
||||
return true
|
||||
}
|
||||
try {
|
||||
let stream = fs.createWriteStream(`${_cRoot}/${ds.file}`)
|
||||
await request('https://genshin.honeyhunterworld.com/' + ds.url).pipe(stream)
|
||||
return new Promise((resolve) => {
|
||||
stream.on('finish', () => {
|
||||
console.log(`图像下载成功: ${ds.file}`)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(`图像下载失败: ${ds.file}`)
|
||||
console.log(e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
async download () {
|
||||
await Data.asyncPool(5, this.imgs, this._down)
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,236 +0,0 @@
|
||||
import lodash from 'lodash'
|
||||
|
||||
const WeaponData = {
|
||||
getBasic ($) {
|
||||
let ret = {}
|
||||
let basic = $('.genshin_table.main_table:first')
|
||||
let title = function (title) {
|
||||
return basic.find(`td:contains('${title}'):last`).next('td').text().trim()
|
||||
}
|
||||
ret.affixTitle = title('Weapon Affix')
|
||||
ret.star = basic.find('td:contains(\'Rarity\')').next('td').find('.cur_icon').length
|
||||
ret.desc = title('Description')
|
||||
return ret
|
||||
},
|
||||
|
||||
getDetailAttr ($) {
|
||||
// 采集属性信息
|
||||
let stat = $('.genshin_table.stat_table:first')
|
||||
let attrs = []
|
||||
let colIdxs = {}
|
||||
const titleMap = {
|
||||
HP: 'hpBase',
|
||||
Atk: 'atkBase',
|
||||
Def: 'defBase'
|
||||
}
|
||||
const bonusMap = {
|
||||
Atk: 'atkPct',
|
||||
HP: 'hpPct',
|
||||
Def: 'defPct',
|
||||
CritDMG: 'cdmg',
|
||||
CritRate: 'cpct',
|
||||
ER: 'recharge',
|
||||
EM: 'mastery',
|
||||
Geo: 'dmg',
|
||||
Hydro: 'dmg',
|
||||
Anemo: 'dmg',
|
||||
Dendro: 'dmg',
|
||||
Pyro: 'dmg',
|
||||
Cryo: 'dmg',
|
||||
Elec: 'dmg',
|
||||
Heal: 'heal',
|
||||
Phys: 'phy'
|
||||
}
|
||||
stat.find('tr:first td:lt(8)').each(function (i) {
|
||||
let title = $(this).text()
|
||||
let titleRet = /^Bonuse?\s(\w+)%*$/.exec(title)
|
||||
if (titleRet && titleRet[1]) {
|
||||
attrs.push(bonusMap[titleRet[1]] || titleRet[1])
|
||||
colIdxs[i] = bonusMap[titleRet[1]] || titleRet[1]
|
||||
} else if (titleMap[title]) {
|
||||
attrs.push(titleMap[title])
|
||||
colIdxs[i] = titleMap[title]
|
||||
}
|
||||
})
|
||||
let lvs = []
|
||||
let atkBase = {}
|
||||
let bonusAttr = {}
|
||||
stat.find('tr:gt(0)').each(function (i) {
|
||||
let tr = $(this)
|
||||
let lvl = tr.find('td:first').text()
|
||||
lvs.push(lvl)
|
||||
tr.find('td:lt(4)').each(function (i) {
|
||||
let title = colIdxs[i]
|
||||
if (!title) {
|
||||
return
|
||||
}
|
||||
if (title === 'atkBase') {
|
||||
atkBase[lvl] = $(this).text().trim('%') * 1
|
||||
} else {
|
||||
bonusAttr[lvl] = lodash.trim($(this).text(), '%') * 1
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return {
|
||||
atk: atkBase,
|
||||
bonusKey: attrs[1],
|
||||
bonusData: bonusAttr
|
||||
}
|
||||
},
|
||||
|
||||
getDetail ($, { id, name }, mData) {
|
||||
let attr = WeaponData.getDetailAttr($)
|
||||
let materials = WeaponData.getMaterials($, mData)
|
||||
let affixData = WeaponData.getAffix($, name)
|
||||
console.log(affixData)
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
...WeaponData.getBasic($),
|
||||
attr,
|
||||
materials,
|
||||
affixData
|
||||
}
|
||||
},
|
||||
|
||||
// 获取正文
|
||||
getDesc (dt) {
|
||||
dt = dt || ''
|
||||
dt = dt.replace(/<color=[^>]*>/g, '')
|
||||
dt = dt.replace(/<\/color=[^>]*>/g, '')
|
||||
dt = dt.replace(/<span class=[^>]*>/g, '<strong>')
|
||||
dt = dt.replace(/<\/span>/g, '</strong>')
|
||||
dt = dt.replace(/<[^>]*>/g, '')
|
||||
dt = dt.replace(/<\/[^>]*>/g, '')
|
||||
dt = dt.split('<br>')
|
||||
let desc = []
|
||||
let isEmpty = true
|
||||
lodash.forEach(dt, (txt, i) => {
|
||||
txt = lodash.trim(txt)
|
||||
if (!txt) {
|
||||
isEmpty = true
|
||||
return
|
||||
} else if (txt.length < 15 && isEmpty) {
|
||||
txt = `${txt}`
|
||||
}
|
||||
desc.push(txt)
|
||||
isEmpty = false
|
||||
})
|
||||
return desc
|
||||
},
|
||||
|
||||
// 获取素材
|
||||
getMaterials ($, mData) {
|
||||
let basic = $('.genshin_table.main_table')
|
||||
let ret = {}
|
||||
lodash.forEach([{
|
||||
title: 'Weapon Ascension Materials',
|
||||
keys: 'weapon,monster,normal,weapon,monster,normal,weapon,monster,normal,weapon',
|
||||
group: { weapon: 9, monster: 7, normal: 8 }
|
||||
}], ({ title, keys, group }) => {
|
||||
let imgs = basic.find(`td:contains('${title}')`).next('td').find('a')
|
||||
keys = keys.split(',')
|
||||
let temp = {}
|
||||
imgs.each(function (idx) {
|
||||
let key = keys[idx]
|
||||
if (key) {
|
||||
let a = $(this)
|
||||
let img = $(this).find('img')
|
||||
let name = img.attr('alt')
|
||||
let idRet = /i_([n\d]+)\//.exec(a.attr('href')) || []
|
||||
let starRet = /rar_bg_(\d)/.exec(a.find('>div').attr('class'))
|
||||
let id = idRet[1] || 0
|
||||
id = (id[0] === 'n' ? id.replace(/^n/, '') : id) * 1
|
||||
let star = starRet[1] * 1 || 0
|
||||
if (id) {
|
||||
$.imgs.add2(name, key, `img/i_n${id}.webp`)
|
||||
} else {
|
||||
console.log('fail', a.attr('href'))
|
||||
}
|
||||
ret[key] = name
|
||||
let ds = {
|
||||
id,
|
||||
name,
|
||||
type: key,
|
||||
star
|
||||
}
|
||||
if (group[key]) {
|
||||
temp[key] = temp[key] || {}
|
||||
temp[key][name] = ds
|
||||
if (group[key] === idx) {
|
||||
mData[name] = {
|
||||
id,
|
||||
name,
|
||||
type: key,
|
||||
star,
|
||||
items: temp[key]
|
||||
}
|
||||
temp[key] = {}
|
||||
}
|
||||
} else {
|
||||
mData[name] = ds
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
return ret
|
||||
},
|
||||
getAffix ($, name) {
|
||||
let affix = {}
|
||||
let cont = $('.genshin_table.affix_table tr:gt(0)')
|
||||
cont.each(function () {
|
||||
let tr = $(this)
|
||||
affix[tr.find('td:first').text()] = WeaponData.getDesc(tr.find('td:eq(1)').text()).join('')
|
||||
})
|
||||
if (name === '白铁大剑') {
|
||||
console.log(affix)
|
||||
}
|
||||
let tmpl = []
|
||||
lodash.forEach(affix, (txt) => {
|
||||
let tpls = txt.match(/([^\d]+)([/\d% \\.]+|$)/g)
|
||||
lodash.forEach(tpls, (tpl, idx) => {
|
||||
let test = /^([^\d/%]+)([/\d% \\.]*)$/.exec(tpl)
|
||||
if (test) {
|
||||
if (!tmpl[idx]) {
|
||||
tmpl[idx] = {
|
||||
txt: test[1],
|
||||
data: [test[2]]
|
||||
}
|
||||
} else {
|
||||
if (test[1] !== tmpl[idx].txt) {
|
||||
console.log('error:', tmpl[idx].txt, test[1], tpl)
|
||||
}
|
||||
tmpl[idx].data.push(test[2])
|
||||
}
|
||||
} else {
|
||||
console.log('error')
|
||||
}
|
||||
})
|
||||
})
|
||||
let tpls = []
|
||||
let datas = {}
|
||||
let idx = 0
|
||||
lodash.forEach(tmpl, (ds) => {
|
||||
let { txt, data } = ds
|
||||
let isSame = true
|
||||
for (let v of data) {
|
||||
if (v !== data[0]) {
|
||||
isSame = false
|
||||
}
|
||||
}
|
||||
if (isSame) {
|
||||
tpls.push(`${txt}${data[0]}`)
|
||||
} else {
|
||||
tpls.push(`${txt}$[${idx}]`)
|
||||
datas[idx] = data
|
||||
idx++
|
||||
}
|
||||
})
|
||||
return {
|
||||
text: tpls.join(''),
|
||||
datas
|
||||
}
|
||||
}
|
||||
}
|
||||
export default WeaponData
|
@ -1,14 +0,0 @@
|
||||
export default {
|
||||
达达利亚: '公子',
|
||||
神里绫华: '绫华',
|
||||
神里绫人: '绫人',
|
||||
枫原万叶: '万叶',
|
||||
雷电将军: '雷神',
|
||||
珊瑚宫心海: '心海',
|
||||
荒泷一斗: '一斗',
|
||||
八重神子: '八重',
|
||||
九条裟罗: '九条',
|
||||
罗莎莉亚: '罗莎',
|
||||
鹿野院平藏: '平藏',
|
||||
艾尔海森: '海森'
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
export default {
|
||||
4: {
|
||||
id: 20000000,
|
||||
title: '异界的旅人',
|
||||
cncv: '宴宁/鹿喑',
|
||||
jpcv: '悠木碧/堀江瞬'
|
||||
},
|
||||
5: {
|
||||
title: '异界的旅人'
|
||||
},
|
||||
7: {
|
||||
title: '异界的旅人'
|
||||
},
|
||||
73: {
|
||||
title: '白草净华'
|
||||
},
|
||||
74: {
|
||||
title: '绮思晚星'
|
||||
}
|
||||
}
|
@ -1,152 +0,0 @@
|
||||
import fetch from 'node-fetch'
|
||||
import cheerio from 'cheerio'
|
||||
import lodash from 'lodash'
|
||||
import { Data } from '#miao'
|
||||
import fs from 'fs'
|
||||
import request from 'request'
|
||||
import WeaponData from './sprider/WeaponData.js'
|
||||
import ImgDownloader from './sprider/ImgDown.js'
|
||||
|
||||
let ret = {}
|
||||
const types = ['sword', 'claymore', 'polearm', 'bow', 'catalyst']
|
||||
for (let type of types) {
|
||||
ret[type] = Data.readJSON(`resources/meta/weapon/${type}/data.json`, 'miao')
|
||||
}
|
||||
|
||||
let mData = Data.readJSON('resources/meta/material/data.json', 'miao')
|
||||
let weaponIdMap = Data.readJSON('tools/meta/weapon.json', 'miao')
|
||||
|
||||
let getWeaponTypeData = async function (type) {
|
||||
let url = `https://genshin.honeyhunterworld.com/fam_${type}/?lang=CHS`
|
||||
console.log('req: ' + url)
|
||||
let req = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.20',
|
||||
referer: 'https://genshin.honeyhunterworld.com/fam_chars/?lang=CHS',
|
||||
'sec-ch-ua': '"Microsoft Edge";v = "105", " Not;A Brand";v = "99", "Chromium";v = "105"',
|
||||
'sec-ch-ua-mobile': '?0',
|
||||
'sec-ch-ua-platform': 'Windows',
|
||||
'sec-fetch-dest': 'document',
|
||||
'sec-fetch-mode': 'navigate',
|
||||
'sec-fetch-site': 'none',
|
||||
'sec-fetch-user': '?1',
|
||||
'upgrade-insecure-requests': 1
|
||||
}
|
||||
})
|
||||
let txt = await req.text()
|
||||
let sTxt = /sortable_data.push\((\[.*?\])[\n\s]*\)/.exec(txt)
|
||||
console.log('1', sTxt[1])
|
||||
if (sTxt && sTxt[1]) {
|
||||
let tmp = eval(sTxt[1])
|
||||
|
||||
lodash.forEach(tmp, (ds) => {
|
||||
let a = cheerio.load(ds[1])('a')
|
||||
let name = a.text()
|
||||
console.log(a.attr('href'))
|
||||
let idRet = /i_(.*)\//.exec(a.attr('href'))
|
||||
let star = cheerio.load(ds[2])('img').length
|
||||
let wid = idRet && idRet[1] ? idRet[1] : ''
|
||||
ret[type] = ret[type] || {}
|
||||
let tmp = {
|
||||
id: weaponIdMap[name] || '',
|
||||
name,
|
||||
star
|
||||
}
|
||||
if (wid !== 'n' + tmp.id) {
|
||||
tmp.wid = wid
|
||||
}
|
||||
console.log(tmp)
|
||||
ret[type][name] = tmp
|
||||
})
|
||||
}
|
||||
}
|
||||
let getWeaponData = async function (type, ds) {
|
||||
let { id, name } = ds
|
||||
let url = `https://genshin.honeyhunterworld.com/i_n${id}/?lang=CHS`
|
||||
console.log(`req:[${name}], ${url}`)
|
||||
let req = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.20',
|
||||
referer: 'https://genshin.honeyhunterworld.com/fam_chars/?lang=CHS',
|
||||
'sec-ch-ua': '"Microsoft Edge";v = "105", " Not;A Brand";v = "99", "Chromium";v = "105"',
|
||||
'sec-ch-ua-mobile': '?0',
|
||||
'sec-ch-ua-platform': 'Windows',
|
||||
'sec-fetch-dest': 'document',
|
||||
'sec-fetch-mode': 'navigate',
|
||||
'sec-fetch-site': 'none',
|
||||
'sec-fetch-user': '?1',
|
||||
'upgrade-insecure-requests': 1
|
||||
}
|
||||
})
|
||||
let txt = await req.text()
|
||||
let $ = cheerio.load(txt)
|
||||
let imgs = new ImgDownloader(name)
|
||||
$.imgs = imgs
|
||||
let ret = WeaponData.getDetail($, ds, mData)
|
||||
await $.imgs.download()
|
||||
return ret
|
||||
}
|
||||
|
||||
async function down (t, n) {
|
||||
for (let type of types) {
|
||||
if (type !== t) {
|
||||
continue
|
||||
}
|
||||
await getWeaponTypeData(type)
|
||||
Data.createDir(`resources/meta/weapon/${type}`, 'miao')
|
||||
Data.writeJSON({ name: `resources/meta/weapon/${type}/data.json`, data: ret[type], rn: true, root: 'miao' })
|
||||
|
||||
let imgs = []
|
||||
await Data.asyncPool(6, lodash.keys(ret[type]), async (name) => {
|
||||
if (n && n !== name) {
|
||||
return
|
||||
}
|
||||
let ds = ret[type][name]
|
||||
Data.createDir(`resources/meta/weapon/${type}/${ds.name}`, 'miao')
|
||||
let data = await getWeaponData(type, ds)
|
||||
Data.writeJSON({ name: `resources/meta/weapon/${type}/${ds.name}/data.json`, data, rn: true, root: 'miao' })
|
||||
lodash.forEach({
|
||||
icon: '',
|
||||
awaken: '_awaken_icon',
|
||||
gacha: '_gacha_icon'
|
||||
}, (affix, key) => {
|
||||
imgs.push({
|
||||
url: `img/i_${ds.id}${affix}.webp`,
|
||||
file: `${type}/${ds.name}/${key}.webp`
|
||||
})
|
||||
})
|
||||
})
|
||||
const _path = process.cwd()
|
||||
const _root = _path + '/plugins/miao-plugin/'
|
||||
const _wRoot = _root + 'resources/meta/weapon/'
|
||||
await Data.asyncPool(5, imgs, async function (ds) {
|
||||
if (fs.existsSync(`${_wRoot}/${ds.file}`)) {
|
||||
// console.log(`已存在,跳过 ${ds.file}`)
|
||||
return true
|
||||
}
|
||||
|
||||
try {
|
||||
let stream = fs.createWriteStream(`${_wRoot}/${ds.file}.tmp`)
|
||||
await request('https://genshin.honeyhunterworld.com/' + ds.url).pipe(stream)
|
||||
return new Promise((resolve) => {
|
||||
stream.on('finish', () => {
|
||||
fs.rename(`${_wRoot}/${ds.file}.tmp`, `${_wRoot}/${ds.file}`, () => {
|
||||
console.log(`图像下载成功: ${ds.file}`)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(`图像下载失败: ${ds.file}`)
|
||||
console.log(e)
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
Data.writeJSON({ name: 'resources/meta/material/data.json', data: mData, rn: true, root: 'miao' })
|
||||
}
|
||||
|
||||
// 'sword', 'claymore', 'polearm', 'bow', 'catalyst'
|
||||
await down('catalyst', '')
|
Loading…
Reference in New Issue
Block a user