diff --git a/src-tauri/src/cmds.rs b/src-tauri/src/cmds.rs index 8b2a6b5..2a7c87c 100644 --- a/src-tauri/src/cmds.rs +++ b/src-tauri/src/cmds.rs @@ -259,10 +259,26 @@ pub fn get_verge_config(verge_state: State<'_, VergeState>) -> Result, verge_state: State<'_, VergeState>, + profiles_state: State<'_, ProfilesState>, ) -> Result<(), String> { + let tun_mode = payload.enable_tun_mode.clone(); + let mut verge = verge_state.0.lock().unwrap(); - verge.patch_config(payload) + verge.patch_config(payload)?; + + // change tun mode + if tun_mode.is_some() { + let mut clash = clash_state.0.lock().unwrap(); + let profiles = profiles_state.0.lock().unwrap(); + + clash.tun_mode(tun_mode.unwrap())?; + clash.update_config(); + profiles.activate(&clash)?; + } + + Ok(()) } /// kill all sidecars when update app diff --git a/src-tauri/src/core/clash.rs b/src-tauri/src/core/clash.rs index c7a23a9..80ea316 100644 --- a/src-tauri/src/core/clash.rs +++ b/src-tauri/src/core/clash.rs @@ -203,6 +203,48 @@ impl Clash { } self.save_config() } + + /// enable tun mode + /// only revise the config and restart the + pub fn tun_mode(&mut self, enable: bool) -> Result<(), String> { + let tun_key = Value::String("tun".into()); + let tun_val = self.config.get(&tun_key); + + let mut new_val = Mapping::new(); + + if tun_val.is_some() && tun_val.as_ref().unwrap().is_mapping() { + new_val = tun_val.as_ref().unwrap().as_mapping().unwrap().clone(); + } + + macro_rules! revise { + ($map: expr, $key: expr, $val: expr) => { + let ret_key = Value::String($key.into()); + if $map.contains_key(&ret_key) { + $map[&ret_key] = $val; + } else { + $map.insert(ret_key, $val); + } + }; + } + + macro_rules! append { + ($map: expr, $key: expr, $val: expr) => { + let ret_key = Value::String($key.into()); + if !$map.contains_key(&ret_key) { + $map.insert(ret_key, $val); + } + }; + } + + revise!(new_val, "enable", Value::from(enable)); + append!(new_val, "stack", Value::from("gvisor")); + append!(new_val, "auto-route", Value::from(true)); + append!(new_val, "auto-detect-interface", Value::from(true)); + + revise!(self.config, "tun", Value::from(new_val)); + + self.save_config() + } } impl Default for Clash { diff --git a/src-tauri/src/core/verge.rs b/src-tauri/src/core/verge.rs index c6959fb..349480a 100644 --- a/src-tauri/src/core/verge.rs +++ b/src-tauri/src/core/verge.rs @@ -20,6 +20,9 @@ pub struct VergeConfig { /// enable traffic graph default is true pub traffic_graph: Option, + /// clash tun mode + pub enable_tun_mode: Option, + /// can the app auto startup pub enable_auto_launch: Option, @@ -258,6 +261,11 @@ impl Verge { Verge::guard_proxy(self.guard_state.clone()); } + // handle the tun mode + if patch.enable_tun_mode.is_some() { + self.config.enable_tun_mode = patch.enable_tun_mode; + } + self.config.save_file() } } diff --git a/src-tauri/src/utils/resolve.rs b/src-tauri/src/utils/resolve.rs index bb1cc6a..9fe90ce 100644 --- a/src-tauri/src/utils/resolve.rs +++ b/src-tauri/src/utils/resolve.rs @@ -22,18 +22,27 @@ pub fn resolve_setup(app: &App) { let mut profiles = profiles_state.0.lock().unwrap(); if let Err(err) = clash.run_sidecar() { - log::error!("{}", err); + log::error!("{err}"); } *profiles = Profiles::read_file(); if let Err(err) = profiles.activate(&clash) { - log::error!("{}", err); + log::error!("{err}"); } verge.init_sysproxy(clash.info.port.clone()); + // enable tun mode + if verge.config.enable_tun_mode.clone().unwrap_or(false) + && verge.cur_sysproxy.is_some() + && verge.cur_sysproxy.as_ref().unwrap().enable + { + log::info!("enable tun mode"); + clash.tun_mode(true).unwrap(); + } + verge.init_launch(); if let Err(err) = verge.sync_launch() { - log::error!("{}", err); + log::error!("{err}"); } } diff --git a/src/components/setting/setting-system.tsx b/src/components/setting/setting-system.tsx index d7db114..dfc482e 100644 --- a/src/components/setting/setting-system.tsx +++ b/src/components/setting/setting-system.tsx @@ -15,6 +15,7 @@ const SettingSystem = ({ onError }: Props) => { const { data: vergeConfig } = useSWR("getVergeConfig", getVergeConfig); const { + enable_tun_mode = false, enable_auto_launch = false, enable_system_proxy = false, system_proxy_bypass = "", @@ -28,6 +29,20 @@ const SettingSystem = ({ onError }: Props) => { return ( + + + onChangeData({ enable_tun_mode: e })} + onGuard={(e) => patchVergeConfig({ enable_tun_mode: e })} + > + + + +