mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2024-11-16 19:56:50 +08:00
feat: system proxy guard
This commit is contained in:
parent
0245baf1b6
commit
e38dcd85ac
|
@ -260,7 +260,7 @@ pub fn get_verge_config(verge_state: State<'_, VergeState>) -> Result<VergeConfi
|
|||
/// patch the verge config
|
||||
/// this command only save the config and not responsible for other things
|
||||
#[tauri::command]
|
||||
pub async fn patch_verge_config(
|
||||
pub fn patch_verge_config(
|
||||
payload: VergeConfig,
|
||||
verge_state: State<'_, VergeState>,
|
||||
) -> Result<(), String> {
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
use crate::utils::{config, dirs, sysopt::SysProxyConfig};
|
||||
use crate::{
|
||||
core::Clash,
|
||||
utils::{config, dirs, sysopt::SysProxyConfig},
|
||||
};
|
||||
use auto_launch::{AutoLaunch, AutoLaunchBuilder};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tauri::api::path::resource_dir;
|
||||
use std::sync::Arc;
|
||||
use tauri::{api::path::resource_dir, async_runtime::Mutex};
|
||||
|
||||
/// ### `verge.yaml` schema
|
||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
||||
|
@ -22,6 +26,9 @@ pub struct VergeConfig {
|
|||
/// set system proxy
|
||||
pub enable_system_proxy: Option<bool>,
|
||||
|
||||
/// enable proxy guard
|
||||
pub enable_proxy_guard: Option<bool>,
|
||||
|
||||
/// set system proxy bypass
|
||||
pub system_proxy_bypass: Option<String>,
|
||||
}
|
||||
|
@ -53,6 +60,9 @@ pub struct Verge {
|
|||
pub cur_sysproxy: Option<SysProxyConfig>,
|
||||
|
||||
pub auto_launch: Option<AutoLaunch>,
|
||||
|
||||
/// record whether the guard async is running or not
|
||||
guard_state: Arc<Mutex<bool>>,
|
||||
}
|
||||
|
||||
impl Default for Verge {
|
||||
|
@ -68,6 +78,7 @@ impl Verge {
|
|||
old_sysproxy: None,
|
||||
cur_sysproxy: None,
|
||||
auto_launch: None,
|
||||
guard_state: Arc::new(Mutex::new(false)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,6 +103,9 @@ impl Verge {
|
|||
|
||||
self.cur_sysproxy = Some(sysproxy);
|
||||
}
|
||||
|
||||
// launchs the system proxy guard
|
||||
Verge::guard_proxy(10, self.guard_state.clone());
|
||||
}
|
||||
|
||||
/// reset the sysproxy
|
||||
|
@ -154,10 +168,9 @@ impl Verge {
|
|||
|
||||
let auto_launch = self.auto_launch.clone().unwrap();
|
||||
|
||||
let result = if enable {
|
||||
auto_launch.enable()
|
||||
} else {
|
||||
auto_launch.disable()
|
||||
let result = match enable {
|
||||
true => auto_launch.enable(),
|
||||
false => auto_launch.disable(),
|
||||
};
|
||||
|
||||
match result {
|
||||
|
@ -169,24 +182,6 @@ impl Verge {
|
|||
}
|
||||
}
|
||||
|
||||
// fn guard_thread(&mut self) -> Result<(), String> {
|
||||
// let sysproxy = self.cur_sysproxy.clone();
|
||||
|
||||
// use std::{thread, time};
|
||||
// tauri::async_runtime::spawn(async move {
|
||||
// if let Some(sysproxy) = sysproxy {
|
||||
// sysproxy.set_sys();
|
||||
// }
|
||||
|
||||
// let ten_millis = time::Duration::from_millis(10);
|
||||
// let now = time::Instant::now();
|
||||
|
||||
// thread::sleep(ten_millis);
|
||||
// });
|
||||
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
/// patch verge config
|
||||
/// There should be only one update at a time here
|
||||
/// so call the save_file at the end is savely
|
||||
|
@ -248,10 +243,75 @@ impl Verge {
|
|||
self.config.system_proxy_bypass = Some(bypass);
|
||||
}
|
||||
|
||||
// proxy guard
|
||||
// only change it
|
||||
if patch.enable_proxy_guard.is_some() {
|
||||
self.config.enable_proxy_guard = patch.enable_proxy_guard;
|
||||
}
|
||||
|
||||
// relaunch the guard
|
||||
if patch.enable_system_proxy.is_some() || patch.enable_proxy_guard.is_some() {
|
||||
Verge::guard_proxy(10, self.guard_state.clone());
|
||||
}
|
||||
|
||||
self.config.save_file()
|
||||
}
|
||||
}
|
||||
|
||||
impl Verge {
|
||||
/// launch a system proxy guard
|
||||
/// read config from file directly
|
||||
pub fn guard_proxy(wait_secs: u64, guard_state: Arc<Mutex<bool>>) {
|
||||
use tokio::time::{sleep, Duration};
|
||||
|
||||
tauri::async_runtime::spawn(async move {
|
||||
// if it is running, exit
|
||||
let mut state = guard_state.lock().await;
|
||||
if *state {
|
||||
return;
|
||||
}
|
||||
*state = true;
|
||||
std::mem::drop(state);
|
||||
|
||||
loop {
|
||||
sleep(Duration::from_secs(wait_secs)).await;
|
||||
|
||||
log::debug!("[Guard]: heartbeat detection");
|
||||
|
||||
let verge = Verge::new();
|
||||
|
||||
let enable_proxy = verge.config.enable_system_proxy.unwrap_or(false);
|
||||
let enable_guard = verge.config.enable_proxy_guard.unwrap_or(false);
|
||||
|
||||
// stop loop
|
||||
if !enable_guard || !enable_proxy {
|
||||
break;
|
||||
}
|
||||
|
||||
log::info!("[Guard]: try to guard proxy");
|
||||
|
||||
let clash = Clash::new();
|
||||
|
||||
match &clash.info.port {
|
||||
Some(port) => {
|
||||
let bypass = verge.config.system_proxy_bypass.clone();
|
||||
let sysproxy = SysProxyConfig::new(true, port.clone(), bypass);
|
||||
|
||||
if let Err(err) = sysproxy.set_sys() {
|
||||
log::error!("[Guard]: {err}");
|
||||
log::error!("[Guard]: fail to set system proxy");
|
||||
}
|
||||
}
|
||||
None => log::error!("[Guard]: fail to parse clash port"),
|
||||
}
|
||||
}
|
||||
|
||||
let mut state = guard_state.lock().await;
|
||||
*state = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Get the target app_path
|
||||
fn get_app_path(app_name: &str) -> String {
|
||||
#[cfg(target_os = "linux")]
|
||||
|
|
|
@ -15,9 +15,10 @@ const SettingSystem = ({ onError }: Props) => {
|
|||
const { data: vergeConfig } = useSWR("getVergeConfig", getVergeConfig);
|
||||
|
||||
const {
|
||||
enable_auto_launch: startup = false,
|
||||
enable_system_proxy: proxy = false,
|
||||
system_proxy_bypass: bypass = "",
|
||||
enable_auto_launch = false,
|
||||
enable_system_proxy = false,
|
||||
system_proxy_bypass = "",
|
||||
enable_proxy_guard = false,
|
||||
} = vergeConfig ?? {};
|
||||
|
||||
const onSwitchFormat = (_e: any, value: boolean) => value;
|
||||
|
@ -30,7 +31,7 @@ const SettingSystem = ({ onError }: Props) => {
|
|||
<SettingItem>
|
||||
<ListItemText primary="Auto Launch" />
|
||||
<GuardState
|
||||
value={startup}
|
||||
value={enable_auto_launch}
|
||||
valueProps="checked"
|
||||
onCatch={onError}
|
||||
onFormat={onSwitchFormat}
|
||||
|
@ -51,7 +52,7 @@ const SettingSystem = ({ onError }: Props) => {
|
|||
}
|
||||
/>
|
||||
<GuardState
|
||||
value={proxy}
|
||||
value={enable_system_proxy}
|
||||
valueProps="checked"
|
||||
onCatch={onError}
|
||||
onFormat={onSwitchFormat}
|
||||
|
@ -65,11 +66,27 @@ const SettingSystem = ({ onError }: Props) => {
|
|||
</GuardState>
|
||||
</SettingItem>
|
||||
|
||||
{proxy && (
|
||||
{enable_system_proxy && (
|
||||
<SettingItem>
|
||||
<ListItemText primary="Proxy Guard" />
|
||||
<GuardState
|
||||
value={enable_proxy_guard}
|
||||
valueProps="checked"
|
||||
onCatch={onError}
|
||||
onFormat={onSwitchFormat}
|
||||
onChange={(e) => onChangeData({ enable_proxy_guard: e })}
|
||||
onGuard={(e) => patchVergeConfig({ enable_proxy_guard: e })}
|
||||
>
|
||||
<Switch edge="end" />
|
||||
</GuardState>
|
||||
</SettingItem>
|
||||
)}
|
||||
|
||||
{enable_system_proxy && (
|
||||
<SettingItem>
|
||||
<ListItemText primary="Proxy Bypass" />
|
||||
<GuardState
|
||||
value={bypass ?? ""}
|
||||
value={system_proxy_bypass ?? ""}
|
||||
onCatch={onError}
|
||||
onFormat={(e: any) => e.target.value}
|
||||
onChange={(e) => onChangeData({ system_proxy_bypass: e })}
|
||||
|
|
|
@ -115,6 +115,7 @@ export namespace CmdType {
|
|||
traffic_graph?: boolean;
|
||||
enable_auto_launch?: boolean;
|
||||
enable_system_proxy?: boolean;
|
||||
enable_proxy_guard?: boolean;
|
||||
system_proxy_bypass?: string;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user