mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-28 07:14:40 +08:00
feat: add bitflags crate and refactor UpdateFlags implementation
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1194,6 +1194,7 @@ dependencies = [
|
||||
"async-trait",
|
||||
"backoff",
|
||||
"base64 0.22.1",
|
||||
"bitflags 2.10.0",
|
||||
"boa_engine",
|
||||
"chrono",
|
||||
"clash-verge-draft",
|
||||
|
||||
@@ -68,6 +68,7 @@ compact_str = { version = "0.9.0", features = ["serde"] }
|
||||
serde = { version = "1.0.228" }
|
||||
serde_json = { version = "1.0.145" }
|
||||
serde_yaml_ng = { version = "0.10.0" }
|
||||
bitflags = { version = "2.10.0" }
|
||||
|
||||
# *** For Windows platform only ***
|
||||
deelevate = "0.2.0"
|
||||
|
||||
@@ -55,6 +55,7 @@ serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
serde_yaml_ng = { workspace = true }
|
||||
smartstring = { workspace = true, features = ["serde"] }
|
||||
bitflags = { workspace = true }
|
||||
warp = { version = "0.4.2", features = ["server"] }
|
||||
open = "5.3.3"
|
||||
dunce = "1.0.5"
|
||||
|
||||
@@ -4,6 +4,7 @@ use crate::{
|
||||
module::{auto_backup::AutoBackupManager, lightweight},
|
||||
};
|
||||
use anyhow::Result;
|
||||
use bitflags::bitflags;
|
||||
use clash_verge_draft::SharedDraft;
|
||||
use clash_verge_logging::{Type, logging, logging_error};
|
||||
use serde_yaml_ng::Mapping;
|
||||
@@ -49,26 +50,29 @@ pub async fn patch_clash(patch: &Mapping) -> Result<()> {
|
||||
}
|
||||
|
||||
// Define update flags as bitflags for better performance
|
||||
#[derive(Clone, Copy)]
|
||||
enum UpdateFlags {
|
||||
None = 0,
|
||||
RestartCore = 1 << 0,
|
||||
ClashConfig = 1 << 1,
|
||||
VergeConfig = 1 << 2,
|
||||
Launch = 1 << 3,
|
||||
SysProxy = 1 << 4,
|
||||
SystrayIcon = 1 << 5,
|
||||
Hotkey = 1 << 6,
|
||||
SystrayMenu = 1 << 7,
|
||||
SystrayTooltip = 1 << 8,
|
||||
SystrayClickBehavior = 1 << 9,
|
||||
LighteWeight = 1 << 10,
|
||||
Language = 1 << 11,
|
||||
bitflags! {
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
struct UpdateFlags: u16 {
|
||||
const RESTART_CORE = 1 << 0;
|
||||
const CLASH_CONFIG = 1 << 1;
|
||||
const VERGE_CONFIG = 1 << 2;
|
||||
const LAUNCH = 1 << 3;
|
||||
const SYS_PROXY = 1 << 4;
|
||||
const SYSTRAY_ICON = 1 << 5;
|
||||
const HOTKEY = 1 << 6;
|
||||
const SYSTRAY_MENU = 1 << 7;
|
||||
const SYSTRAY_TOOLTIP = 1 << 8;
|
||||
const SYSTRAY_CLICK_BEHAVIOR = 1 << 9;
|
||||
const LIGHT_WEIGHT = 1 << 10;
|
||||
const LANGUAGE = 1 << 11;
|
||||
|
||||
const GROUP_SYS_TRAY = Self::SYSTRAY_MENU.bits()
|
||||
| Self::SYSTRAY_TOOLTIP.bits()
|
||||
| Self::SYSTRAY_ICON.bits();
|
||||
}
|
||||
}
|
||||
|
||||
fn determine_update_flags(patch: &IVerge) -> i32 {
|
||||
let mut update_flags: i32 = UpdateFlags::None as i32;
|
||||
|
||||
fn determine_update_flags(patch: &IVerge) -> UpdateFlags {
|
||||
let tun_mode = patch.enable_tun_mode;
|
||||
let auto_launch = patch.enable_auto_launch;
|
||||
let system_proxy = patch.enable_system_proxy;
|
||||
@@ -108,142 +112,124 @@ fn determine_update_flags(patch: &IVerge) -> i32 {
|
||||
let enable_proxy_guard = patch.enable_proxy_guard;
|
||||
let proxy_guard_duration = patch.proxy_guard_duration;
|
||||
|
||||
if tun_mode.is_some() {
|
||||
update_flags |= UpdateFlags::ClashConfig as i32;
|
||||
update_flags |= UpdateFlags::SystrayMenu as i32;
|
||||
update_flags |= UpdateFlags::SystrayTooltip as i32;
|
||||
update_flags |= UpdateFlags::SystrayIcon as i32;
|
||||
}
|
||||
if enable_global_hotkey.is_some() || home_cards.is_some() {
|
||||
update_flags |= UpdateFlags::VergeConfig as i32;
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
if redir_enabled.is_some() || redir_port.is_some() {
|
||||
update_flags |= UpdateFlags::RestartCore as i32;
|
||||
}
|
||||
#[cfg(target_os = "linux")]
|
||||
if tproxy_enabled.is_some() || tproxy_port.is_some() {
|
||||
update_flags |= UpdateFlags::RestartCore as i32;
|
||||
}
|
||||
if socks_enabled.is_some()
|
||||
let mut restart_core_needed = socks_enabled.is_some()
|
||||
|| http_enabled.is_some()
|
||||
|| socks_port.is_some()
|
||||
|| http_port.is_some()
|
||||
|| mixed_port.is_some()
|
||||
|| enable_external_controller.is_some();
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
update_flags |= UpdateFlags::RestartCore as i32;
|
||||
restart_core_needed |= redir_enabled.is_some() || redir_port.is_some();
|
||||
}
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
restart_core_needed |= tproxy_enabled.is_some() || tproxy_port.is_some();
|
||||
}
|
||||
|
||||
let mut update_flags = UpdateFlags::empty();
|
||||
if restart_core_needed {
|
||||
update_flags.insert(UpdateFlags::RESTART_CORE);
|
||||
}
|
||||
if tun_mode.is_some() {
|
||||
update_flags.insert(UpdateFlags::CLASH_CONFIG | UpdateFlags::GROUP_SYS_TRAY);
|
||||
}
|
||||
if enable_global_hotkey.is_some() || home_cards.is_some() {
|
||||
update_flags.insert(UpdateFlags::VERGE_CONFIG);
|
||||
}
|
||||
if auto_launch.is_some() {
|
||||
update_flags |= UpdateFlags::Launch as i32;
|
||||
update_flags.insert(UpdateFlags::LAUNCH);
|
||||
}
|
||||
|
||||
if system_proxy.is_some() {
|
||||
update_flags |= UpdateFlags::SysProxy as i32;
|
||||
update_flags |= UpdateFlags::SystrayMenu as i32;
|
||||
update_flags |= UpdateFlags::SystrayTooltip as i32;
|
||||
update_flags |= UpdateFlags::SystrayIcon as i32;
|
||||
update_flags.insert(UpdateFlags::SYS_PROXY | UpdateFlags::GROUP_SYS_TRAY);
|
||||
}
|
||||
|
||||
if proxy_bypass.is_some()
|
||||
|| pac_content.is_some()
|
||||
|| pac.is_some()
|
||||
|| enable_proxy_guard.is_some()
|
||||
|| proxy_guard_duration.is_some()
|
||||
{
|
||||
update_flags |= UpdateFlags::SysProxy as i32;
|
||||
update_flags.insert(UpdateFlags::SYS_PROXY);
|
||||
}
|
||||
|
||||
if language.is_some() {
|
||||
update_flags |= UpdateFlags::Language as i32;
|
||||
update_flags |= UpdateFlags::SystrayMenu as i32;
|
||||
update_flags |= UpdateFlags::SystrayTooltip as i32;
|
||||
update_flags.insert(UpdateFlags::LANGUAGE | UpdateFlags::SYSTRAY_MENU | UpdateFlags::SYSTRAY_TOOLTIP);
|
||||
}
|
||||
if common_tray_icon.is_some()
|
||||
|| sysproxy_tray_icon.is_some()
|
||||
|| tun_tray_icon.is_some()
|
||||
|| tray_icon.is_some()
|
||||
|| enable_tray_speed.is_some()
|
||||
// || enable_tray_icon.is_some()
|
||||
{
|
||||
update_flags |= UpdateFlags::SystrayIcon as i32;
|
||||
update_flags.insert(UpdateFlags::SYSTRAY_ICON);
|
||||
}
|
||||
|
||||
if patch.hotkeys.is_some() {
|
||||
update_flags |= UpdateFlags::Hotkey as i32;
|
||||
update_flags |= UpdateFlags::SystrayMenu as i32;
|
||||
update_flags.insert(UpdateFlags::HOTKEY | UpdateFlags::SYSTRAY_MENU);
|
||||
}
|
||||
|
||||
if tray_event.is_some() {
|
||||
update_flags |= UpdateFlags::SystrayClickBehavior as i32;
|
||||
update_flags.insert(UpdateFlags::SYSTRAY_CLICK_BEHAVIOR);
|
||||
}
|
||||
|
||||
if enable_auto_light_weight.is_some() {
|
||||
update_flags |= UpdateFlags::LighteWeight as i32;
|
||||
update_flags.insert(UpdateFlags::LIGHT_WEIGHT);
|
||||
}
|
||||
|
||||
if enable_external_controller.is_some() {
|
||||
update_flags |= UpdateFlags::RestartCore as i32;
|
||||
}
|
||||
|
||||
if tray_proxy_groups_display_mode.is_some() {
|
||||
update_flags |= UpdateFlags::SystrayMenu as i32;
|
||||
update_flags.insert(UpdateFlags::SYSTRAY_MENU);
|
||||
}
|
||||
if tray_inline_outbound_modes.is_some() {
|
||||
update_flags |= UpdateFlags::SystrayMenu as i32;
|
||||
update_flags.insert(UpdateFlags::SYSTRAY_MENU);
|
||||
}
|
||||
|
||||
update_flags
|
||||
}
|
||||
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
async fn process_terminated_flags(update_flags: i32, patch: &IVerge) -> Result<()> {
|
||||
async fn process_terminated_flags(update_flags: UpdateFlags, patch: &IVerge) -> Result<()> {
|
||||
// Process updates based on flags
|
||||
if (update_flags & (UpdateFlags::RestartCore as i32)) != 0 {
|
||||
if update_flags.contains(UpdateFlags::RESTART_CORE) {
|
||||
Config::generate().await?;
|
||||
CoreManager::global().restart_core().await?;
|
||||
}
|
||||
if (update_flags & (UpdateFlags::ClashConfig as i32)) != 0 {
|
||||
if update_flags.contains(UpdateFlags::CLASH_CONFIG) {
|
||||
CoreManager::global().update_config().await?;
|
||||
handle::Handle::refresh_clash();
|
||||
}
|
||||
if (update_flags & (UpdateFlags::VergeConfig as i32)) != 0 {
|
||||
if update_flags.contains(UpdateFlags::VERGE_CONFIG) {
|
||||
Config::verge()
|
||||
.await
|
||||
.edit_draft(|d| d.enable_global_hotkey = patch.enable_global_hotkey);
|
||||
handle::Handle::refresh_verge();
|
||||
}
|
||||
if (update_flags & (UpdateFlags::Launch as i32)) != 0 {
|
||||
if update_flags.contains(UpdateFlags::LAUNCH) {
|
||||
sysopt::Sysopt::global().update_launch().await?;
|
||||
}
|
||||
if (update_flags & (UpdateFlags::Language as i32)) != 0
|
||||
if update_flags.contains(UpdateFlags::LANGUAGE)
|
||||
&& let Some(language) = &patch.language
|
||||
{
|
||||
clash_verge_i18n::set_locale(language.as_str());
|
||||
}
|
||||
if (update_flags & (UpdateFlags::SysProxy as i32)) != 0 {
|
||||
if update_flags.contains(UpdateFlags::SYS_PROXY) {
|
||||
sysopt::Sysopt::global().update_sysproxy().await?;
|
||||
sysopt::Sysopt::global().refresh_guard().await;
|
||||
}
|
||||
if (update_flags & (UpdateFlags::Hotkey as i32)) != 0
|
||||
if update_flags.contains(UpdateFlags::HOTKEY)
|
||||
&& let Some(hotkeys) = &patch.hotkeys
|
||||
{
|
||||
hotkey::Hotkey::global().update(hotkeys.to_owned()).await?;
|
||||
}
|
||||
if (update_flags & (UpdateFlags::SystrayMenu as i32)) != 0 {
|
||||
if update_flags.contains(UpdateFlags::SYSTRAY_MENU) {
|
||||
tray::Tray::global().update_menu().await?;
|
||||
}
|
||||
if (update_flags & (UpdateFlags::SystrayIcon as i32)) != 0 {
|
||||
if update_flags.contains(UpdateFlags::SYSTRAY_ICON) {
|
||||
tray::Tray::global()
|
||||
.update_icon(&Config::verge().await.latest_arc())
|
||||
.await?;
|
||||
}
|
||||
if (update_flags & (UpdateFlags::SystrayTooltip as i32)) != 0 {
|
||||
if update_flags.contains(UpdateFlags::SYSTRAY_TOOLTIP) {
|
||||
tray::Tray::global().update_tooltip().await?;
|
||||
}
|
||||
if (update_flags & (UpdateFlags::SystrayClickBehavior as i32)) != 0 {
|
||||
if update_flags.contains(UpdateFlags::SYSTRAY_CLICK_BEHAVIOR) {
|
||||
tray::Tray::global().update_click_behavior().await?;
|
||||
}
|
||||
if (update_flags & (UpdateFlags::LighteWeight as i32)) != 0 {
|
||||
if update_flags.contains(UpdateFlags::LIGHT_WEIGHT) {
|
||||
if patch.enable_auto_light_weight_mode.unwrap_or(false) {
|
||||
lightweight::enable_auto_light_weight_mode().await;
|
||||
} else {
|
||||
@@ -257,6 +243,7 @@ pub async fn patch_verge(patch: &IVerge, not_save_file: bool) -> Result<()> {
|
||||
Config::verge().await.edit_draft(|d| d.patch_config(patch));
|
||||
|
||||
let update_flags = determine_update_flags(patch);
|
||||
logging!(debug, Type::Setup, "Determined update flags: {:?}", update_flags);
|
||||
let process_flag_result: std::result::Result<(), anyhow::Error> = {
|
||||
process_terminated_flags(update_flags, patch).await?;
|
||||
Ok(())
|
||||
@@ -271,7 +258,7 @@ pub async fn patch_verge(patch: &IVerge, not_save_file: bool) -> Result<()> {
|
||||
if !not_save_file {
|
||||
// 分离数据获取和异步调用
|
||||
let verge_data = Config::verge().await.data_arc();
|
||||
logging!(info, Type::Setup, "Saving Verge configuration to file...");
|
||||
logging!(debug, Type::Setup, "Saving Verge configuration to file...");
|
||||
verge_data.save_file().await?;
|
||||
}
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user