diff --git a/Cargo.lock b/Cargo.lock index 41ae5801..287ac00f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1561,7 +1561,7 @@ dependencies = [ [[package]] name = "hoyo_gacha" -version = "0.4.0" +version = "0.4.1" dependencies = [ "anyhow", "async-trait", diff --git a/package.json b/package.json index 8f71f8b7..ecd9bea5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hoyo.gacha", - "version": "0.4.0", + "version": "0.4.1", "description": "An unofficial tool for managing and analyzing your miHoYo gacha records", "author": "lgou2w ", "homepage": "https://github.com/lgou2w/HoYo.Gacha#readme", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 17e30fa7..1858c081 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hoyo_gacha" -version = "0.4.0" +version = "0.4.1" edition = "2021" authors = ["lgou2w"] description = "An unofficial tool for managing and analyzing your miHoYo gacha records" diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index 5704d398..27494ce3 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -1,9 +1,12 @@ -use crate::constants; -use crate::error::Result; +use std::time::Duration; + use reqwest::Client as Reqwest; use serde::{Deserialize, Serialize}; use tauri::{Invoke, Runtime}; +use crate::constants; +use crate::error::Result; + pub fn get_handlers() -> Box) + Send + Sync> { Box::new(tauri::generate_handler![ get_current_exe_dir, @@ -67,6 +70,7 @@ async fn get_latest_version() -> Result { Reqwest::builder() .build()? .get("https://hoyo-gacha.lgou2w.com/release/latest") + .timeout(Duration::from_secs(15)) .send() .await? .json::() @@ -93,6 +97,7 @@ async fn update_app(latest_version: LatestVersion) -> Result<()> { .build()? .get("https://hoyo-gacha.lgou2w.com/release/download") .query(&[("id", latest_version.id.to_string())]) + .timeout(Duration::from_secs(15)) .send() .await? .error_for_status()?; diff --git a/src-tauri/src/error.rs b/src-tauri/src/error.rs index 69d04782..d136aaa9 100644 --- a/src-tauri/src/error.rs +++ b/src-tauri/src/error.rs @@ -13,9 +13,6 @@ pub enum Error { #[error(transparent)] Db(#[from] sea_orm::error::DbErr), - #[error(transparent)] - SerdeJson(#[from] serde_json::Error), - #[error(transparent)] Tauri(#[from] tauri::Error), @@ -54,6 +51,9 @@ pub enum Error { GachaRecordFetcherChannelJoin, // UIGF & SRGF + #[error("{0}")] + UIGFOrSRGFSerdeJson(serde_json::Error), + #[error("UIGF or SRGF Mismatched UID: expected {expected:?}, actual {actual:?}")] UIGFOrSRGFMismatchedUID { expected: String, actual: String }, @@ -95,6 +95,7 @@ impl_error_identifiers! { GachaRecordRetcode => GACHA_RECORD_RETCODE, GachaRecordFetcherChannelSend => GACHA_RECORD_FETCHER_CHANNEL_SEND, GachaRecordFetcherChannelJoin => GACHA_RECORD_FETCHER_CHANNEL_JOIN, + UIGFOrSRGFSerdeJson => UIGF_OR_SRGF_SERDE_JSON, UIGFOrSRGFMismatchedUID => UIGF_OR_SRGF_MISMATCHED_UID, UIGFOrSRGFInvalidField => UIGF_OR_SRGF_INVALID_FIELD, AccountAlreadyExists => ACCOUNT_ALREADY_EXISTS, diff --git a/src-tauri/src/gacha/srgf.rs b/src-tauri/src/gacha/srgf.rs index 40f87c7a..9d014483 100644 --- a/src-tauri/src/gacha/srgf.rs +++ b/src-tauri/src/gacha/srgf.rs @@ -66,14 +66,14 @@ impl SRGF { } pub fn from_reader(reader: impl Read) -> Result { - Ok(serde_json::from_reader(reader)?) + serde_json::from_reader(reader).map_err(Error::UIGFOrSRGFSerdeJson) } pub fn to_writer(&self, writer: impl Write, pretty: bool) -> Result<()> { if pretty { - Ok(serde_json::to_writer_pretty(writer, self)?) + serde_json::to_writer_pretty(writer, self).map_err(Error::UIGFOrSRGFSerdeJson) } else { - Ok(serde_json::to_writer(writer, self)?) + serde_json::to_writer(writer, self).map_err(Error::UIGFOrSRGFSerdeJson) } } } diff --git a/src-tauri/src/gacha/uigf.rs b/src-tauri/src/gacha/uigf.rs index 20a18261..ae82f7ea 100644 --- a/src-tauri/src/gacha/uigf.rs +++ b/src-tauri/src/gacha/uigf.rs @@ -68,14 +68,14 @@ impl UIGF { } pub fn from_reader(reader: impl Read) -> Result { - Ok(serde_json::from_reader(reader)?) + serde_json::from_reader(reader).map_err(Error::UIGFOrSRGFSerdeJson) } pub fn to_writer(&self, writer: impl Write, pretty: bool) -> Result<()> { if pretty { - Ok(serde_json::to_writer_pretty(writer, self)?) + serde_json::to_writer_pretty(writer, self).map_err(Error::UIGFOrSRGFSerdeJson) } else { - Ok(serde_json::to_writer(writer, self)?) + serde_json::to_writer(writer, self).map_err(Error::UIGFOrSRGFSerdeJson) } } } diff --git a/src-tauri/src/gacha/utilities.rs b/src-tauri/src/gacha/utilities.rs index 92ce907c..92aa9278 100644 --- a/src-tauri/src/gacha/utilities.rs +++ b/src-tauri/src/gacha/utilities.rs @@ -143,6 +143,10 @@ pub(super) fn lookup_valid_cache_data_dir>(game_data_dir: P) -> R // Read webCaches directory let web_caches_dir = game_data_dir.as_ref().join("webCaches"); + if !web_caches_dir.exists() { + return Err(Error::WebCaches); + } + for entry in read_dir(&web_caches_dir)? { let entry = entry?; let entry_path = entry.path(); @@ -309,13 +313,18 @@ async fn request_gacha_url( ) -> Result> { let response: GachaResponse = reqwest.get(url).send().await?.json().await?; if response.retcode != 0 { - match response.retcode { - -101 => Err(Error::TimeoutdGachaUrl), - -110 => Err(Error::VisitTooFrequentlyGachaUrl), - _ => Err(Error::GachaRecordRetcode { - retcode: response.retcode, + let retcode = response.retcode; + let message = &response.message; + + if retcode == -101 || message.contains("authkey") || message.contains("auth key") { + Err(Error::TimeoutdGachaUrl) + } else if retcode == -110 || message.contains("visit too frequently") { + Err(Error::VisitTooFrequentlyGachaUrl) + } else { + Err(Error::GachaRecordRetcode { + retcode, message: response.message, - }), + }) } } else { Ok(response) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 737d46c6..339d8166 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -7,7 +7,7 @@ }, "package": { "productName": "HoYo_Gacha", - "version": "0.4.0" + "version": "0.4.1" }, "tauri": { "allowlist": { diff --git a/src/components/account/AccountMenuDialog.tsx b/src/components/account/AccountMenuDialog.tsx index 08f80434..69428818 100644 --- a/src/components/account/AccountMenuDialog.tsx +++ b/src/components/account/AccountMenuDialog.tsx @@ -281,13 +281,13 @@ function AccountMenuDialogForm (props: AccountMenuDialogFormProps) { name="gameDataDir" label="游戏数据文件夹" type="text" placeholder={'例如:' + FacetGameDataDirExamples[facet]} variant="filled" size="small" margin="dense" - fullWidth required + fullWidth required multiline disabled={busy} error={!!errors.gameDataDir} helperText={errors.gameDataDir?.message} InputProps={{ ...register('gameDataDir', { - required: '请选择游戏数据目录!' + required: '请选择游戏数据文件夹!' }), readOnly: true, startAdornment: ( diff --git a/src/components/common/VersionChecker.tsx b/src/components/common/VersionChecker.tsx index 86fca6cd..ac28e1b5 100644 --- a/src/components/common/VersionChecker.tsx +++ b/src/components/common/VersionChecker.tsx @@ -47,14 +47,31 @@ export default function VersionChecker () { }, [latestVersion.data, setBusy]) if (!version.data) { - return 版本更新不可用 + return ( + 版本更新不可用 + ) } - if (latestVersion.isLoading) return 加载中... - if (latestVersion.isError) return 检查最新版本失败 + if (latestVersion.isLoading) { + return ( + 检查更新中... + ) + } + + if (latestVersion.isError) { + return ( + + 检查最新版本失败:{latestVersion.error.message} + + ) + } const needUpdate = isNeedUpdate(version.data, latestVersion.data) - if (!needUpdate) return 已是最新版本 + if (!needUpdate) { + return ( + 已是最新版本 + ) + } return (