From 5b6c9be99f8907bc89c793e564544a12587b6fa3 Mon Sep 17 00:00:00 2001 From: Tunglies Date: Mon, 12 May 2025 19:04:08 +0800 Subject: [PATCH] feat: better service status and TUN mode usable checks in Setting Page --- src-tauri/src/cmd/clash.rs | 3 +- src-tauri/src/cmd/service.rs | 9 ++++ src-tauri/src/config/prfitem.rs | 10 ++-- src-tauri/src/core/service.rs | 8 +-- src-tauri/src/core/service_ipc.rs | 23 +++++---- src-tauri/src/core/tray/mod.rs | 11 +++- src-tauri/src/core/tray/speed_rate.rs | 6 ++- src-tauri/src/feat/proxy.rs | 13 ----- src-tauri/src/lib.rs | 1 + src-tauri/src/utils/logging.rs | 4 +- src-tauri/src/utils/network.rs | 6 ++- src/components/setting/setting-system.tsx | 61 ++++++++++++----------- src/hooks/use-system-state.ts | 41 +++++++++------ src/services/cmds.ts | 19 +++++-- 14 files changed, 127 insertions(+), 88 deletions(-) diff --git a/src-tauri/src/cmd/clash.rs b/src-tauri/src/cmd/clash.rs index abaa9514d..c790a350e 100644 --- a/src-tauri/src/cmd/clash.rs +++ b/src-tauri/src/cmd/clash.rs @@ -237,8 +237,7 @@ pub async fn get_dns_config_content() -> CmdResult { /// 验证DNS配置文件 #[tauri::command] pub async fn validate_dns_config() -> CmdResult<(bool, String)> { - use crate::core::CoreManager; - use crate::utils::dirs; + use crate::{core::CoreManager, utils::dirs}; let app_dir = dirs::app_home_dir().map_err(|e| e.to_string())?; let dns_path = app_dir.join("dns_config.yaml"); diff --git a/src-tauri/src/cmd/service.rs b/src-tauri/src/cmd/service.rs index fc8efdc15..96b9ff5f0 100644 --- a/src-tauri/src/cmd/service.rs +++ b/src-tauri/src/cmd/service.rs @@ -1,6 +1,7 @@ use super::CmdResult; use crate::{ core::{service, CoreManager}, + feat, utils::i18n::t, }; @@ -38,3 +39,11 @@ pub async fn reinstall_service() -> CmdResult { pub async fn repair_service() -> CmdResult { execute_service_operation(service::force_reinstall_service(), "Repair").await } + +#[tauri::command] +pub async fn is_service_available() -> CmdResult { + service::is_service_available() + .await + .map(|_| true) + .map_err(|e| e.to_string()) +} diff --git a/src-tauri/src/config/prfitem.rs b/src-tauri/src/config/prfitem.rs index a062ead9e..a900256e2 100644 --- a/src-tauri/src/config/prfitem.rs +++ b/src-tauri/src/config/prfitem.rs @@ -1,11 +1,13 @@ -use crate::utils::network::{NetworkManager, ProxyType}; -use crate::utils::{dirs, help, tmpl}; +use crate::utils::{ + dirs, help, + network::{NetworkManager, ProxyType}, + tmpl, +}; use anyhow::{bail, Context, Result}; use reqwest::StatusCode; use serde::{Deserialize, Serialize}; use serde_yaml::Mapping; -use std::fs; -use std::time::Duration; +use std::{fs, time::Duration}; use super::Config; diff --git a/src-tauri/src/core/service.rs b/src-tauri/src/core/service.rs index 3b81b508e..d19d89c9e 100644 --- a/src-tauri/src/core/service.rs +++ b/src-tauri/src/core/service.rs @@ -473,7 +473,7 @@ pub async fn reinstall_service() -> Result<()> { } /// 检查服务状态 - 使用IPC通信 -pub async fn check_service() -> Result { +pub async fn check_ipc_service_status() -> Result { logging!(info, Type::Service, true, "开始检查服务状态 (IPC)"); // 使用IPC通信 @@ -876,7 +876,7 @@ pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> { } // 检查服务状态 - match check_service().await { + match check_ipc_service_status().await { Ok(_) => { log::info!(target: "app", "服务可用但未运行核心,尝试启动"); if let Ok(()) = start_with_existing_service(config_file).await { @@ -947,7 +947,7 @@ pub(super) async fn stop_core_by_service() -> Result<()> { pub async fn is_service_running() -> Result { logging!(info, Type::Service, true, "开始检查服务是否正在运行"); - match check_service().await { + match check_ipc_service_status().await { Ok(resp) => { if resp.code == 0 && resp.msg == "ok" && resp.data.is_some() { logging!(info, Type::Service, true, "服务正在运行"); @@ -1010,7 +1010,7 @@ pub async fn is_service_running() -> Result { pub async fn is_service_available() -> Result<()> { logging!(info, Type::Service, true, "开始检查服务是否可用"); - match check_service().await { + match check_ipc_service_status().await { Ok(resp) => { if resp.code == 0 && resp.msg == "ok" && resp.data.is_some() { logging!(info, Type::Service, true, "服务可用"); diff --git a/src-tauri/src/core/service_ipc.rs b/src-tauri/src/core/service_ipc.rs index b1d9640e4..a0c6f93e1 100644 --- a/src-tauri/src/core/service_ipc.rs +++ b/src-tauri/src/core/service_ipc.rs @@ -1,5 +1,4 @@ -use crate::logging; -use crate::utils::logging::Type; +use crate::{logging, utils::logging::Type}; use anyhow::{bail, Context, Result}; use hmac::{Hmac, Mac}; use serde::{Deserialize, Serialize}; @@ -117,14 +116,18 @@ pub async fn send_ipc_request( command: IpcCommand, payload: serde_json::Value, ) -> Result { - use std::ffi::CString; - use std::fs::File; - use std::io::{Read, Write}; - use std::os::windows::io::{FromRawHandle, RawHandle}; - use std::ptr; - use winapi::um::fileapi::{CreateFileA, OPEN_EXISTING}; - use winapi::um::handleapi::INVALID_HANDLE_VALUE; - use winapi::um::winnt::{FILE_SHARE_READ, FILE_SHARE_WRITE, GENERIC_READ, GENERIC_WRITE}; + use std::{ + ffi::CString, + fs::File, + io::{Read, Write}, + os::windows::io::{FromRawHandle, RawHandle}, + ptr, + }; + use winapi::um::{ + fileapi::{CreateFileA, OPEN_EXISTING}, + handleapi::INVALID_HANDLE_VALUE, + winnt::{FILE_SHARE_READ, FILE_SHARE_WRITE, GENERIC_READ, GENERIC_WRITE}, + }; logging!( info, diff --git a/src-tauri/src/core/tray/mod.rs b/src-tauri/src/core/tray/mod.rs index a7dafda35..2d08d7d11 100644 --- a/src-tauri/src/core/tray/mod.rs +++ b/src-tauri/src/core/tray/mod.rs @@ -5,13 +5,14 @@ pub mod speed_rate; use crate::{ cmd, config::Config, - feat, + feat, logging, module::{ lightweight::{entry_lightweight_mode, is_in_lightweight_mode}, mihomo::Rate, }, resolve, utils::{dirs::find_target_icons, i18n::t, resolve::VERSION}, + Type, }; use anyhow::Result; @@ -828,7 +829,13 @@ fn on_menu_event(_: &AppHandle, event: MenuEvent) { match event.id.as_ref() { mode @ ("rule_mode" | "global_mode" | "direct_mode") => { let mode = &mode[0..mode.len() - 5]; - println!("change mode to: {}", mode); + logging!( + info, + Type::ProxyMode, + true, + "Switch Proxy Mode To: {}", + mode + ); feat::change_clash_mode(mode.into()); } "open_window" => { diff --git a/src-tauri/src/core/tray/speed_rate.rs b/src-tauri/src/core/tray/speed_rate.rs index c36fc0ac2..000ffcebb 100644 --- a/src-tauri/src/core/tray/speed_rate.rs +++ b/src-tauri/src/core/tray/speed_rate.rs @@ -240,8 +240,10 @@ pub struct Traffic { impl Traffic { pub async fn get_traffic_stream() -> Result>> { - use futures::future::FutureExt; - use futures::stream::{self, StreamExt}; + use futures::{ + future::FutureExt, + stream::{self, StreamExt}, + }; use std::time::Duration; // 先处理错误和超时情况 diff --git a/src-tauri/src/feat/proxy.rs b/src-tauri/src/feat/proxy.rs index feef34b79..b76243029 100644 --- a/src-tauri/src/feat/proxy.rs +++ b/src-tauri/src/feat/proxy.rs @@ -43,19 +43,6 @@ pub fn toggle_system_proxy() { /// Toggle TUN mode on/off pub fn toggle_tun_mode(not_save_file: Option) { - // AsyncHandler::spawn(async { - // logging!( - // info, - // Type::Service, - // true, - // "Toggle TUN mode need install service" - // ); - // if is_service_available().await.is_err() { - // logging_error!(Type::Service, true, install_service().await); - // } - // logging_error!(Type::Core, true, CoreManager::global().restart_core().await); - // }); - let enable = Config::verge().data().enable_tun_mode; let enable = enable.unwrap_or(false); diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index f905a15cc..ac01be12a 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -235,6 +235,7 @@ pub fn run() { cmd::uninstall_service, cmd::reinstall_service, cmd::repair_service, + cmd::is_service_available, // clash cmd::get_clash_info, cmd::patch_clash_config, diff --git a/src-tauri/src/utils/logging.rs b/src-tauri/src/utils/logging.rs index 3255c1c3a..aff7849ee 100644 --- a/src-tauri/src/utils/logging.rs +++ b/src-tauri/src/utils/logging.rs @@ -1,4 +1,4 @@ -use std::fmt; +use std::fmt::{self, write}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Type { @@ -16,6 +16,7 @@ pub enum Type { Backup, Lightweight, Network, + ProxyMode, } impl fmt::Display for Type { @@ -35,6 +36,7 @@ impl fmt::Display for Type { Type::Backup => write!(f, "[Backup]"), Type::Lightweight => write!(f, "[Lightweight]"), Type::Network => write!(f, "[Network]"), + Type::ProxyMode => write!(f, "[ProxMode]"), } } } diff --git a/src-tauri/src/utils/network.rs b/src-tauri/src/utils/network.rs index 542e2ef9e..897cec804 100644 --- a/src-tauri/src/utils/network.rs +++ b/src-tauri/src/utils/network.rs @@ -1,8 +1,10 @@ use anyhow::Result; use lazy_static::lazy_static; use reqwest::{Client, ClientBuilder, Proxy, RequestBuilder, Response}; -use std::sync::{Arc, Mutex, Once}; -use std::time::{Duration, Instant}; +use std::{ + sync::{Arc, Mutex, Once}, + time::{Duration, Instant}, +}; use tokio::runtime::{Builder, Runtime}; use crate::{config::Config, logging, utils::logging::Type}; diff --git a/src/components/setting/setting-system.tsx b/src/components/setting/setting-system.tsx index 29232c5fd..fe60ac579 100644 --- a/src/components/setting/setting-system.tsx +++ b/src/components/setting/setting-system.tsx @@ -20,6 +20,7 @@ import { getAutotemProxy, installService, getAutoLaunchStatus, + restartCore, } from "@/services/cmds"; import { useLockFn } from "ahooks"; import { Button, Tooltip } from "@mui/material"; @@ -41,25 +42,18 @@ const SettingSystem = ({ onError }: Props) => { const { data: autoLaunchEnabled } = useSWR( "getAutoLaunchStatus", getAutoLaunchStatus, - { revalidateOnFocus: false } + { revalidateOnFocus: false }, ); - const { isAdminMode, isSidecarMode, mutateRunningMode } = useSystemState(); + const { isAdminMode, isSidecarMode, mutateRunningMode, isServiceOk } = + useSystemState(); + + console.log("Is service running:", isServiceOk); // 判断Tun模式是否可用 - 当处于服务模式或管理员模式时可用 - const isTunAvailable = !isSidecarMode || isAdminMode; + const isTunAvailable = isServiceOk || (isSidecarMode && !isAdminMode); - // 当实际自启动状态与配置不同步时更新配置 - useEffect(() => { - if ( - autoLaunchEnabled !== undefined && - verge && - verge.enable_auto_launch !== autoLaunchEnabled - ) { - // 静默更新配置,不触发UI刷新 - mutateVerge({ ...verge, enable_auto_launch: autoLaunchEnabled }, false); - } - }, [autoLaunchEnabled]); + console.log("is tun isTunAvailable:", isTunAvailable); const sysproxyRef = useRef(null); const tunRef = useRef(null); @@ -87,13 +81,16 @@ const SettingSystem = ({ onError }: Props) => { // 安装系统服务 const onInstallService = useLockFn(async () => { try { - showNotice('info', t("Installing Service..."), 1000); + showNotice("info", t("Installing Service..."), 1000); await installService(); - showNotice('success', t("Service Installed Successfully"), 2000); + showNotice("success", t("Service Installed Successfully"), 2000); + await restartCore(); + showNotice("info", t("Restarting Core"), 1000); + console.log("restartCore"); // 重新获取运行模式 await mutateRunningMode(); } catch (err: any) { - showNotice('error', err.message || err.toString(), 3000); + showNotice("error", err.message || err.toString(), 3000); } }); @@ -111,12 +108,12 @@ const SettingSystem = ({ onError }: Props) => { icon={SettingsRounded} onClick={() => tunRef.current?.open()} /> - {isSidecarMode && !isAdminMode && ( + {!isServiceOk && !isAdminMode && ( )} - {isSidecarMode && !isAdminMode && ( + {!isServiceOk && !isAdminMode && (