refactor: optimize enhance mode strategy
This commit is contained in:
parent
0a9c81772f
commit
5a38468144
src-tauri/src
@ -88,7 +88,7 @@ pub async fn update_profile(
|
||||
// reactivate the profile
|
||||
if Some(index) == profiles.get_current() {
|
||||
let clash = clash_state.0.lock().unwrap();
|
||||
wrap_err!(clash.activate(&profiles, false))?;
|
||||
wrap_err!(clash.activate_enhanced(&profiles, false, false))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -105,7 +105,7 @@ pub fn select_profile(
|
||||
wrap_err!(profiles.put_current(index))?;
|
||||
|
||||
let clash = clash_state.0.lock().unwrap();
|
||||
wrap_err!(clash.activate(&profiles, false))
|
||||
wrap_err!(clash.activate_enhanced(&profiles, false, false))
|
||||
}
|
||||
|
||||
/// change the profile chain
|
||||
@ -122,7 +122,7 @@ pub fn change_profile_chain(
|
||||
profiles.put_chain(chain);
|
||||
clash.set_window(app_handle.get_window("main"));
|
||||
|
||||
wrap_err!(clash.activate_enhanced(&profiles, false))
|
||||
wrap_err!(clash.activate_enhanced(&profiles, false, false))
|
||||
}
|
||||
|
||||
/// manually exec enhanced profile
|
||||
@ -137,7 +137,7 @@ pub fn enhance_profiles(
|
||||
|
||||
clash.set_window(app_handle.get_window("main"));
|
||||
|
||||
wrap_err!(clash.activate_enhanced(&profiles, false))
|
||||
wrap_err!(clash.activate_enhanced(&profiles, false, false))
|
||||
}
|
||||
|
||||
/// delete profile item
|
||||
@ -151,7 +151,7 @@ pub fn delete_profile(
|
||||
|
||||
if wrap_err!(profiles.delete_item(index))? {
|
||||
let clash = clash_state.0.lock().unwrap();
|
||||
wrap_err!(clash.activate(&profiles, false))?;
|
||||
wrap_err!(clash.activate_enhanced(&profiles, false, false))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -324,7 +324,7 @@ pub fn patch_verge_config(
|
||||
|
||||
wrap_err!(clash.tun_mode(tun_mode.unwrap()))?;
|
||||
clash.update_config();
|
||||
wrap_err!(clash.activate(&profiles, false))?;
|
||||
wrap_err!(clash.activate_enhanced(&profiles, false, false))?;
|
||||
}
|
||||
|
||||
let mut verge = verge_state.0.lock().unwrap();
|
||||
|
@ -1,4 +1,5 @@
|
||||
use super::{PrfEnhancedResult, Profiles, Verge};
|
||||
use crate::log_if_err;
|
||||
use crate::utils::{config, dirs, help};
|
||||
use anyhow::{bail, Result};
|
||||
use reqwest::header::HeaderMap;
|
||||
@ -176,7 +177,8 @@ impl Clash {
|
||||
self.update_config();
|
||||
self.drop_sidecar()?;
|
||||
self.run_sidecar()?;
|
||||
self.activate(profiles, false)
|
||||
self.activate(profiles)?;
|
||||
self.activate_enhanced(profiles, false, true)
|
||||
}
|
||||
|
||||
/// update the clash info
|
||||
@ -221,7 +223,7 @@ impl Clash {
|
||||
}
|
||||
|
||||
/// enable tun mode
|
||||
/// only revise the config and restart the
|
||||
/// only revise the config
|
||||
pub fn tun_mode(&mut self, enable: bool) -> Result<()> {
|
||||
// Windows 需要wintun.dll文件
|
||||
#[cfg(target_os = "windows")]
|
||||
@ -354,62 +356,57 @@ impl Clash {
|
||||
}
|
||||
|
||||
/// enhanced profiles mode
|
||||
/// only change the enhanced profiles
|
||||
pub fn activate_enhanced(&self, profiles: &Profiles, delay: bool) -> Result<()> {
|
||||
/// - (sync) refresh config if enhance chain is null
|
||||
/// - (async) enhanced config
|
||||
pub fn activate_enhanced(&self, profiles: &Profiles, delay: bool, skip: bool) -> Result<()> {
|
||||
if self.window.is_none() {
|
||||
bail!("failed to get the main window");
|
||||
}
|
||||
|
||||
let win = self.window.clone().unwrap();
|
||||
let event_name = help::get_uid("e");
|
||||
let event_name = format!("enhanced-cb-{event_name}");
|
||||
|
||||
let info = self.info.clone();
|
||||
let mut config = self.config.clone();
|
||||
|
||||
// generate the payload
|
||||
let payload = profiles.gen_enhanced(event_name.clone())?;
|
||||
let window = self.window.clone();
|
||||
|
||||
win.once(&event_name, move |event| {
|
||||
let info = self.info.clone();
|
||||
|
||||
// do not run enhanced
|
||||
if payload.chain.len() == 0 {
|
||||
if skip {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut config = self.config.clone();
|
||||
let filter_data = Clash::strict_filter(payload.current);
|
||||
|
||||
for (key, value) in filter_data.into_iter() {
|
||||
config.insert(key, value);
|
||||
}
|
||||
|
||||
return Clash::_activate(info, config, self.window.clone());
|
||||
}
|
||||
|
||||
let window = self.window.clone().unwrap();
|
||||
let window_move = self.window.clone();
|
||||
|
||||
window.once(&event_name, move |event| {
|
||||
if let Some(result) = event.payload() {
|
||||
let result: PrfEnhancedResult = serde_json::from_str(result).unwrap();
|
||||
|
||||
if let Some(data) = result.data {
|
||||
// all of these can not be revised by script
|
||||
// http/https/socks port should be under control
|
||||
let not_allow = vec![
|
||||
"port",
|
||||
"socks-port",
|
||||
"mixed-port",
|
||||
"allow-lan",
|
||||
"mode",
|
||||
"external-controller",
|
||||
"secret",
|
||||
"log-level",
|
||||
];
|
||||
let mut config = Clash::read_config();
|
||||
let filter_data = Clash::loose_filter(data); // loose filter
|
||||
|
||||
for (key, value) in data.into_iter() {
|
||||
key.as_str().map(|key_str| {
|
||||
// change to lowercase
|
||||
let mut key_str = String::from(key_str);
|
||||
key_str.make_ascii_lowercase();
|
||||
|
||||
// filter
|
||||
if !not_allow.contains(&&*key_str) {
|
||||
config.insert(Value::String(key_str), value);
|
||||
}
|
||||
});
|
||||
for (key, value) in filter_data.into_iter() {
|
||||
config.insert(key, value);
|
||||
}
|
||||
|
||||
log_if_err!(Clash::_activate(info, config, window_move));
|
||||
log::info!("profile enhanced status {}", result.status);
|
||||
|
||||
Self::_activate(info, config, window).unwrap();
|
||||
}
|
||||
|
||||
if let Some(error) = result.error {
|
||||
log::error!("{error}");
|
||||
}
|
||||
result.error.map(|err| log::error!("{err}"));
|
||||
}
|
||||
});
|
||||
|
||||
@ -418,7 +415,7 @@ impl Clash {
|
||||
if delay {
|
||||
sleep(Duration::from_secs(2)).await;
|
||||
}
|
||||
win.emit("script-handler", payload).unwrap();
|
||||
window.emit("script-handler", payload).unwrap();
|
||||
});
|
||||
|
||||
Ok(())
|
||||
@ -426,17 +423,83 @@ impl Clash {
|
||||
|
||||
/// activate the profile
|
||||
/// auto activate enhanced profile
|
||||
pub fn activate(&self, profiles: &Profiles, delay: bool) -> Result<()> {
|
||||
let gen_map = profiles.gen_activate()?;
|
||||
pub fn activate(&self, profiles: &Profiles) -> Result<()> {
|
||||
let data = profiles.gen_activate()?;
|
||||
let data = Clash::strict_filter(data);
|
||||
|
||||
let info = self.info.clone();
|
||||
let mut config = self.config.clone();
|
||||
|
||||
for (key, value) in gen_map.into_iter() {
|
||||
for (key, value) in data.into_iter() {
|
||||
config.insert(key, value);
|
||||
}
|
||||
|
||||
Self::_activate(info, config, self.window.clone())?;
|
||||
self.activate_enhanced(profiles, delay)
|
||||
Clash::_activate(info, config, self.window.clone())
|
||||
}
|
||||
|
||||
/// only 5 default fields available (clash config fields)
|
||||
/// convert to lowercase
|
||||
fn strict_filter(config: Mapping) -> Mapping {
|
||||
// Only the following fields are allowed:
|
||||
// proxies/proxy-providers/proxy-groups/rule-providers/rules
|
||||
let valid_keys = vec![
|
||||
"proxies",
|
||||
"proxy-providers",
|
||||
"proxy-groups",
|
||||
"rules",
|
||||
"rule-providers",
|
||||
];
|
||||
|
||||
let mut new_config = Mapping::new();
|
||||
|
||||
for (key, value) in config.into_iter() {
|
||||
key.as_str().map(|key_str| {
|
||||
// change to lowercase
|
||||
let mut key_str = String::from(key_str);
|
||||
key_str.make_ascii_lowercase();
|
||||
|
||||
// filter
|
||||
if valid_keys.contains(&&*key_str) {
|
||||
new_config.insert(Value::String(key_str), value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
new_config
|
||||
}
|
||||
|
||||
/// more clash config fields available
|
||||
/// convert to lowercase
|
||||
fn loose_filter(config: Mapping) -> Mapping {
|
||||
// all of these can not be revised by script or merge
|
||||
// http/https/socks port should be under control
|
||||
let not_allow = vec![
|
||||
"port",
|
||||
"socks-port",
|
||||
"mixed-port",
|
||||
"allow-lan",
|
||||
"mode",
|
||||
"external-controller",
|
||||
"secret",
|
||||
"log-level",
|
||||
];
|
||||
|
||||
let mut new_config = Mapping::new();
|
||||
|
||||
for (key, value) in config.into_iter() {
|
||||
key.as_str().map(|key_str| {
|
||||
// change to lowercase
|
||||
let mut key_str = String::from(key_str);
|
||||
key_str.make_ascii_lowercase();
|
||||
|
||||
// filter
|
||||
if !not_allow.contains(&&*key_str) {
|
||||
new_config.insert(Value::String(key_str), value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
new_config
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::utils::{config, dirs, help, tmpl};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use serde_yaml::Mapping;
|
||||
use std::{fs, io::Write};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
@ -575,32 +575,7 @@ impl Profiles {
|
||||
bail!("failed to read the file \"{}\"", file_path.display());
|
||||
}
|
||||
|
||||
let mut new_config = Mapping::new();
|
||||
let def_config = config::read_yaml::<Mapping>(file_path.clone());
|
||||
|
||||
// Only the following fields are allowed:
|
||||
// proxies/proxy-providers/proxy-groups/rule-providers/rules
|
||||
let valid_keys = vec![
|
||||
"proxies",
|
||||
"proxy-providers",
|
||||
"proxy-groups",
|
||||
"rule-providers",
|
||||
"rules",
|
||||
];
|
||||
|
||||
for (key, value) in def_config.into_iter() {
|
||||
key.as_str().map(|key_str| {
|
||||
// change to lowercase
|
||||
let mut key_str = String::from(key_str);
|
||||
key_str.make_ascii_lowercase();
|
||||
|
||||
if valid_keys.contains(&&*key_str) {
|
||||
new_config.insert(Value::String(key_str), value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return Ok(new_config);
|
||||
return Ok(config::read_yaml::<Mapping>(file_path.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -634,11 +609,11 @@ impl Profiles {
|
||||
|
||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PrfEnhanced {
|
||||
current: Mapping,
|
||||
pub current: Mapping,
|
||||
|
||||
chain: Vec<PrfData>,
|
||||
pub chain: Vec<PrfData>,
|
||||
|
||||
callback: String,
|
||||
pub callback: String,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
||||
|
@ -24,7 +24,8 @@ pub fn resolve_setup(app: &App) {
|
||||
*profiles = Profiles::read_file();
|
||||
|
||||
clash.set_window(app.get_window("main"));
|
||||
log_if_err!(clash.activate(&profiles, true));
|
||||
log_if_err!(clash.activate(&profiles));
|
||||
log_if_err!(clash.activate_enhanced(&profiles, true, true));
|
||||
|
||||
verge.init_sysproxy(clash.info.port.clone());
|
||||
// enable tun mode
|
||||
|
Loading…
x
Reference in New Issue
Block a user