mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2024-11-16 03:32:36 +08:00
feat: enhance system proxy setting
This commit is contained in:
parent
e08032c0fa
commit
013dc5f4b5
|
@ -3,3 +3,4 @@
|
|||
theme_mode: light
|
||||
enable_self_startup: false
|
||||
enable_system_proxy: false
|
||||
system_proxy_bypass: localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*;<local>
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
|||
utils::{
|
||||
clash::run_clash_bin,
|
||||
config::{read_clash, save_clash, save_verge},
|
||||
sysopt::{get_proxy_config, set_proxy_config, SysProxyConfig},
|
||||
sysopt::{get_proxy_config, set_proxy_config, SysProxyConfig, DEFAULT_BYPASS},
|
||||
},
|
||||
};
|
||||
use serde_yaml::Mapping;
|
||||
|
@ -53,12 +53,21 @@ pub fn patch_clash_config(payload: Mapping) -> Result<(), String> {
|
|||
/// set the system proxy
|
||||
/// Tips: only support windows now
|
||||
#[tauri::command]
|
||||
pub fn set_sys_proxy(enable: bool, clash_info: State<'_, ClashInfoState>) -> Result<(), String> {
|
||||
pub fn set_sys_proxy(
|
||||
enable: bool,
|
||||
clash_info: State<'_, ClashInfoState>,
|
||||
verge_lock: State<'_, VergeConfLock>,
|
||||
) -> Result<(), String> {
|
||||
let clash_info = match clash_info.0.lock() {
|
||||
Ok(arc) => arc.clone(),
|
||||
_ => return Err(format!("can not get clash info")),
|
||||
};
|
||||
|
||||
let verge_info = match verge_lock.0.lock() {
|
||||
Ok(arc) => arc.clone(),
|
||||
_ => return Err(format!("can not get verge info")),
|
||||
};
|
||||
|
||||
let port = match clash_info.controller {
|
||||
Some(ctrl) => ctrl.port,
|
||||
None => None,
|
||||
|
@ -70,9 +79,9 @@ pub fn set_sys_proxy(enable: bool, clash_info: State<'_, ClashInfoState>) -> Res
|
|||
|
||||
let config = if enable {
|
||||
let server = format!("127.0.0.1:{}", port.unwrap());
|
||||
// todo
|
||||
let bypass = String::from("localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*;<local>");
|
||||
|
||||
let bypass = verge_info
|
||||
.system_proxy_bypass
|
||||
.unwrap_or(String::from(DEFAULT_BYPASS));
|
||||
SysProxyConfig {
|
||||
enable,
|
||||
server,
|
||||
|
@ -112,6 +121,7 @@ pub fn get_verge_config(verge_lock: State<'_, VergeConfLock>) -> Result<VergeCon
|
|||
}
|
||||
|
||||
/// patch the verge config
|
||||
/// this command only save the config and not responsible for other things
|
||||
#[tauri::command]
|
||||
pub async fn patch_verge_config(
|
||||
payload: VergeConfig,
|
||||
|
@ -136,5 +146,9 @@ pub async fn patch_verge_config(
|
|||
verge.enable_system_proxy = payload.enable_system_proxy;
|
||||
}
|
||||
|
||||
if payload.system_proxy_bypass.is_some() {
|
||||
verge.system_proxy_bypass = payload.system_proxy_bypass;
|
||||
}
|
||||
|
||||
save_verge(&verge)
|
||||
}
|
||||
|
|
|
@ -11,4 +11,7 @@ pub struct VergeConfig {
|
|||
|
||||
/// set system proxy
|
||||
pub enable_system_proxy: Option<bool>,
|
||||
|
||||
/// set system proxy bypass
|
||||
pub system_proxy_bypass: Option<String>,
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use super::emit::ClashInfoPayload;
|
||||
use crate::config::VergeConfig;
|
||||
use crate::{config::VergeConfig, utils::sysopt::SysProxyConfig};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ClashInfoState(pub Arc<Mutex<ClashInfoPayload>>);
|
||||
|
@ -11,3 +11,6 @@ pub struct ProfileLock(pub Mutex<bool>);
|
|||
|
||||
#[derive(Default)]
|
||||
pub struct VergeConfLock(pub Arc<Mutex<VergeConfig>>);
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SomthingState(pub Arc<Mutex<Option<SysProxyConfig>>>);
|
||||
|
|
|
@ -12,19 +12,14 @@ mod utils;
|
|||
|
||||
use crate::{
|
||||
events::state,
|
||||
utils::{
|
||||
clash::put_clash_profile,
|
||||
config::read_verge,
|
||||
server::{check_singleton, embed_server},
|
||||
},
|
||||
utils::{resolve, server},
|
||||
};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tauri::{
|
||||
api, CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem,
|
||||
};
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
if check_singleton().is_err() {
|
||||
if server::check_singleton().is_err() {
|
||||
println!("app exists");
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -35,44 +30,28 @@ fn main() -> std::io::Result<()> {
|
|||
.add_item(CustomMenuItem::new("quit", "退出").accelerator("CmdOrControl+Q"));
|
||||
|
||||
tauri::Builder::default()
|
||||
.setup(|app| {
|
||||
// a simple http server
|
||||
embed_server(&app.handle());
|
||||
|
||||
// init app config
|
||||
utils::init::init_app(app.package_info());
|
||||
// run clash sidecar
|
||||
let info = utils::clash::run_clash_bin(&app.handle());
|
||||
// update the profile
|
||||
let info_copy = info.clone();
|
||||
tauri::async_runtime::spawn(async move {
|
||||
match put_clash_profile(&info_copy).await {
|
||||
Ok(_) => {}
|
||||
Err(err) => log::error!("failed to put config for `{}`", err),
|
||||
};
|
||||
});
|
||||
|
||||
app.manage(state::VergeConfLock(Arc::new(Mutex::new(read_verge()))));
|
||||
app.manage(state::ClashInfoState(Arc::new(Mutex::new(info))));
|
||||
app.manage(state::ProfileLock::default());
|
||||
Ok(())
|
||||
})
|
||||
.manage(state::VergeConfLock::default())
|
||||
.manage(state::ClashInfoState::default())
|
||||
.manage(state::SomthingState::default())
|
||||
.manage(state::ProfileLock::default())
|
||||
.setup(|app| Ok(resolve::resolve_setup(app)))
|
||||
.system_tray(SystemTray::new().with_menu(menu))
|
||||
.on_system_tray_event(move |app, event| match event {
|
||||
.on_system_tray_event(move |app_handle, event| match event {
|
||||
SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
|
||||
"open_window" => {
|
||||
let window = app.get_window("main").unwrap();
|
||||
let window = app_handle.get_window("main").unwrap();
|
||||
window.show().unwrap();
|
||||
window.set_focus().unwrap();
|
||||
}
|
||||
"quit" => {
|
||||
api::process::kill_children();
|
||||
app.exit(0);
|
||||
resolve::resolve_reset(app_handle);
|
||||
app_handle.exit(0);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
SystemTrayEvent::LeftClick { .. } => {
|
||||
let window = app.get_window("main").unwrap();
|
||||
let window = app_handle.get_window("main").unwrap();
|
||||
window.show().unwrap();
|
||||
window.set_focus().unwrap();
|
||||
}
|
||||
|
@ -104,6 +83,7 @@ fn main() -> std::io::Result<()> {
|
|||
api.prevent_exit();
|
||||
}
|
||||
tauri::Event::Exit => {
|
||||
resolve::resolve_reset(app_handle);
|
||||
api::process::kill_children();
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
@ -5,5 +5,6 @@ pub mod clash;
|
|||
pub mod config;
|
||||
pub mod fetch;
|
||||
pub mod init;
|
||||
pub mod resolve;
|
||||
pub mod server;
|
||||
pub mod sysopt;
|
||||
|
|
80
src-tauri/src/utils/resolve.rs
Normal file
80
src-tauri/src/utils/resolve.rs
Normal file
|
@ -0,0 +1,80 @@
|
|||
use super::{clash, config, init, server, sysopt};
|
||||
use crate::events::state;
|
||||
use tauri::{App, AppHandle, Manager};
|
||||
|
||||
/// handle something when start app
|
||||
pub fn resolve_setup(app: &App) {
|
||||
// setup a simple http server for singleton
|
||||
server::embed_server(&app.handle());
|
||||
|
||||
// init app config
|
||||
init::init_app(app.package_info());
|
||||
|
||||
// run clash sidecar
|
||||
let info = clash::run_clash_bin(&app.handle());
|
||||
|
||||
// update the profile
|
||||
let info_ = info.clone();
|
||||
tauri::async_runtime::spawn(async move {
|
||||
if let Err(err) = clash::put_clash_profile(&info_).await {
|
||||
log::error!("failed to put config for `{}`", err);
|
||||
};
|
||||
});
|
||||
|
||||
// resolve the verge config - enable system proxy
|
||||
let mut original: Option<sysopt::SysProxyConfig> = None;
|
||||
let verge = config::read_verge();
|
||||
let enable = verge.enable_system_proxy.unwrap_or(false);
|
||||
|
||||
if enable && info.controller.is_some() {
|
||||
if let Ok(original_conf) = sysopt::get_proxy_config() {
|
||||
original = Some(original_conf)
|
||||
};
|
||||
let ctl = info.controller.clone().unwrap();
|
||||
if ctl.port.is_some() {
|
||||
let server = format!("127.0.0.1:{}", ctl.port.unwrap());
|
||||
let bypass = verge
|
||||
.system_proxy_bypass
|
||||
.clone()
|
||||
.unwrap_or(String::from(sysopt::DEFAULT_BYPASS));
|
||||
let config = sysopt::SysProxyConfig {
|
||||
enable,
|
||||
server,
|
||||
bypass,
|
||||
};
|
||||
if let Err(err) = sysopt::set_proxy_config(&config) {
|
||||
log::error!("can not set system proxy for `{}`", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
// update state
|
||||
let verge_state = app.state::<state::VergeConfLock>();
|
||||
let mut verge_arc = verge_state.0.lock().unwrap();
|
||||
*verge_arc = verge;
|
||||
|
||||
let clash_state = app.state::<state::ClashInfoState>();
|
||||
let mut clash_arc = clash_state.0.lock().unwrap();
|
||||
*clash_arc = info;
|
||||
|
||||
let some_state = app.state::<state::SomthingState>();
|
||||
let mut some_arc = some_state.0.lock().unwrap();
|
||||
*some_arc = original;
|
||||
}
|
||||
|
||||
/// reset system proxy
|
||||
pub fn resolve_reset(app_handle: &AppHandle) {
|
||||
let state = app_handle.try_state::<state::SomthingState>();
|
||||
if state.is_none() {
|
||||
return;
|
||||
}
|
||||
match state.unwrap().0.lock() {
|
||||
Ok(arc) => {
|
||||
if arc.is_some() {
|
||||
if let Err(err) = sysopt::set_proxy_config(arc.as_ref().unwrap()) {
|
||||
log::error!("failed to reset proxy for `{}`", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
|
@ -1,13 +1,25 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct SysProxyConfig {
|
||||
pub enable: bool,
|
||||
pub server: String,
|
||||
pub bypass: String,
|
||||
}
|
||||
|
||||
impl Default for SysProxyConfig {
|
||||
fn default() -> Self {
|
||||
SysProxyConfig {
|
||||
enable: false,
|
||||
server: String::from(""),
|
||||
bypass: String::from(""),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub static DEFAULT_BYPASS: &str = "localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*;<local>";
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
mod win {
|
||||
use super::*;
|
||||
|
|
Loading…
Reference in New Issue
Block a user