Compare commits

..

4 Commits

10 changed files with 366 additions and 240 deletions

View File

@@ -1,4 +1,4 @@
## v2.2.1 ## v2.2.2
**发行代号:拓** **发行代号:拓**
@@ -6,8 +6,24 @@
代号释义: 本次发布在功能上的大幅扩展。新首页设计为用户带来全新交互体验DNS 覆写功能增强网络控制能力解锁测试页面助力内容访问自由度提升轻量模式提供灵活使用选择。此外macOS 应用菜单集成、sidecar 模式、诊断信息导出等新特性进一步丰富了软件的适用场景。这些新增功能显著拓宽了 Clash Verge 的功能边界,为用户提供了更强大的工具和可能性。 代号释义: 本次发布在功能上的大幅扩展。新首页设计为用户带来全新交互体验DNS 覆写功能增强网络控制能力解锁测试页面助力内容访问自由度提升轻量模式提供灵活使用选择。此外macOS 应用菜单集成、sidecar 模式、诊断信息导出等新特性进一步丰富了软件的适用场景。这些新增功能显著拓宽了 Clash Verge 的功能边界,为用户提供了更强大的工具和可能性。
2.2.1 相对于 2.2.0(已下架不在提供) #### 已知问题
修复了: - 仅在Ubuntu 22.04/24.04Fedora 41 **Gnome桌面环境** 做过简单测试不保证其他其他Linux发行版可用将在未来做进一步适配和调优
### 2.2.2 相对于 2.2.1(已下架不在提供)
#### 修复了:
- 弹黑框的问题(原因是服务崩溃触发重装机制)
- MacOS进入轻量模式以后影藏Dock图标
- 增加轻量模式缺失的tray翻译
- Linux下的窗口边框被削掉的问题
#### 新增了:
- 加强服务检测和重装逻辑
- 增强内核与服务保活机制
- 增加服务模式下的僵尸进程清理机制
- 新增当服务模式多次尝试失败后自动回退至用户空间模式
### 2.2.1 相对于 2.2.0(已下架不在提供)
#### 修复了:
1. **首页** 1. **首页**
- 修复 Direct 模式首页无法渲染 - 修复 Direct 模式首页无法渲染
- 修复 首页启用轻量模式导致 ClashVergeRev 从托盘退出 - 修复 首页启用轻量模式导致 ClashVergeRev 从托盘退出
@@ -23,7 +39,7 @@
4. **轻量模式** 4. **轻量模式**
- 修复 MacOS 轻量模式下 Dock 栏图标无法隐藏。 - 修复 MacOS 轻量模式下 Dock 栏图标无法隐藏。
新增了: #### 新增了:
1. **首页** 1. **首页**
- 首页文本过长自动截断 - 首页文本过长自动截断
2. **轻量模式** 2. **轻量模式**
@@ -37,7 +53,7 @@
--- ---
## v2.2.0(已下架不在提供) ## 2.2.0(已下架不在提供)
#### 新增功能 #### 新增功能
1. **首页** 1. **首页**
@@ -78,6 +94,7 @@
- 修复 macOS tray图标错位到左上角的问题。 - 修复 macOS tray图标错位到左上角的问题。
- 修复 Windows/Linux 运行时崩溃。 - 修复 Windows/Linux 运行时崩溃。
- 修复 Win10 阴影和边框问题。 - 修复 Win10 阴影和边框问题。
- 修复 升级或重装后开机自启状态检测和同步问题。
2. **构建** 2. **构建**
- 修复构建失败问题。 - 修复构建失败问题。

View File

