Compare commits

...
3 Commits
12 changed files with 666 additions and 1082 deletions
+2 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "clash-verge", "name": "clash-verge",
"version": "2.2.2", "version": "--help",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"scripts": { "scripts": {
"dev": "cross-env RUST_BACKTRACE=1 tauri dev -f verge-dev -- --profile fast-dev", "dev": "cross-env RUST_BACKTRACE=1 tauri dev -f verge-dev -- --profile fast-dev",
@@ -17,6 +17,7 @@
"portable": "node scripts/portable.mjs", "portable": "node scripts/portable.mjs",
"portable-fixed-webview2": "node scripts/portable-fixed-webview2.mjs", "portable-fixed-webview2": "node scripts/portable-fixed-webview2.mjs",
"fix-alpha-version": "node scripts/fix-alpha_version.mjs", "fix-alpha-version": "node scripts/fix-alpha_version.mjs",
"release-version": "node scripts/release_version.mjs",
"release-alpha-version": "node scripts/release-alpha_version.mjs", "release-alpha-version": "node scripts/release-alpha_version.mjs",
"prepare": "husky", "prepare": "husky",
"clean": "cd ./src-tauri && cargo clean && cd -" "clean": "cd ./src-tauri && cargo clean && cd -"
+1 -3
View File
@@ -1,9 +1,8 @@
use super::CmdResult; use super::CmdResult;
use crate::{core::CoreManager, module::mihomo::MihomoManager}; use crate::module::mihomo::MihomoManager;
#[tauri::command] #[tauri::command]
pub async fn get_proxies() -> CmdResult<serde_json::Value> { pub async fn get_proxies() -> CmdResult<serde_json::Value> {
CoreManager::global().ensure_running_core().await;
let mannager = MihomoManager::global(); let mannager = MihomoManager::global();
let proxies = mannager let proxies = mannager
.refresh_proxies() .refresh_proxies()
@@ -15,7 +14,6 @@ pub async fn get_proxies() -> CmdResult<serde_json::Value> {
#[tauri::command] #[tauri::command]
pub async fn get_providers_proxies() -> CmdResult<serde_json::Value> { pub async fn get_providers_proxies() -> CmdResult<serde_json::Value> {
CoreManager::global().ensure_running_core().await;
let mannager = MihomoManager::global(); let mannager = MihomoManager::global();
let providers = mannager let providers = mannager
.refresh_providers_proxies() .refresh_providers_proxies()
+1 -1
View File
@@ -47,7 +47,7 @@ pub async fn get_system_info() -> CmdResult<String> {
pub async fn get_running_mode() -> Result<String, String> { pub async fn get_running_mode() -> Result<String, String> {
match CoreManager::global().get_running_mode().await { match CoreManager::global().get_running_mode().await {
core::RunningMode::Service => Ok("service".to_string()), core::RunningMode::Service => Ok("service".to_string()),
core::RunningMode::Sidecar => Ok("sidecar".to_string()), core::RunningMode::Sidecar => Ok("standalone".to_string()),
core::RunningMode::NotRunning => Ok("not_running".to_string()), core::RunningMode::NotRunning => Ok("not_running".to_string()),
} }
} }
+372 -902
View File
File diff suppressed because it is too large Load Diff
-38
View File
@@ -3,15 +3,11 @@ use once_cell::sync::OnceCell;
use parking_lot::RwLock; use parking_lot::RwLock;
use std::sync::Arc; use std::sync::Arc;
use tauri::{AppHandle, Emitter, Manager, WebviewWindow}; use tauri::{AppHandle, Emitter, Manager, WebviewWindow};
use tauri_plugin_shell::process::CommandChild;
use std::fs::File;
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub struct Handle { pub struct Handle {
pub app_handle: Arc<RwLock<Option<AppHandle>>>, pub app_handle: Arc<RwLock<Option<AppHandle>>>,
pub is_exiting: Arc<RwLock<bool>>, pub is_exiting: Arc<RwLock<bool>>,
pub core_process: Arc<RwLock<Option<CommandChild>>>,
pub core_lock: Arc<RwLock<Option<File>>>,
} }
impl Handle { impl Handle {
@@ -21,8 +17,6 @@ impl Handle {
HANDLE.get_or_init(|| Handle { HANDLE.get_or_init(|| Handle {
app_handle: Arc::new(RwLock::new(None)), app_handle: Arc::new(RwLock::new(None)),
is_exiting: Arc::new(RwLock::new(false)), is_exiting: Arc::new(RwLock::new(false)),
core_process: Arc::new(RwLock::new(None)),
core_lock: Arc::new(RwLock::new(None)),
}) })
} }
@@ -74,39 +68,7 @@ impl Handle {
*is_exiting = true; *is_exiting = true;
} }
pub fn set_core_process(&self, process: CommandChild) {
let mut core_process = self.core_process.write();
*core_process = Some(process);
}
pub fn take_core_process(&self) -> Option<CommandChild> {
let mut core_process = self.core_process.write();
core_process.take()
}
/// 检查是否有运行中的核心进程
pub fn has_core_process(&self) -> bool {
self.core_process.read().is_some()
}
pub fn is_exiting(&self) -> bool { pub fn is_exiting(&self) -> bool {
*self.is_exiting.read() *self.is_exiting.read()
} }
/// 设置核心文件锁
pub fn set_core_lock(&self, file: File) {
let mut core_lock = self.core_lock.write();
*core_lock = Some(file);
}
/// 释放核心文件锁
pub fn release_core_lock(&self) -> Option<File> {
let mut core_lock = self.core_lock.write();
core_lock.take()
}
/// 检查是否持有核心文件锁
pub fn has_core_lock(&self) -> bool {
self.core_lock.read().is_some()
}
} }
+113 -50
View File
@@ -1,6 +1,9 @@
use crate::{ use crate::{
config::Config, core::handle, feat, log_err, module::lightweight::entry_lightweight_mode, config::Config,
utils::resolve, core::handle,
feat, log_err, logging,
module::lightweight::entry_lightweight_mode,
utils::{logging::Type, resolve},
}; };
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use once_cell::sync::OnceCell; use once_cell::sync::OnceCell;
@@ -26,22 +29,27 @@ impl Hotkey {
let verge = Config::verge(); let verge = Config::verge();
let enable_global_hotkey = verge.latest().enable_global_hotkey.unwrap_or(true); let enable_global_hotkey = verge.latest().enable_global_hotkey.unwrap_or(true);
println!( logging!(
"Initializing hotkeys, global hotkey enabled: {}", info,
Type::Hotkey,
true,
"Initializing hotkeys with enable: {}",
enable_global_hotkey enable_global_hotkey
); );
log::info!(target: "app", "Initializing hotkeys, global hotkey enabled: {}", enable_global_hotkey);
// 如果全局热键被禁用,则不注册热键 // 如果全局热键被禁用,则不注册热键
if !enable_global_hotkey { if !enable_global_hotkey {
println!("Global hotkey is disabled, skipping registration");
log::info!(target: "app", "Global hotkey is disabled, skipping registration");
return Ok(()); return Ok(());
} }
if let Some(hotkeys) = verge.latest().hotkeys.as_ref() { if let Some(hotkeys) = verge.latest().hotkeys.as_ref() {
println!("Found {} hotkeys to register", hotkeys.len()); logging!(
log::info!(target: "app", "Found {} hotkeys to register", hotkeys.len()); info,
Type::Hotkey,
true,
"Has {} hotkeys need to register",
hotkeys.len()
);
for hotkey in hotkeys.iter() { for hotkey in hotkeys.iter() {
let mut iter = hotkey.split(','); let mut iter = hotkey.split(',');
@@ -50,28 +58,52 @@ impl Hotkey {
match (key, func) { match (key, func) {
(Some(key), Some(func)) => { (Some(key), Some(func)) => {
println!("Registering hotkey: {} -> {}", key, func); logging!(
log::info!(target: "app", "Registering hotkey: {} -> {}", key, func); info,
Type::Hotkey,
true,
"Registering hotkey: {} -> {}",
key,
func
);
if let Err(e) = self.register(key, func) { if let Err(e) = self.register(key, func) {
println!("Failed to register hotkey {} -> {}: {:?}", key, func, e); logging!(
log::error!(target: "app", "Failed to register hotkey {} -> {}: {:?}", key, func, e); error,
Type::Hotkey,
true,
"Failed to register hotkey {} -> {}: {:?}",
key,
func,
e
);
} else { } else {
println!("Successfully registered hotkey {} -> {}", key, func); logging!(
log::info!(target: "app", "Successfully registered hotkey {} -> {}", key, func); info,
Type::Hotkey,
true,
"Successfully registered hotkey {} -> {}",
key,
func
);
} }
} }
_ => { _ => {
let key = key.unwrap_or("None"); let key = key.unwrap_or("None");
let func = func.unwrap_or("None"); let func = func.unwrap_or("None");
println!("Invalid hotkey configuration: `{key}`:`{func}`"); logging!(
log::error!(target: "app", "Invalid hotkey configuration: `{key}`:`{func}`"); error,
Type::Hotkey,
true,
"Invalid hotkey configuration: `{}`:`{}`",
key,
func
);
} }
} }
} }
self.current.lock().clone_from(hotkeys); self.current.lock().clone_from(hotkeys);
} else { } else {
println!("No hotkeys configured"); logging!(info, Type::Hotkey, true, "No hotkeys configured");
log::info!(target: "app", "No hotkeys configured");
} }
Ok(()) Ok(())
@@ -88,45 +120,60 @@ impl Hotkey {
let app_handle = handle::Handle::global().app_handle().unwrap(); let app_handle = handle::Handle::global().app_handle().unwrap();
let manager = app_handle.global_shortcut(); let manager = app_handle.global_shortcut();
println!( logging!(
info,
Type::Hotkey,
true,
"Attempting to register hotkey: {} for function: {}", "Attempting to register hotkey: {} for function: {}",
hotkey, func hotkey,
func
); );
log::info!(target: "app", "Attempting to register hotkey: {} for function: {}", hotkey, func);
if manager.is_registered(hotkey) { if manager.is_registered(hotkey) {
println!( logging!(
info,
Type::Hotkey,
true,
"Hotkey {} was already registered, unregistering first", "Hotkey {} was already registered, unregistering first",
hotkey hotkey
); );
log::info!(target: "app", "Hotkey {} was already registered, unregistering first", hotkey);
manager.unregister(hotkey)?; manager.unregister(hotkey)?;
} }
let f = match func.trim() { let f = match func.trim() {
"open_or_close_dashboard" => { "open_or_close_dashboard" => {
println!("Registering open_or_close_dashboard function"); logging!(
log::info!(target: "app", "Registering open_or_close_dashboard function"); info,
Type::Hotkey,
true,
"Registering open_or_close_dashboard function"
);
|| { || {
println!("=== Hotkey Dashboard Window Operation Start ==="); logging!(
log::info!(target: "app", "=== Hotkey Dashboard Window Operation Start ==="); info,
Type::Hotkey,
true,
"=== Hotkey Dashboard Window Operation Start ==="
);
// 使用 spawn_blocking 来确保在正确的线程上执行 // 使用 spawn_blocking 来确保在正确的线程上执行
async_runtime::spawn_blocking(|| { async_runtime::spawn_blocking(|| {
println!("Toggle dashboard window visibility"); logging!(
log::info!(target: "app", "Toggle dashboard window visibility"); info,
Type::Hotkey,
true,
"Toggle dashboard window visibility"
);
// 检查窗口是否存在 // 检查窗口是否存在
if let Some(window) = handle::Handle::global().get_window() { if let Some(window) = handle::Handle::global().get_window() {
// 如果窗口可见,则隐藏它 // 如果窗口可见,则隐藏它
if window.is_visible().unwrap_or(false) { if window.is_visible().unwrap_or(false) {
println!("Window is visible, hiding it"); logging!(info, Type::Window, true, "Window is visible, hiding it");
log::info!(target: "app", "Window is visible, hiding it");
let _ = window.hide(); let _ = window.hide();
} else { } else {
// 如果窗口不可见,则显示它 // 如果窗口不可见,则显示它
println!("Window is hidden, showing it"); logging!(info, Type::Window, true, "Window is hidden, showing it");
log::info!(target: "app", "Window is hidden, showing it");
if window.is_minimized().unwrap_or(false) { if window.is_minimized().unwrap_or(false) {
let _ = window.unminimize(); let _ = window.unminimize();
} }
@@ -135,14 +182,22 @@ impl Hotkey {
} }
} else { } else {
// 如果窗口不存在,创建一个新窗口 // 如果窗口不存在,创建一个新窗口
println!("Window does not exist, creating a new one"); logging!(
log::info!(target: "app", "Window does not exist, creating a new one"); info,
Type::Window,
true,
"Window does not exist, creating a new one"
);
resolve::create_window(); resolve::create_window();
} }
}); });
println!("=== Hotkey Dashboard Window Operation End ==="); logging!(
log::info!(target: "app", "=== Hotkey Dashboard Window Operation End ==="); info,
Type::Hotkey,
true,
"=== Hotkey Dashboard Window Operation End ==="
);
} }
} }
"clash_mode_rule" => || feat::change_clash_mode("rule".into()), "clash_mode_rule" => || feat::change_clash_mode("rule".into()),
@@ -156,8 +211,7 @@ impl Hotkey {
"hide" => || feat::hide(), "hide" => || feat::hide(),
_ => { _ => {
println!("Invalid function: {}", func); logging!(error, Type::Hotkey, true, "Invalid function: {}", func);
log::error!(target: "app", "Invalid function: {}", func);
bail!("invalid function \"{func}\""); bail!("invalid function \"{func}\"");
} }
}; };
@@ -166,21 +220,18 @@ impl Hotkey {
let _ = manager.on_shortcut(hotkey, move |app_handle, hotkey, event| { let _ = manager.on_shortcut(hotkey, move |app_handle, hotkey, event| {
if event.state == ShortcutState::Pressed { if event.state == ShortcutState::Pressed {
println!("Hotkey pressed: {:?}", hotkey); logging!(info, Type::Hotkey, true, "Hotkey pressed: {:?}", hotkey);
log::info!(target: "app", "Hotkey pressed: {:?}", hotkey);
if hotkey.key == Code::KeyQ && is_quit { if hotkey.key == Code::KeyQ && is_quit {
if let Some(window) = app_handle.get_webview_window("main") { if let Some(window) = app_handle.get_webview_window("main") {
if window.is_focused().unwrap_or(false) { if window.is_focused().unwrap_or(false) {
println!("Executing quit function"); logging!(info, Type::Hotkey, true, "Executing quit function");
log::info!(target: "app", "Executing quit function");
f(); f();
} }
} }
} else { } else {
// 直接执行函数,不做任何状态检查 // 直接执行函数,不做任何状态检查
println!("Executing function directly"); logging!(info, Type::Hotkey, true, "Executing function directly");
log::info!(target: "app", "Executing function directly");
// 获取全局热键状态 // 获取全局热键状态
let is_enable_global_hotkey = Config::verge() let is_enable_global_hotkey = Config::verge()
@@ -203,8 +254,14 @@ impl Hotkey {
} }
}); });
println!("Successfully registered hotkey {} for {}", hotkey, func); logging!(
log::info!(target: "app", "Successfully registered hotkey {} for {}", hotkey, func); info,
Type::Hotkey,
true,
"Successfully registered hotkey {} for {}",
hotkey,
func
);
Ok(()) Ok(())
} }
@@ -212,7 +269,7 @@ impl Hotkey {
let app_handle = handle::Handle::global().app_handle().unwrap(); let app_handle = handle::Handle::global().app_handle().unwrap();
let manager = app_handle.global_shortcut(); let manager = app_handle.global_shortcut();
manager.unregister(hotkey)?; manager.unregister(hotkey)?;
log::debug!(target: "app", "unregister hotkey {hotkey}"); logging!(debug, Type::Hotkey, true, "Unregister hotkey {}", hotkey);
Ok(()) Ok(())
} }
@@ -285,7 +342,13 @@ impl Drop for Hotkey {
fn drop(&mut self) { fn drop(&mut self) {
let app_handle = handle::Handle::global().app_handle().unwrap(); let app_handle = handle::Handle::global().app_handle().unwrap();
if let Err(e) = app_handle.global_shortcut().unregister_all() { if let Err(e) = app_handle.global_shortcut().unregister_all() {
log::error!(target:"app", "Error unregistering all hotkeys: {:?}", e); logging!(
error,
Type::Hotkey,
true,
"Error unregistering all hotkeys: {:?}",
e
);
} }
} }
} }
+59 -37
View File
@@ -1,7 +1,17 @@
use crate::{config::Config, utils::dirs}; use crate::{
config::Config,
logging,
utils::{dirs, logging::Type},
};
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{collections::HashMap, env::current_exe, path::PathBuf, process::Command as StdCommand, time::{SystemTime, UNIX_EPOCH}}; use std::{
collections::HashMap,
env::current_exe,
path::PathBuf,
process::Command as StdCommand,
time::{SystemTime, UNIX_EPOCH},
};
use tokio::time::Duration; use tokio::time::Duration;
// Windows only // Windows only
@@ -11,15 +21,15 @@ const REQUIRED_SERVICE_VERSION: &str = "1.0.5"; // 定义所需的服务版本
// 限制重装时间和次数的常量 // 限制重装时间和次数的常量
const REINSTALL_COOLDOWN_SECS: u64 = 300; // 5分钟冷却期 const REINSTALL_COOLDOWN_SECS: u64 = 300; // 5分钟冷却期
const MAX_REINSTALLS_PER_DAY: u32 = 3; // 每24小时最多重装3次 const MAX_REINSTALLS_PER_DAY: u32 = 3; // 每24小时最多重装3次
const ONE_DAY_SECS: u64 = 86400; // 24小时的秒数 const ONE_DAY_SECS: u64 = 86400; // 24小时的秒数
#[derive(Debug, Deserialize, Serialize, Clone, Default)] #[derive(Debug, Deserialize, Serialize, Clone, Default)]
pub struct ServiceState { pub struct ServiceState {
pub last_install_time: u64, // 上次安装时间戳 (Unix 时间戳,秒) pub last_install_time: u64, // 上次安装时间戳 (Unix 时间戳,秒)
pub install_count: u32, // 24小时内安装次数 pub install_count: u32, // 24小时内安装次数
pub last_check_time: u64, // 上次检查时间 pub last_check_time: u64, // 上次检查时间
pub last_error: Option<String>, // 上次错误信息 pub last_error: Option<String>, // 上次错误信息
} }
impl ServiceState { impl ServiceState {
@@ -47,12 +57,12 @@ impl ServiceState {
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)
.unwrap_or_default() .unwrap_or_default()
.as_secs(); .as_secs();
// 检查是否需要重置计数器(24小时已过) // 检查是否需要重置计数器(24小时已过)
if now - self.last_install_time > ONE_DAY_SECS { if now - self.last_install_time > ONE_DAY_SECS {
self.install_count = 0; self.install_count = 0;
} }
self.last_install_time = now; self.last_install_time = now;
self.install_count += 1; self.install_count += 1;
} }
@@ -63,17 +73,19 @@ impl ServiceState {
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)
.unwrap_or_default() .unwrap_or_default()
.as_secs(); .as_secs();
// 如果在冷却期内,不允许重装 // 如果在冷却期内,不允许重装
if now - self.last_install_time < REINSTALL_COOLDOWN_SECS { if now - self.last_install_time < REINSTALL_COOLDOWN_SECS {
return false; return false;
} }
// 如果24小时内安装次数过多,也不允许 // 如果24小时内安装次数过多,也不允许
if now - self.last_install_time < ONE_DAY_SECS && self.install_count >= MAX_REINSTALLS_PER_DAY { if now - self.last_install_time < ONE_DAY_SECS
&& self.install_count >= MAX_REINSTALLS_PER_DAY
{
return false; return false;
} }
true true
} }
} }
@@ -112,7 +124,7 @@ pub async fn reinstall_service() -> Result<()> {
// 获取当前服务状态 // 获取当前服务状态
let mut service_state = ServiceState::get(); let mut service_state = ServiceState::get();
// 检查是否允许重装 // 检查是否允许重装
if !service_state.can_reinstall() { if !service_state.can_reinstall() {
log::warn!(target:"app", "service reinstall rejected: cooldown period or max attempts reached"); log::warn!(target:"app", "service reinstall rejected: cooldown period or max attempts reached");
@@ -327,7 +339,7 @@ pub async fn check_service_version() -> Result<String> {
pub async fn check_service_needs_reinstall() -> bool { pub async fn check_service_needs_reinstall() -> bool {
// 获取当前服务状态 // 获取当前服务状态
let service_state = ServiceState::get(); let service_state = ServiceState::get();
// 首先检查是否在冷却期或超过重装次数限制 // 首先检查是否在冷却期或超过重装次数限制
if !service_state.can_reinstall() { if !service_state.can_reinstall() {
log::info!(target: "app", "service reinstall check: in cooldown period or max attempts reached"); log::info!(target: "app", "service reinstall check: in cooldown period or max attempts reached");
@@ -339,21 +351,21 @@ pub async fn check_service_needs_reinstall() -> bool {
Ok(version) => { Ok(version) => {
// 打印更详细的日志,方便排查问题 // 打印更详细的日志,方便排查问题
log::info!(target: "app", "服务版本检测:当前={}, 要求={}", version, REQUIRED_SERVICE_VERSION); log::info!(target: "app", "服务版本检测:当前={}, 要求={}", version, REQUIRED_SERVICE_VERSION);
let needs_reinstall = version != REQUIRED_SERVICE_VERSION; let needs_reinstall = version != REQUIRED_SERVICE_VERSION;
if needs_reinstall { if needs_reinstall {
log::warn!(target: "app", "发现服务版本不匹配,需要重装! 当前={}, 要求={}", log::warn!(target: "app", "发现服务版本不匹配,需要重装! 当前={}, 要求={}",
version, REQUIRED_SERVICE_VERSION); version, REQUIRED_SERVICE_VERSION);
// 打印版本字符串的原始字节,确认没有隐藏字符 // 打印版本字符串的原始字节,确认没有隐藏字符
log::debug!(target: "app", "当前版本字节: {:?}", version.as_bytes()); log::debug!(target: "app", "当前版本字节: {:?}", version.as_bytes());
log::debug!(target: "app", "要求版本字节: {:?}", REQUIRED_SERVICE_VERSION.as_bytes()); log::debug!(target: "app", "要求版本字节: {:?}", REQUIRED_SERVICE_VERSION.as_bytes());
} else { } else {
log::info!(target: "app", "服务版本匹配,无需重装"); log::info!(target: "app", "服务版本匹配,无需重装");
} }
needs_reinstall needs_reinstall
}, }
Err(err) => { Err(err) => {
// 检查服务是否可用,如果可用但版本检查失败,可能只是版本API有问题 // 检查服务是否可用,如果可用但版本检查失败,可能只是版本API有问题
match is_service_running().await { match is_service_running().await {
@@ -421,9 +433,9 @@ pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> {
// 先检查服务版本,不受冷却期限制 // 先检查服务版本,不受冷却期限制
let version_check = match check_service_version().await { let version_check = match check_service_version().await {
Ok(version) => { Ok(version) => {
log::info!(target: "app", "检测到服务版本: {}, 要求版本: {}", log::info!(target: "app", "检测到服务版本: {}, 要求版本: {}",
version, REQUIRED_SERVICE_VERSION); version, REQUIRED_SERVICE_VERSION);
// 通过字节比较确保完全匹配 // 通过字节比较确保完全匹配
if version.as_bytes() != REQUIRED_SERVICE_VERSION.as_bytes() { if version.as_bytes() != REQUIRED_SERVICE_VERSION.as_bytes() {
log::warn!(target: "app", "服务版本不匹配,需要重装"); log::warn!(target: "app", "服务版本不匹配,需要重装");
@@ -432,7 +444,7 @@ pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> {
log::info!(target: "app", "服务版本匹配"); log::info!(target: "app", "服务版本匹配");
true // 版本匹配 true // 版本匹配
} }
}, }
Err(err) => { Err(err) => {
log::warn!(target: "app", "无法获取服务版本: {}", err); log::warn!(target: "app", "无法获取服务版本: {}", err);
false // 无法获取版本 false // 无法获取版本
@@ -447,11 +459,11 @@ pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> {
return start_with_existing_service(config_file).await; return start_with_existing_service(config_file).await;
} }
} }
// 强制执行版本检查,如果版本不匹配则重装 // 强制执行版本检查,如果版本不匹配则重装
if !version_check { if !version_check {
log::info!(target: "app", "服务版本不匹配,尝试重装"); log::info!(target: "app", "服务版本不匹配,尝试重装");
// 获取服务状态,检查是否可以重装 // 获取服务状态,检查是否可以重装
let service_state = ServiceState::get(); let service_state = ServiceState::get();
if !service_state.can_reinstall() { if !service_state.can_reinstall() {
@@ -464,22 +476,22 @@ pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> {
bail!("服务版本不匹配且无法重装,启动失败"); bail!("服务版本不匹配且无法重装,启动失败");
} }
} }
// 尝试重装 // 尝试重装
log::info!(target: "app", "开始重装服务"); log::info!(target: "app", "开始重装服务");
if let Err(err) = reinstall_service().await { if let Err(err) = reinstall_service().await {
log::warn!(target: "app", "服务重装失败: {}", err); log::warn!(target: "app", "服务重装失败: {}", err);
// 尝试使用现有服务 // 尝试使用现有服务
log::info!(target: "app", "尝试使用现有服务"); log::info!(target: "app", "尝试使用现有服务");
return start_with_existing_service(config_file).await; return start_with_existing_service(config_file).await;
} }
// 重装成功,尝试启动 // 重装成功,尝试启动
log::info!(target: "app", "服务重装成功,尝试启动"); log::info!(target: "app", "服务重装成功,尝试启动");
return start_with_existing_service(config_file).await; return start_with_existing_service(config_file).await;
} }
// 检查服务状态 // 检查服务状态
match check_service().await { match check_service().await {
Ok(_) => { Ok(_) => {
@@ -488,22 +500,22 @@ pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> {
if let Ok(()) = start_with_existing_service(config_file).await { if let Ok(()) = start_with_existing_service(config_file).await {
return Ok(()); return Ok(());
} }
}, }
Err(err) => { Err(err) => {
log::warn!(target: "app", "服务检查失败: {}", err); log::warn!(target: "app", "服务检查失败: {}", err);
} }
} }
// 服务不可用或启动失败,检查是否需要重装 // 服务不可用或启动失败,检查是否需要重装
if check_service_needs_reinstall().await { if check_service_needs_reinstall().await {
log::info!(target: "app", "服务需要重装"); log::info!(target: "app", "服务需要重装");
// 尝试重装 // 尝试重装
if let Err(err) = reinstall_service().await { if let Err(err) = reinstall_service().await {
log::warn!(target: "app", "服务重装失败: {}", err); log::warn!(target: "app", "服务重装失败: {}", err);
bail!("Failed to reinstall service: {}", err); bail!("Failed to reinstall service: {}", err);
} }
// 重装后再次尝试启动 // 重装后再次尝试启动
log::info!(target: "app", "服务重装完成,尝试启动核心"); log::info!(target: "app", "服务重装完成,尝试启动核心");
start_with_existing_service(config_file).await start_with_existing_service(config_file).await
@@ -534,12 +546,22 @@ pub async fn is_service_running() -> Result<bool> {
// 检查服务状态码和消息 // 检查服务状态码和消息
if resp.code == 0 && resp.msg == "ok" && resp.data.is_some() { if resp.code == 0 && resp.msg == "ok" && resp.data.is_some() {
logging!(debug, Type::Service, "Service is running");
Ok(true) Ok(true)
} else { } else {
logging!(debug, Type::Service, "Service is not running");
Ok(false) Ok(false)
} }
} }
pub async fn is_service_available() -> Result<()> {
let resp = check_service().await?;
if resp.code == 0 && resp.msg == "ok" && resp.data.is_some() {
logging!(debug, Type::Service, "Service is available");
}
Ok(())
}
/// 强制重装服务(用于UI中的修复服务按钮) /// 强制重装服务(用于UI中的修复服务按钮)
pub async fn force_reinstall_service() -> Result<()> { pub async fn force_reinstall_service() -> Result<()> {
log::info!(target: "app", "用户请求强制重装服务"); log::info!(target: "app", "用户请求强制重装服务");
@@ -547,15 +569,15 @@ pub async fn force_reinstall_service() -> Result<()> {
// 创建默认服务状态(重置所有限制) // 创建默认服务状态(重置所有限制)
let service_state = ServiceState::default(); let service_state = ServiceState::default();
service_state.save()?; service_state.save()?;
log::info!(target: "app", "已重置服务状态,开始执行重装"); log::info!(target: "app", "已重置服务状态,开始执行重装");
// 执行重装 // 执行重装
match reinstall_service().await { match reinstall_service().await {
Ok(()) => { Ok(()) => {
log::info!(target: "app", "服务重装成功"); log::info!(target: "app", "服务重装成功");
Ok(()) Ok(())
}, }
Err(err) => { Err(err) => {
log::error!(target: "app", "强制重装服务失败: {}", err); log::error!(target: "app", "强制重装服务失败: {}", err);
bail!("强制重装服务失败: {}", err) bail!("强制重装服务失败: {}", err)
-3
View File
@@ -47,8 +47,6 @@ pub fn change_clash_mode(mode: String) {
}); });
tauri::async_runtime::spawn(async move { tauri::async_runtime::spawn(async move {
log::debug!(target: "app", "change clash mode to {mode}"); log::debug!(target: "app", "change clash mode to {mode}");
CoreManager::global().ensure_running_core().await;
match MihomoManager::global().patch_configs(json_value).await { match MihomoManager::global().patch_configs(json_value).await {
Ok(_) => { Ok(_) => {
// 更新订阅 // 更新订阅
@@ -67,7 +65,6 @@ pub fn change_clash_mode(mode: String) {
/// Test connection delay to a URL /// Test connection delay to a URL
pub async fn test_delay(url: String) -> anyhow::Result<u32> { pub async fn test_delay(url: String) -> anyhow::Result<u32> {
CoreManager::global().ensure_running_core().await;
use tokio::time::{Duration, Instant}; use tokio::time::{Duration, Instant};
let mut builder = reqwest::ClientBuilder::new().use_rustls_tls().no_proxy(); let mut builder = reqwest::ClientBuilder::new().use_rustls_tls().no_proxy();
+1 -1
View File
@@ -37,7 +37,7 @@ impl PlatformSpecification {
tokio::runtime::Handle::current().block_on(async { tokio::runtime::Handle::current().block_on(async {
match CoreManager::global().get_running_mode().await { match CoreManager::global().get_running_mode().await {
crate::core::RunningMode::Service => "Service".to_string(), crate::core::RunningMode::Service => "Service".to_string(),
crate::core::RunningMode::Sidecar => "Sidecar".to_string(), crate::core::RunningMode::Sidecar => "Standalone".to_string(),
crate::core::RunningMode::NotRunning => "Not Running".to_string(), crate::core::RunningMode::NotRunning => "Not Running".to_string(),
} }
}) })
-46
View File
@@ -136,52 +136,6 @@ pub fn linux_elevator() -> String {
} }
} }
#[macro_export]
macro_rules! error {
($result: expr) => {
log::error!(target: "app", "{}", $result);
};
}
#[macro_export]
macro_rules! log_err {
($result: expr) => {
if let Err(err) = $result {
log::error!(target: "app", "{err}");
}
};
($result: expr, $err_str: expr) => {
if let Err(_) = $result {
log::error!(target: "app", "{}", $err_str);
}
};
}
#[macro_export]
macro_rules! trace_err {
($result: expr, $err_str: expr) => {
if let Err(err) = $result {
log::trace!(target: "app", "{}, err {}", $err_str, err);
}
}
}
/// wrap the anyhow error
/// transform the error to String
#[macro_export]
macro_rules! wrap_err {
($stat: expr) => {
match $stat {
Ok(a) => Ok(a),
Err(err) => {
log::error!(target: "app", "{}", err.to_string());
Err(format!("{}", err.to_string()))
}
}
};
}
/// return the string literal error /// return the string literal error
#[macro_export] #[macro_export]
macro_rules! ret_err { macro_rules! ret_err {
+116
View File
@@ -0,0 +1,116 @@
use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Type {
Core,
Service,
Hotkey,
Window,
}
impl fmt::Display for Type {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Type::Core => write!(f, "[Core]"),
Type::Service => write!(f, "[Service]"),
Type::Hotkey => write!(f, "[Hotkey]"),
Type::Window => write!(f, "[Window]"),
}
}
}
#[macro_export]
macro_rules! error {
($result: expr) => {
log::error!(target: "app", "{}", $result);
};
}
#[macro_export]
macro_rules! log_err {
($result: expr) => {
if let Err(err) = $result {
log::error!(target: "app", "{err}");
}
};
($result: expr, $err_str: expr) => {
if let Err(_) = $result {
log::error!(target: "app", "{}", $err_str);
}
};
}
#[macro_export]
macro_rules! trace_err {
($result: expr, $err_str: expr) => {
if let Err(err) = $result {
log::trace!(target: "app", "{}, err {}", $err_str, err);
}
}
}
/// wrap the anyhow error
/// transform the error to String
#[macro_export]
macro_rules! wrap_err {
($stat: expr) => {
match $stat {
Ok(a) => Ok(a),
Err(err) => {
log::error!(target: "app", "{}", err.to_string());
Err(format!("{}", err.to_string()))
}
}
};
}
#[macro_export]
macro_rules! logging {
// 带 println 的版本(支持格式化参数)
($level:ident, $type:expr, $print:expr, $($arg:tt)*) => {
println!("{} {}", $type, format_args!($($arg)*));
log::$level!(target: "app", "{} {}", $type, format_args!($($arg)*));
};
// 不带 println 的版本
($level:ident, $type:expr, $($arg:tt)*) => {
log::$level!(target: "app", "{} {}", $type, format_args!($($arg)*));
};
}
#[macro_export]
macro_rules! logging_error {
// Version with println and Result expression
($type:expr, $print:expr, $expr:expr) => {
match $expr {
Ok(_) => {},
Err(err) => {
if $print {
println!("[{}] Error: {}", $type, err);
}
log::error!(target: "app", "{} {}", $type, err);
}
}
};
// Version without println and Result expression
($type:expr, $expr:expr) => {
if let Err(err) = $expr {
log::error!(target: "app", "{} {}", $type, err);
}
};
// Version with println and custom message
($type:expr, $print:expr, $($arg:tt)*) => {
if $print {
println!("[{}] {}", $type, format_args!($($arg)*));
}
log::error!(target: "app", "{} {}", $type, format_args!($($arg)*));
};
// Version without println and custom message
($type:expr, $($arg:tt)*) => {
log::error!(target: "app", "{} {}", $type, format_args!($($arg)*));
};
}
+1
View File
@@ -3,6 +3,7 @@ pub mod error;
pub mod help; pub mod help;
pub mod i18n; pub mod i18n;
pub mod init; pub mod init;
pub mod logging;
pub mod resolve; pub mod resolve;
pub mod server; pub mod server;
pub mod tmpl; pub mod tmpl;