mirror of
https://github.com/earthjasonlin/zzz-signal-search-export.git
synced 2025-04-11 19:20:19 +08:00
Compare commits
28 Commits
v1.0.9
...
16e01b7a13
Author | SHA1 | Date | |
---|---|---|---|
16e01b7a13
|
|||
8f492376a0
|
|||
0642c52db2
|
|||
af256fba7d
|
|||
6599fbe6d3
|
|||
a99959e6e5
|
|||
c9c92da926
|
|||
fcff120657
|
|||
0ec7cb7c4f
|
|||
5a3159d4cb
|
|||
38b99bf4dc
|
|||
0cd9c071d7
|
|||
bf582d0194
|
|||
5dec6a8273
|
|||
0e429a4762
|
|||
5164a17dca
|
|||
a660c03bb5
|
|||
d7457f2bfb
|
|||
223ab899e0
|
|||
f62ca1d7e7
|
|||
c034b2e70a
|
|||
a2faa86f0c
|
|||
510bfdab7a
|
|||
f616944755
|
|||
7300c6e719
|
|||
6fe12da9be
|
|||
14cfda3986
|
|||
8156b5a9b7
|
@ -2,7 +2,7 @@ const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const crypto = require('crypto')
|
||||
const AdmZip = require('adm-zip')
|
||||
const { version } = require('../package.json')
|
||||
const { version, autoUpdateActive, autoUpdateFrom } = require('../package.json')
|
||||
|
||||
const hash = (data, type = 'sha256') => {
|
||||
const hmac = crypto.createHmac(type, 'nap')
|
||||
@ -32,9 +32,9 @@ const start = async () => {
|
||||
await fs.copy(zipPath, path.resolve(outputPath, `${hashName}.zip`))
|
||||
await fs.remove(zipPath)
|
||||
await fs.outputJSON(path.join(outputPath, 'manifest.json'), {
|
||||
active: true,
|
||||
version,
|
||||
from: '0.0.1',
|
||||
active: autoUpdateActive,
|
||||
version: version,
|
||||
from: autoUpdateFrom,
|
||||
name: `${hashName}.zip`,
|
||||
hash: sha256
|
||||
})
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
一个使用 Electron 制作的小工具,需要在 Windows 操作系统上运行。
|
||||
|
||||
通过读取游戏日志或者代理模式获取访问游戏跃迁记录 API 所需的 authKey,然后再使用获取到的 authKey 来读取游戏跃迁记录。
|
||||
通过读取游戏日志或者代理模式获取访问游戏调频记录 API 所需的 authKey,然后再使用获取到的 authKey 来读取游戏调频记录。
|
||||
|
||||
## 其它语言
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
## 使用说明
|
||||
|
||||
1. 下载工具后解压 - 下载地址: [GitHub](https://github.com/earthjasonlin/zzz-signal-search-export/releases/latest/download/ZzzSignalSearchExport.zip) / [123云盘](https://www.123pan.com/s/Vs9uVv-ShhE.html) / [蓝奏云(密码:zzzz)](https://www.lanzouh.com/b00eewtvxa)
|
||||
2. 打开游戏的跃迁详情页面
|
||||
2. 打开游戏的调频详情页面
|
||||
|
||||

|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
|
||||
如果需要导出多个账号的数据,可以点击旁边的加号按钮。
|
||||
|
||||
然后游戏切换的新账号,再打开跃迁历史记录,工具再点击“加载数据”按钮。
|
||||
然后游戏切换的新账号,再打开调频历史记录,工具再点击“加载数据”按钮。
|
||||
|
||||
## Devlopment
|
||||
|
||||
|
@ -6,7 +6,7 @@ This project is modified from the [star-rail-warp-export](https://github.com/biu
|
||||
|
||||
A tool made from Electron that runs on the Windows operating system.
|
||||
|
||||
Read the game log or proxy to get the authKey needed to access the game warp history API, and then use the authKey to read the game wish history.
|
||||
Read the game log or proxy to get the authKey needed to access the game signal search history API, and then use the authKey to read the game wish history.
|
||||
|
||||
## Other languages
|
||||
|
||||
@ -18,7 +18,7 @@ If you feel that the existing translation is inappropriate, you can send a pull
|
||||
|
||||
1. Unzip after downloading the tool - [GitHub](https://github.com/earthjasonlin/zzz-signal-search-export/releases/latest/download/ZzzSignalSearchExport.zip)
|
||||
|
||||
2. Open the warp details page of the game
|
||||
2. Open the signal search details page of the game
|
||||
|
||||

|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
{
|
||||
"name": "zzz-signal-search-export",
|
||||
"version": "1.0.9",
|
||||
"version": "1.1.10",
|
||||
"autoUpdateActive": true,
|
||||
"autoUpdateFrom": "1.1.0",
|
||||
"main": "./dist/electron/main/main.js",
|
||||
"author": "earthjasonlin <https://git.loliquq.cn/earthjasonlin>",
|
||||
"homepage": "https://github.com/earthjasonlin/zzz-signal-search-export",
|
||||
@ -108,7 +110,7 @@
|
||||
"tailwindcss": "^3.0.16",
|
||||
"vite": "2.7.13",
|
||||
"vue": "^3.2.29",
|
||||
"winreg": "^1.2.4",
|
||||
"winreg": "1.2.4",
|
||||
"yauzl": "^2.10.0"
|
||||
},
|
||||
"keywords": [
|
||||
|
@ -3,9 +3,10 @@
|
||||
"ui.button.load": "Load data",
|
||||
"ui.button.update": "Update",
|
||||
"ui.button.directUpdate": "Direct update",
|
||||
"ui.button.files": "Export Files",
|
||||
"ui.button.files": "Import/Export",
|
||||
"ui.button.excel": "Export Excel",
|
||||
"ui.button.uigf": "Export UIGF (Beta)",
|
||||
"ui.button.uigf": "Export UIGF",
|
||||
"ui.button.import": "Import UIGF",
|
||||
"ui.button.url": "Input URL",
|
||||
"ui.button.setting": "Settings",
|
||||
"ui.button.option": "Option",
|
||||
@ -56,6 +57,7 @@
|
||||
"ui.setting.fetchFullHistoryHint": "When this option is enabled, click the \"Update Data\" button to get all the card draw records within 6 months. When there are incorrect data within 6 months, this function can be used to repair.",
|
||||
"ui.setting.closeProxy": "Disable system proxy",
|
||||
"ui.setting.closeProxyHint": "When you choose proxy mode, if the program crashes it can cause unwanted results that may affect your system. You can click this button to clear the system proxy settings.",
|
||||
"ui.setting.idVersion": "ID database version",
|
||||
"ui.about.title": "About",
|
||||
"ui.about.license": "This software is opensource using MIT license.",
|
||||
"ui.urlDialog.title": "Input URL manually",
|
||||
|
@ -3,9 +3,10 @@
|
||||
"ui.button.load": "加载数据",
|
||||
"ui.button.update": "更新数据",
|
||||
"ui.button.directUpdate": "直接更新",
|
||||
"ui.button.files": "导出文件",
|
||||
"ui.button.files": "导入/导出",
|
||||
"ui.button.excel": "导出Excel",
|
||||
"ui.button.uigf":"导出UIGF (Beta)",
|
||||
"ui.button.uigf":"导出UIGF",
|
||||
"ui.button.import":"导入UIGF",
|
||||
"ui.button.url": "输入URL",
|
||||
"ui.button.setting": "设置",
|
||||
"ui.button.option": "选项",
|
||||
@ -55,6 +56,7 @@
|
||||
"ui.setting.fetchFullHistoryHint": "开启时点击“更新数据”按钮会完整获取6个月内所有的抽卡记录,当记录里有6个月范围以内的错误数据时可以通过这个功能修复。",
|
||||
"ui.setting.closeProxy": "关闭系统代理",
|
||||
"ui.setting.closeProxyHint": "如果使用过代理模式时工具非正常关闭,可能导致系统代理设置没能清除,可以通过这个按钮来清除设置过的系统代理。",
|
||||
"ui.setting.idVersion": "ID 数据库版本",
|
||||
"ui.about.title": "关于",
|
||||
"ui.about.license": "本工具为开源软件,源代码使用 MIT 协议授权",
|
||||
"ui.urlDialog.title": "手动输入URL",
|
||||
|
@ -3,9 +3,10 @@
|
||||
"ui.button.load": "加載數據",
|
||||
"ui.button.update": "更新數據",
|
||||
"ui.button.directUpdate": "直接更新",
|
||||
"ui.button.files": "導出文件",
|
||||
"ui.button.files": "導入/匯出",
|
||||
"ui.button.excel": "導出Excel",
|
||||
"ui.button.uigf":"導出UIGF (Beta)",
|
||||
"ui.button.uigf":"導出UIGF",
|
||||
"ui.button.import":"導入UIGF",
|
||||
"ui.button.url": "輸入URL",
|
||||
"ui.button.setting": "設置",
|
||||
"ui.button.option": "選項",
|
||||
@ -54,6 +55,7 @@
|
||||
"ui.setting.fetchFullHistoryHint": "開啟時點擊「更新數據」按鈕會完整獲取6個月內所有的抽卡記錄,當記錄裏有6個月範圍以內的錯誤數據時可以通過這個功能修復。",
|
||||
"ui.setting.closeProxy": "關閉系統代理",
|
||||
"ui.setting.closeProxyHint": "如果使用過代理模式時工具非正常關閉,可能導致系統代理設置沒能清除,可以通過這個按鈕來清除設置過的系統代理。",
|
||||
"ui.setting.idVersion": "ID 數據庫版本",
|
||||
"ui.about.title": "關於",
|
||||
"ui.about.license": "本工具為開源軟件,源代碼使用 MIT 協議授權",
|
||||
"ui.urlDialog.title": "手動輸入URL",
|
||||
|
2838
src/idJson.json
Normal file
2838
src/idJson.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,13 @@
|
||||
const { app, ipcMain, dialog } = require('electron')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const getData = require('./getData').getData
|
||||
const { getData, saveData, changeCurrent, convertTimeZone } = require('./getData')
|
||||
const config = require('./config')
|
||||
const { name, version } = require('../../package.json')
|
||||
const i18n = require('./i18n')
|
||||
const { exit } = require('process')
|
||||
const { mergeData } = require('./utils/mergeData')
|
||||
const { sendMsg } = require('./utils')
|
||||
const idJson = require('../idJson.json')
|
||||
|
||||
const getTimeString = () => {
|
||||
return new Date().toLocaleString('sv').replace(/[- :]/g, '').slice(0, -2)
|
||||
@ -16,8 +19,7 @@ const formatDate = (date) => {
|
||||
let d = `${date.getDate()}`.padStart(2, '0')
|
||||
return `${y}-${m}-${d} ${date.toLocaleString('zh-cn', { hour12: false }).slice(-8)}`
|
||||
}
|
||||
|
||||
const start = async (uids) => {
|
||||
const exportUIGF = async (uids) => {
|
||||
const result = {
|
||||
info: {
|
||||
export_timestamp: Math.ceil(Date.now() / 1000),
|
||||
@ -35,15 +37,7 @@ const start = async (uids) => {
|
||||
if (!fulldata.length) {
|
||||
throw new Error('数据为空')
|
||||
}
|
||||
const serverTimeZone = new Map([
|
||||
["prod_gf_cn", 8]
|
||||
])
|
||||
fulldata.forEach(data => {
|
||||
let timezone
|
||||
timezone = serverTimeZone.get(data.region)
|
||||
if(!timezone) {
|
||||
throw new Error('不支持此服务器')
|
||||
}
|
||||
const listTemp = []
|
||||
for (let [type, arr] of data.result) {
|
||||
arr.forEach(log => {
|
||||
@ -63,7 +57,7 @@ const start = async (uids) => {
|
||||
listTemp.sort((a, b) => Number(BigInt(a.id) - BigInt(b.id)))
|
||||
let dataTemp = {
|
||||
uid: data.uid,
|
||||
timezone: timezone,
|
||||
timezone: data.region_time_zone,
|
||||
lang: data.lang,
|
||||
list: []
|
||||
}
|
||||
@ -86,6 +80,95 @@ const start = async (uids) => {
|
||||
}
|
||||
}
|
||||
|
||||
const importUIGF = async () => {
|
||||
const filepath = await dialog.showOpenDialogSync({
|
||||
properties: ['openFile'],
|
||||
filters: [
|
||||
{ name: i18n.uigf.fileType, extensions: ['json'] }
|
||||
]
|
||||
})
|
||||
if (!filepath) return
|
||||
const { dataMap, current } = await getData()
|
||||
try {
|
||||
const jsonData = fs.readJsonSync(filepath[0])
|
||||
if('info' in jsonData && 'version' in jsonData.info) {
|
||||
if (jsonData.info.version !== 'v4.0') {
|
||||
sendMsg('不支持此版本UIGF')
|
||||
console.error('不支持此版本UIGF')
|
||||
return
|
||||
}
|
||||
} else {
|
||||
sendMsg('UIGF格式错误')
|
||||
console.error('UIGF格式错误')
|
||||
return
|
||||
}
|
||||
jsonData.nap.forEach(uidData => {
|
||||
const resultTemp = []
|
||||
const isNew = !Boolean(dataMap.has(uidData.uid))
|
||||
|
||||
let region_time_zone
|
||||
if (!isNew) region_time_zone = dataMap.get(uidData.uid).region_time_zone
|
||||
else region_time_zone = uidData.timezone
|
||||
|
||||
let targetLang
|
||||
if (!isNew) targetLang = dataMap.get(uidData.uid).lang
|
||||
else targetLang = uidData.lang
|
||||
if(!idJson[targetLang] && (!uidData.list[0].name || !uidData.list[0].item_type || !uidData.list[0].rank_type)) targetLang = config.lang
|
||||
|
||||
let idTargetLangJson = idJson[targetLang]
|
||||
|
||||
uidData.list.forEach(recordEntry => {
|
||||
let rank_type
|
||||
if (idTargetLangJson?.[recordEntry.item_id].rank_type) rank_type = String(idTargetLangJson[recordEntry.item_id].rank_type)
|
||||
else rank_type = recordEntry.rank_type
|
||||
resultTemp.push({
|
||||
gacha_id: recordEntry.gacha_id,
|
||||
gacha_type: recordEntry.gacha_type,
|
||||
item_id: recordEntry.item_id,
|
||||
count: recordEntry.count ?? "1",
|
||||
time: convertTimeZone(recordEntry.time, uidData.timezone, region_time_zone),
|
||||
name: idTargetLangJson?.[recordEntry.item_id].name ?? recordEntry.name,
|
||||
item_type: idTargetLangJson?.[recordEntry.item_id].item_type ?? recordEntry.item_type,
|
||||
rank_type: rank_type,
|
||||
id: recordEntry.id
|
||||
})
|
||||
})
|
||||
|
||||
const resultTempGrouped = resultTemp.reduce((acc, curr) => {
|
||||
if (!acc[curr.gacha_type]) {
|
||||
acc[curr.gacha_type] = []
|
||||
}
|
||||
acc[curr.gacha_type].push(curr)
|
||||
return acc;
|
||||
}, {})
|
||||
const resultTempMap = new Map(Object.entries(resultTempGrouped))
|
||||
const resultMap = { result: resultTempMap, uid: uidData.uid}
|
||||
let data
|
||||
const mergedData = mergeData(dataMap.get(uidData.uid), resultMap)
|
||||
if (isNew) {
|
||||
data = { result: mergedData, time: Date.now(), uid: uidData.uid, lang: targetLang, region_time_zone: uidData.timezone, deleted: false }
|
||||
} else {
|
||||
data = { result: mergedData, time: Date.now(), uid: dataMap.get(uidData.uid).uid, lang: targetLang, region_time_zone: dataMap.get(uidData.uid).region_time_zone, deleted: dataMap.get(uidData.uid).deleted }
|
||||
}
|
||||
|
||||
saveData(data, '')
|
||||
changeCurrent(uidData.uid)
|
||||
dataMap.set(uidData.uid, data)
|
||||
})
|
||||
return {
|
||||
dataMap,
|
||||
current: config.current
|
||||
}
|
||||
} catch (error) {
|
||||
sendMsg(error, 'ERROR')
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
ipcMain.handle('EXPORT_UIGF_JSON', async (event, uids) => {
|
||||
await start(uids)
|
||||
await exportUIGF(uids)
|
||||
})
|
||||
|
||||
ipcMain.handle('IMPORT_UIGF_JSON', async () => {
|
||||
return await importUIGF()
|
||||
})
|
@ -29,6 +29,27 @@ const defaultTypeMap = new Map([
|
||||
['5', '邦布频段']
|
||||
])
|
||||
|
||||
const serverTimeZone = new Map([
|
||||
["prod_gf_cn", 8],
|
||||
["prod_gf_jp", 8],
|
||||
["prod_gf_us", -5],
|
||||
["prod_gf_eu", 1],
|
||||
["prod_gf_sg", 8]
|
||||
])
|
||||
|
||||
const convertTimeZone = (dateTimeStr, fromTimeZoneOffset, toTimeZoneOffset) => {
|
||||
let date = new Date(dateTimeStr.replace(' ', 'T') + 'Z');
|
||||
let utcDate = new Date(date.getTime() - fromTimeZoneOffset * 60 * 60 * 1000);
|
||||
let targetDate = new Date(utcDate.getTime() + toTimeZoneOffset * 60 * 60 * 1000);
|
||||
let year = targetDate.getUTCFullYear();
|
||||
let month = String(targetDate.getUTCMonth() + 1).padStart(2, '0');
|
||||
let day = String(targetDate.getUTCDate()).padStart(2, '0');
|
||||
let hours = String(targetDate.getUTCHours()).padStart(2, '0');
|
||||
let minutes = String(targetDate.getUTCMinutes()).padStart(2, '0');
|
||||
let seconds = String(targetDate.getUTCSeconds()).padStart(2, '0');
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
}
|
||||
|
||||
const findDataFiles = async (dataPath, fileMap) => {
|
||||
const files = await readdir(dataPath)
|
||||
if (files?.length) {
|
||||
@ -93,7 +114,7 @@ const changeCurrent = async (uid) => {
|
||||
const detectGameLocale = async (userPath) => {
|
||||
let list = []
|
||||
const lang = app.getLocale()
|
||||
const arr = ['/miHoYo/绝区零/', '/Cognosphere/Zenless Zone Zero/']
|
||||
const arr = ['/miHoYo/绝区零/', '/miHoYo/ZenlessZoneZero/']
|
||||
arr.forEach(str => {
|
||||
try {
|
||||
const pathname = path.join(userPath, '/AppData/LocalLow/', str, 'Player.log')
|
||||
@ -203,7 +224,6 @@ const getGachaLogs = async ({ name, key }, queryString) => {
|
||||
let logs = []
|
||||
let uid = ''
|
||||
let region = ''
|
||||
let region_time_zone = ''
|
||||
let endId = '0'
|
||||
const url = `${apiDomain}/common/gacha_record/api/getGachaLog?${queryString}`
|
||||
do {
|
||||
@ -221,9 +241,6 @@ const getGachaLogs = async ({ name, key }, queryString) => {
|
||||
if (!region) {
|
||||
region = res.region
|
||||
}
|
||||
if (!region_time_zone) {
|
||||
region_time_zone = res.region_time_zone
|
||||
}
|
||||
list.push(...logs)
|
||||
page += 1
|
||||
|
||||
@ -252,7 +269,7 @@ const getGachaLogs = async ({ name, key }, queryString) => {
|
||||
}
|
||||
}
|
||||
} while (logs.length > 0)
|
||||
return { list, uid, region, region_time_zone }
|
||||
return { list, uid, region }
|
||||
}
|
||||
|
||||
const checkResStatus = (res) => {
|
||||
@ -425,10 +442,25 @@ const fetchData = async (urlOverride) => {
|
||||
const typeMap = new Map()
|
||||
const lang = searchParams.get('lang')
|
||||
let originUid = ''
|
||||
let originRegion = ''
|
||||
let originTimeZone = ''
|
||||
let localTimeZone
|
||||
for (const type of gachaType) {
|
||||
const { list, uid, region, region_time_zone } = await getGachaLogs(type, queryString)
|
||||
const { list, uid, region} = await getGachaLogs(type, queryString)
|
||||
const region_time_zone = serverTimeZone.get(region)
|
||||
if(!region_time_zone) {
|
||||
sendMsg('不支持此服务器')
|
||||
console.error('不支持此服务器')
|
||||
return
|
||||
}
|
||||
if (localTimeZone === undefined) {
|
||||
localTimeZone = dataMap.get(uid)?.region_time_zone
|
||||
if (localTimeZone === undefined) {
|
||||
localTimeZone = region_time_zone
|
||||
}
|
||||
}
|
||||
localTimeZone === Number(localTimeZone)
|
||||
list.forEach(item => {
|
||||
item.time = convertTimeZone(item.time, region_time_zone, localTimeZone)
|
||||
})
|
||||
const logs = list.map((item) => {
|
||||
const { id, item_id, item_type, name, rank_type, time, gacha_id, gacha_type, count} = item
|
||||
return { id, item_id, item_type, name, rank_type, time, gacha_id, gacha_type, count }
|
||||
@ -439,14 +471,8 @@ const fetchData = async (urlOverride) => {
|
||||
if (!originUid) {
|
||||
originUid = uid
|
||||
}
|
||||
if (!originRegion) {
|
||||
originRegion = region
|
||||
}
|
||||
if (!originTimeZone) {
|
||||
originTimeZone = region_time_zone
|
||||
}
|
||||
}
|
||||
const data = { result, typeMap, time: Date.now(), uid: originUid, lang, region: originRegion, region_time_zone: originTimeZone }
|
||||
const data = { result, typeMap, time: Date.now(), uid: originUid, lang, region_time_zone: localTimeZone }
|
||||
const localData = dataMap.get(originUid)
|
||||
const mergedResult = mergeData(localData, data)
|
||||
data.result = mergedResult
|
||||
@ -527,5 +553,9 @@ exports.getData = () => {
|
||||
}
|
||||
}
|
||||
|
||||
exports.serverTimeZone = serverTimeZone
|
||||
exports.getUrl = getUrl
|
||||
exports.deleteData = deleteData
|
||||
exports.saveData = saveData
|
||||
exports.changeCurrent = changeCurrent
|
||||
exports.convertTimeZone = convertTimeZone
|
@ -12,6 +12,7 @@
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="excel">{{ui.button.excel}}</el-dropdown-item>
|
||||
<el-dropdown-item command="uigf-json">{{ui.button.uigf}}</el-dropdown-item>
|
||||
<el-dropdown-item command="import-json" divided>{{ui.button.import}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
@ -272,11 +273,25 @@ const exportUIGFJSON = () => {
|
||||
});
|
||||
}
|
||||
|
||||
const importData = async () => {
|
||||
state.status = 'loading'
|
||||
const data = await ipcRenderer.invoke('IMPORT_UIGF_JSON')
|
||||
if (data) {
|
||||
state.dataMap = data.dataMap
|
||||
state.current = data.current
|
||||
state.status = 'loaded'
|
||||
} else {
|
||||
state.status = 'failed'
|
||||
}
|
||||
}
|
||||
|
||||
const exportCommand = (type) => {
|
||||
if (type === 'excel') {
|
||||
saveExcel()
|
||||
} else if (type === 'uigf-json') {
|
||||
exportUIGFJSON()
|
||||
} else if (type === 'import-json') {
|
||||
importData()
|
||||
}
|
||||
}
|
||||
const openCacheFolder = async () => {
|
||||
|
@ -32,7 +32,7 @@ const props = defineProps({
|
||||
|
||||
const chart = ref(null);
|
||||
|
||||
const colors = ["#eeaa66", "#fac858", "#ee6666", "#5470c6", "#ba66ee", "#91cc75", "#73c0de"];
|
||||
const colors = ["#fac858", "#fac858", "#ee6666", "#5470c6", "#5470c6", "#91cc75", "#73c0de"];
|
||||
|
||||
const parseData = (detail, type) => {
|
||||
const text = props.i18n.ui.data;
|
||||
|
@ -47,6 +47,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<h3 class="text-lg my-4">{{about.title}}</h3>
|
||||
<p class="text-gray-600 text-xs mt-1">{{text.idVersion}} {{idJson.version}}</p>
|
||||
<p class="text-gray-600 text-xs mt-1">{{about.license}}</p>
|
||||
<p class="text-gray-600 text-xs mt-1">GitHub: <a @click="openGithub" class="cursor-pointer text-blue-400">https://github.com/earthjasonlin/zzz-signal-search-export</a></p>
|
||||
<p class="text-gray-600 text-xs mt-1 pb-6">UIGF: <a @click="openUIGF" class="cursor-pointer text-blue-400">https://uigf.org/</a></p>
|
||||
@ -82,6 +83,7 @@
|
||||
|
||||
<script setup>
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
import idJson from '../../idJson.json'
|
||||
import { reactive, onMounted, computed } from 'vue'
|
||||
|
||||
const emit = defineEmits(['close', 'changeLang', 'refreshData'])
|
||||
|
81
tools/getIdMap.py
Normal file
81
tools/getIdMap.py
Normal file
@ -0,0 +1,81 @@
|
||||
# pylint: disable=C0116, C0103, C0201
|
||||
"""Download and process data from the Hakushin API"""
|
||||
|
||||
import json
|
||||
import requests
|
||||
from opencc import OpenCC
|
||||
|
||||
# 初始化 OpenCC 转换器
|
||||
cc = OpenCC('s2t')
|
||||
|
||||
# 获取 JSON 数据
|
||||
weapon_url = 'https://api.hakush.in/zzz/data/weapon.json'
|
||||
character_url = 'https://api.hakush.in/zzz/data/character.json'
|
||||
bangboo_url = 'https://api.hakush.in/zzz/data/bangboo.json'
|
||||
version_url = 'https://api.hakush.in/zzz/new.json'
|
||||
|
||||
# 语言映射配置
|
||||
language_map = {
|
||||
"zh-cn": "CHS",
|
||||
"zh-tw": "CHS", # 简体转繁体
|
||||
"en-us": "EN",
|
||||
"ja-jp": "JA",
|
||||
"ko-kr": "KO"
|
||||
}
|
||||
|
||||
# 类型映射配置
|
||||
type_map = {
|
||||
"weapon": {"zh-cn": "音擎", "zh-tw": "音擎", "en-us": "W-Engines", "ja-jp": "音動機", "ko-kr": "W-엔진"},
|
||||
"character": {"zh-cn": "代理人", "zh-tw": "代理人", "en-us": "Agents",
|
||||
"ja-jp": "エージェント", "ko-kr": "에이전트"},
|
||||
"bangboo": {"zh-cn": "邦布", "zh-tw": "邦布", "en-us": "Bangboo",
|
||||
"ja-jp": "ボンプ", "ko-kr": "「Bangboo」"}
|
||||
}
|
||||
|
||||
def fetch_json(url):
|
||||
response = requests.get(url, timeout=10)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
def transform_data(data, item_type):
|
||||
transformed = {lang: {} for lang in language_map.keys()}
|
||||
for id_, item in data.items():
|
||||
for lang, key in language_map.items():
|
||||
name = item[key] if lang != 'zh-tw' else cc.convert(item['CHS'])
|
||||
transformed[lang][id_] = {
|
||||
"name": name,
|
||||
"item_type": type_map[item_type][lang],
|
||||
"rank_type": item['rank']
|
||||
}
|
||||
return transformed
|
||||
|
||||
def main():
|
||||
try:
|
||||
weapon_data = fetch_json(weapon_url)
|
||||
character_data = fetch_json(character_url)
|
||||
bangboo_data = fetch_json(bangboo_url)
|
||||
version_data = fetch_json(version_url)
|
||||
|
||||
transformed_data = {lang: {} for lang in language_map.keys()}
|
||||
|
||||
transformed_data["version"] = version_data["version"]
|
||||
|
||||
weapon_transformed = transform_data(weapon_data, "weapon")
|
||||
character_transformed = transform_data(character_data, "character")
|
||||
bangboo_transformed = transform_data(bangboo_data, "bangboo")
|
||||
|
||||
for lang in language_map.keys():
|
||||
transformed_data[lang].update(weapon_transformed[lang])
|
||||
transformed_data[lang].update(character_transformed[lang])
|
||||
transformed_data[lang].update(bangboo_transformed[lang])
|
||||
|
||||
with open('./src/idJson.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(transformed_data, f, ensure_ascii=False, indent=2)
|
||||
|
||||
print("Data successfully transformed and saved")
|
||||
|
||||
except requests.RequestException as e:
|
||||
print(f"Error fetching data: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -5205,10 +5205,10 @@ window-size@^1.1.1:
|
||||
define-property "^1.0.0"
|
||||
is-number "^3.0.0"
|
||||
|
||||
winreg@^1.2.4:
|
||||
winreg@1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/winreg/-/winreg-1.2.4.tgz#ba065629b7a925130e15779108cf540990e98d1b"
|
||||
integrity sha1-ugZWKbepJRMOFXeRCM9UCZDpjRs=
|
||||
integrity sha512-IHpzORub7kYlb8A43Iig3reOvlcBJGX9gZ0WycHhghHtA65X0LYnMRuJs+aH1abVnMJztQkvQNlltnbPi5aGIA==
|
||||
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
|
||||
version "7.0.0"
|
||||
@ -5326,4 +5326,4 @@ zrender@5.2.1:
|
||||
resolved "https://registry.npmmirror.com/zrender/download/zrender-5.2.1.tgz#5f4bbda915ba6d412b0b19dc2431beaad05417bb"
|
||||
integrity sha1-X0u9qRW6bUErCxncJDG+qtBUF7s=
|
||||
dependencies:
|
||||
tslib "2.3.0"
|
||||
tslib "2.3.0"
|
||||
|
Reference in New Issue
Block a user