logs translated from Chinese into English
This commit is contained in:
@@ -30,7 +30,7 @@ async fn cleanup_processing_state(sequence: u64, reason: &str) {
|
||||
info,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"{},清理状态,序列号: {}",
|
||||
"{},Cleanup status, serial number: {}",
|
||||
reason,
|
||||
sequence
|
||||
);
|
||||
@@ -55,14 +55,14 @@ pub async fn get_profiles() -> CmdResult<IProfiles> {
|
||||
|
||||
match latest_result {
|
||||
Ok(Ok(profiles)) => {
|
||||
logging!(info, Type::Cmd, false, "快速获取配置列表成功");
|
||||
logging!(info, Type::Cmd, false, "Quickly fetched profiles list successfully");
|
||||
return Ok(profiles);
|
||||
}
|
||||
Ok(Err(join_err)) => {
|
||||
logging!(warn, Type::Cmd, true, "快速获取配置任务失败: {}", join_err);
|
||||
logging!(warn, Type::Cmd, true, "Quick profile list fetch task failed: {}", join_err);
|
||||
}
|
||||
Err(_) => {
|
||||
logging!(warn, Type::Cmd, true, "快速获取配置超时(500ms)");
|
||||
logging!(warn, Type::Cmd, true, "Quick profile list fetch timeout (500ms)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ pub async fn get_profiles() -> CmdResult<IProfiles> {
|
||||
|
||||
match data_result {
|
||||
Ok(Ok(profiles)) => {
|
||||
logging!(info, Type::Cmd, false, "获取draft配置列表成功");
|
||||
logging!(info, Type::Cmd, false, "Fetched draft profile list successfully");
|
||||
return Ok(profiles);
|
||||
}
|
||||
Ok(Err(join_err)) => {
|
||||
@@ -90,12 +90,12 @@ pub async fn get_profiles() -> CmdResult<IProfiles> {
|
||||
error,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"获取draft配置任务失败: {}",
|
||||
"Failed to obtain draft configuration task: {}",
|
||||
join_err
|
||||
);
|
||||
}
|
||||
Err(_) => {
|
||||
logging!(error, Type::Cmd, true, "获取draft配置超时(2秒)");
|
||||
logging!(error, Type::Cmd, true, "Draft profile list fetch timeout (2s)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,16 +104,16 @@ pub async fn get_profiles() -> CmdResult<IProfiles> {
|
||||
warn,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"所有获取配置策略都失败,尝试fallback"
|
||||
"All attempts to obtain configuration policies failed. Trying fallback"
|
||||
);
|
||||
|
||||
match tokio::task::spawn_blocking(IProfiles::new).await {
|
||||
Ok(profiles) => {
|
||||
logging!(info, Type::Cmd, true, "使用fallback配置成功");
|
||||
logging!(info, Type::Cmd, true, "Fallback profiles created successfully");
|
||||
Ok(profiles)
|
||||
}
|
||||
Err(err) => {
|
||||
logging!(error, Type::Cmd, true, "fallback配置也失败: {}", err);
|
||||
logging!(error, Type::Cmd, true, "Fallback profiles creation failed: {}", err);
|
||||
// 返回空配置避免崩溃
|
||||
Ok(IProfiles {
|
||||
current: None,
|
||||
@@ -268,7 +268,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
info,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"开始修改配置文件,请求序列号: {}, 目标profile: {:?}",
|
||||
"Starting to modify profiles, sequence: {}, target profile: {:?}",
|
||||
current_sequence,
|
||||
target_profile
|
||||
);
|
||||
@@ -285,7 +285,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
info,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"检测到更新的请求 (序列号: {} < {}),放弃当前请求",
|
||||
"Newer request detected (seq: {} < {}), abandoning current",
|
||||
current_sequence,
|
||||
latest_sequence
|
||||
);
|
||||
@@ -295,7 +295,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
info,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"强制获取锁以处理最新请求: {}",
|
||||
"Force acquiring lock to process latest request: {}",
|
||||
current_sequence
|
||||
);
|
||||
PROFILE_UPDATE_MUTEX.lock().await
|
||||
@@ -308,7 +308,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
info,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"获取锁后发现更新的请求 (序列号: {} < {}),放弃当前请求",
|
||||
"After acquiring lock, found newer request (seq: {} < {}), abandoning current",
|
||||
current_sequence,
|
||||
latest_sequence
|
||||
);
|
||||
@@ -317,12 +317,12 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
|
||||
// 保存当前配置,以便在验证失败时恢复
|
||||
let current_profile = Config::profiles().latest().current.clone();
|
||||
logging!(info, Type::Cmd, true, "当前配置: {:?}", current_profile);
|
||||
logging!(info, Type::Cmd, true, "Current profile: {:?}", current_profile);
|
||||
|
||||
// 如果要切换配置,先检查目标配置文件是否有语法错误
|
||||
if let Some(new_profile) = profiles.current.as_ref() {
|
||||
if current_profile.as_ref() != Some(new_profile) {
|
||||
logging!(info, Type::Cmd, true, "正在切换到新配置: {}", new_profile);
|
||||
logging!(info, Type::Cmd, true, "Switching to new profile: {}", new_profile);
|
||||
|
||||
// 获取目标配置文件路径
|
||||
let config_file_result = {
|
||||
@@ -338,7 +338,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
logging!(error, Type::Cmd, true, "获取目标配置信息失败: {}", e);
|
||||
logging!(error, Type::Cmd, true, "Failed to get target profile info: {}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -351,7 +351,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
error,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"目标配置文件不存在: {}",
|
||||
"Target profile does not exist: {}",
|
||||
file_path.display()
|
||||
);
|
||||
handle::Handle::notice_message(
|
||||
@@ -377,7 +377,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
|
||||
match yaml_parse_result {
|
||||
Ok(Ok(_)) => {
|
||||
logging!(info, Type::Cmd, true, "目标配置文件语法正确");
|
||||
logging!(info, Type::Cmd, true, "Target profile file syntax is correct");
|
||||
}
|
||||
Ok(Err(err)) => {
|
||||
let error_msg = format!(" {err}");
|
||||
@@ -385,7 +385,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
error,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"目标配置文件存在YAML语法错误:{}",
|
||||
"YAML syntax error in target profile file: {}",
|
||||
error_msg
|
||||
);
|
||||
handle::Handle::notice_message(
|
||||
@@ -395,7 +395,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
return Ok(false);
|
||||
}
|
||||
Err(join_err) => {
|
||||
let error_msg = format!("YAML解析任务失败: {join_err}");
|
||||
let error_msg = format!("YAML parse task failed: {join_err}");
|
||||
logging!(error, Type::Cmd, true, "{}", error_msg);
|
||||
handle::Handle::notice_message(
|
||||
"config_validate::yaml_parse_error",
|
||||
@@ -406,7 +406,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
}
|
||||
}
|
||||
Ok(Err(err)) => {
|
||||
let error_msg = format!("无法读取目标配置文件: {err}");
|
||||
let error_msg = format!("Failed to read target profile file: {err}");
|
||||
logging!(error, Type::Cmd, true, "{}", error_msg);
|
||||
handle::Handle::notice_message(
|
||||
"config_validate::file_read_error",
|
||||
@@ -415,7 +415,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
return Ok(false);
|
||||
}
|
||||
Err(_) => {
|
||||
let error_msg = "读取配置文件超时(5秒)".to_string();
|
||||
let error_msg = "Reading config file timed out (5s)".to_string();
|
||||
logging!(error, Type::Cmd, true, "{}", error_msg);
|
||||
handle::Handle::notice_message(
|
||||
"config_validate::file_read_timeout",
|
||||
@@ -435,7 +435,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
info,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"在核心操作前发现更新的请求 (序列号: {} < {}),放弃当前请求",
|
||||
"Found newer request before core operation (seq: {} < {}), abandoning current",
|
||||
current_sequence,
|
||||
latest_sequence
|
||||
);
|
||||
@@ -448,7 +448,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
info,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"设置当前处理profile: {}, 序列号: {}",
|
||||
"Set current processing profile: {}, serial number: {}",
|
||||
profile,
|
||||
current_sequence
|
||||
);
|
||||
@@ -459,7 +459,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
info,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"正在更新配置草稿,序列号: {}",
|
||||
"Updating draft profiles, sequence: {}",
|
||||
current_sequence
|
||||
);
|
||||
|
||||
@@ -474,7 +474,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
info,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"在内核交互前发现更新的请求 (序列号: {} < {}),放弃当前请求",
|
||||
"Detect updated requests before kernel interaction (sequence number: {} < {}) and abandon the current request.",
|
||||
current_sequence,
|
||||
latest_sequence
|
||||
);
|
||||
@@ -487,7 +487,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
info,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"开始内核配置更新,序列号: {}",
|
||||
"Starting kernel config update, sequence: {}",
|
||||
current_sequence
|
||||
);
|
||||
let update_result = tokio::time::timeout(
|
||||
@@ -506,7 +506,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
info,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"内核操作后发现更新的请求 (序列号: {} < {}),忽略当前结果",
|
||||
"After kernel operation, an updated request was found (sequence number: {} < {}), ignore the current result.",
|
||||
current_sequence,
|
||||
latest_sequence
|
||||
);
|
||||
@@ -518,7 +518,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
info,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"配置更新成功,序列号: {}",
|
||||
"Configuration update successful, serial number: {}",
|
||||
current_sequence
|
||||
);
|
||||
Config::profiles().apply();
|
||||
@@ -527,22 +527,22 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
// 强制刷新代理缓存,确保profile切换后立即获取最新节点数据
|
||||
crate::process::AsyncHandler::spawn(|| async move {
|
||||
if let Err(e) = super::proxy::force_refresh_proxies().await {
|
||||
log::warn!(target: "app", "强制刷新代理缓存失败: {e}");
|
||||
log::warn!(target: "app", "Force refresh proxy cache failed: {e}");
|
||||
}
|
||||
});
|
||||
|
||||
crate::process::AsyncHandler::spawn(|| async move {
|
||||
if let Err(e) = Tray::global().update_tooltip() {
|
||||
log::warn!(target: "app", "异步更新托盘提示失败: {e}");
|
||||
log::warn!(target: "app", "Async tray tooltip update failed: {e}");
|
||||
}
|
||||
|
||||
if let Err(e) = Tray::global().update_menu() {
|
||||
log::warn!(target: "app", "异步更新托盘菜单失败: {e}");
|
||||
log::warn!(target: "app", "Async tray menu update failed: {e}");
|
||||
}
|
||||
|
||||
// 保存配置文件
|
||||
if let Err(e) = Config::profiles().data().save_file() {
|
||||
log::warn!(target: "app", "异步保存配置文件失败: {e}");
|
||||
log::warn!(target: "app", "Async save profiles file failed: {e}");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -552,19 +552,19 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
info,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"向前端发送配置变更事件: {}, 序列号: {}",
|
||||
"Sending profile change event to frontend: {}, sequence: {}",
|
||||
current,
|
||||
current_sequence
|
||||
);
|
||||
handle::Handle::notify_profile_changed(current.clone());
|
||||
}
|
||||
|
||||
cleanup_processing_state(current_sequence, "配置切换完成").await;
|
||||
cleanup_processing_state(current_sequence, "Profile switch completed").await;
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
Ok(Ok((false, error_msg))) => {
|
||||
logging!(warn, Type::Cmd, true, "配置验证失败: {}", error_msg);
|
||||
logging!(warn, Type::Cmd, true, "Profile validation failed: {}", error_msg);
|
||||
Config::profiles().discard();
|
||||
// 如果验证失败,恢复到之前的配置
|
||||
if let Some(prev_profile) = current_profile {
|
||||
@@ -572,7 +572,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
info,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"尝试恢复到之前的配置: {}",
|
||||
"Attempting to restore previous profile: {}",
|
||||
prev_profile
|
||||
);
|
||||
let restore_profiles = IProfiles {
|
||||
@@ -585,17 +585,17 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
|
||||
crate::process::AsyncHandler::spawn(|| async move {
|
||||
if let Err(e) = Config::profiles().data().save_file() {
|
||||
log::warn!(target: "app", "异步保存恢复配置文件失败: {e}");
|
||||
log::warn!(target: "app", "Failed to save and restore configuration file asynchronously: {e}");
|
||||
}
|
||||
});
|
||||
|
||||
logging!(info, Type::Cmd, true, "成功恢复到之前的配置");
|
||||
logging!(info, Type::Cmd, true, "Successfully restored previous profile");
|
||||
}
|
||||
|
||||
// 发送验证错误通知
|
||||
handle::Handle::notice_message("config_validate::error", &error_msg);
|
||||
|
||||
cleanup_processing_state(current_sequence, "配置验证失败").await;
|
||||
cleanup_processing_state(current_sequence, "Profile validation failed").await;
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
@@ -604,25 +604,25 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
warn,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"更新过程发生错误: {}, 序列号: {}",
|
||||
"Error occurred during update: {}, sequence: {}",
|
||||
e,
|
||||
current_sequence
|
||||
);
|
||||
Config::profiles().discard();
|
||||
handle::Handle::notice_message("config_validate::boot_error", e.to_string());
|
||||
|
||||
cleanup_processing_state(current_sequence, "更新过程错误").await;
|
||||
cleanup_processing_state(current_sequence, "Update process error").await;
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
Err(_) => {
|
||||
// 超时处理
|
||||
let timeout_msg = "配置更新超时(30秒),可能是配置验证或核心通信阻塞";
|
||||
let timeout_msg = "Profile update timed out (30s), possibly due to validation or kernel communication";
|
||||
logging!(
|
||||
error,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"{}, 序列号: {}",
|
||||
"{}, sequence: {}",
|
||||
timeout_msg,
|
||||
current_sequence
|
||||
);
|
||||
@@ -633,7 +633,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
info,
|
||||
Type::Cmd,
|
||||
true,
|
||||
"超时后尝试恢复到之前的配置: {}, 序列号: {}",
|
||||
"After timeout, attempting to restore previous profile: {}, sequence: {}",
|
||||
prev_profile,
|
||||
current_sequence
|
||||
);
|
||||
@@ -647,7 +647,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
|
||||
handle::Handle::notice_message("config_validate::timeout", timeout_msg);
|
||||
|
||||
cleanup_processing_state(current_sequence, "配置更新超时").await;
|
||||
cleanup_processing_state(current_sequence, "Profile update timeout").await;
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
@@ -660,7 +660,7 @@ pub async fn patch_profiles_config_by_profile_index(
|
||||
_app_handle: tauri::AppHandle,
|
||||
profile_index: String,
|
||||
) -> CmdResult<bool> {
|
||||
logging!(info, Type::Cmd, true, "切换配置到: {}", profile_index);
|
||||
logging!(info, Type::Cmd, true, "Switching profile to: {}", profile_index);
|
||||
|
||||
let profiles = IProfiles {
|
||||
current: Some(profile_index),
|
||||
@@ -689,9 +689,9 @@ pub fn patch_profile(index: String, profile: PrfItem) -> CmdResult {
|
||||
if update_interval_changed {
|
||||
let index_clone = index.clone();
|
||||
crate::process::AsyncHandler::spawn(move || async move {
|
||||
logging!(info, Type::Timer, "定时器更新间隔已变更,正在刷新定时器...");
|
||||
logging!(info, Type::Timer, "Timer update interval changed; refreshing timers...");
|
||||
if let Err(e) = crate::core::Timer::global().refresh() {
|
||||
logging!(error, Type::Timer, "刷新定时器失败: {}", e);
|
||||
logging!(error, Type::Timer, "Failed to refresh timers: {}", e);
|
||||
} else {
|
||||
// 刷新成功后发送自定义事件,不触发配置重载
|
||||
crate::core::handle::Handle::notify_timer_updated(index_clone);
|
||||
|
||||
@@ -84,7 +84,7 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
|
||||
wrap_err!(fs::write(&file_path, original_content))?;
|
||||
// 发送合并文件专用错误通知
|
||||
let result = (false, error_msg.clone());
|
||||
crate::cmd::validate::handle_yaml_validation_notice(&result, "合并配置文件");
|
||||
crate::cmd::validate::handle_yaml_validation_notice(&result, "Merge config file");
|
||||
return Ok(());
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -135,7 +135,7 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
|
||||
// 普通YAML错误使用YAML通知处理
|
||||
log::info!(target: "app", "[cmd config save] YAML config file validation failed, sending notification");
|
||||
let result = (false, error_msg.clone());
|
||||
crate::cmd::validate::handle_yaml_validation_notice(&result, "YAML配置文件");
|
||||
crate::cmd::validate::handle_yaml_validation_notice(&result, "YAML config file");
|
||||
} else if is_script_error {
|
||||
// 脚本错误使用专门的通知处理
|
||||
log::info!(target: "app", "[cmd config save] Script file validation failed, sending notification");
|
||||
|
||||
@@ -32,7 +32,7 @@ pub fn handle_script_validation_notice(result: &(bool, String), file_type: &str)
|
||||
warn,
|
||||
Type::Config,
|
||||
true,
|
||||
"{} 验证失败: {}",
|
||||
"{} validation failed: {}",
|
||||
file_type,
|
||||
error_msg
|
||||
);
|
||||
@@ -43,14 +43,14 @@ pub fn handle_script_validation_notice(result: &(bool, String), file_type: &str)
|
||||
/// 验证指定脚本文件
|
||||
#[tauri::command]
|
||||
pub async fn validate_script_file(file_path: String) -> CmdResult<bool> {
|
||||
logging!(info, Type::Config, true, "验证脚本文件: {}", file_path);
|
||||
logging!(info, Type::Config, true, "Validating script file: {}", file_path);
|
||||
|
||||
match CoreManager::global()
|
||||
.validate_config_file(&file_path, None)
|
||||
.await
|
||||
{
|
||||
Ok(result) => {
|
||||
handle_script_validation_notice(&result, "脚本文件");
|
||||
handle_script_validation_notice(&result, "Script file");
|
||||
Ok(result.0) // 返回验证结果布尔值
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -129,7 +129,7 @@ pub fn handle_yaml_validation_notice(result: &(bool, String), file_type: &str) {
|
||||
info,
|
||||
Type::Config,
|
||||
true,
|
||||
"[通知] 发送通知: status={}, msg={}",
|
||||
"[Notice] Sending notice: status={}, msg={}",
|
||||
status,
|
||||
error_msg
|
||||
);
|
||||
|
||||
@@ -69,9 +69,9 @@ impl Config {
|
||||
}
|
||||
// 生成运行时配置
|
||||
if let Err(err) = Self::generate().await {
|
||||
logging!(error, Type::Config, true, "生成运行时配置失败: {}", err);
|
||||
logging!(error, Type::Config, true, "Failed to generate runtime config: {}", err);
|
||||
} else {
|
||||
logging!(info, Type::Config, true, "生成运行时配置成功");
|
||||
logging!(info, Type::Config, true, "Runtime config generated successfully");
|
||||
}
|
||||
|
||||
// 生成运行时配置文件并验证
|
||||
@@ -79,7 +79,7 @@ impl Config {
|
||||
|
||||
let validation_result = if config_result.is_ok() {
|
||||
// 验证配置文件
|
||||
logging!(info, Type::Config, true, "开始验证配置");
|
||||
logging!(info, Type::Config, true, "Starting config validation");
|
||||
|
||||
match CoreManager::global().validate_config().await {
|
||||
Ok((is_valid, error_msg)) => {
|
||||
@@ -88,7 +88,7 @@ impl Config {
|
||||
warn,
|
||||
Type::Config,
|
||||
true,
|
||||
"[首次启动] 配置验证失败,使用默认最小配置启动: {}",
|
||||
"[First launch] Config validation failed, starting with minimal default config: {}",
|
||||
error_msg
|
||||
);
|
||||
CoreManager::global()
|
||||
@@ -96,12 +96,12 @@ impl Config {
|
||||
.await?;
|
||||
Some(("config_validate::boot_error", error_msg))
|
||||
} else {
|
||||
logging!(info, Type::Config, true, "配置验证成功");
|
||||
logging!(info, Type::Config, true, "Config validation succeeded");
|
||||
Some(("config_validate::success", String::new()))
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
logging!(warn, Type::Config, true, "验证进程执行失败: {}", err);
|
||||
logging!(warn, Type::Config, true, "Validation process execution failed: {}", err);
|
||||
CoreManager::global()
|
||||
.use_default_config("config_validate::process_terminated", "")
|
||||
.await?;
|
||||
@@ -109,7 +109,7 @@ impl Config {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logging!(warn, Type::Config, true, "生成配置文件失败,使用默认配置");
|
||||
logging!(warn, Type::Config, true, "Failed to generate config file; using default config");
|
||||
CoreManager::global()
|
||||
.use_default_config("config_validate::error", "")
|
||||
.await?;
|
||||
|
||||
@@ -257,7 +257,7 @@ impl IVerge {
|
||||
warn,
|
||||
Type::Config,
|
||||
true,
|
||||
"启动时发现无效的clash_core配置: '{}', 将自动修正为 'koala-mihomo'",
|
||||
"Invalid clash_core config detected at startup: '{}', auto-fixing to 'koala-mihomo'",
|
||||
core
|
||||
);
|
||||
config.clash_core = Some("koala-mihomo".to_string());
|
||||
@@ -268,7 +268,7 @@ impl IVerge {
|
||||
info,
|
||||
Type::Config,
|
||||
true,
|
||||
"启动时发现未配置clash_core, 将设置为默认值 'koala-mihomo'"
|
||||
"clash_core not configured at startup; setting default to 'koala-mihomo'"
|
||||
);
|
||||
config.clash_core = Some("koala-mihomo".to_string());
|
||||
needs_fix = true;
|
||||
@@ -276,13 +276,13 @@ impl IVerge {
|
||||
|
||||
// 修正后保存配置
|
||||
if needs_fix {
|
||||
logging!(info, Type::Config, true, "正在保存修正后的配置文件...");
|
||||
logging!(info, Type::Config, true, "Saving fixed configuration file...");
|
||||
help::save_yaml(&config_path, &config, Some("# Koala Clash Config"))?;
|
||||
logging!(
|
||||
info,
|
||||
Type::Config,
|
||||
true,
|
||||
"配置文件修正完成,需要重新加载配置"
|
||||
"Configuration file fixed; reloading config required"
|
||||
);
|
||||
|
||||
Self::reload_config_after_fix(config)?;
|
||||
@@ -291,7 +291,7 @@ impl IVerge {
|
||||
info,
|
||||
Type::Config,
|
||||
true,
|
||||
"clash_core配置验证通过: {:?}",
|
||||
"clash_core config validation passed: {:?}",
|
||||
config.clash_core
|
||||
);
|
||||
}
|
||||
|
||||
@@ -611,7 +611,7 @@ impl CoreManager {
|
||||
info,
|
||||
Type::Core,
|
||||
true,
|
||||
"清理完成,共终止了 {} 个多余的 mihomo 进程",
|
||||
"Cleanup complete, a total of {} redundant mihomo processes terminated",
|
||||
killed_count
|
||||
);
|
||||
}
|
||||
@@ -720,7 +720,7 @@ impl CoreManager {
|
||||
info,
|
||||
Type::Core,
|
||||
true,
|
||||
"尝试终止进程: {} (PID: {})",
|
||||
"Attempt to terminate process: {} (PID: {})",
|
||||
process_name,
|
||||
pid
|
||||
);
|
||||
@@ -767,7 +767,7 @@ impl CoreManager {
|
||||
warn,
|
||||
Type::Core,
|
||||
true,
|
||||
"进程 {} (PID: {}) 终止命令成功但进程仍在运行",
|
||||
"Process {} (PID: {}) Termination command successful, but process still running",
|
||||
process_name,
|
||||
pid
|
||||
);
|
||||
@@ -777,7 +777,7 @@ impl CoreManager {
|
||||
info,
|
||||
Type::Core,
|
||||
true,
|
||||
"成功终止进程: {} (PID: {})",
|
||||
"Successfully terminated process: {} (PID: {})",
|
||||
process_name,
|
||||
pid
|
||||
);
|
||||
@@ -788,7 +788,7 @@ impl CoreManager {
|
||||
warn,
|
||||
Type::Core,
|
||||
true,
|
||||
"无法终止进程: {} (PID: {})",
|
||||
"Unable to terminate process: {} (PID: {})",
|
||||
process_name,
|
||||
pid
|
||||
);
|
||||
@@ -953,7 +953,7 @@ impl CoreManager {
|
||||
warn,
|
||||
Type::Core,
|
||||
true,
|
||||
"服务重装失败 during attempt_service_init: {}",
|
||||
"Service reinstallation failed during attempt_service_init: {}",
|
||||
e
|
||||
);
|
||||
return Err(e);
|
||||
@@ -985,7 +985,7 @@ impl CoreManager {
|
||||
error,
|
||||
Type::Core,
|
||||
true,
|
||||
"保存ServiceState失败 (in attempt_service_init/start_core_by_service): {}",
|
||||
"Failed to save ServiceState (in attempt_service_init/start_core_by_service): {}",
|
||||
save_err
|
||||
);
|
||||
}
|
||||
@@ -1004,7 +1004,7 @@ impl CoreManager {
|
||||
warn,
|
||||
Type::Core,
|
||||
true,
|
||||
"应用初始化时清理多余 mihomo 进程失败: {}",
|
||||
"Failed to clean up unnecessary mihomo processes during application initialization: {}",
|
||||
e
|
||||
);
|
||||
}
|
||||
@@ -1158,7 +1158,7 @@ impl CoreManager {
|
||||
info,
|
||||
Type::Core,
|
||||
true,
|
||||
"有服务安装记录但服务不可用/未启动,强制切换到Sidecar模式"
|
||||
"There is a service installation record, but the service is unavailable/not started. Force switch to Sidecar mode"
|
||||
);
|
||||
let mut final_state = service::ServiceState::get();
|
||||
if !final_state.prefer_sidecar {
|
||||
@@ -1166,7 +1166,7 @@ impl CoreManager {
|
||||
warn,
|
||||
Type::Core,
|
||||
true,
|
||||
"prefer_sidecar 为 false,因服务启动失败或不可用而强制设置为 true"
|
||||
"prefer_sidecar is false, but is forced to true due to service startup failure or unavailability"
|
||||
);
|
||||
final_state.prefer_sidecar = true;
|
||||
final_state.last_error =
|
||||
|
||||
@@ -85,7 +85,7 @@ fn sign_message(message: &str) -> Result<String> {
|
||||
type HmacSha256 = Hmac<Sha256>;
|
||||
|
||||
let secret_key = derive_secret_key();
|
||||
let mut mac = HmacSha256::new_from_slice(&secret_key).context("HMAC初始化失败")?;
|
||||
let mut mac = HmacSha256::new_from_slice(&secret_key).context("Failed to initialize HMAC")?;
|
||||
|
||||
mac.update(message.as_bytes());
|
||||
let result = mac.finalize();
|
||||
@@ -187,10 +187,10 @@ pub async fn send_ipc_request(
|
||||
error,
|
||||
Type::Service,
|
||||
true,
|
||||
"连接到服务命名管道失败: {}",
|
||||
"Failed to connect to service named pipe: {}",
|
||||
error
|
||||
);
|
||||
return Err(anyhow::anyhow!("无法连接到服务命名管道: {}", error));
|
||||
return Err(anyhow::anyhow!("Unable to connect to service named pipe: {}", error));
|
||||
}
|
||||
|
||||
let mut pipe = unsafe { File::from_raw_handle(handle as RawHandle) };
|
||||
@@ -212,7 +212,7 @@ pub async fn send_ipc_request(
|
||||
"Failed to write request length: {}",
|
||||
e
|
||||
);
|
||||
return Err(anyhow::anyhow!("写入请求长度失败: {}", e));
|
||||
return Err(anyhow::anyhow!("Failed to write request length: {}", e));
|
||||
}
|
||||
|
||||
if let Err(e) = pipe.write_all(request_bytes) {
|
||||
@@ -223,12 +223,12 @@ pub async fn send_ipc_request(
|
||||
"Failed to write request body: {}",
|
||||
e
|
||||
);
|
||||
return Err(anyhow::anyhow!("写入请求内容失败: {}", e));
|
||||
return Err(anyhow::anyhow!("Failed to write request body: {}", e));
|
||||
}
|
||||
|
||||
if let Err(e) = pipe.flush() {
|
||||
logging!(error, Type::Service, true, "Failed to flush pipe: {}", e);
|
||||
return Err(anyhow::anyhow!("刷新管道失败: {}", e));
|
||||
return Err(anyhow::anyhow!("Failed to flush pipe: {}", e));
|
||||
}
|
||||
|
||||
let mut response_len_bytes = [0u8; 4];
|
||||
@@ -240,7 +240,7 @@ pub async fn send_ipc_request(
|
||||
"Failed to read response length: {}",
|
||||
e
|
||||
);
|
||||
return Err(anyhow::anyhow!("读取响应长度失败: {}", e));
|
||||
return Err(anyhow::anyhow!("Failed to read response length: {}", e));
|
||||
}
|
||||
|
||||
let response_len = u32::from_be_bytes(response_len_bytes) as usize;
|
||||
@@ -254,7 +254,7 @@ pub async fn send_ipc_request(
|
||||
"Failed to read response body: {}",
|
||||
e
|
||||
);
|
||||
return Err(anyhow::anyhow!("读取响应内容失败: {}", e));
|
||||
return Err(anyhow::anyhow!("Failed to read response body: {}", e));
|
||||
}
|
||||
|
||||
let response: IpcResponse = match serde_json::from_slice::<IpcResponse>(&response_bytes) {
|
||||
@@ -267,7 +267,7 @@ pub async fn send_ipc_request(
|
||||
"Failed to parse service response: {}",
|
||||
e
|
||||
);
|
||||
return Err(anyhow::anyhow!("解析响应失败: {}", e));
|
||||
return Err(anyhow::anyhow!("Failed to parse response: {}", e));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -280,7 +280,7 @@ pub async fn send_ipc_request(
|
||||
true,
|
||||
"Service response signature verification failed"
|
||||
);
|
||||
bail!("服务响应签名验证失败");
|
||||
bail!("Service response signature verification failed");
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -325,7 +325,7 @@ pub async fn send_ipc_request(
|
||||
let request = match create_signed_request(command, payload) {
|
||||
Ok(req) => req,
|
||||
Err(e) => {
|
||||
logging!(error, Type::Service, true, "创建签名请求失败: {}", e);
|
||||
logging!(error, Type::Service, true, "Failed to create signed request: {}", e);
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
@@ -350,7 +350,7 @@ pub async fn send_ipc_request(
|
||||
"Failed to connect to Unix socket: {}",
|
||||
e
|
||||
);
|
||||
return Err(anyhow::anyhow!("无法连接到服务Unix套接字: {}", e));
|
||||
return Err(anyhow::anyhow!("Unable to connect to service Unix socket: {}", e));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -358,27 +358,27 @@ pub async fn send_ipc_request(
|
||||
let len_bytes = (request_bytes.len() as u32).to_be_bytes();
|
||||
|
||||
if let Err(e) = std::io::Write::write_all(&mut stream, &len_bytes) {
|
||||
logging!(error, Type::Service, true, "写入请求长度失败: {}", e);
|
||||
return Err(anyhow::anyhow!("写入请求长度失败: {}", e));
|
||||
logging!(error, Type::Service, true, "Failed to write request length: {}", e);
|
||||
return Err(anyhow::anyhow!("Failed to write request length: {}", e));
|
||||
}
|
||||
|
||||
if let Err(e) = std::io::Write::write_all(&mut stream, request_bytes) {
|
||||
logging!(error, Type::Service, true, "写入请求内容失败: {}", e);
|
||||
return Err(anyhow::anyhow!("写入请求内容失败: {}", e));
|
||||
logging!(error, Type::Service, true, "Failed to write request body: {}", e);
|
||||
return Err(anyhow::anyhow!("Failed to write request body: {}", e));
|
||||
}
|
||||
|
||||
let mut response_len_bytes = [0u8; 4];
|
||||
if let Err(e) = std::io::Read::read_exact(&mut stream, &mut response_len_bytes) {
|
||||
logging!(error, Type::Service, true, "读取响应长度失败: {}", e);
|
||||
return Err(anyhow::anyhow!("读取响应长度失败: {}", e));
|
||||
logging!(error, Type::Service, true, "Failed to read response length: {}", e);
|
||||
return Err(anyhow::anyhow!("Failed to read response length: {}", e));
|
||||
}
|
||||
|
||||
let response_len = u32::from_be_bytes(response_len_bytes) as usize;
|
||||
|
||||
let mut response_bytes = vec![0u8; response_len];
|
||||
if let Err(e) = std::io::Read::read_exact(&mut stream, &mut response_bytes) {
|
||||
logging!(error, Type::Service, true, "读取响应内容失败: {}", e);
|
||||
return Err(anyhow::anyhow!("读取响应内容失败: {}", e));
|
||||
logging!(error, Type::Service, true, "Failed to read response body: {}", e);
|
||||
return Err(anyhow::anyhow!("Failed to read response body: {}", e));
|
||||
}
|
||||
|
||||
let response: IpcResponse = match serde_json::from_slice::<IpcResponse>(&response_bytes) {
|
||||
@@ -391,15 +391,15 @@ pub async fn send_ipc_request(
|
||||
"Failed to parse service response: {}",
|
||||
e,
|
||||
);
|
||||
return Err(anyhow::anyhow!("解析响应失败: {}", e));
|
||||
return Err(anyhow::anyhow!("Failed to parse response: {}", e));
|
||||
}
|
||||
};
|
||||
|
||||
match verify_response_signature(&response) {
|
||||
Ok(valid) => {
|
||||
if !valid {
|
||||
logging!(error, Type::Service, true, "服务响应签名验证失败");
|
||||
bail!("服务响应签名验证失败");
|
||||
logging!(error, Type::Service, true, "Service response signature verification failed");
|
||||
bail!("Service response signature verification failed");
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
|
||||
@@ -325,7 +325,7 @@ impl Timer {
|
||||
*self.timer_count.lock() = next_id;
|
||||
}
|
||||
|
||||
logging!(debug, Type::Timer, "定时任务变更数量: {}", diff_map.len());
|
||||
logging!(debug, Type::Timer, "Number of scheduled task changes: {}", diff_map.len());
|
||||
logging!(
|
||||
debug,
|
||||
Type::Timer,
|
||||
|
||||
@@ -46,7 +46,7 @@ pub fn run_once_auto_lightweight() {
|
||||
info,
|
||||
Type::Lightweight,
|
||||
true,
|
||||
"在静默启动的情况下,创建窗口再添加自动进入轻量模式窗口监听器"
|
||||
"Silent start detected: create window, then attach auto lightweight-mode listener"
|
||||
);
|
||||
set_lightweight_mode(false);
|
||||
enable_auto_light_weight_mode();
|
||||
@@ -70,7 +70,7 @@ pub fn auto_lightweight_mode_init() {
|
||||
info,
|
||||
Type::Lightweight,
|
||||
true,
|
||||
"非静默启动直接挂载自动进入轻量模式监听器!"
|
||||
"Non-silent start: directly attach auto lightweight-mode listener"
|
||||
);
|
||||
set_lightweight_mode(true);
|
||||
enable_auto_light_weight_mode();
|
||||
@@ -102,13 +102,13 @@ pub fn set_lightweight_mode(value: bool) {
|
||||
|
||||
pub fn enable_auto_light_weight_mode() {
|
||||
Timer::global().init().unwrap();
|
||||
logging!(info, Type::Lightweight, true, "开启自动轻量模式");
|
||||
logging!(info, Type::Lightweight, true, "Enable auto lightweight mode");
|
||||
setup_window_close_listener();
|
||||
setup_webview_focus_listener();
|
||||
}
|
||||
|
||||
pub fn disable_auto_light_weight_mode() {
|
||||
logging!(info, Type::Lightweight, true, "关闭自动轻量模式");
|
||||
logging!(info, Type::Lightweight, true, "Disable auto lightweight mode");
|
||||
let _ = cancel_light_weight_timer();
|
||||
cancel_window_close_listener();
|
||||
}
|
||||
@@ -121,7 +121,7 @@ pub fn entry_lightweight_mode() {
|
||||
info,
|
||||
Type::Lightweight,
|
||||
true,
|
||||
"轻量模式隐藏窗口结果: {:?}",
|
||||
"Lightweight mode window hide result: {:?}",
|
||||
result
|
||||
);
|
||||
|
||||
@@ -150,7 +150,7 @@ pub fn exit_lightweight_mode() {
|
||||
info,
|
||||
Type::Lightweight,
|
||||
true,
|
||||
"轻量模式退出操作已在进行中,跳过重复调用"
|
||||
"Lightweight mode exit already in progress; skipping duplicate call"
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -162,7 +162,7 @@ pub fn exit_lightweight_mode() {
|
||||
|
||||
// 确保当前确实处于轻量模式才执行退出操作
|
||||
if !is_in_lightweight_mode() {
|
||||
logging!(info, Type::Lightweight, true, "当前不在轻量模式,无需退出");
|
||||
logging!(info, Type::Lightweight, true, "Not in lightweight mode; skip exit");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ fn setup_window_close_listener() -> u32 {
|
||||
info,
|
||||
Type::Lightweight,
|
||||
true,
|
||||
"监听到关闭请求,开始轻量模式计时"
|
||||
"Close requested; starting lightweight-mode timer"
|
||||
);
|
||||
});
|
||||
return handler;
|
||||
@@ -207,7 +207,7 @@ fn setup_webview_focus_listener() -> u32 {
|
||||
logging!(
|
||||
info,
|
||||
Type::Lightweight,
|
||||
"监听到窗口获得焦点,取消轻量模式计时"
|
||||
"Window focused; cancel lightweight-mode timer"
|
||||
);
|
||||
});
|
||||
return handler;
|
||||
@@ -218,7 +218,7 @@ fn setup_webview_focus_listener() -> u32 {
|
||||
fn cancel_window_close_listener() {
|
||||
if let Some(window) = handle::Handle::global().get_window() {
|
||||
window.unlisten(setup_window_close_listener());
|
||||
logging!(info, Type::Lightweight, true, "取消了窗口关闭监听");
|
||||
logging!(info, Type::Lightweight, true, "Removed window close listener");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ fn setup_light_weight_timer() -> Result<()> {
|
||||
.set_maximum_parallel_runnable_num(1)
|
||||
.set_frequency_once_by_minutes(once_by_minutes)
|
||||
.spawn_async_routine(move || async move {
|
||||
logging!(info, Type::Timer, true, "计时器到期,开始进入轻量模式");
|
||||
logging!(info, Type::Timer, true, "Timer expired; entering lightweight mode");
|
||||
entry_lightweight_mode();
|
||||
})
|
||||
.context("failed to create timer task")?;
|
||||
@@ -271,7 +271,7 @@ fn setup_light_weight_timer() -> Result<()> {
|
||||
info,
|
||||
Type::Timer,
|
||||
true,
|
||||
"计时器已设置,{} 分钟后将自动进入轻量模式",
|
||||
"Timer set; will auto-enter lightweight mode after {} minute(s)",
|
||||
once_by_minutes
|
||||
);
|
||||
|
||||
@@ -286,7 +286,7 @@ fn cancel_light_weight_timer() -> Result<()> {
|
||||
delay_timer
|
||||
.remove_task(task.task_id)
|
||||
.context("failed to remove timer task")?;
|
||||
logging!(info, Type::Timer, true, "计时器已取消");
|
||||
logging!(info, Type::Timer, true, "Timer canceled");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -9,7 +9,7 @@ use std::{fs, os::windows::process::CommandExt, path::Path, path::PathBuf};
|
||||
/// Windows 下的开机启动文件夹路径
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn get_startup_dir() -> Result<PathBuf> {
|
||||
let appdata = std::env::var("APPDATA").map_err(|_| anyhow!("无法获取 APPDATA 环境变量"))?;
|
||||
let appdata = std::env::var("APPDATA").map_err(|_| anyhow!("Unable to obtain APPDATA environment variable"))?;
|
||||
|
||||
let startup_dir = Path::new(&appdata)
|
||||
.join("Microsoft")
|
||||
@@ -19,7 +19,7 @@ pub fn get_startup_dir() -> Result<PathBuf> {
|
||||
.join("Startup");
|
||||
|
||||
if !startup_dir.exists() {
|
||||
return Err(anyhow!("Startup 目录不存在: {:?}", startup_dir));
|
||||
return Err(anyhow!("Startup directory does not exist: {:?}", startup_dir));
|
||||
}
|
||||
|
||||
Ok(startup_dir)
|
||||
@@ -29,7 +29,7 @@ pub fn get_startup_dir() -> Result<PathBuf> {
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn get_exe_path() -> Result<PathBuf> {
|
||||
let exe_path =
|
||||
std::env::current_exe().map_err(|e| anyhow!("无法获取当前可执行文件路径: {}", e))?;
|
||||
std::env::current_exe().map_err(|e| anyhow!("Unable to obtain the path of the current executable file: {}", e))?;
|
||||
|
||||
Ok(exe_path)
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ impl NetworkManager {
|
||||
pub fn init(&self) {
|
||||
self.init.call_once(|| {
|
||||
self.runtime.spawn(async {
|
||||
logging!(info, Type::Network, true, "初始化网络管理器");
|
||||
logging!(info, Type::Network, true, "Initializing network manager");
|
||||
|
||||
// 创建无代理客户端
|
||||
let no_proxy_client = ClientBuilder::new()
|
||||
@@ -81,7 +81,7 @@ impl NetworkManager {
|
||||
let mut no_proxy_guard = NETWORK_MANAGER.no_proxy_client.lock().unwrap();
|
||||
*no_proxy_guard = Some(no_proxy_client);
|
||||
|
||||
logging!(info, Type::Network, true, "网络管理器初始化完成");
|
||||
logging!(info, Type::Network, true, "Network manager initialization completed");
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -112,7 +112,7 @@ impl NetworkManager {
|
||||
}
|
||||
|
||||
pub fn reset_clients(&self) {
|
||||
logging!(info, Type::Network, true, "正在重置所有HTTP客户端");
|
||||
logging!(info, Type::Network, true, "Resetting all HTTP clients");
|
||||
{
|
||||
let mut client = self.self_proxy_client.lock().unwrap();
|
||||
*client = None;
|
||||
@@ -409,7 +409,7 @@ impl NetworkManager {
|
||||
let watchdog = tokio::spawn(async move {
|
||||
tokio::time::sleep(Duration::from_secs(timeout_duration)).await;
|
||||
let _ = cancel_tx.send(());
|
||||
logging!(warn, Type::Network, true, "请求超时取消: {}", url_clone);
|
||||
logging!(warn, Type::Network, true, "Request canceled due to timeout: {}", url_clone);
|
||||
});
|
||||
|
||||
let result = tokio::select! {
|
||||
|
||||
@@ -128,7 +128,7 @@ pub fn update_ui_ready_stage(stage: UiReadyStage) {
|
||||
pub fn mark_ui_ready() {
|
||||
let mut ready = get_ui_ready().write();
|
||||
*ready = true;
|
||||
logging!(info, Type::Window, true, "UI已标记为完全就绪");
|
||||
logging!(info, Type::Window, true, "UI marked as fully ready");
|
||||
|
||||
// If any deep links were queued while UI was not ready, handle them now
|
||||
// No queued deep links list anymore; early and runtime deep links are deduped
|
||||
@@ -145,7 +145,7 @@ pub fn reset_ui_ready() {
|
||||
let mut stage = state.stage.write();
|
||||
*stage = UiReadyStage::NotStarted;
|
||||
}
|
||||
logging!(info, Type::Window, true, "UI就绪状态已重置");
|
||||
logging!(info, Type::Window, true, "UI readiness state has been reset");
|
||||
}
|
||||
|
||||
/// Schedule robust deep-link handling to avoid races with lightweight mode and window creation
|
||||
@@ -244,12 +244,12 @@ pub async fn find_unused_port() -> Result<u16> {
|
||||
/// 异步方式处理启动后的额外任务
|
||||
pub async fn resolve_setup_async(app_handle: &AppHandle) {
|
||||
let start_time = std::time::Instant::now();
|
||||
logging!(info, Type::Setup, true, "开始执行异步设置任务...");
|
||||
logging!(info, Type::Setup, true, "Starting asynchronous setup tasks...");
|
||||
|
||||
if VERSION.get().is_none() {
|
||||
let version = app_handle.package_info().version.to_string();
|
||||
VERSION.get_or_init(|| {
|
||||
logging!(info, Type::Setup, true, "初始化版本信息: {}", version);
|
||||
logging!(info, Type::Setup, true, "Initializing version information: {}", version);
|
||||
version.clone()
|
||||
});
|
||||
}
|
||||
@@ -268,40 +268,40 @@ pub async fn resolve_setup_async(app_handle: &AppHandle) {
|
||||
);
|
||||
}
|
||||
|
||||
logging!(trace, Type::Config, true, "初始化配置...");
|
||||
logging!(trace, Type::Config, true, "Initializing configuration...");
|
||||
logging_error!(Type::Config, true, Config::init_config().await);
|
||||
|
||||
// 启动时清理冗余的 Profile 文件
|
||||
logging!(info, Type::Setup, true, "清理冗余的Profile文件...");
|
||||
logging!(info, Type::Setup, true, "Cleaning redundant profile files...");
|
||||
let profiles = Config::profiles();
|
||||
if let Err(e) = profiles.latest().auto_cleanup() {
|
||||
logging!(warn, Type::Setup, true, "启动时清理Profile文件失败: {}", e);
|
||||
logging!(warn, Type::Setup, true, "Failed to clean profile files at startup: {}", e);
|
||||
} else {
|
||||
logging!(info, Type::Setup, true, "启动时Profile文件清理完成");
|
||||
logging!(info, Type::Setup, true, "Startup profile files cleanup completed");
|
||||
}
|
||||
|
||||
logging!(trace, Type::Core, true, "启动核心管理器...");
|
||||
logging!(trace, Type::Core, true, "Starting core manager...");
|
||||
logging_error!(Type::Core, true, CoreManager::global().init().await);
|
||||
|
||||
log::trace!(target: "app", "启动内嵌服务器...");
|
||||
log::trace!(target: "app", "Starting embedded server...");
|
||||
server::embed_server();
|
||||
|
||||
logging_error!(Type::Tray, true, tray::Tray::global().init());
|
||||
|
||||
if let Some(app_handle) = handle::Handle::global().app_handle() {
|
||||
logging!(info, Type::Tray, true, "创建系统托盘...");
|
||||
logging!(info, Type::Tray, true, "Creating system tray...");
|
||||
let result = tray::Tray::global().create_tray_from_handle(&app_handle);
|
||||
if result.is_ok() {
|
||||
logging!(info, Type::Tray, true, "系统托盘创建成功");
|
||||
logging!(info, Type::Tray, true, "System tray created successfully");
|
||||
} else if let Err(e) = result {
|
||||
logging!(error, Type::Tray, true, "系统托盘创建失败: {}", e);
|
||||
logging!(error, Type::Tray, true, "Failed to create system tray: {}", e);
|
||||
}
|
||||
} else {
|
||||
logging!(
|
||||
error,
|
||||
Type::Tray,
|
||||
true,
|
||||
"无法创建系统托盘: app_handle不存在"
|
||||
"Unable to create system tray: app_handle missing"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ pub async fn resolve_setup_async(app_handle: &AppHandle) {
|
||||
|
||||
logging_error!(Type::Tray, true, tray::Tray::global().update_part());
|
||||
|
||||
logging!(trace, Type::System, true, "初始化热键...");
|
||||
logging!(trace, Type::System, true, "Initializing hotkeys...");
|
||||
logging_error!(Type::System, true, hotkey::Hotkey::global().init());
|
||||
|
||||
let elapsed = start_time.elapsed();
|
||||
@@ -345,7 +345,7 @@ pub async fn resolve_setup_async(app_handle: &AppHandle) {
|
||||
info,
|
||||
Type::Setup,
|
||||
true,
|
||||
"异步设置任务完成,耗时: {:?}",
|
||||
"Asynchronous task completed, time taken: {:?}",
|
||||
elapsed
|
||||
);
|
||||
|
||||
@@ -355,7 +355,7 @@ pub async fn resolve_setup_async(app_handle: &AppHandle) {
|
||||
warn,
|
||||
Type::Setup,
|
||||
true,
|
||||
"异步设置任务耗时较长({:?})",
|
||||
"Asynchronous task setup takes a long time ({:?})",
|
||||
elapsed
|
||||
);
|
||||
}
|
||||
@@ -387,12 +387,12 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
info,
|
||||
Type::Window,
|
||||
true,
|
||||
"开始创建/显示主窗口, is_show={}",
|
||||
"Creating/showing main window, is_show={}",
|
||||
is_show
|
||||
);
|
||||
|
||||
if !is_show {
|
||||
logging!(info, Type::Window, true, "静默模式启动时不创建窗口");
|
||||
logging!(info, Type::Window, true, "Silent start: do not create window");
|
||||
lightweight::set_lightweight_mode(true);
|
||||
handle::Handle::notify_startup_completed();
|
||||
return false;
|
||||
@@ -400,10 +400,10 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
|
||||
if let Some(app_handle) = handle::Handle::global().app_handle() {
|
||||
if let Some(window) = app_handle.get_webview_window("main") {
|
||||
logging!(info, Type::Window, true, "主窗口已存在,将尝试显示现有窗口");
|
||||
logging!(info, Type::Window, true, "Main window already exists; will try to show it");
|
||||
if is_show {
|
||||
if window.is_minimized().unwrap_or(false) {
|
||||
logging!(info, Type::Window, true, "窗口已最小化,正在取消最小化");
|
||||
logging!(info, Type::Window, true, "Window is minimized; unminimizing");
|
||||
let _ = window.unminimize();
|
||||
}
|
||||
let show_result = window.show();
|
||||
@@ -415,7 +415,7 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
warn,
|
||||
Type::Window,
|
||||
true,
|
||||
"现有窗口显示失败,尝试销毁并重新创建"
|
||||
"Failed to show existing window; will destroy and recreate"
|
||||
);
|
||||
let _ = window.destroy();
|
||||
} else {
|
||||
@@ -442,7 +442,7 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
info,
|
||||
Type::Window,
|
||||
true,
|
||||
"窗口创建请求被忽略,因为最近创建过 ({:?}ms)",
|
||||
"Window creation request ignored because recently created ({:?}ms)",
|
||||
elapsed.as_millis()
|
||||
);
|
||||
return false;
|
||||
@@ -453,7 +453,7 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
// ScopeGuard 确保创建状态重置,防止 webview 卡死
|
||||
let _guard = scopeguard::guard(creating, |mut creating_guard| {
|
||||
*creating_guard = (false, Instant::now());
|
||||
logging!(debug, Type::Window, true, "[ScopeGuard] 窗口创建状态已重置");
|
||||
logging!(debug, Type::Window, true, "[ScopeGuard] Window creation state reset");
|
||||
});
|
||||
|
||||
match tauri::WebviewWindowBuilder::new(
|
||||
@@ -470,16 +470,16 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
.visible(true) // 立即显示窗口,避免用户等待
|
||||
.initialization_script(
|
||||
r#"
|
||||
console.log('[Tauri] 窗口初始化脚本开始执行');
|
||||
console.log('[Tauri] Window init script started');
|
||||
|
||||
function createLoadingOverlay() {
|
||||
|
||||
if (document.getElementById('initial-loading-overlay')) {
|
||||
console.log('[Tauri] 加载指示器已存在');
|
||||
console.log('[Tauri] Loading indicator already exists');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('[Tauri] 创建加载指示器');
|
||||
console.log('[Tauri] Creating loading indicator');
|
||||
const loadingDiv = document.createElement('div');
|
||||
loadingDiv.id = 'initial-loading-overlay';
|
||||
loadingDiv.innerHTML = `
|
||||
@@ -498,7 +498,7 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
animation: spin 1s linear infinite;
|
||||
"></div>
|
||||
</div>
|
||||
<div style="font-size: 14px; opacity: 0.7;">Loading Clash Verge...</div>
|
||||
<div style="font-size: 14px; opacity: 0.7;">Loading Koala Clash...</div>
|
||||
</div>
|
||||
<style>
|
||||
@keyframes spin {
|
||||
@@ -530,13 +530,13 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
createLoadingOverlay();
|
||||
}
|
||||
|
||||
console.log('[Tauri] 窗口初始化脚本执行完成');
|
||||
console.log('[Tauri] Window init script finished');
|
||||
"#,
|
||||
)
|
||||
.build()
|
||||
{
|
||||
Ok(newly_created_window) => {
|
||||
logging!(debug, Type::Window, true, "主窗口实例创建成功");
|
||||
logging!(debug, Type::Window, true, "Main window instance created successfully");
|
||||
|
||||
update_ui_ready_stage(UiReadyStage::NotStarted);
|
||||
|
||||
@@ -546,7 +546,7 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
debug,
|
||||
Type::Window,
|
||||
true,
|
||||
"异步窗口任务开始 (启动已标记完成)"
|
||||
"Async window task started (startup marked completed)"
|
||||
);
|
||||
|
||||
// 先运行轻量模式检测
|
||||
@@ -557,7 +557,7 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
debug,
|
||||
Type::Window,
|
||||
true,
|
||||
"发送 verge://startup-completed 事件"
|
||||
"Sending verge://startup-completed event"
|
||||
);
|
||||
handle::Handle::notify_startup_completed();
|
||||
|
||||
@@ -567,7 +567,7 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
// 立即显示窗口
|
||||
let _ = window_clone.show();
|
||||
let _ = window_clone.set_focus();
|
||||
logging!(info, Type::Window, true, "窗口已立即显示");
|
||||
logging!(info, Type::Window, true, "Window shown immediately");
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
AppHandleManager::global().set_activation_policy_regular();
|
||||
@@ -583,7 +583,7 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
info,
|
||||
Type::Window,
|
||||
true,
|
||||
"开始监控UI加载状态 (最多{}秒)...",
|
||||
"Start monitoring UI load status (up to {} seconds)...",
|
||||
timeout_seconds
|
||||
);
|
||||
|
||||
@@ -602,7 +602,7 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
debug,
|
||||
Type::Window,
|
||||
true,
|
||||
"UI加载状态检查... ({}秒)",
|
||||
"UI loading status check... ({}s)",
|
||||
check_count / 10
|
||||
);
|
||||
}
|
||||
@@ -612,7 +612,7 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
|
||||
match wait_result {
|
||||
Ok(_) => {
|
||||
logging!(info, Type::Window, true, "UI已完全加载就绪");
|
||||
logging!(info, Type::Window, true, "UI fully loaded and ready");
|
||||
// 移除初始加载指示器
|
||||
if let Some(window) = handle::Handle::global().get_window() {
|
||||
let _ = window.eval(r#"
|
||||
@@ -629,7 +629,7 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
warn,
|
||||
Type::Window,
|
||||
true,
|
||||
"UI加载监控超时({}秒),但窗口已正常显示",
|
||||
"UI load monitoring timed out ({}s), but window is already visible",
|
||||
timeout_seconds
|
||||
);
|
||||
*get_ui_ready().write() = true;
|
||||
@@ -637,20 +637,20 @@ pub fn create_window(is_show: bool) -> bool {
|
||||
}
|
||||
});
|
||||
|
||||
logging!(info, Type::Window, true, "窗口显示流程完成");
|
||||
logging!(info, Type::Window, true, "Window display flow completed");
|
||||
} else {
|
||||
logging!(
|
||||
debug,
|
||||
Type::Window,
|
||||
true,
|
||||
"is_show为false,窗口保持隐藏状态"
|
||||
"is_show is false; keeping window hidden"
|
||||
);
|
||||
}
|
||||
});
|
||||
true
|
||||
}
|
||||
Err(e) => {
|
||||
logging!(error, Type::Window, true, "主窗口构建失败: {}", e);
|
||||
logging!(error, Type::Window, true, "Failed to build main window: {}", e);
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ impl WindowManager {
|
||||
finish_window_operation();
|
||||
});
|
||||
|
||||
logging!(info, Type::Window, true, "开始智能显示主窗口");
|
||||
logging!(info, Type::Window, true, "Starting smart show for main window");
|
||||
logging!(
|
||||
debug,
|
||||
Type::Window,
|
||||
@@ -140,18 +140,18 @@ impl WindowManager {
|
||||
|
||||
match current_state {
|
||||
WindowState::NotExist => {
|
||||
logging!(info, Type::Window, true, "窗口不存在,创建新窗口");
|
||||
logging!(info, Type::Window, true, "Main window not found; creating new window");
|
||||
if Self::create_new_window() {
|
||||
logging!(info, Type::Window, true, "窗口创建成功");
|
||||
logging!(info, Type::Window, true, "Window created successfully");
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
WindowOperationResult::Created
|
||||
} else {
|
||||
logging!(warn, Type::Window, true, "窗口创建失败");
|
||||
logging!(warn, Type::Window, true, "Window creation failed");
|
||||
WindowOperationResult::Failed
|
||||
}
|
||||
}
|
||||
WindowState::VisibleFocused => {
|
||||
logging!(info, Type::Window, true, "窗口已经可见且有焦点,无需操作");
|
||||
logging!(info, Type::Window, true, "Window already visible and focused; no action needed");
|
||||
WindowOperationResult::NoAction
|
||||
}
|
||||
WindowState::VisibleUnfocused | WindowState::Minimized | WindowState::Hidden => {
|
||||
@@ -184,14 +184,14 @@ impl WindowManager {
|
||||
finish_window_operation();
|
||||
});
|
||||
|
||||
logging!(info, Type::Window, true, "开始切换主窗口显示状态");
|
||||
logging!(info, Type::Window, true, "Toggling main window visibility");
|
||||
|
||||
let current_state = Self::get_main_window_state();
|
||||
logging!(
|
||||
info,
|
||||
Type::Window,
|
||||
true,
|
||||
"当前窗口状态: {:?} | 详细状态: {}",
|
||||
"Current window state: {:?} | Details: {}",
|
||||
current_state,
|
||||
Self::get_window_status_info()
|
||||
);
|
||||
@@ -199,7 +199,7 @@ impl WindowManager {
|
||||
match current_state {
|
||||
WindowState::NotExist => {
|
||||
// 窗口不存在,创建新窗口
|
||||
logging!(info, Type::Window, true, "窗口不存在,将创建新窗口");
|
||||
logging!(info, Type::Window, true, "Main window not found; will create new window");
|
||||
// 由于已经有防抖保护,直接调用内部方法
|
||||
if Self::create_new_window() {
|
||||
WindowOperationResult::Created
|
||||
@@ -212,26 +212,26 @@ impl WindowManager {
|
||||
info,
|
||||
Type::Window,
|
||||
true,
|
||||
"窗口可见(焦点状态: {}),将隐藏窗口",
|
||||
"Window visible (focused: {}), hiding window",
|
||||
if current_state == WindowState::VisibleFocused {
|
||||
"有焦点"
|
||||
"focused"
|
||||
} else {
|
||||
"无焦点"
|
||||
"unfocused"
|
||||
}
|
||||
);
|
||||
if let Some(window) = Self::get_main_window() {
|
||||
match window.hide() {
|
||||
Ok(_) => {
|
||||
logging!(info, Type::Window, true, "窗口已成功隐藏");
|
||||
logging!(info, Type::Window, true, "Window hidden successfully");
|
||||
WindowOperationResult::Hidden
|
||||
}
|
||||
Err(e) => {
|
||||
logging!(warn, Type::Window, true, "隐藏窗口失败: {}", e);
|
||||
logging!(warn, Type::Window, true, "Failed to hide window: {}", e);
|
||||
WindowOperationResult::Failed
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logging!(warn, Type::Window, true, "无法获取窗口实例");
|
||||
logging!(warn, Type::Window, true, "Unable to get window instance");
|
||||
WindowOperationResult::Failed
|
||||
}
|
||||
}
|
||||
@@ -240,12 +240,12 @@ impl WindowManager {
|
||||
info,
|
||||
Type::Window,
|
||||
true,
|
||||
"窗口存在但被隐藏或最小化,将激活窗口"
|
||||
"Window exists but is hidden or minimized; activating"
|
||||
);
|
||||
if let Some(window) = Self::get_main_window() {
|
||||
Self::activate_window(&window)
|
||||
} else {
|
||||
logging!(warn, Type::Window, true, "无法获取窗口实例");
|
||||
logging!(warn, Type::Window, true, "Unable to get window instance");
|
||||
WindowOperationResult::Failed
|
||||
}
|
||||
}
|
||||
@@ -254,35 +254,35 @@ impl WindowManager {
|
||||
|
||||
/// 激活窗口(取消最小化、显示、设置焦点)
|
||||
fn activate_window(window: &WebviewWindow<Wry>) -> WindowOperationResult {
|
||||
logging!(info, Type::Window, true, "开始激活窗口");
|
||||
logging!(info, Type::Window, true, "Starting to activate window");
|
||||
|
||||
let mut operations_successful = true;
|
||||
|
||||
// 1. 如果窗口最小化,先取消最小化
|
||||
if window.is_minimized().unwrap_or(false) {
|
||||
logging!(info, Type::Window, true, "窗口已最小化,正在取消最小化");
|
||||
logging!(info, Type::Window, true, "Window minimized; unminimizing");
|
||||
if let Err(e) = window.unminimize() {
|
||||
logging!(warn, Type::Window, true, "取消最小化失败: {}", e);
|
||||
logging!(warn, Type::Window, true, "Failed to unminimize window: {}", e);
|
||||
operations_successful = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 显示窗口
|
||||
if let Err(e) = window.show() {
|
||||
logging!(warn, Type::Window, true, "显示窗口失败: {}", e);
|
||||
logging!(warn, Type::Window, true, "Failed to show window: {}", e);
|
||||
operations_successful = false;
|
||||
}
|
||||
|
||||
// 3. 设置焦点
|
||||
if let Err(e) = window.set_focus() {
|
||||
logging!(warn, Type::Window, true, "设置窗口焦点失败: {}", e);
|
||||
logging!(warn, Type::Window, true, "Failed to set window focus: {}", e);
|
||||
operations_successful = false;
|
||||
}
|
||||
|
||||
// 4. 平台特定的激活策略
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
logging!(info, Type::Window, true, "应用 macOS 特定的激活策略");
|
||||
logging!(info, Type::Window, true, "Applying macOS-specific activation policy");
|
||||
AppHandleManager::global().set_activation_policy_regular();
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ impl WindowManager {
|
||||
debug,
|
||||
Type::Window,
|
||||
true,
|
||||
"设置置顶失败(非关键错误): {}",
|
||||
"Failed to set always-on-top (non-critical): {}",
|
||||
e
|
||||
);
|
||||
}
|
||||
@@ -304,38 +304,38 @@ impl WindowManager {
|
||||
debug,
|
||||
Type::Window,
|
||||
true,
|
||||
"取消置顶失败(非关键错误): {}",
|
||||
"Failed to unset always-on-top (non-critical): {}",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if operations_successful {
|
||||
logging!(info, Type::Window, true, "窗口激活成功");
|
||||
logging!(info, Type::Window, true, "Window activation successful");
|
||||
WindowOperationResult::Shown
|
||||
} else {
|
||||
logging!(warn, Type::Window, true, "窗口激活部分失败");
|
||||
logging!(warn, Type::Window, true, "Window activation partially failed");
|
||||
WindowOperationResult::Failed
|
||||
}
|
||||
}
|
||||
|
||||
/// 隐藏主窗口
|
||||
pub fn hide_main_window() -> WindowOperationResult {
|
||||
logging!(info, Type::Window, true, "开始隐藏主窗口");
|
||||
logging!(info, Type::Window, true, "Starting to hide main window");
|
||||
|
||||
match Self::get_main_window() {
|
||||
Some(window) => match window.hide() {
|
||||
Ok(_) => {
|
||||
logging!(info, Type::Window, true, "窗口已隐藏");
|
||||
logging!(info, Type::Window, true, "Window hidden");
|
||||
WindowOperationResult::Hidden
|
||||
}
|
||||
Err(e) => {
|
||||
logging!(warn, Type::Window, true, "隐藏窗口失败: {}", e);
|
||||
logging!(warn, Type::Window, true, "Failed to hide window: {}", e);
|
||||
WindowOperationResult::Failed
|
||||
}
|
||||
},
|
||||
None => {
|
||||
logging!(info, Type::Window, true, "窗口不存在,无需隐藏");
|
||||
logging!(info, Type::Window, true, "Window does not exist; nothing to hide");
|
||||
WindowOperationResult::NoAction
|
||||
}
|
||||
}
|
||||
@@ -376,7 +376,7 @@ impl WindowManager {
|
||||
let is_minimized = Self::is_main_window_minimized();
|
||||
|
||||
format!(
|
||||
"窗口状态: {state:?} | 可见: {is_visible} | 有焦点: {is_focused} | 最小化: {is_minimized}"
|
||||
"WindowState: {state:?} | visible: {is_visible} | focused: {is_focused} | minimized: {is_minimized}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,11 +429,11 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("代理状态更新失败:", err);
|
||||
console.warn("Proxy status update failed:", err);
|
||||
}
|
||||
}, 50);
|
||||
} catch (err: any) {
|
||||
console.error("配置保存失败:", err);
|
||||
console.error("Configuration save failed:", err);
|
||||
mutateVerge();
|
||||
showNotice("error", err.toString());
|
||||
// setOpen(true);
|
||||
|
||||
@@ -56,7 +56,7 @@ export const useProfiles = () => {
|
||||
// 根据selected的节点选择
|
||||
const activateSelected = async () => {
|
||||
try {
|
||||
console.log("[ActivateSelected] 开始处理代理选择");
|
||||
console.log("[ActivateSelected] Start processing proxy selection");
|
||||
|
||||
const [proxiesData, profileData] = await Promise.all([
|
||||
getProxies(),
|
||||
@@ -64,7 +64,9 @@ export const useProfiles = () => {
|
||||
]);
|
||||
|
||||
if (!profileData || !proxiesData) {
|
||||
console.log("[ActivateSelected] 代理或配置数据不可用,跳过处理");
|
||||
console.log(
|
||||
"[ActivateSelected] Proxy or configuration data unavailable, skipping processing",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -73,19 +75,23 @@ export const useProfiles = () => {
|
||||
);
|
||||
|
||||
if (!current) {
|
||||
console.log("[ActivateSelected] 未找到当前profile配置");
|
||||
console.log(
|
||||
"[ActivateSelected] Current profile configuration not found",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否有saved的代理选择
|
||||
const { selected = [] } = current;
|
||||
if (selected.length === 0) {
|
||||
console.log("[ActivateSelected] 当前profile无保存的代理选择,跳过");
|
||||
console.log(
|
||||
"[ActivateSelected] The current profile has no saved proxy selection, so it will be skipped",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(
|
||||
`[ActivateSelected] 当前profile有 ${selected.length} 个代理选择配置`,
|
||||
`[ActivateSelected] The current profile has ${selected.length} proxy selection configurations`,
|
||||
);
|
||||
|
||||
const selectedMap = Object.fromEntries(
|
||||
@@ -108,7 +114,7 @@ export const useProfiles = () => {
|
||||
const targetProxy = selectedMap[name];
|
||||
if (targetProxy != null && targetProxy !== now) {
|
||||
console.log(
|
||||
`[ActivateSelected] 需要切换代理组 ${name}: ${now} -> ${targetProxy}`,
|
||||
`[ActivateSelected] Need to switch proxy groups ${name}: ${now} -> ${targetProxy}`,
|
||||
);
|
||||
hasChange = true;
|
||||
updateProxy(name, targetProxy);
|
||||
@@ -118,27 +124,36 @@ export const useProfiles = () => {
|
||||
});
|
||||
|
||||
if (!hasChange) {
|
||||
console.log("[ActivateSelected] 所有代理选择已经是目标状态,无需更新");
|
||||
console.log(
|
||||
"[ActivateSelected] All agent selections are already in the target state and do not need to be updated",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`[ActivateSelected] 完成代理切换,保存新的选择配置`);
|
||||
console.log(
|
||||
`[ActivateSelected] Complete the proxy switch and save the new selection configuration`,
|
||||
);
|
||||
|
||||
try {
|
||||
await patchProfile(profileData.current!, { selected: newSelected });
|
||||
console.log("[ActivateSelected] 代理选择配置保存成功");
|
||||
console.log(
|
||||
"[ActivateSelected] Proxy selection configuration saved successfully",
|
||||
);
|
||||
|
||||
setTimeout(() => {
|
||||
mutate("getProxies", getProxies());
|
||||
}, 100);
|
||||
} catch (error: any) {
|
||||
console.error(
|
||||
"[ActivateSelected] 保存代理选择配置失败:",
|
||||
"[ActivateSelected] Failed to save proxy selection configuration:",
|
||||
error.message,
|
||||
);
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error("[ActivateSelected] 处理代理选择失败:", error.message);
|
||||
console.error(
|
||||
"[ActivateSelected] Handling proxy selection failure:",
|
||||
error.message,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -66,9 +66,9 @@ root.render(
|
||||
|
||||
// 错误处理
|
||||
window.addEventListener("error", (event) => {
|
||||
console.error("[main.tsx] 全局错误:", event.error);
|
||||
console.error("[main.tsx] Global error:", event.error);
|
||||
});
|
||||
|
||||
window.addEventListener("unhandledrejection", (event) => {
|
||||
console.error("[main.tsx] 未处理的Promise拒绝:", event.reason);
|
||||
console.error("[main.tsx] Unhandled promise rejection:", event.reason);
|
||||
});
|
||||
|
||||
@@ -88,13 +88,13 @@ export const AppDataProvider = ({
|
||||
const newProfileId = event.payload;
|
||||
const now = Date.now();
|
||||
|
||||
console.log(`[AppDataProvider] Profile切换事件: ${newProfileId}`);
|
||||
console.log(`[AppDataProvider] Profile switched: ${newProfileId}`);
|
||||
|
||||
if (
|
||||
lastProfileId === newProfileId &&
|
||||
now - lastUpdateTime < refreshThrottle
|
||||
) {
|
||||
console.log("[AppDataProvider] 重复事件被防抖,跳过");
|
||||
console.log("[AppDataProvider] Duplicate event debounced, skip");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ export const AppDataProvider = ({
|
||||
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
console.log("[AppDataProvider] 强制刷新代理缓存");
|
||||
console.log("[AppDataProvider] Force refresh proxy cache");
|
||||
|
||||
const refreshPromise = Promise.race([
|
||||
forceRefreshProxies(),
|
||||
@@ -117,15 +117,15 @@ export const AppDataProvider = ({
|
||||
|
||||
await refreshPromise;
|
||||
|
||||
console.log("[AppDataProvider] 刷新前端代理数据");
|
||||
console.log("[AppDataProvider] Refresh frontend proxy data");
|
||||
await refreshProxy();
|
||||
|
||||
console.log("[AppDataProvider] Profile切换的代理数据刷新完成");
|
||||
console.log("[AppDataProvider] Proxy data refreshed for profile switch");
|
||||
} catch (error) {
|
||||
console.error("[AppDataProvider] 强制刷新代理缓存失败:", error);
|
||||
console.error("[AppDataProvider] Force refresh proxy cache failed:", error);
|
||||
|
||||
refreshProxy().catch((e) =>
|
||||
console.warn("[AppDataProvider] 普通刷新也失败:", e),
|
||||
console.warn("[AppDataProvider] Normal refresh also failed:", e),
|
||||
);
|
||||
}
|
||||
}, 0);
|
||||
@@ -134,14 +134,14 @@ export const AppDataProvider = ({
|
||||
// 监听Clash配置刷新事件(enhance操作等)
|
||||
const handleRefreshClash = () => {
|
||||
const now = Date.now();
|
||||
console.log("[AppDataProvider] Clash配置刷新事件");
|
||||
console.log("[AppDataProvider] Clash config refresh event");
|
||||
|
||||
if (now - lastUpdateTime > refreshThrottle) {
|
||||
lastUpdateTime = now;
|
||||
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
console.log("[AppDataProvider] Clash刷新 - 强制刷新代理缓存");
|
||||
console.log("[AppDataProvider] Clash refresh - force refresh proxy cache");
|
||||
|
||||
// 添加超时保护
|
||||
const refreshPromise = Promise.race([
|
||||
@@ -158,11 +158,11 @@ export const AppDataProvider = ({
|
||||
await refreshProxy();
|
||||
} catch (error) {
|
||||
console.error(
|
||||
"[AppDataProvider] Clash刷新时强制刷新代理缓存失败:",
|
||||
"[AppDataProvider] Clash refresh forcing proxy cache refresh failed:",
|
||||
error,
|
||||
);
|
||||
refreshProxy().catch((e) =>
|
||||
console.warn("[AppDataProvider] Clash刷新普通刷新也失败:", e),
|
||||
console.warn("[AppDataProvider] Clash refresh normal refresh also failed:", e),
|
||||
);
|
||||
}
|
||||
}, 0);
|
||||
@@ -181,7 +181,7 @@ export const AppDataProvider = ({
|
||||
);
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("[AppDataProvider] 事件监听器设置失败:", error);
|
||||
console.error("[AppDataProvider] Failed to set up event listeners:", error);
|
||||
return () => {};
|
||||
}
|
||||
};
|
||||
@@ -279,7 +279,7 @@ export const AppDataProvider = ({
|
||||
if (!server) return () => {};
|
||||
|
||||
console.log(
|
||||
`[Connections][${AppDataProvider.name}] 正在连接: ${server}/connections`,
|
||||
`[Connections][${AppDataProvider.name}] Connecting: ${server}/connections`,
|
||||
);
|
||||
const socket = createAuthSockette(`${server}/connections`, secret, {
|
||||
timeout: 5000,
|
||||
@@ -322,7 +322,7 @@ export const AppDataProvider = ({
|
||||
);
|
||||
} catch (err) {
|
||||
console.error(
|
||||
`[Connections][${AppDataProvider.name}] 解析数据错误:`,
|
||||
`[Connections][${AppDataProvider.name}] Failed to parse data:`,
|
||||
err,
|
||||
event.data,
|
||||
);
|
||||
@@ -330,26 +330,26 @@ export const AppDataProvider = ({
|
||||
},
|
||||
onopen: (event) => {
|
||||
console.log(
|
||||
`[Connections][${AppDataProvider.name}] WebSocket 连接已建立`,
|
||||
`[Connections][${AppDataProvider.name}] WebSocket connected`,
|
||||
event,
|
||||
);
|
||||
},
|
||||
onerror(event) {
|
||||
console.error(
|
||||
`[Connections][${AppDataProvider.name}] WebSocket 连接错误或达到最大重试次数`,
|
||||
`[Connections][${AppDataProvider.name}] WebSocket error or max retries reached`,
|
||||
event,
|
||||
);
|
||||
next(null, { connections: [], uploadTotal: 0, downloadTotal: 0 });
|
||||
},
|
||||
onclose: (event) => {
|
||||
console.log(
|
||||
`[Connections][${AppDataProvider.name}] WebSocket 连接关闭`,
|
||||
`[Connections][${AppDataProvider.name}] WebSocket closed`,
|
||||
event.code,
|
||||
event.reason,
|
||||
);
|
||||
if (event.code !== 1000 && event.code !== 1001) {
|
||||
console.warn(
|
||||
`[Connections][${AppDataProvider.name}] 连接非正常关闭,重置数据`,
|
||||
`[Connections][${AppDataProvider.name}] Abnormal close, resetting data`,
|
||||
);
|
||||
next(null, { connections: [], uploadTotal: 0, downloadTotal: 0 });
|
||||
}
|
||||
@@ -357,7 +357,7 @@ export const AppDataProvider = ({
|
||||
});
|
||||
|
||||
return () => {
|
||||
console.log(`[Connections][${AppDataProvider.name}] 清理WebSocket连接`);
|
||||
console.log(`[Connections][${AppDataProvider.name}] Cleaning up WebSocket connection`);
|
||||
socket.close();
|
||||
};
|
||||
},
|
||||
@@ -373,7 +373,7 @@ export const AppDataProvider = ({
|
||||
if (!server) return () => {};
|
||||
|
||||
console.log(
|
||||
`[Traffic][${AppDataProvider.name}] 正在连接: ${server}/traffic`,
|
||||
`[Traffic][${AppDataProvider.name}] Connecting: ${server}/traffic`,
|
||||
);
|
||||
const socket = createAuthSockette(`${server}/traffic`, secret, {
|
||||
onmessage(event) {
|
||||
@@ -387,13 +387,13 @@ export const AppDataProvider = ({
|
||||
next(null, data);
|
||||
} else {
|
||||
console.warn(
|
||||
`[Traffic][${AppDataProvider.name}] 收到无效数据:`,
|
||||
`[Traffic][${AppDataProvider.name}] Received invalid data:`,
|
||||
data,
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(
|
||||
`[Traffic][${AppDataProvider.name}] 解析数据错误:`,
|
||||
`[Traffic][${AppDataProvider.name}] Failed to parse data:`,
|
||||
err,
|
||||
event.data,
|
||||
);
|
||||
@@ -401,26 +401,26 @@ export const AppDataProvider = ({
|
||||
},
|
||||
onopen: (event) => {
|
||||
console.log(
|
||||
`[Traffic][${AppDataProvider.name}] WebSocket 连接已建立`,
|
||||
`[Traffic][${AppDataProvider.name}] WebSocket connected`,
|
||||
event,
|
||||
);
|
||||
},
|
||||
onerror(event) {
|
||||
console.error(
|
||||
`[Traffic][${AppDataProvider.name}] WebSocket 连接错误或达到最大重试次数`,
|
||||
`[Traffic][${AppDataProvider.name}] WebSocket error or max retries reached`,
|
||||
event,
|
||||
);
|
||||
next(null, { up: 0, down: 0 });
|
||||
},
|
||||
onclose: (event) => {
|
||||
console.log(
|
||||
`[Traffic][${AppDataProvider.name}] WebSocket 连接关闭`,
|
||||
`[Traffic][${AppDataProvider.name}] WebSocket closed`,
|
||||
event.code,
|
||||
event.reason,
|
||||
);
|
||||
if (event.code !== 1000 && event.code !== 1001) {
|
||||
console.warn(
|
||||
`[Traffic][${AppDataProvider.name}] 连接非正常关闭,重置数据`,
|
||||
`[Traffic][${AppDataProvider.name}] Abnormal close, resetting data`,
|
||||
);
|
||||
next(null, { up: 0, down: 0 });
|
||||
}
|
||||
@@ -428,7 +428,7 @@ export const AppDataProvider = ({
|
||||
});
|
||||
|
||||
return () => {
|
||||
console.log(`[Traffic][${AppDataProvider.name}] 清理WebSocket连接`);
|
||||
console.log(`[Traffic][${AppDataProvider.name}] Cleaning up WebSocket connection`);
|
||||
socket.close();
|
||||
};
|
||||
},
|
||||
@@ -443,7 +443,7 @@ export const AppDataProvider = ({
|
||||
if (!server) return () => {};
|
||||
|
||||
console.log(
|
||||
`[Memory][${AppDataProvider.name}] 正在连接: ${server}/memory`,
|
||||
`[Memory][${AppDataProvider.name}] Connecting: ${server}/memory`,
|
||||
);
|
||||
const socket = createAuthSockette(`${server}/memory`, secret, {
|
||||
onmessage(event) {
|
||||
@@ -453,13 +453,13 @@ export const AppDataProvider = ({
|
||||
next(null, data);
|
||||
} else {
|
||||
console.warn(
|
||||
`[Memory][${AppDataProvider.name}] 收到无效数据:`,
|
||||
`[Memory][${AppDataProvider.name}] Received invalid data:`,
|
||||
data,
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(
|
||||
`[Memory][${AppDataProvider.name}] 解析数据错误:`,
|
||||
`[Memory][${AppDataProvider.name}] Failed to parse data:`,
|
||||
err,
|
||||
event.data,
|
||||
);
|
||||
@@ -467,26 +467,26 @@ export const AppDataProvider = ({
|
||||
},
|
||||
onopen: (event) => {
|
||||
console.log(
|
||||
`[Memory][${AppDataProvider.name}] WebSocket 连接已建立`,
|
||||
`[Memory][${AppDataProvider.name}] WebSocket connected`,
|
||||
event,
|
||||
);
|
||||
},
|
||||
onerror(event) {
|
||||
console.error(
|
||||
`[Memory][${AppDataProvider.name}] WebSocket 连接错误或达到最大重试次数`,
|
||||
`[Memory][${AppDataProvider.name}] WebSocket error or max retries reached`,
|
||||
event,
|
||||
);
|
||||
next(null, { inuse: 0 });
|
||||
},
|
||||
onclose: (event) => {
|
||||
console.log(
|
||||
`[Memory][${AppDataProvider.name}] WebSocket 连接关闭`,
|
||||
`[Memory][${AppDataProvider.name}] WebSocket closed`,
|
||||
event.code,
|
||||
event.reason,
|
||||
);
|
||||
if (event.code !== 1000 && event.code !== 1001) {
|
||||
console.warn(
|
||||
`[Memory][${AppDataProvider.name}] 连接非正常关闭,重置数据`,
|
||||
`[Memory][${AppDataProvider.name}] Abnormal close, resetting data`,
|
||||
);
|
||||
next(null, { inuse: 0 });
|
||||
}
|
||||
@@ -494,7 +494,7 @@ export const AppDataProvider = ({
|
||||
});
|
||||
|
||||
return () => {
|
||||
console.log(`[Memory][${AppDataProvider.name}] 清理WebSocket连接`);
|
||||
console.log(`[Memory][${AppDataProvider.name}] Cleaning up WebSocket connection`);
|
||||
socket.close();
|
||||
};
|
||||
},
|
||||
@@ -521,13 +521,13 @@ export const AppDataProvider = ({
|
||||
const isPacMode = verge.proxy_auto_config ?? false;
|
||||
|
||||
if (isPacMode) {
|
||||
// PAC模式:显示我们期望设置的代理地址
|
||||
// PAC mode: show expected proxy address
|
||||
const proxyHost = verge.proxy_host || "127.0.0.1";
|
||||
const proxyPort =
|
||||
verge.verge_mixed_port || clashConfig["mixed-port"] || 7897;
|
||||
return `${proxyHost}:${proxyPort}`;
|
||||
} else {
|
||||
// HTTP代理模式:优先使用系统地址,但如果格式不正确则使用期望地址
|
||||
// HTTP proxy mode: prefer system address, else fallback to expected address
|
||||
const systemServer = sysproxy?.server;
|
||||
if (
|
||||
systemServer &&
|
||||
@@ -536,7 +536,7 @@ export const AppDataProvider = ({
|
||||
) {
|
||||
return systemServer;
|
||||
} else {
|
||||
// 系统地址无效,返回期望的代理地址
|
||||
// Invalid system address; return expected proxy address
|
||||
const proxyHost = verge.proxy_host || "127.0.0.1";
|
||||
const proxyPort =
|
||||
verge.verge_mixed_port || clashConfig["mixed-port"] || 7897;
|
||||
@@ -612,7 +612,7 @@ export const useAppData = () => {
|
||||
const context = useContext(AppDataContext);
|
||||
|
||||
if (!context) {
|
||||
throw new Error("useAppData必须在AppDataProvider内使用");
|
||||
throw new Error("useAppData must be used within AppDataProvider");
|
||||
}
|
||||
|
||||
return context;
|
||||
|
||||
@@ -279,13 +279,13 @@ export const getGroupProxyDelays = async (
|
||||
};
|
||||
|
||||
console.log(
|
||||
`[API] 获取代理组延迟,组: ${groupName}, URL: ${params.url}, 超时: ${params.timeout}ms`,
|
||||
`[API] Get proxy group delay, group: ${groupName}, URL: ${params.url}, timeout: ${params.timeout}ms`,
|
||||
);
|
||||
|
||||
try {
|
||||
const instance = await getAxios();
|
||||
console.log(
|
||||
`[API] 发送HTTP请求: GET /group/${encodeURIComponent(groupName)}/delay`,
|
||||
`[API] Send HTTP request: GET /group/${encodeURIComponent(groupName)}/delay`,
|
||||
);
|
||||
|
||||
const result = await instance.get(
|
||||
@@ -294,12 +294,12 @@ export const getGroupProxyDelays = async (
|
||||
);
|
||||
|
||||
console.log(
|
||||
`[API] 获取代理组延迟成功,组: ${groupName}, 结果数量:`,
|
||||
`[API] Get proxy group delay success, group: ${groupName}, result count:`,
|
||||
Object.keys(result || {}).length,
|
||||
);
|
||||
return result as any as Record<string, number>;
|
||||
} catch (error) {
|
||||
console.error(`[API] 获取代理组延迟失败,组: ${groupName}`, error);
|
||||
console.error(`[API] Get proxy group delay failed, group: ${groupName}`, error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
@@ -476,7 +476,7 @@ export const getIpInfo = async (): Promise<IpInfo> => {
|
||||
// 配置参数
|
||||
const maxRetries = 3;
|
||||
const serviceTimeout = 5000;
|
||||
const overallTimeout = 20000; // 增加总超时时间以容纳延迟
|
||||
const overallTimeout = 20000; // increase total timeout to accommodate delays
|
||||
|
||||
const overallTimeoutController = new AbortController();
|
||||
const overallTimeoutId = setTimeout(() => {
|
||||
@@ -488,7 +488,7 @@ export const getIpInfo = async (): Promise<IpInfo> => {
|
||||
let lastError: Error | null = null;
|
||||
|
||||
for (const service of shuffledServices) {
|
||||
console.log(`尝试IP检测服务: ${service.url}`);
|
||||
console.log(`Trying IP detection service: ${service.url}`);
|
||||
|
||||
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
||||
let timeoutId: ReturnType<typeof setTimeout> | null = null;
|
||||
@@ -508,17 +508,17 @@ export const getIpInfo = async (): Promise<IpInfo> => {
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
|
||||
if (response.data && response.data.ip) {
|
||||
console.log(`IP检测成功,使用服务: ${service.url}`);
|
||||
console.log(`IP detection succeeded, using service: ${service.url}`);
|
||||
return service.mapping(response.data);
|
||||
} else {
|
||||
throw new Error(`无效的响应格式 from ${service.url}`);
|
||||
throw new Error(`Invalid response format from ${service.url}`);
|
||||
}
|
||||
} catch (error: any) {
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
|
||||
lastError = error;
|
||||
console.log(
|
||||
`尝试 ${attempt + 1}/${maxRetries} 失败 (${service.url}):`,
|
||||
`Attempt ${attempt + 1}/${maxRetries} failed (${service.url}):`,
|
||||
error.message,
|
||||
);
|
||||
|
||||
@@ -534,9 +534,9 @@ export const getIpInfo = async (): Promise<IpInfo> => {
|
||||
}
|
||||
|
||||
if (lastError) {
|
||||
throw new Error(`所有IP检测服务都失败: ${lastError.message}`);
|
||||
throw new Error(`All IP detection services failed: ${lastError.message}`);
|
||||
} else {
|
||||
throw new Error("没有可用的IP检测服务");
|
||||
throw new Error("No available IP detection services");
|
||||
}
|
||||
} finally {
|
||||
clearTimeout(overallTimeoutId);
|
||||
|
||||
@@ -112,15 +112,15 @@ export async function getSystemProxy() {
|
||||
|
||||
export async function getAutotemProxy() {
|
||||
try {
|
||||
console.log("[API] 开始调用 get_auto_proxy");
|
||||
console.log("[API] Start calling get_auto_proxy");
|
||||
const result = await invoke<{
|
||||
enable: boolean;
|
||||
url: string;
|
||||
}>("get_auto_proxy");
|
||||
console.log("[API] get_auto_proxy 调用成功:", result);
|
||||
console.log("[API] get_auto_proxy success:", result);
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error("[API] get_auto_proxy 调用失败:", error);
|
||||
console.error("[API] get_auto_proxy failed:", error);
|
||||
return {
|
||||
enable: false,
|
||||
url: "",
|
||||
@@ -132,7 +132,7 @@ export async function getAutoLaunchStatus() {
|
||||
try {
|
||||
return await invoke<boolean>("get_auto_launch_status");
|
||||
} catch (error) {
|
||||
console.error("获取自启动状态失败:", error);
|
||||
console.error("Failed to get auto-launch state:", error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -195,7 +195,7 @@ export async function cmdGetProxyDelay(
|
||||
// 确保URL不为空
|
||||
const testUrl = url || "https://cp.cloudflare.com/generate_204";
|
||||
console.log(
|
||||
`[API] 调用延迟测试API,代理: ${name}, 超时: ${timeout}ms, URL: ${testUrl}`,
|
||||
`[API] Calling delay test API, proxy: ${name}, timeout: ${timeout}ms, URL: ${testUrl}`,
|
||||
);
|
||||
|
||||
try {
|
||||
@@ -212,19 +212,19 @@ export async function cmdGetProxyDelay(
|
||||
// 验证返回结果中是否有delay字段,并且值是一个有效的数字
|
||||
if (result && typeof result.delay === "number") {
|
||||
console.log(
|
||||
`[API] 延迟测试API调用成功,代理: ${name}, 延迟: ${result.delay}ms`,
|
||||
`[API] Delay test API success, proxy: ${name}, delay: ${result.delay}ms`,
|
||||
);
|
||||
return result;
|
||||
} else {
|
||||
console.error(
|
||||
`[API] 延迟测试API返回无效结果,代理: ${name}, 结果:`,
|
||||
`[API] Delay test API returned invalid result, proxy: ${name}, result:`,
|
||||
result,
|
||||
);
|
||||
// 返回一个有效的结果对象,但标记为超时
|
||||
return { delay: 1e6 };
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`[API] 延迟测试API调用失败,代理: ${name}`, error);
|
||||
console.error(`[API] Delay test API failed, proxy: ${name}`, error);
|
||||
// 返回一个有效的结果对象,但标记为错误
|
||||
return { delay: 1e6 };
|
||||
}
|
||||
@@ -232,7 +232,7 @@ export async function cmdGetProxyDelay(
|
||||
|
||||
/// 用于profile切换等场景
|
||||
export async function forceRefreshProxies() {
|
||||
console.log("[API] 强制刷新代理缓存");
|
||||
console.log("[API] Force refresh proxy cache");
|
||||
return invoke<any>("force_refresh_proxies");
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ export const isAdmin = async () => {
|
||||
try {
|
||||
return await invoke<boolean>("is_admin");
|
||||
} catch (error) {
|
||||
console.error("检查管理员权限失败:", error);
|
||||
console.error("Failed to check admin privileges:", error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -83,10 +83,10 @@ export const initGlobalLogService = (
|
||||
|
||||
// 创建新的WebSocket连接,使用新的认证方法
|
||||
const wsUrl = buildWSUrl(server, logLevel);
|
||||
console.log(`[GlobalLog] 正在连接日志服务: ${wsUrl}`);
|
||||
console.log(`[GlobalLog] Connecting to log service: ${wsUrl}`);
|
||||
|
||||
if (!server) {
|
||||
console.warn("[GlobalLog] 服务器地址为空,无法建立连接");
|
||||
console.warn("[GlobalLog] Server URL is empty, cannot establish connection");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -98,11 +98,11 @@ export const initGlobalLogService = (
|
||||
const time = dayjs().format("MM-DD HH:mm:ss");
|
||||
appendLog({ ...data, time });
|
||||
} catch (error) {
|
||||
console.error("[GlobalLog] 解析日志数据失败:", error);
|
||||
console.error("[GlobalLog] Failed to parse log data:", error);
|
||||
}
|
||||
},
|
||||
onerror(event) {
|
||||
console.error("[GlobalLog] WebSocket连接错误", event);
|
||||
console.error("[GlobalLog] WebSocket connection error", event);
|
||||
|
||||
// 记录错误状态但不关闭连接,让重连机制起作用
|
||||
useGlobalLogStore.setState({ isConnected: false });
|
||||
@@ -114,16 +114,16 @@ export const initGlobalLogService = (
|
||||
"type" in event &&
|
||||
event.type === "error"
|
||||
) {
|
||||
console.error("[GlobalLog] 连接已彻底失败,关闭连接");
|
||||
console.error("[GlobalLog] Connection exhausted retries, closing");
|
||||
closeGlobalLogConnection();
|
||||
}
|
||||
},
|
||||
onclose(event) {
|
||||
console.log("[GlobalLog] WebSocket连接关闭", event);
|
||||
console.log("[GlobalLog] WebSocket connection closed", event);
|
||||
useGlobalLogStore.setState({ isConnected: false });
|
||||
},
|
||||
onopen(event) {
|
||||
console.log("[GlobalLog] WebSocket连接已建立", event);
|
||||
console.log("[GlobalLog] WebSocket connection established", event);
|
||||
useGlobalLogStore.setState({ isConnected: true });
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user