Compare commits

..

8 Commits

8 changed files with 90 additions and 46 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "star-rail-warp-export", "name": "star-rail-warp-export",
"version": "0.0.4", "version": "0.0.8",
"main": "./dist/electron/main/main.js", "main": "./dist/electron/main/main.js",
"author": "biuuu <https://github.com/biuuu>", "author": "biuuu <https://github.com/biuuu>",
"license": "MIT", "license": "MIT",

View File

@ -1,4 +1,4 @@
const { readJSON, saveJSON, decipherAes, cipherAes, detectLocale } = require('./utils') const { readJSON, saveJSON, decipherAes, cipherAes, detectLocale, userDataPath, globalUserDataPath } = require('./utils')
const config = { const config = {
urls: [], urls: [],
@ -13,7 +13,10 @@ const config = {
} }
const getLocalConfig = async () => { const getLocalConfig = async () => {
const localConfig = await readJSON('config.json') let localConfig = await readJSON(userDataPath, 'config.json')
if (!localConfig) {
localConfig = await readJSON(globalUserDataPath, 'config.json')
}
if (!localConfig) return if (!localConfig) return
const configTemp = {} const configTemp = {}
for (let key in localConfig) { for (let key in localConfig) {

View File

@ -3,7 +3,7 @@ const util = require('util')
const path = require('path') const path = require('path')
const { URL } = require('url') const { URL } = require('url')
const { app, ipcMain, shell } = require('electron') const { app, ipcMain, shell } = require('electron')
const { sleep, request, sendMsg, readJSON, saveJSON, detectLocale, userDataPath, userPath, localIp, langMap } = require('./utils') const { sleep, request, sendMsg, readJSON, saveJSON, detectLocale, userDataPath, userPath, localIp, langMap, globalUserDataPath } = require('./utils')
const config = require('./config') const config = require('./config')
const i18n = require('./i18n') const i18n = require('./i18n')
const { enableProxy, disableProxy } = require('./module/system-proxy') const { enableProxy, disableProxy } = require('./module/system-proxy')
@ -29,25 +29,42 @@ const defaultTypeMap = new Map([
['2', '始发跃迁'] ['2', '始发跃迁']
]) ])
const findDataFiles = async (dataPath, fileMap) => {
const files = await readdir(dataPath)
if (files?.length) {
for (let name of files) {
if (/^gacha-list-\d+\.json$/.test(name) && !fileMap.has(name)) {
fileMap.set(name, dataPath)
}
}
}
}
const collectDataFiles = async () => {
await fs.ensureDir(userDataPath)
await fs.ensureDir(globalUserDataPath)
const fileMap = new Map()
await findDataFiles(userDataPath, fileMap)
await findDataFiles(globalUserDataPath, fileMap)
return fileMap
}
let localDataReaded = false let localDataReaded = false
const readdir = util.promisify(fs.readdir) const readdir = util.promisify(fs.readdir)
const readData = async () => { const readData = async () => {
if (localDataReaded) return if (localDataReaded) return
localDataReaded = true localDataReaded = true
await fs.ensureDir(userDataPath) const fileMap = await collectDataFiles()
const files = await readdir(userDataPath) for (let [name, dataPath] of fileMap) {
for (let name of files) { try {
if (/^gacha-list-\d+\.json$/.test(name)) { const data = await readJSON(dataPath, name)
try { data.typeMap = new Map(data.typeMap) || defaultTypeMap
const data = await readJSON(name) data.result = new Map(data.result)
data.typeMap = new Map(data.typeMap) || defaultTypeMap if (data.uid) {
data.result = new Map(data.result) dataMap.set(data.uid, data)
if (data.uid) {
dataMap.set(data.uid, data)
}
} catch (e) {
sendMsg(e, 'ERROR')
} }
} catch (e) {
sendMsg(e, 'ERROR')
} }
} }
if ((!config.current && dataMap.size) || (config.current && dataMap.size && !dataMap.has(config.current))) { if ((!config.current && dataMap.size) || (config.current && dataMap.size && !dataMap.has(config.current))) {
@ -115,9 +132,12 @@ const readLog = async () => {
} }
const promises = logPaths.map(async logpath => { const promises = logPaths.map(async logpath => {
const logText = await fs.readFile(logpath, 'utf8') const logText = await fs.readFile(logpath, 'utf8')
const gamePathMch = logText.match(/\w:\/.*?(Star\sRail\/Game\/StarRail_Data)/) const gamePathMch = logText.match(/\w:\/.*?\/StarRail_Data\//)
if (gamePathMch) { if (gamePathMch) {
const cacheText = await fs.readFile(path.join(gamePathMch[0], '/webCaches/Cache/Cache_Data/data_2'), 'utf8') let cacheText = ''
try {
cacheText = await fs.readFile(path.join(gamePathMch[0], '/webCaches/Cache/Cache_Data/data_2'), 'utf8')
} catch (e) {}
const urlMch = cacheText.match(/https.+?&auth_appid=webview_gacha&.+?authkey=.+?&game_biz=hkrpg_.+?&plat_type=pc/g) const urlMch = cacheText.match(/https.+?&auth_appid=webview_gacha&.+?authkey=.+?&game_biz=hkrpg_.+?&plat_type=pc/g)
if (urlMch) { if (urlMch) {
cacheFolder = path.join(gamePathMch[0], '/webCaches/Cache/') cacheFolder = path.join(gamePathMch[0], '/webCaches/Cache/')
@ -235,7 +255,6 @@ const tryGetUid = async (queryString) => {
try { try {
for (let [key] of defaultTypeMap) { for (let [key] of defaultTypeMap) {
const res = await request(`${url}&gacha_type=${key}&page=1&size=6`) const res = await request(`${url}&gacha_type=${key}&page=1&size=6`)
checkResStatus(res)
if (res.data.list && res.data.list.length) { if (res.data.list && res.data.list.length) {
return res.data.list[0].uid return res.data.list[0].uid
} }
@ -333,10 +352,7 @@ const tryRequest = async (url, retry = false) => {
const gachaTypeUrl = `${apiDomain}/common/gacha_record/api/getGachaLog?${queryString}&page=1&size=5&gacha_type=1&end_id=0` const gachaTypeUrl = `${apiDomain}/common/gacha_record/api/getGachaLog?${queryString}&page=1&size=5&gacha_type=1&end_id=0`
try { try {
const res = await request(gachaTypeUrl) const res = await request(gachaTypeUrl)
if (res.retcode !== 0) { checkResStatus(res)
return false
}
return true
} catch (e) { } catch (e) {
if (e.code === 'ERR_PROXY_CONNECTION_FAILED' && !retry) { if (e.code === 'ERR_PROXY_CONNECTION_FAILED' && !retry) {
await disableProxy() await disableProxy()
@ -351,11 +367,6 @@ const getUrl = async () => {
let url = await readLog() let url = await readLog()
if (!url && config.proxyMode) { if (!url && config.proxyMode) {
url = await useProxy() url = await useProxy()
} else if (url) {
const result = await tryRequest(url)
if (!result && config.proxyMode) {
url = await useProxy()
}
} }
return url return url
} }
@ -372,6 +383,9 @@ const fetchData = async (urlOverride) => {
sendMsg(message) sendMsg(message)
throw new Error(message) throw new Error(message)
} }
await tryRequest(url)
const searchParams = getQuerystring(url) const searchParams = getQuerystring(url)
if (!searchParams) { if (!searchParams) {
const message = text.url.incorrect const message = text.url.incorrect
@ -456,7 +470,7 @@ ipcMain.handle('READ_DATA', async () => {
}) })
ipcMain.handle('CHANGE_UID', (event, uid) => { ipcMain.handle('CHANGE_UID', (event, uid) => {
config.current = uid changeCurrent(uid)
}) })
ipcMain.handle('GET_CONFIG', () => { ipcMain.handle('GET_CONFIG', () => {

View File

@ -42,14 +42,24 @@ const parseData = (data) => {
return result return result
} }
const assignData = (objA, objB) => {
const temp = { ...objA }
for (let key in objB) {
if (objB[key]) {
temp[key] = objB[key]
}
}
return temp
}
const i18nMap = new Map() const i18nMap = new Map()
const prepareData = () => { const prepareData = () => {
for (let key in raw) { for (let key in raw) {
let temp = {} let temp = {}
if (key === 'zh-tw') { if (key === 'zh-tw') {
Object.assign(temp, raw['zh-cn'], raw[key]) temp = assignData(raw['zh-cn'], raw[key])
} else { } else {
Object.assign(temp, raw['zh-cn'], raw['en-us'], raw[key]) temp = assignData(raw['zh-cn'], assignData(raw['en-us'], raw[key]))
} }
i18nMap.set(key, parseData(temp)) i18nMap.set(key, parseData(temp))
} }

View File

@ -11,8 +11,9 @@ const Registry = require('winreg')
const isDev = !app.isPackaged const isDev = !app.isPackaged
const userPath = app.getPath('userData') const userPath = app.getPath('userData')
const appRoot = isDev ? path.resolve(__dirname, '..', '..') : userPath const appRoot = isDev ? path.resolve(__dirname, '..', '..') : path.resolve(app.getAppPath(), '..', '..')
const userDataPath = path.resolve(appRoot, 'userData') const userDataPath = path.resolve(appRoot, 'userData')
const globalUserDataPath = path.resolve(userPath, 'userData')
let win = null let win = null
const initWindow = () => { const initWindow = () => {
@ -56,7 +57,7 @@ const saveLog = () => {
const text = item[2] const text = item[2]
return `[${type}][${time}]${text}` return `[${type}][${time}]${text}`
}).join('\r\n') }).join('\r\n')
fs.outputFileSync(path.join(userDataPath, 'log.txt'), text) fs.outputFile(path.join(userDataPath, 'log.txt'), text)
} }
const authkeyMask = (text = '') => { const authkeyMask = (text = '') => {
@ -144,19 +145,20 @@ const detectLocale = (value) => {
const saveJSON = async (name, data) => { const saveJSON = async (name, data) => {
try { try {
await fs.outputJSON(path.join(userDataPath, name), data, { await fs.outputJSON(path.join(userDataPath, name), data)
spaces: 2 if (!isDev) {
}) await fs.outputJSON(path.join(globalUserDataPath, name), data)
}
} catch (e) { } catch (e) {
sendMsg(e, 'ERROR') sendMsg(e, 'ERROR')
await sleep(3) await sleep(3)
} }
} }
const readJSON = async (name) => { const readJSON = async (dataPath, name) => {
let data = null let data = null
try { try {
data = await fs.readJSON(path.join(userDataPath, name)) data = await fs.readJSON(path.join(dataPath, name))
} catch (e) {} } catch (e) {}
return data return data
} }
@ -203,5 +205,5 @@ const localIp = () => {
module.exports = { module.exports = {
sleep, request, hash, cipherAes, decipherAes, saveLog, sleep, request, hash, cipherAes, decipherAes, saveLog,
sendMsg, readJSON, saveJSON, initWindow, getWin, localIp, userPath, detectLocale, langMap, sendMsg, readJSON, saveJSON, initWindow, getWin, localIp, userPath, detectLocale, langMap,
appRoot, userDataPath appRoot, userDataPath, globalUserDataPath
} }

View File

@ -55,10 +55,12 @@
</template> </template>
</el-dialog> </el-dialog>
<el-dialog :title="ui.button.solution" v-model="state.showCacheCleanDlg" width="90%" custom-class="max-w-md"> <el-dialog :title="ui.button.solution" v-model="state.showCacheCleanDlg" width="90%" custom-class="max-w-md cache-clean-dialog">
<el-button plain icon="folder" type="primary" @click="openCacheFolder">{{ui.button.cacheFolder}}</el-button> <el-button plain icon="folder" type="success" @click="openCacheFolder">{{ui.button.cacheFolder}}</el-button>
<p class="my-4 leading-2 text-gray-600 text-sm whitespace-pre-line">{{ui.extra.cacheClean}}</p> <p class="my-2 flex flex-col text-teal-800 text-[13px]">
<p class="my-2 text-gray-400 text-xs">{{ui.extra.findCacheFolder}}</p> <span class="my-1" v-for="txt of cacheCleanTextList">{{ txt }}</span>
</p>
<p class="my-2 text-gray-500 text-xs">{{ui.extra.findCacheFolder}}</p>
<template #footer> <template #footer>
<div class="dialog-footer text-center"> <div class="dialog-footer text-center">
<el-button type="primary" @click="state.showCacheCleanDlg = false" class="focus:outline-none">{{ui.common.ok}}</el-button> <el-button type="primary" @click="state.showCacheCleanDlg = false" class="focus:outline-none">{{ui.common.ok}}</el-button>
@ -99,6 +101,13 @@ const ui = computed(() => {
} }
}) })
const cacheCleanTextList = computed(() => {
if (ui.value) {
return ui.value.extra?.cacheClean?.split('\n')
}
return []
})
const gachaData = computed(() => { const gachaData = computed(() => {
return state.dataMap.get(state.current) return state.dataMap.get(state.current)
}) })

View File

@ -13,4 +13,10 @@
body::-webkit-scrollbar-thumb { body::-webkit-scrollbar-thumb {
@apply rounded-full bg-gray-300; @apply rounded-full bg-gray-300;
} }
}
@layer utilities {
.cache-clean-dialog .el-dialog__body {
padding: 0 20px;
}
} }

View File

@ -1,11 +1,11 @@
import * as IconComponents from '@element-plus/icons-vue' import * as IconComponents from '@element-plus/icons-vue'
const weaponTypeNames = new Set([ const weaponTypeNames = new Set([
'光锥', 'Light Cone', '光錐', 'Lichtkegel', 'Conos de luz', 'cônes de lumière', '光円錐', '광추', 'Cones de Luz', 'Световые конусы', 'Nón Ánh Sáng' '光锥', '光錐', 'Lichtkegel', 'Light Cone', 'Conos de luz', 'cônes de lumière', '光円錐', '광추', 'Cones de Luz', 'Световые конусы', 'Nón Ánh Sáng'
]) ])
const characterTypeNames = new Set([ const characterTypeNames = new Set([
'角色', 'Character', '캐릭터', 'キャラクター', 'Personaje', 'Personnage', 'Персонажи', 'ตัวละคร', 'Nhân Vật', 'Figur', 'Karakter', 'Personagem' '角色', 'Figur', 'Character', 'Personajes', 'Personnages', 'Karakter', 'キャラクター', '캐릭터', 'Personagens', 'Персонажи', 'ตัวละคร', 'Nhân Vật'
]) ])
const isCharacter = (name) => characterTypeNames.has(name) const isCharacter = (name) => characterTypeNames.has(name)