diff --git a/README.md b/README.md index 0d448c3..f3d51fe 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ ## 其他事项 - 使用tauri做的,所以会有web页面,改动一下应该是可以做一个通过网页控制的应用 -- tauri发布2.0正式版后是可以打包安卓和ios的,不过正常应该没有这个需求 +- tauri发布2.0正式版后是可以打包安卓和ios的, ~~不过正常应该没有这个需求。~~ 怎么说呢,安卓应该是可以保持后台运行的,ios由于有墓碑机制,不一定可能顺利做出来。需求来自[这里](https://github.com/orgs/MaaAssistantArknights/discussions/10468) - 稳定性如何? - 实话实说,由于本来我技术栈不在前端和rust,所以我自己也对这个没有保障,目前阶段将就着用吧 - 为什么不发布windows包? diff --git a/components.d.ts b/components.d.ts index 4b953f0..87e3a79 100644 --- a/components.d.ts +++ b/components.d.ts @@ -7,6 +7,7 @@ export {} /* prettier-ignore */ declare module 'vue' { export interface GlobalComponents { + AboutMaaBo: typeof import('./src/components/AboutMaaBo.vue')['default'] AwardSetting: typeof import('./src/components/OneKey/AwardSetting.vue')['default'] ElAffix: typeof import('element-plus/es')['ElAffix'] ElButton: typeof import('element-plus/es')['ElButton'] @@ -30,10 +31,12 @@ declare module 'vue' { ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] ElSelect: typeof import('element-plus/es')['ElSelect'] ElSlider: typeof import('element-plus/es')['ElSlider'] + ElSpace: typeof import('element-plus/es')['ElSpace'] ElSwitch: typeof import('element-plus/es')['ElSwitch'] ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] ElTabPane: typeof import('element-plus/es')['ElTabPane'] ElTabs: typeof import('element-plus/es')['ElTabs'] + ElTag: typeof import('element-plus/es')['ElTag'] ElText: typeof import('element-plus/es')['ElText'] ElTooltip: typeof import('element-plus/es')['ElTooltip'] FightSetting: typeof import('./src/components/OneKey/FightSetting.vue')['default'] diff --git a/package-lock.json b/package-lock.json index 1b61ce0..7bc3435 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "element-plus": "^2.8.1", "moment": "^2.30.1", "pinia": "^2.1.7", - "vue": "^3.4.29", + "vue": "^3.5.2", "vue-router": "^4.3.3" }, "devDependencies": { @@ -1305,39 +1305,39 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.0.tgz", - "integrity": "sha512-ja7cpqAOfw4tyFAxgBz70Z42miNDeaqTxExTsnXDLomRpqfyCgyvZvFp482fmsElpfvsoMJUsvzULhvxUTW6Iw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.3.tgz", + "integrity": "sha512-adAfy9boPkP233NTyvLbGEqVuIfK/R0ZsBsIOW4BZNfb4BRpRW41Do1u+ozJpsb+mdoy80O20IzAsHaihRb5qA==", "license": "MIT", "dependencies": { "@babel/parser": "^7.25.3", - "@vue/shared": "3.5.0", + "@vue/shared": "3.5.3", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.0.tgz", - "integrity": "sha512-xYjUybWZXl+1R/toDy815i4PbeehL2hThiSGkcpmIOCy2HoYyeeC/gAWK/Y/xsoK+GSw198/T5O31bYuQx5uvQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.3.tgz", + "integrity": "sha512-wnzFArg9zpvk/811CDOZOadJRugf1Bgl/TQ3RfV4nKfSPok4hi0w10ziYUQR6LnnBAUlEXYLUfZ71Oj9ds/+QA==", "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.0", - "@vue/shared": "3.5.0" + "@vue/compiler-core": "3.5.3", + "@vue/shared": "3.5.3" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.0.tgz", - "integrity": "sha512-B9DgLtrqok2GLuaFjLlSL15ZG3ZDBiitUH1ecex9guh/ZcA5MCdwuVE6nsfQxktuZY/QY0awJ35/ripIviCQTQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.3.tgz", + "integrity": "sha512-P3uATLny2tfyvMB04OQFe7Sczteno7SLFxwrOA/dw01pBWQHB5HL15a8PosoNX2aG/EAMGqnXTu+1LnmzFhpTQ==", "license": "MIT", "dependencies": { "@babel/parser": "^7.25.3", - "@vue/compiler-core": "3.5.0", - "@vue/compiler-dom": "3.5.0", - "@vue/compiler-ssr": "3.5.0", - "@vue/shared": "3.5.0", + "@vue/compiler-core": "3.5.3", + "@vue/compiler-dom": "3.5.3", + "@vue/compiler-ssr": "3.5.3", + "@vue/shared": "3.5.3", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.44", @@ -1345,13 +1345,13 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.0.tgz", - "integrity": "sha512-E263QZmA1dqRd7c3u/sWTLRMpQOT0aZ8av/L9SoD/v/BVMZaWFHPUUBswS+bzrfvG2suJF8vSLKx6k6ba5SUdA==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.3.tgz", + "integrity": "sha512-F/5f+r2WzL/2YAPl7UlKcJWHrvoZN8XwEBLnT7S4BXwncH25iDOabhO2M2DWioyTguJAGavDOawejkFXj8EM1w==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.0", - "@vue/shared": "3.5.0" + "@vue/compiler-dom": "3.5.3", + "@vue/shared": "3.5.3" } }, "node_modules/@vue/compiler-vue2": { @@ -1437,53 +1437,53 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.0.tgz", - "integrity": "sha512-Ew3F5riP3B3ZDGjD3ZKb9uZylTTPSqt8hAf4sGbvbjrjDjrFb3Jm15Tk1/w7WwTE5GbQ2Qhwxx1moc9hr8A/OQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.3.tgz", + "integrity": "sha512-2w61UnRWTP7+rj1H/j6FH706gRBHdFVpIqEkSDAyIpafBXYH8xt4gttstbbCWdU3OlcSWO8/3mbKl/93/HSMpw==", "license": "MIT", "dependencies": { - "@vue/shared": "3.5.0" + "@vue/shared": "3.5.3" } }, "node_modules/@vue/runtime-core": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.0.tgz", - "integrity": "sha512-mQyW0F9FaNRdt8ghkAs+BMG3iQ7LGgWKOpkzUzR5AI5swPNydHGL5hvVTqFaeMzwecF1g0c86H4yFQsSxJhH1w==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.3.tgz", + "integrity": "sha512-5b2AQw5OZlmCzSsSBWYoZOsy75N4UdMWenTfDdI5bAzXnuVR7iR8Q4AOzQm2OGoA41xjk53VQKrqQhOz2ktWaw==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.0", - "@vue/shared": "3.5.0" + "@vue/reactivity": "3.5.3", + "@vue/shared": "3.5.3" } }, "node_modules/@vue/runtime-dom": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.0.tgz", - "integrity": "sha512-NQQXjpdXgyYVJ2M56FJ+lSJgZiecgQ2HhxhnQBN95FymXegRNY/N2htI7vOTwpP75pfxhIeYOJ8mE8sW8KAW6A==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.3.tgz", + "integrity": "sha512-wPR1DEGc3XnQ7yHbmkTt3GoY0cEnVGQnARRdAkDzZ8MbUKEs26gogCQo6AOvvgahfjIcnvWJzkZArQ1fmWjcSg==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.0", - "@vue/runtime-core": "3.5.0", - "@vue/shared": "3.5.0", + "@vue/reactivity": "3.5.3", + "@vue/runtime-core": "3.5.3", + "@vue/shared": "3.5.3", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.0.tgz", - "integrity": "sha512-HyDIFUg+l7L4PKrEnJlCYWHUOlm6NxZhmSxIefZ5MTYjkIPfDfkwhX7hqxAQHfgIAE1uLMLQZwuNR/ozI0NhZg==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.3.tgz", + "integrity": "sha512-28volmaZVG2PGO3V3+gBPKoSHvLlE8FGfG/GKXKkjjfxLuj/50B/0OQGakM/g6ehQeqCrZYM4eHC4Ks48eig1Q==", "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.5.0", - "@vue/shared": "3.5.0" + "@vue/compiler-ssr": "3.5.3", + "@vue/shared": "3.5.3" }, "peerDependencies": { - "vue": "3.5.0" + "vue": "3.5.3" } }, "node_modules/@vue/shared": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.0.tgz", - "integrity": "sha512-m9IgiteBpCkFaMNwCOBkFksA7z8QiKc30ooRuoXWUFRDu0mGyNPlFHmbncF0/Kra1RlX8QrmBbRaIxVvikaR0Q==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.3.tgz", + "integrity": "sha512-Jp2v8nylKBT+PlOUjun2Wp/f++TfJVFjshLzNtJDdmFJabJa7noGMncqXRM1vXGX+Yo2V7WykQFNxusSim8SCA==", "license": "MIT" }, "node_modules/@vue/tsconfig": { @@ -4353,16 +4353,16 @@ "license": "MIT" }, "node_modules/vue": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.0.tgz", - "integrity": "sha512-1t70favYoFijwfWJ7g81aTd32obGaAnKYE9FNyMgnEzn3F4YncRi/kqAHHKloG0VXTD8vBYMhbgLKCA+Sk6QDw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.3.tgz", + "integrity": "sha512-xvRbd0HpuLovYbOHXRHlSBsSvmUJbo0pzbkKTApWnQGf3/cu5Z39mQeA5cZdLRVIoNf3zI6MSoOgHUT5i2jO+Q==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.0", - "@vue/compiler-sfc": "3.5.0", - "@vue/runtime-dom": "3.5.0", - "@vue/server-renderer": "3.5.0", - "@vue/shared": "3.5.0" + "@vue/compiler-dom": "3.5.3", + "@vue/compiler-sfc": "3.5.3", + "@vue/runtime-dom": "3.5.3", + "@vue/server-renderer": "3.5.3", + "@vue/shared": "3.5.3" }, "peerDependencies": { "typescript": "*" diff --git a/package.json b/package.json index 8eb986c..fbaaae0 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "element-plus": "^2.8.1", "moment": "^2.30.1", "pinia": "^2.1.7", - "vue": "^3.4.29", + "vue": "^3.5.2", "vue-router": "^4.3.3" }, "devDependencies": { diff --git a/src-tauri/src/consts.rs b/src-tauri/src/consts.rs index 2ebb0f0..36a704b 100644 --- a/src-tauri/src/consts.rs +++ b/src-tauri/src/consts.rs @@ -1,6 +1,9 @@ pub const SUCCESS: i32 = 0; -pub const MAA_CLI_NEED_UPDATE:i32 = 50; +pub const MAA_CLI_NEED_UPDATE: i32 = 50; pub const DONE: i32 = 1; pub const ERROR: i32 = -999; -pub const MAA_STATUS_STOP:u8 = 0; -pub const MAA_STATUS_RUNNING:u8 = 1; \ No newline at end of file +pub const MAA_STATUS_STOP: u8 = 0; +pub const MAA_STATUS_RUNNING: u8 = 1; +pub const MAABO_ONLINE_VERSION_URL: &str = + "https://api.github.com/repos/BoredTape/MaaBo/releases/latest"; +pub const REQUEST_QA:&str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0"; diff --git a/src-tauri/src/events/config.rs b/src-tauri/src/events/config.rs index cb9b71c..0e87e6a 100644 --- a/src-tauri/src/events/config.rs +++ b/src-tauri/src/events/config.rs @@ -156,4 +156,22 @@ pub fn get_item_index() -> payload::Payload { .unwrap_or_else(|err| panic!("读取{}失败:{}",maa_cli::data_dir().join(&"resource").join(&"item_index.json").to_str().unwrap(), err.to_string())); let data =serde_json::from_str(&item_index_str).unwrap_or_else(|err| panic!("读取{}失败:{}",maa_cli::data_dir().join(&"resource").join(&"item_index.json").to_str().unwrap(), err.to_string())); payload::new(consts::SUCCESS, "success".to_string(), data) +} + +#[tauri::command] +pub fn get_fight_stages() -> payload::Payload { + let fight_stages_str = + fs::read_to_string(maa_cli::data_dir().join(&"resource").join(&"stages.json")) + .unwrap_or_else(|err| panic!("读取{}失败:{}",maa_cli::data_dir().join(&"resource").join(&"stages.json").to_str().unwrap(), err.to_string())); + let data =serde_json::from_str(&fight_stages_str).unwrap_or_else(|err| panic!("读取{}失败:{}",maa_cli::data_dir().join(&"resource").join(&"stages").to_str().unwrap(), err.to_string())); + payload::new(consts::SUCCESS, "success".to_string(), data) +} + +#[tauri::command] +pub fn get_current_sidestory() -> payload::Payload { + let sidestory_stages_str = + fs::read_to_string(maa_cli::data_dir().join(&"MaaResource").join(&"cache").join(&"resource").join(&"tasks.json")) + .unwrap_or_else(|err| panic!("读取{}失败:{}",maa_cli::data_dir().join(&"MaaResource").join(&"cache").join(&"resource").join(&"tasks.json").to_str().unwrap(), err.to_string())); + let data =serde_json::from_str(&sidestory_stages_str).unwrap_or_else(|err| panic!("读取{}失败:{}",maa_cli::data_dir().join(&"MaaResource").join(&"cache").join(&"resource").join(&"tasks.json").to_str().unwrap(), err.to_string())); + payload::new(consts::SUCCESS, "success".to_string(), data) } \ No newline at end of file diff --git a/src-tauri/src/events/consts.rs b/src-tauri/src/events/consts.rs index dfb68f6..8691f16 100644 --- a/src-tauri/src/events/consts.rs +++ b/src-tauri/src/events/consts.rs @@ -1,4 +1,4 @@ pub const EVENT_GLOBAL_NOTIFICATION: &str = "global_notification"; pub const EVENT_INIT_MSG: &str = "init_msg"; pub const EVENT_UPDATE_CONFIG_STATUS: &str = "update_config_status"; -pub const EVENT_UPDATE_MAA_CLI:&str = "maa_cli_update_msg"; +pub const EVENT_UPDATE_MAA_CLI: &str = "maa_cli_update_msg"; diff --git a/src-tauri/src/events/mod.rs b/src-tauri/src/events/mod.rs index de2e4d9..151fe8d 100644 --- a/src-tauri/src/events/mod.rs +++ b/src-tauri/src/events/mod.rs @@ -4,10 +4,12 @@ mod init; mod payload; mod run; mod update; +mod version; pub use config::{ - delete_user_config, get_cli_config, get_item_index, get_user_configs, save_cli_config, - save_core_config, save_task_config, + delete_user_config, get_cli_config, get_current_sidestory, get_fight_stages, get_item_index, + get_user_configs, save_cli_config, save_core_config, save_task_config, }; pub use init::init_process; pub use run::{copilot, one_key, stop}; pub use update::{ignore_maa_cli_update, maa_cli_update_process}; +pub use version::{check_update, version_info}; diff --git a/src-tauri/src/events/version.rs b/src-tauri/src/events/version.rs new file mode 100644 index 0000000..f2d7589 --- /dev/null +++ b/src-tauri/src/events/version.rs @@ -0,0 +1,58 @@ +use serde::Serialize; + +use crate::consts; +use crate::events::payload; +use crate::maa_cli; +use crate::utils; + +#[derive(Debug, Clone, Serialize)] +pub struct VersionInfo { + maabo: String, + maa_cli: String, + maa_core: String, + tauri: String, + webview: String, +} + +#[tauri::command] +pub fn version_info() -> payload::Payload { + let wv_version = tauri::webview_version().unwrap_or_else(|error| { + log::info!("获取webview版本失败,请确认是否安装\n{}", error.to_string()); + "获取失败".to_string() + }); + let (maa_cli_version, maa_core_version) = + maa_cli::get_current_version().unwrap_or_else(|error| { + log::info!("获取本地组件版本失败\n{}", error.to_string()); + return ("获取失败".to_string(), "获取失败".to_string()); + }); + let info = VersionInfo { + maabo: env!("CARGO_PKG_VERSION").to_string(), + maa_cli: maa_cli_version, + maa_core: maa_core_version, + tauri: tauri::VERSION.to_string(), + webview: wv_version, + }; + payload::new(consts::SUCCESS, "success".to_string(), info) +} + +#[derive(Debug, Clone, Serialize)] +pub struct CheckUpdateData { + require_update: bool, + from: String, + to: String, +} + +#[tauri::command] +pub fn check_update() -> payload::Payload { + let online_version = semver::Version::parse(&utils::fetch_online_version()) + .unwrap_or_else(|_| semver::Version::parse(&"0.0.0").unwrap()); + let current_version = semver::Version::parse(env!("CARGO_PKG_VERSION")) + .unwrap_or_else(|_| semver::Version::parse(&"0.0.0").unwrap()); + + let resp_data = CheckUpdateData { + require_update: online_version > current_version, + from: current_version.to_string(), + to: online_version.to_string(), + }; + payload::new(consts::SUCCESS, "success".to_string(), resp_data) +} diff --git a/src-tauri/src/maa_cli/init.rs b/src-tauri/src/maa_cli/init.rs index 80ed1c7..873bdc0 100644 --- a/src-tauri/src/maa_cli/init.rs +++ b/src-tauri/src/maa_cli/init.rs @@ -200,7 +200,7 @@ pub fn init_process(tx: Sender<(i32, String)>) { }); } - maa_utils::get_current_version().unwrap_or_else(|error| { + let (maa_cli_version, _) = maa_utils::get_current_version().unwrap_or_else(|error| { tx.send(( pconsts::SUCCESS, format!("获取MAA CLI本地版本失败:\n{}", error.to_string()), @@ -209,11 +209,20 @@ pub fn init_process(tx: Sender<(i32, String)>) { panic!("获取MAA CLI本地版本失败"); }); + version::set_maa_cli_current_version(&maa_cli_version).unwrap_or_else(|error| { + tx.send(( + pconsts::SUCCESS, + format!("设置MAA CLI本地版本失败:\n{}", error.to_string()), + )) + .unwrap_or_else(|err| log::error!("{}", err.to_string())); + panic!("设置MAA CLI本地版本失败"); + }); let core_lib_dir = maa_utils::core_lib_dir(); if !core_lib_dir.exists() || !core_lib_dir.join(maa_utils::core_lib_name()).exists() { tx.send((pconsts::SUCCESS, "安装MAA CORE".to_string())) .unwrap_or_else(|err| log::error!("{}", err.to_string())); if let Err(error_msg) = maa_utils::install_maa_core() { + log::error!("安装MAA CORE失败,错误:{}", error_msg.to_string()); tx.send((pconsts::ERROR, error_msg.to_string())) .unwrap_or_else(|err| log::error!("{}", err.to_string())); } @@ -224,6 +233,7 @@ pub fn init_process(tx: Sender<(i32, String)>) { let mut maa_update_msg = (pconsts::SUCCESS, "更新资源成功".to_string()); if let Err(error_msg) = maa_utils::maa_update() { + log::error!("更新资源失败{}", error_msg.to_string()); maa_update_msg = (pconsts::ERROR, error_msg.to_string()); } tx.send(maa_update_msg) @@ -233,6 +243,7 @@ pub fn init_process(tx: Sender<(i32, String)>) { loop { if !version::get_maa_cli_ignore_update() { maa_utils::get_remote_version_info().unwrap_or_else(|error| { + log::error!("获取MAA CLI远程更新信息失败:\n{}", error.to_string()); tx.send(( pconsts::ERROR, format!("获取MAA CLI远程更新信息失败:\n{}", error.to_string()), @@ -250,6 +261,7 @@ pub fn init_process(tx: Sender<(i32, String)>) { } thread::sleep(Duration::from_secs(3600)); if let Err(error_msg) = maa_utils::maa_hot_update() { + log::error!("资源热更新失败,错误:{}", error_msg.to_string()); maa_hot_update_msg = ( pconsts::ERROR, format!("资源热更新失败,错误:{}", error_msg.to_string()), diff --git a/src-tauri/src/maa_cli/mod.rs b/src-tauri/src/maa_cli/mod.rs index ffca4d0..21cfd79 100644 --- a/src-tauri/src/maa_cli/mod.rs +++ b/src-tauri/src/maa_cli/mod.rs @@ -5,7 +5,8 @@ mod utils; pub use init::{deploy_latest, init_process}; pub use utils::{ - config_dir, config_name, core_config_dir, data_dir, dir, get_user_config_names, task_dir, + config_dir, config_name, core_config_dir, data_dir, dir, get_current_version, + get_user_config_names, task_dir, }; pub use run::{copilot_process, one_key_process}; diff --git a/src-tauri/src/maa_cli/utils.rs b/src-tauri/src/maa_cli/utils.rs index bbd16a9..0cb3471 100644 --- a/src-tauri/src/maa_cli/utils.rs +++ b/src-tauri/src/maa_cli/utils.rs @@ -155,7 +155,7 @@ fn command_result(command: Result<(os_pipe::PipeReader, Child), Error>) -> Resul Ok(result) } -pub fn get_current_version() -> Result<(), CError> { +pub fn get_current_version() -> Result<(String, String), CError> { let (mut reader, _) = cli_command(&"", vec!["version"]).unwrap(); let mut cmd_text = String::new(); if let Err(error) = reader.read_to_string(&mut cmd_text) { @@ -163,10 +163,12 @@ pub fn get_current_version() -> Result<(), CError> { } let text_array: Vec<&str> = cmd_text.split("\n").collect(); - if text_array.len() < 1 { + if text_array.len() < 2 { return Err(CError::MaaCliLocalVersionError("".to_string())); } - version::set_maa_cli_current_version(&text_array[0].replace("maa-cli v", "")) + let maa_cli_version = &text_array[0].replace("maa-cli v", ""); + let maa_core_version = &text_array[1].replace("MaaCore v", ""); + return Ok((maa_cli_version.to_string(), maa_core_version.to_string())); } #[derive(Debug, Serialize, Deserialize)] diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 8f47ac1..8810942 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -16,12 +16,24 @@ use tauri::{ }; use events::{ - copilot, delete_user_config, get_cli_config, get_item_index, get_user_configs, - ignore_maa_cli_update, init_process, maa_cli_update_process, one_key, save_cli_config, - save_core_config, save_task_config, stop, + check_update, copilot, delete_user_config, get_cli_config, get_current_sidestory, + get_fight_stages, get_item_index, get_user_configs, ignore_maa_cli_update, init_process, + maa_cli_update_process, one_key, save_cli_config, save_core_config, save_task_config, stop, + version_info, }; fn main() { + // 临时解决方案-start + // n卡会白屏,WebKit新版的渲染器与nvidia驱动暂时还不兼容导致 + // 使用env WEBKIT_DISABLE_DMABUF_RENDERER=1可以退回旧版渲染器解决问题 + // 比env WEBKIT_DISABLE_COMPOSITING_MODE=1直接禁用硬件加速好 + // 感谢 @Darkatse + // 详情:https://github.com/BoredTape/MaaBo/pull/1#issuecomment-2333454094 + if std::env::consts::OS == "linux" { + std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1"); + } + // 临时解决方案-end + let maa_bo_dir = maa_cli::dir(); if !maa_bo_dir.exists() { utils::make_dir_exist(&maa_bo_dir).unwrap(); @@ -67,7 +79,11 @@ fn main() { ignore_maa_cli_update, maa_cli_update_process, get_item_index, - copilot + get_fight_stages, + get_current_sidestory, + copilot, + version_info, + check_update ]) .system_tray(tray) .on_system_tray_event(|app, event| match event { diff --git a/src-tauri/src/utils/mod.rs b/src-tauri/src/utils/mod.rs index f4666aa..5fa3acd 100644 --- a/src-tauri/src/utils/mod.rs +++ b/src-tauri/src/utils/mod.rs @@ -2,6 +2,7 @@ use std::{fs, path::PathBuf}; use directories; +use crate::consts; use crate::errors::Error; pub fn get_user_dir() -> Result { @@ -19,3 +20,26 @@ pub fn make_dir_exist(path: &PathBuf) -> Result<(), Error> { } Ok(()) } + +pub fn fetch_online_version() -> String { + let client = reqwest::blocking::Client::new(); + let request = client + .request(reqwest::Method::GET, consts::MAABO_ONLINE_VERSION_URL) + .header("User-Agent", consts::REQUEST_QA); + match request.send() { + Ok(resp) => match resp.json::() { + Ok(json_value) => json_value["tag_name"] + .as_str() + .unwrap_or("0.0.0") + .to_string(), + Err(error) => { + log::info!("获取maabo在线版本失败(format json)\n{}", error.to_string()); + "0.0.0".to_string() + } + }, + Err(error) => { + log::info!("获取maabo在线版本失败\n{}", error.to_string()); + "0.0.0".to_string() + } + } +} diff --git a/src/App.vue b/src/App.vue index 242da0e..d9d40dd 100644 --- a/src/App.vue +++ b/src/App.vue @@ -6,6 +6,31 @@ + + +
+
+ {{ updateMaaboMsg }} +
+
+ +
+ event.preventDefault()) const userConfigStore = UserConfigStore() +const updateMaaboVisible = ref(false) +const updateMaaboMsg = ref('') + +const ignoreMaaboUpdate = () => { + updateMaaboVisible.value = false +} + +const confirmMaaboUpdate = () => { + open('https://github.com/BoredTape/MaaBo/releases/latest') + updateMaaboVisible.value = false +} + +const checkUpdate = async () => { + const checkUpdateData = await CheckMaaBoUpdate() + updateMaaboVisible.value = checkUpdateData.require_update + if (updateMaaboVisible.value) { + updateMaaboMsg.value = 'MaaBo更新: ' + checkUpdateData.from + ' => ' + checkUpdateData.to + } +} + const updateVisible = ref(false) const updateMsg = ref('') const processMsg = ref('该操作会停止所有在运行的MAA') @@ -62,7 +109,6 @@ const update = async () => { const unlisten = await listen('maa_cli_update_msg', (event: any) => { const payload = event.payload as Payload processMsg.value = payload.msg - console.log(payload.msg) if (payload.code === 1) { processMsg.value = processMsg.value + ' 5秒后自动关闭该窗口' ;(async () => { @@ -120,6 +166,7 @@ const listen_update_config_status = async () => { } onMounted(() => { + checkUpdate() listen_update_msg() listen_update_config_status() }) diff --git a/src/apis/FightStages.ts b/src/apis/FightStages.ts new file mode 100644 index 0000000..fa70730 --- /dev/null +++ b/src/apis/FightStages.ts @@ -0,0 +1,105 @@ +import { invoke } from '@tauri-apps/api/tauri'; + +interface StageItem { + value: string; + label: string; +} + +interface StageData { + stageId: string; + code: string; +} + +interface Payload { + code: number; + msg: string; + data: StageData[]; +} + +// 标准 / 磨难 +const StageExtraSuffix = { + NORMAL: '-NORMAL', + TOUGH: '-HARD', +} + +const currentStages: StageItem[] = [ + { label: '当前关卡/上次作战', value: 'NotSpecified' }, +] + +const appendSuffixAndCreateItems = (stage: any, suffix: string) => { + const suffixLabel = suffix === StageExtraSuffix.NORMAL ? ' (标准)' : ' (磨难)'; + return { + value: stage.code + suffix, + label: stage.code + suffixLabel + }; +}; + +const basicSupportStages: StageItem[] = [ + { label: '1-7', value: '1-7' }, + { label: '剿灭', value: 'Annihilation' }, + { label: '龙门币-6/5', value: 'CE-6' }, + { label: '经验-6/5', value: 'LS-6' }, + { label: '红票-5', value: 'AP-5' }, + { label: '技能-5', value: 'CA-5' }, + { label: '重装/医疗-小', value: 'PR-A-1' }, + { label: '重装/医疗-大', value: 'PR-A-2' }, + { label: '狙击/术士-小', value: 'PR-B-1' }, + { label: '狙击/术士-大', value: 'PR-B-2' }, + { label: '辅助/先锋-小', value: 'PR-C-1' }, + { label: '辅助/先锋-大', value: 'PR-C-2' }, + { label: '特种/近卫-小', value: 'PR-D-1' }, + { label: '特种/近卫-大', value: 'PR-D-2' }, +] + +function filterSideStoryStages(sideStoryData: Record): StageItem[] { + const stageItems: StageItem[] = []; + + for (const key of Object.keys(sideStoryData)) { + // 只取出有效的关卡名称 + const parts = key.split('-'); + if (parts.length > 1 && /^\d+$/.test(parts[1])) { + stageItems.push({ + value: key, + label: key + }); + } + } + + return stageItems; +} + +const GetFightStages = async (): Promise => { + try { + const result = await invoke('get_fight_stages'); + const sideStoryData = await invoke('get_current_sidestory'); + + const filteredStages = result.data + .filter(stage => stage.stageId.includes('main') || stage.stageId.includes('sub')) + .flatMap(stage => { + // 只要关卡号开头为9(如 9-1, 9-2 等) + if (stage.code.startsWith('9-')) { + return [appendSuffixAndCreateItems(stage, StageExtraSuffix.NORMAL)]; + } + // 处理关卡号开头为10或更高的情况(如 10-1, 11-1, 12-1 等) + else if (/^1[0-9]-/.test(stage.code)) { + return [ + appendSuffixAndCreateItems(stage, StageExtraSuffix.NORMAL), + appendSuffixAndCreateItems(stage, StageExtraSuffix.TOUGH) + ]; + } + return [{ value: stage.code, label: stage.code }]; + }); + + const filteredSideStoryStages = filterSideStoryStages(sideStoryData.data); + + // 合并全部可选关卡 + return [...currentStages, ...filteredSideStoryStages, ...basicSupportStages, ...filteredStages]; + } catch (error) { + console.error('Failed to retrieve fight stages:', error); + return []; + } +} + +export type { StageItem }; + +export default GetFightStages; \ No newline at end of file diff --git a/src/apis/Version.ts b/src/apis/Version.ts new file mode 100644 index 0000000..9cc6e62 --- /dev/null +++ b/src/apis/Version.ts @@ -0,0 +1,41 @@ +import { invoke } from '@tauri-apps/api/tauri' + + + +interface VersionInfo { + maabo: string + maa_cli: string + maa_core: string + tauri: string + webview: string +} + +interface CheckUpdateData { + require_update: boolean + from: string + to: string +} + +interface Payload { + code: number + msg: string + data: VersionInfo | CheckUpdateData +} + +const GetVersionInfo = async (): Promise => { + let response: any + await invoke('version_info').then((res) => { + response = (res as Payload).data + }) + return response as VersionInfo +} + +const CheckMaaBoUpdate = async (): Promise => { + let response: any + await invoke('check_update').then((res) => { + response = (res as Payload).data + }) + return response as CheckUpdateData +} + +export { GetVersionInfo, type VersionInfo, type CheckUpdateData, CheckMaaBoUpdate } \ No newline at end of file diff --git a/src/components/AboutMaaBo.vue b/src/components/AboutMaaBo.vue new file mode 100644 index 0000000..424e227 --- /dev/null +++ b/src/components/AboutMaaBo.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/src/components/MaaCopilot.vue b/src/components/MaaCopilot.vue index 5b11cbc..035c478 100644 --- a/src/components/MaaCopilot.vue +++ b/src/components/MaaCopilot.vue @@ -99,7 +99,6 @@ const uri = ref('') const autoFormation = ref(false) const scrollbarRef = ref>() const changeText = () => { - console.log() const container = scrollbarRef.value!.$el.querySelector('.el-scrollbar__wrap') container.style.scrollBehavior = 'smooth' container.scrollTop = container.scrollHeight diff --git a/src/components/OneKey/FightSetting.vue b/src/components/OneKey/FightSetting.vue index 394ce0f..6e4c4cd 100644 --- a/src/components/OneKey/FightSetting.vue +++ b/src/components/OneKey/FightSetting.vue @@ -56,8 +56,10 @@ > @@ -91,14 +93,21 @@ " > - - - + + (userConfigStore.GetTaskParams('Fight') as FightTaskParams) @@ -136,6 +147,9 @@ const userConfig = ref(userConfigStore.GetConfig(userConfigStore.selectedConfig) const saveSetting = () => { drops_set() + if (stage_value.value !== 'NotSpecified') { + params.value.stage = stage_value.value + } if (userConfig.value!.status === 0) { userConfigStore.SaveTask() } @@ -144,14 +158,19 @@ const saveSetting = () => { const drops_value = ref('NotSpecified') const drops_times = ref(1) -const drops_options = ref() -const selectLoading = ref(false) -const GetItem = async (visible: boolean) => { - if (visible) { - selectLoading.value = true - drops_options.value = await GetFightItems() - selectLoading.value = false +const drops_options = ref([]) +const dropsLoading = ref(false) +const fetchDrops = async (query: string) => { + dropsLoading.value = true + const fight_items = await GetFightItems() + if (query !== '') { + drops_options.value = fight_items.filter((item) => { + return item.label.includes(query) + }) + } else { + drops_options.value = fight_items } + dropsLoading.value = false } const drops_set = () => { @@ -168,9 +187,35 @@ const drops_set = () => { } } +// Reactive data for stages +const stage_options = ref([]) +const StageLoading = ref(false) +const stage_value = ref('NotSpecified') + +// Fetch stages data when needed +const fetchStages = async (query: string) => { + StageLoading.value = true + const fight_stages = await GetFightStages() + if (query !== '') { + stage_options.value = fight_stages.filter((item) => { + return item.label.includes(query) + }) + } else { + stage_options.value = fight_stages + } + StageLoading.value = false +} + onMounted(() => { + // 如果不加这个,重新打开的时候不能正常读取label + fetchDrops('') + fetchStages('') + if (params.value.drops) { - drops_value.value = Object.keys(params.value.drops)[0] + drops_value.value = Object.keys(params.value.drops!)[0] + } + if (params.value.stage !== '') { + stage_value.value = params.value.stage } }) diff --git a/src/components/OneKey/RoguelikeSetting.vue b/src/components/OneKey/RoguelikeSetting.vue index 44fe2b2..df31a0e 100644 --- a/src/components/OneKey/RoguelikeSetting.vue +++ b/src/components/OneKey/RoguelikeSetting.vue @@ -23,6 +23,7 @@ + @@ -40,7 +41,7 @@ @change="modeChange" :disabled="userConfig!.status == 1 && params.enable" > - + diff --git a/src/views/SettingsView.vue b/src/views/SettingsView.vue index 076a3f7..9e635b8 100644 --- a/src/views/SettingsView.vue +++ b/src/views/SettingsView.vue @@ -2,6 +2,7 @@ +