mirror of
https://github.com/earthjasonlin/zzz-signal-search-export.git
synced 2025-04-21 07:50:19 +08:00
Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
66188231bc
|
|||
5624af3fb2
|
|||
3c848a97f8
|
|||
6ddc29af5a
|
|||
e83fe42268
|
|||
f9e74b4fb8
|
|||
84179ccc8d
|
|||
8b725053ce
|
|||
bebb14b63d
|
|||
2adf56d062
|
|||
ee94ae36cd
|
|||
e575e46238
|
|||
3fac233471
|
|||
d99af2cc26
|
|||
681e664e32
|
|||
5f9fc94709
|
|||
d96bd9f355
|
|||
3ff2879041
|
51
.electron-vite/update.js
Normal file
51
.electron-vite/update.js
Normal file
@ -0,0 +1,51 @@
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const crypto = require('crypto')
|
||||
const AdmZip = require('adm-zip')
|
||||
const { version } = require('../package.json')
|
||||
|
||||
const hash = (data, type = 'sha256') => {
|
||||
const hmac = crypto.createHmac(type, 'nap')
|
||||
hmac.update(data)
|
||||
return hmac.digest('hex')
|
||||
}
|
||||
|
||||
const createZip = (filePath, dest) => {
|
||||
const zip = new AdmZip()
|
||||
zip.addLocalFolder(filePath)
|
||||
zip.toBuffer()
|
||||
zip.writeZip(dest)
|
||||
}
|
||||
|
||||
const start = async () => {
|
||||
copyAppZip()
|
||||
const appPath = './build/win-ia32-unpacked/resources/app'
|
||||
const name = 'app.zip'
|
||||
const outputPath = path.resolve('./build/update/update/')
|
||||
const zipPath = path.resolve(outputPath, name)
|
||||
await fs.ensureDir(outputPath)
|
||||
await fs.emptyDir(outputPath)
|
||||
createZip(appPath, zipPath)
|
||||
const buffer = await fs.readFile(zipPath)
|
||||
const sha256 = hash(buffer)
|
||||
const hashName = sha256.slice(7, 12)
|
||||
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',
|
||||
name: `${hashName}.zip`,
|
||||
hash: sha256
|
||||
})
|
||||
}
|
||||
|
||||
const copyAppZip = () => {
|
||||
try {
|
||||
const dir = path.resolve('./build')
|
||||
const filePath = path.resolve(dir, `ZzzSignalSearchExport-${version}-ia32-win.zip`)
|
||||
fs.copySync(filePath, path.join(dir, 'app.zip'))
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
start()
|
55
.github/workflows/release.yml
vendored
Normal file
55
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
# Sequence of patterns matched against refs/tag
|
||||
tags:
|
||||
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
||||
|
||||
name: Release
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Release
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '16.x'
|
||||
- name: Build App
|
||||
run: |
|
||||
yarn --frozen-lockfile
|
||||
yarn build:win32
|
||||
yarn build-update
|
||||
- name: Create Release
|
||||
if: success()
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: ZzzSignalSearchExport ${{ github.ref }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
- name: Upload Release Asset
|
||||
if: success()
|
||||
id: upload-release-asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
|
||||
asset_path: ./build/app.zip
|
||||
asset_name: ZzzSignalSearchExport.zip
|
||||
asset_content_type: application/zip
|
||||
- name: Deploy update
|
||||
if: success()
|
||||
uses: crazy-max/ghaction-github-pages@v2
|
||||
with:
|
||||
commit_message: Update app
|
||||
build_dir: ./build/update
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.TOKEN }}
|
@ -1,6 +1,6 @@
|
||||
# 绝区零记录导出工具
|
||||
# 绝区零调频记录导出工具
|
||||
|
||||
中文 | [English](https://git.loliquq.cn/earthjasonlin/zzz-signal-search-export/blob/main/docs/README_EN.md)
|
||||
中文 | [English](https://github.com/earthjasonlin/zzz-signal-search-export/blob/main/docs/README_EN.md)
|
||||
|
||||
这个项目由[star-rail-warp-export](https://github.com/biuuu/star-rail-warp-export/)修改而来,功能基本一致。
|
||||
|
||||
@ -14,7 +14,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)
|
||||
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. 打开游戏的跃迁详情页面
|
||||
|
||||

|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 264 KiB After Width: | Height: | Size: 42 KiB |
@ -1,6 +1,6 @@
|
||||
# Zenless Zone Zero Signal Search History Exporter
|
||||
|
||||
[中文](https://git.loliquq.cn/earthjasonlin/zzz-signal-search-export/blob/main/README.md) | English
|
||||
[中文](https://github.com/earthjasonlin/zzz-signal-search-export) | English
|
||||
|
||||
This project is modified from the [star-rail-warp-export](https://github.com/biuuu/star-rail-warp-export/) repository, and its functions are basically the same.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "zzz-signal-search-export",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.6",
|
||||
"main": "./dist/electron/main/main.js",
|
||||
"author": "earthjasonlin <https://git.loliquq.cn/earthjasonlin>",
|
||||
"homepage": "https://github.com/earthjasonlin/zzz-signal-search-export",
|
||||
@ -16,6 +16,7 @@
|
||||
"build:dir": "cross-env BUILD_TARGET=clean node .electron-vite/build.js && electron-builder --dir",
|
||||
"build:clean": "cross-env BUILD_TARGET=onlyClean node .electron-vite/build.js",
|
||||
"build:web": "cross-env BUILD_TARGET=web node .electron-vite/build.js",
|
||||
"build-update": "node .electron-vite/update.js",
|
||||
"dev:web": "cross-env TARGET=web node .electron-vite/dev-runner.js",
|
||||
"start": "electron ./src/main/main.js",
|
||||
"dep:upgrade": "yarn upgrade-interactive --latest",
|
||||
|
@ -87,6 +87,7 @@
|
||||
"log.proxy.hint": "Using proxy mode [${ip}:${port}] to get URL,please reopen warp history inside the game client.",
|
||||
"log.url.notFound2": "Unable to find URL, please make sure you already opened warp history inside the game client",
|
||||
"log.url.incorrect": "Unable to get URL parameters",
|
||||
"log.autoUpdate.success": "Auto update successful,please restart the program",
|
||||
"excel.header.time": "time",
|
||||
"excel.header.name": "name",
|
||||
"excel.header.type": "type",
|
||||
|
@ -86,6 +86,7 @@
|
||||
"log.proxy.hint": "正在使用代理模式[${ip}:${port}]获取URL,请重新打开游戏抽卡记录。",
|
||||
"log.url.notFound2": "未找到URL,请确认是否已打开游戏抽卡记录",
|
||||
"log.url.incorrect": "获取URL参数失败",
|
||||
"log.autoUpdate.success": "自动更新已完成,重启工具后生效",
|
||||
"excel.header.time": "时间",
|
||||
"excel.header.name": "名称",
|
||||
"excel.header.type": "类别",
|
||||
|
@ -138,15 +138,20 @@ const readLog = async () => {
|
||||
}
|
||||
const promises = logPaths.map(async logpath => {
|
||||
const logText = await fs.readFile(logpath, 'utf8')
|
||||
const gamePathMch = logText.match(/\w:\/.*?\/StarRail_Data\//i)
|
||||
const url = logText.match(/https:\/\/.*?\/info/g)
|
||||
if (url) {
|
||||
return getLatestUrl(url)
|
||||
}
|
||||
const gamePathMch = logText.match(/([A-Z]:\/.*?\/)(?=ZenlessZoneZero_Data)/i)
|
||||
if (gamePathMch) {
|
||||
const [cacheText, cacheFile] = await getCacheText(gamePathMch[0])
|
||||
const urlMch = cacheText.match(/https[^?]+?\?[^?]+?&auth_appid=webview_gacha&.+?authkey=.+?&game_biz=hkrpg_.+?&plat_type=pc/g)
|
||||
const[cacheText, cacheFile] = await getCacheText(gamePathMch[0]+"/ZenlessZoneZero_Data")
|
||||
const urlMch = cacheText.match(/https.+?authkey=.+?end_id=/g)
|
||||
if (urlMch) {
|
||||
cacheFolder = cacheFile.replace(/Cache_Data[/\\]data_2$/, '')
|
||||
return getLatestUrl(urlMch)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
const result = await Promise.all(promises)
|
||||
for (let url of result) {
|
||||
@ -288,8 +293,8 @@ const fixAuthkey = (url) => {
|
||||
const getQuerystring = (url) => {
|
||||
const text = i18n.log
|
||||
const { searchParams, host } = new URL(fixAuthkey(url))
|
||||
if (host.includes('webstatic-sea') || host.includes('hkrpg-api-os') || host.includes('api-os-takumi') || host.includes('hoyoverse.com')) {
|
||||
apiDomain = 'https://api-os-takumi.mihoyo.com'
|
||||
if (host.includes('webstatic-sea') || host.includes('hoyoverse.com')) {
|
||||
apiDomain = 'https://public-operation-nap-sg.hoyoverse.com'
|
||||
} else {
|
||||
apiDomain = 'https://public-operation-nap.mihoyo.com'
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ require('./getData')
|
||||
require('./bridge')
|
||||
require('./excel')
|
||||
require('./SRGFJson')
|
||||
const { getUpdateInfo } = require('./update/index')
|
||||
|
||||
const isDev = !app.isPackaged
|
||||
let win = null
|
||||
@ -53,6 +54,12 @@ if (!isFirstInstance) {
|
||||
if (proxyStatus.started) {
|
||||
disableProxy()
|
||||
}
|
||||
if (getUpdateInfo().status === 'moving') {
|
||||
e.preventDefault()
|
||||
setTimeout(() => {
|
||||
app.quit()
|
||||
}, 3000)
|
||||
}
|
||||
})
|
||||
|
||||
app.on('quit', () => {
|
||||
|
185
src/main/module/extract-zip.js
Normal file
185
src/main/module/extract-zip.js
Normal file
@ -0,0 +1,185 @@
|
||||
// Copyright (c) 2014 Max Ogden and other contributors
|
||||
// All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
|
||||
// * Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
// https://github.com/maxogden/extract-zip
|
||||
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||
const { createWriteStream, promises: fs } = require('original-fs')
|
||||
const getStream = require('get-stream')
|
||||
const path = require('path')
|
||||
const { promisify } = require('util')
|
||||
const stream = require('stream')
|
||||
const yauzl = require('yauzl')
|
||||
|
||||
const openZip = promisify(yauzl.open)
|
||||
const pipeline = promisify(stream.pipeline)
|
||||
|
||||
class Extractor {
|
||||
constructor (zipPath, opts) {
|
||||
this.zipPath = zipPath
|
||||
this.opts = opts
|
||||
}
|
||||
|
||||
async extract () {
|
||||
|
||||
this.zipfile = await openZip(this.zipPath, { lazyEntries: true })
|
||||
this.canceled = false
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.zipfile.on('error', err => {
|
||||
this.canceled = true
|
||||
reject(err)
|
||||
})
|
||||
this.zipfile.readEntry()
|
||||
|
||||
this.zipfile.on('close', () => {
|
||||
if (!this.canceled) {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
|
||||
this.zipfile.on('entry', async entry => {
|
||||
/* istanbul ignore if */
|
||||
if (this.canceled) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if (entry.fileName.startsWith('__MACOSX/')) {
|
||||
this.zipfile.readEntry()
|
||||
return
|
||||
}
|
||||
|
||||
const destDir = path.dirname(path.join(this.opts.dir, entry.fileName))
|
||||
|
||||
try {
|
||||
await fs.mkdir(destDir, { recursive: true })
|
||||
|
||||
const canonicalDestDir = await fs.realpath(destDir)
|
||||
const relativeDestDir = path.relative(this.opts.dir, canonicalDestDir)
|
||||
|
||||
if (relativeDestDir.split(path.sep).includes('..')) {
|
||||
throw new Error(`Out of bound path "${canonicalDestDir}" found while processing file ${entry.fileName}`)
|
||||
}
|
||||
|
||||
await this.extractEntry(entry)
|
||||
this.zipfile.readEntry()
|
||||
} catch (err) {
|
||||
this.canceled = true
|
||||
this.zipfile.close()
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async extractEntry (entry) {
|
||||
/* istanbul ignore if */
|
||||
if (this.canceled) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.opts.onEntry) {
|
||||
this.opts.onEntry(entry, this.zipfile)
|
||||
}
|
||||
|
||||
const dest = path.join(this.opts.dir, entry.fileName)
|
||||
|
||||
// convert external file attr int into a fs stat mode int
|
||||
const mode = (entry.externalFileAttributes >> 16) & 0xFFFF
|
||||
// check if it's a symlink or dir (using stat mode constants)
|
||||
const IFMT = 61440
|
||||
const IFDIR = 16384
|
||||
const IFLNK = 40960
|
||||
const symlink = (mode & IFMT) === IFLNK
|
||||
let isDir = (mode & IFMT) === IFDIR
|
||||
|
||||
// Failsafe, borrowed from jsZip
|
||||
if (!isDir && entry.fileName.endsWith('/')) {
|
||||
isDir = true
|
||||
}
|
||||
|
||||
// check for windows weird way of specifying a directory
|
||||
// https://github.com/maxogden/extract-zip/issues/13#issuecomment-154494566
|
||||
const madeBy = entry.versionMadeBy >> 8
|
||||
if (!isDir) isDir = (madeBy === 0 && entry.externalFileAttributes === 16)
|
||||
|
||||
|
||||
const procMode = this.getExtractedMode(mode, isDir) & 0o777
|
||||
|
||||
// always ensure folders are created
|
||||
const destDir = isDir ? dest : path.dirname(dest)
|
||||
|
||||
const mkdirOptions = { recursive: true }
|
||||
if (isDir) {
|
||||
mkdirOptions.mode = procMode
|
||||
}
|
||||
await fs.mkdir(destDir, mkdirOptions)
|
||||
if (isDir) return
|
||||
|
||||
const readStream = await promisify(this.zipfile.openReadStream.bind(this.zipfile))(entry)
|
||||
|
||||
if (symlink) {
|
||||
const link = await getStream(readStream)
|
||||
await fs.symlink(link, dest)
|
||||
} else {
|
||||
await pipeline(readStream, createWriteStream(dest, { mode: procMode }))
|
||||
}
|
||||
}
|
||||
|
||||
getExtractedMode (entryMode, isDir) {
|
||||
let mode = entryMode
|
||||
// Set defaults, if necessary
|
||||
if (mode === 0) {
|
||||
if (isDir) {
|
||||
if (this.opts.defaultDirMode) {
|
||||
mode = parseInt(this.opts.defaultDirMode, 10)
|
||||
}
|
||||
|
||||
if (!mode) {
|
||||
mode = 0o755
|
||||
}
|
||||
} else {
|
||||
if (this.opts.defaultFileMode) {
|
||||
mode = parseInt(this.opts.defaultFileMode, 10)
|
||||
}
|
||||
|
||||
if (!mode) {
|
||||
mode = 0o644
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mode
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = async function (zipPath, opts) {
|
||||
|
||||
if (!path.isAbsolute(opts.dir)) {
|
||||
throw new Error('Target directory is expected to be absolute')
|
||||
}
|
||||
|
||||
await fs.mkdir(opts.dir, { recursive: true })
|
||||
opts.dir = await fs.realpath(opts.dir)
|
||||
return new Extractor(zipPath, opts).extract()
|
||||
}
|
65
src/main/update/index.js
Normal file
65
src/main/update/index.js
Normal file
@ -0,0 +1,65 @@
|
||||
const { app } = require('electron')
|
||||
const fetch = require('electron-fetch').default
|
||||
const semver = require('semver')
|
||||
const util = require('util')
|
||||
const path = require('path')
|
||||
const fs = require('fs-extra')
|
||||
const extract = require('../module/extract-zip')
|
||||
const { version } = require('../../../package.json')
|
||||
const { hash, sendMsg } = require('../utils')
|
||||
const config = require('../config')
|
||||
const i18n = require('../i18n')
|
||||
const streamPipeline = util.promisify(require('stream').pipeline)
|
||||
|
||||
async function download(url, filePath) {
|
||||
const response = await fetch(url)
|
||||
if (!response.ok) throw new Error(`unexpected response ${response.statusText}`)
|
||||
await streamPipeline(response.body, fs.createWriteStream(filePath))
|
||||
}
|
||||
|
||||
const updateInfo = {
|
||||
status: 'init'
|
||||
}
|
||||
|
||||
const isDev = !app.isPackaged
|
||||
const appPath = isDev ? path.resolve(__dirname, '../../', 'update-dev/app'): app.getAppPath()
|
||||
const updatePath = isDev ? path.resolve(__dirname, '../../', 'update-dev/download') : path.resolve(appPath, '..', '..', 'update')
|
||||
|
||||
const update = async () => {
|
||||
if (isDev) return
|
||||
try {
|
||||
const url = 'https://earthjasonlin.github.io/zzz-signal-search-export/update'
|
||||
const res = await fetch(`${url}/manifest.json?t=${Math.floor(Date.now() / (1000 * 60 * 10))}`)
|
||||
const data = await res.json()
|
||||
if (!data.active) return
|
||||
if (semver.gt(data.version, version) && semver.gte(version, data.from)) {
|
||||
await fs.emptyDir(updatePath)
|
||||
const filePath = path.join(updatePath, data.name)
|
||||
if (!config.autoUpdate) {
|
||||
sendMsg(data.version, 'NEW_VERSION')
|
||||
return
|
||||
}
|
||||
updateInfo.status = 'downloading'
|
||||
await download(`${url}/${data.name}`, filePath)
|
||||
const buffer = await fs.readFile(filePath)
|
||||
const sha256 = hash(buffer)
|
||||
if (sha256 !== data.hash) return
|
||||
const appPathTemp = path.join(updatePath, 'app')
|
||||
await extract(filePath, { dir: appPathTemp })
|
||||
updateInfo.status = 'moving'
|
||||
await fs.emptyDir(appPath)
|
||||
await fs.copy(appPathTemp, appPath)
|
||||
updateInfo.status = 'finished'
|
||||
sendMsg(i18n.log.autoUpdate.success, 'UPDATE_HINT')
|
||||
}
|
||||
} catch (e) {
|
||||
updateInfo.status = 'failed'
|
||||
sendMsg(e, 'ERROR')
|
||||
}
|
||||
}
|
||||
|
||||
const getUpdateInfo = () => updateInfo
|
||||
|
||||
setTimeout(update, 1000)
|
||||
|
||||
exports.getUpdateInfo = getUpdateInfo
|
@ -142,12 +142,12 @@ const readJSON = async (dataPath, name) => {
|
||||
}
|
||||
|
||||
const hash = (data, type = 'sha256') => {
|
||||
const hmac = crypto.createHmac(type, 'hk4e')
|
||||
const hmac = crypto.createHmac(type, 'nap')
|
||||
hmac.update(data)
|
||||
return hmac.digest('hex')
|
||||
}
|
||||
|
||||
const scryptKey = crypto.scryptSync(userPath, 'hk4e', 24)
|
||||
const scryptKey = crypto.scryptSync(userPath, 'nap', 24)
|
||||
const cipherAes = (data) => {
|
||||
const algorithm = 'aes-192-cbc'
|
||||
const iv = Buffer.alloc(16, 0)
|
||||
|
@ -327,6 +327,11 @@ onMounted(async () => {
|
||||
console.error(err)
|
||||
})
|
||||
|
||||
ipcRenderer.on('UPDATE_HINT', (event, message) => {
|
||||
state.log = message
|
||||
state.status = 'updated'
|
||||
})
|
||||
|
||||
ipcRenderer.on('AUTHKEY_TIMEOUT', (event, message) => {
|
||||
state.authkeyTimeout = message
|
||||
})
|
||||
|
@ -23,6 +23,12 @@
|
||||
<el-button type="primary" plain @click="state.showDataDialog = true">{{common.dataManage}}</el-button>
|
||||
<p class="text-gray-400 text-xs m-1.5">{{text.dataManagerHint}}</p>
|
||||
</el-form-item>
|
||||
<el-form-item :label="text.autoUpdate">
|
||||
<el-switch
|
||||
@change="saveSetting"
|
||||
v-model="settingForm.autoUpdate">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item :label="text.fetchFullHistory">
|
||||
<el-switch
|
||||
@change="saveSetting"
|
||||
@ -92,6 +98,7 @@ const settingForm = reactive({
|
||||
lang: 'zh-cn',
|
||||
logType: 1,
|
||||
proxyMode: true,
|
||||
autoUpdate: true,
|
||||
fetchFullHistory: false,
|
||||
})
|
||||
|
||||
@ -105,7 +112,7 @@ const text = computed(() => props.i18n.ui.setting)
|
||||
const about = computed(() => props.i18n.ui.about)
|
||||
|
||||
const saveSetting = async () => {
|
||||
const keys = ['lang', 'logType', 'proxyMode', 'fetchFullHistory']
|
||||
const keys = ['lang', 'logType', 'proxyMode', 'autoUpdate', 'fetchFullHistory']
|
||||
for (let key of keys) {
|
||||
await ipcRenderer.invoke('SAVE_CONFIG', [key, settingForm[key]])
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ const gachaDetail = (data) => {
|
||||
detail.ssrPos.push([name, index + 1 - lastSSR, time, key])
|
||||
lastSSR = index + 1
|
||||
detail.count4++
|
||||
detail.countMio++
|
||||
detail.countMio = 0
|
||||
if (isWeapon(type)) {
|
||||
detail.count4w++
|
||||
itemCount(detail.weapon4, name)
|
||||
|
Reference in New Issue
Block a user