@@ -1,6 +1,6 @@
{ {
"name": "clash-verge", "name": "clash-verge",
"version": "2.2.1", "version": "2.2.2",
"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",

View File

@@ -8,8 +8,8 @@ const UPDATE_JSON_FILE = "update.json";
const UPDATE_JSON_PROXY = "update-proxy.json"; const UPDATE_JSON_PROXY = "update-proxy.json";
// Add alpha update JSON filenames // Add alpha update JSON filenames
const ALPHA_TAG_NAME = "updater-alpha"; const ALPHA_TAG_NAME = "updater-alpha";
const ALPHA_UPDATE_JSON_FILE = "update-alpha.json"; const ALPHA_UPDATE_JSON_FILE = "update.json";
const ALPHA_UPDATE_JSON_PROXY = "update-alpha-proxy.json"; const ALPHA_UPDATE_JSON_PROXY = "update-proxy.json";
/// generate update.json /// generate update.json
/// upload to update tag's release asset /// upload to update tag's release asset
@@ -78,6 +78,7 @@ async function resolveUpdater() {
async function processRelease(github, options, tag, isAlpha) { async function processRelease(github, options, tag, isAlpha) {
if (!tag) return; if (!tag) return;
try {
const { data: release } = await github.rest.repos.getReleaseByTag({ const { data: release } = await github.rest.repos.getReleaseByTag({
...options, ...options,
tag: tag.name, tag: tag.name,
@@ -297,6 +298,16 @@ async function processRelease(github, options, tag, isAlpha) {
error.message, error.message,
); );
} }
} catch (error) {
if (error.status === 404) {
console.log(`Release not found for tag: ${tag.name}, skipping...`);
} else {
console.error(
`Failed to get release for tag: ${tag.name}`,
error.message,
);
}
}
} }
// get the signature file content // get the signature file content

2
src-tauri/Cargo.lock generated
View File

@@ -1132,7 +1132,7 @@ dependencies = [
[[package]] [[package]]
name = "clash-verge" name = "clash-verge"
version = "2.2.1" version = "2.2.2"
dependencies = [ dependencies = [
"ab_glyph", "ab_glyph",
"aes-gcm", "aes-gcm",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "clash-verge" name = "clash-verge"
version = "2.2.1" version = "2.2.2"
description = "clash verge" description = "clash verge"
authors = ["zzzgydi", "wonfen", "MystiPanda"] authors = ["zzzgydi", "wonfen", "MystiPanda"]
license = "GPL-3.0-only" license = "GPL-3.0-only"

View File

@@ -19,6 +19,7 @@ use super::service::is_service_running;
#[derive(Debug)] #[derive(Debug)]
pub struct CoreManager { pub struct CoreManager {
running: Arc<Mutex<bool>>, running: Arc<Mutex<bool>>,
last_check_time: Arc<Mutex<Option<std::time::Instant>>>,
} }
/// 内核运行模式 /// 内核运行模式
@@ -37,6 +38,7 @@ impl CoreManager {
static CORE_MANAGER: OnceCell<CoreManager> = OnceCell::new(); static CORE_MANAGER: OnceCell<CoreManager> = OnceCell::new();
CORE_MANAGER.get_or_init(|| CoreManager { CORE_MANAGER.get_or_init(|| CoreManager {
running: Arc::new(Mutex::new(false)), running: Arc::new(Mutex::new(false)),
last_check_time: Arc::new(Mutex::new(None)),
}) })
} }
@@ -681,8 +683,25 @@ impl CoreManager {
// 5. 应用新配置 // 5. 应用新配置
println!("[core配置更新] 应用新配置"); println!("[core配置更新] 应用新配置");
for i in 0..3 {
CoreManager::global().ensure_running_core().await; // 检查当前运行模式
let running_mode = self.get_running_mode().await;
// 使用指数退避策略进行重试
let mut retry_count = 0;
let max_retries = 3;
loop {
// 仅在服务模式下确保服务在运行
match running_mode {
RunningMode::Service => {
println!("[core配置更新] 服务模式下检查服务状态");
self.ensure_running_core().await;
},
_ => {
println!("[core配置更新] 非服务模式,跳过服务状态检查");
}
}
match MihomoManager::global().put_configs_force(run_path).await { match MihomoManager::global().put_configs_force(run_path).await {
Ok(_) => { Ok(_) => {
@@ -691,19 +710,21 @@ impl CoreManager {
return Ok((true, String::new())); return Ok((true, String::new()));
} }
Err(err) => { Err(err) => {
if i < 2 { retry_count += 1;
println!("[core配置更新] 第{}次重试应用配置", i + 1); if retry_count < max_retries {
log::info!(target: "app", "{err}"); // 使用指数退避策略计算下一次重试间隔
sleep(Duration::from_millis(100)).await; let wait_time = 200 * (2_u64.pow(retry_count as u32 - 1));
println!("[core配置更新] 第{}次重试应用配置,等待{}ms", retry_count, wait_time);
log::info!(target: "app", "配置应用失败: {},将在{}ms后重试", err, wait_time);
sleep(Duration::from_millis(wait_time)).await;
} else { } else {
println!("[core配置更新] 配置应用失败: {}", err); println!("[core配置更新] 已重试{}次,配置应用失败: {}", max_retries, err);
Config::runtime().discard(); Config::runtime().discard();
return Ok((false, err.to_string())); return Ok((false, err.to_string()));
} }
} }
} }
} }
Ok((true, String::new()))
} }
Ok((false, error_msg)) => { Ok((false, error_msg)) => {
println!("[core配置更新] 配置验证失败: {}", error_msg); println!("[core配置更新] 配置验证失败: {}", error_msg);
@@ -990,17 +1011,74 @@ impl CoreManager {
} }
/// 确保 Mihomo 和 Verge service 都在运行 /// 确保 Mihomo 和 Verge service 都在运行
pub async fn ensure_running_core(&self) { pub async fn ensure_running_core(&self) {
if MihomoManager::global().is_mihomo_running().await.is_err() { // 添加时间间隔检查,避免频繁执行
log_err!(self.restart_core().await); let min_check_interval = Duration::from_secs(20); // 最小检查间隔为20秒
let should_check = {
let mut last_check = self.last_check_time.lock().await;
let now = std::time::Instant::now();
match *last_check {
Some(time) if now.duration_since(time) < min_check_interval => {
// 如果距离上次检查时间不足30秒跳过本次检查
false
},
_ => {
// 更新最后检查时间
*last_check = Some(now);
true
} }
}
};
if !should_check {
return;
}
// 检查当前运行模式,只在服务模式下执行完整的检查
match self.get_running_mode().await {
RunningMode::Service => {
println!("[确保核心运行] 服务模式下检查核心状态");
// 检查Mihomo是否运行
if MihomoManager::global().is_mihomo_running().await.is_err() {
println!("[确保核心运行] Mihomo未运行尝试重启");
log_err!(self.restart_core().await);
return; // 已重启,无需继续检查
}
// 检查服务是否运行
match is_service_running().await { match is_service_running().await {
Ok(false) => log_err!(self.restart_core().await), Ok(false) => {
println!("[确保核心运行] 服务未运行,尝试重启");
log_err!(self.restart_core().await);
},
Ok(true) => { Ok(true) => {
// 服务运行中再次确认Mihomo状态
if MihomoManager::global().is_mihomo_running().await.is_err() { if MihomoManager::global().is_mihomo_running().await.is_err() {
println!("[确保核心运行] 服务运行但Mihomo未响应尝试重启");
log_err!(self.restart_core().await);
} else {
println!("[确保核心运行] 服务和Mihomo都正常运行");
}
},
Err(err) => {
println!("[确保核心运行] 检查服务状态失败: {:?}", err);
}
}
},
RunningMode::Sidecar => {
println!("[确保核心运行] Sidecar模式下仅检查Mihomo状态");
// 在Sidecar模式下只检查Mihomo是否运行
if MihomoManager::global().is_mihomo_running().await.is_err() {
println!("[确保核心运行] Mihomo未运行尝试重启");
log_err!(self.restart_core().await); log_err!(self.restart_core().await);
} }
},
RunningMode::NotRunning => {
println!("[确保核心运行] 核心未运行,尝试启动");
log_err!(self.start_core().await);
} }
_ => {}
} }
} }
} }

View File

@@ -216,6 +216,12 @@ pub async fn reinstall_service() -> Result<()> {
); );
} }
// 记录安装信息并保存
let mut service_state = ServiceState::get();
service_state.record_install();
service_state.last_error = None;
service_state.save()?;
Ok(()) Ok(())
} }
@@ -268,6 +274,13 @@ pub async fn reinstall_service() -> Result<()> {
status.code().unwrap() status.code().unwrap()
); );
} }
// 记录安装信息并保存
let mut service_state = ServiceState::get();
service_state.record_install();
service_state.last_error = None;
service_state.save()?;
Ok(()) Ok(())
} }

View File

@@ -1,5 +1,5 @@
{ {
"version": "2.2.1", "version": "2.2.2",
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json", "$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"bundle": { "bundle": {
"active": true, "active": true,
@@ -30,6 +30,14 @@
"plugins": { "plugins": {
"updater": { "updater": {
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK", "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK",
"endpoints": [
"https://download.clashverge.dev/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-proxy.json",
"https://gh-proxy.com/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-proxy.json",
"https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update.json",
"https://download.clashverge.dev/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater-alpha/update-alpha-proxy.json",
"https://gh-proxy.com/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater-alpha/update-alpha-proxy.json",
"https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater-alpha/update-alpha.json"
],
"windows": { "windows": {
"installMode": "basicUi" "installMode": "basicUi"
} }

View File

@@ -353,7 +353,6 @@
"clash_mode_direct": "直连模式", "clash_mode_direct": "直连模式",
"toggle_system_proxy": "打开/关闭系统代理", "toggle_system_proxy": "打开/关闭系统代理",
"toggle_tun_mode": "打开/关闭 TUN 模式", "toggle_tun_mode": "打开/关闭 TUN 模式",
"toggle_lightweight_mode": "进入轻量模式",
"entry_lightweight_mode": "进入轻量模式", "entry_lightweight_mode": "进入轻量模式",
"Backup Setting": "备份设置", "Backup Setting": "备份设置",
"Backup Setting Info": "支持 WebDAV 备份配置文件", "Backup Setting Info": "支持 WebDAV 备份配置文件",

View File

@@ -249,8 +249,8 @@ const Layout = () => {
? { ? {
borderRadius: "8px", borderRadius: "8px",
border: "1px solid var(--divider-color)", border: "1px solid var(--divider-color)",
width: "calc(100vw - 0px)", width: "calc(100vw - 4px)",
height: "calc(100vh - 0px)", height: "calc(100vh - 4px)",
} }
: {}, : {},
]} ]}