feat: reimplement enhanced mode

This commit is contained in:
GyDi 2022-08-11 02:55:10 +08:00
parent cfd04e9bb4
commit 1641e02a7d
No known key found for this signature in database
GPG Key ID: 1C95E0D3467B3084
9 changed files with 555 additions and 399 deletions

View File

@ -19,7 +19,8 @@ pub fn get_profiles(core: State<'_, Core>) -> CmdResult<Profiles> {
/// manually exec enhanced profile /// manually exec enhanced profile
#[tauri::command] #[tauri::command]
pub fn enhance_profiles(core: State<'_, Core>) -> CmdResult { pub fn enhance_profiles(core: State<'_, Core>) -> CmdResult {
wrap_err!(core.activate_enhanced(false)) // wrap_err!(core.activate_enhanced(false))
wrap_err!(core.activate())
} }
/// import the profile from url /// import the profile from url
@ -69,7 +70,8 @@ pub fn select_profile(index: String, core: State<'_, Core>) -> CmdResult {
drop(profiles); drop(profiles);
wrap_err!(core.activate_enhanced(false)) // wrap_err!(core.activate_enhanced(false))
wrap_err!(core.activate())
} }
/// change the profile chain /// change the profile chain
@ -80,7 +82,8 @@ pub fn change_profile_chain(chain: Option<Vec<String>>, core: State<'_, Core>) -
drop(profiles); drop(profiles);
wrap_err!(core.activate_enhanced(false)) // wrap_err!(core.activate_enhanced(false))
wrap_err!(core.activate())
} }
/// change the profile valid fields /// change the profile valid fields
@ -91,7 +94,8 @@ pub fn change_profile_valid(valid: Option<Vec<String>>, core: State<Core>) -> Cm
drop(profiles); drop(profiles);
wrap_err!(core.activate_enhanced(false)) // wrap_err!(core.activate_enhanced(false))
wrap_err!(core.activate())
} }
/// delete profile item /// delete profile item
@ -102,7 +106,8 @@ pub fn delete_profile(index: String, core: State<'_, Core>) -> CmdResult {
if wrap_err!(profiles.delete_item(index))? { if wrap_err!(profiles.delete_item(index))? {
drop(profiles); drop(profiles);
log_if_err!(core.activate_enhanced(false)); // log_if_err!(core.activate_enhanced(false));
log_if_err!(core.activate());
} }
Ok(()) Ok(())

View File

@ -0,0 +1,97 @@
use serde_yaml::{Mapping, Value};
pub const HANDLE_FIELDS: [&str; 9] = [
"port",
"socks-port",
"mixed-port",
"mode",
"ipv6",
"log-level",
"allow-lan",
"external-controller",
"secret",
];
pub const DEFAULT_FIELDS: [&str; 5] = [
"proxies",
"proxy-groups",
"rules",
"proxy-providers",
"rule-providers",
];
pub const OTHERS_FIELDS: [&str; 20] = [
"tun",
"dns",
"ebpf",
"hosts",
"script",
"profile",
"payload",
"auto-redir",
"experimental",
"interface-name",
"routing-mark",
"redir-port",
"tproxy-port",
"iptables",
"external-ui",
"bind-address",
"authentication",
"sniffer", // meta
"geodata-mode", // meta
"tcp-concurrent", // meta
];
pub fn use_clash_fields() -> Vec<String> {
DEFAULT_FIELDS
.into_iter()
.chain(HANDLE_FIELDS)
.chain(OTHERS_FIELDS)
.map(|s| s.to_string())
.collect()
}
pub fn use_valid_fields(mut valid: Vec<String>) -> Vec<String> {
let others = Vec::from(OTHERS_FIELDS);
valid.iter_mut().for_each(|s| s.make_ascii_lowercase());
valid
.into_iter()
.filter(|s| others.contains(&s.as_str()))
.chain(DEFAULT_FIELDS.iter().map(|s| s.to_string()))
.collect()
}
pub fn use_filter(config: Mapping, filter: Vec<String>) -> Mapping {
let mut ret = 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();
if filter.contains(&key_str) {
ret.insert(Value::from(key_str), value);
}
});
}
ret
}
pub fn use_sort(config: Mapping) -> Mapping {
let mut ret = Mapping::new();
HANDLE_FIELDS
.into_iter()
.chain(OTHERS_FIELDS)
.chain(DEFAULT_FIELDS)
.for_each(|key| {
let key = Value::from(key);
config.get(&key).map(|value| {
ret.insert(key, value.clone());
});
});
ret
}

View File

@ -0,0 +1,99 @@
use super::{use_filter, use_valid_fields};
use serde_yaml::{self, Mapping, Sequence, Value};
#[allow(unused)]
const MERGE_FIELDS: [&str; 6] = [
"prepend-rules",
"append-rules",
"prepend-proxies",
"append-proxies",
"prepend-proxy-groups",
"append-proxy-groups",
];
pub fn use_merge(merge: Mapping, mut config: Mapping, valid: Vec<String>) -> Mapping {
let valid_list = use_valid_fields(valid);
let merge_valid = use_filter(merge.clone(), valid_list);
// 直接覆盖原字段
merge_valid.into_iter().for_each(|(key, value)| {
config.insert(key, value);
});
let merge_list = MERGE_FIELDS.iter().map(|s| s.to_string());
let merge = use_filter(merge, merge_list.collect());
["rules", "proxies", "proxy-groups"]
.iter()
.for_each(|key_str| {
let key_val = Value::from(key_str.to_string());
let mut list = Sequence::default();
list = config.get(&key_val).map_or(list.clone(), |val| {
val.as_sequence().map_or(list, |v| v.clone())
});
let pre_key = Value::from(format!("prepend-{key_str}"));
let post_key = Value::from(format!("append-{key_str}"));
if let Some(pre_val) = merge.get(&pre_key) {
if pre_val.is_sequence() {
let mut pre_val = pre_val.as_sequence().unwrap().clone();
pre_val.extend(list);
list = pre_val;
}
}
if let Some(post_val) = merge.get(&post_key) {
if post_val.is_sequence() {
list.extend(post_val.as_sequence().unwrap().clone());
}
}
config.insert(key_val, Value::from(list));
});
config
}
#[test]
fn test_merge() -> anyhow::Result<()> {
let merge = r"
prepend-rules:
- prepend
- 1123123
append-rules:
- append
prepend-proxies:
- 9999
append-proxies:
- 1111
rules:
- replace
proxy-groups:
- 123781923810
tun:
enable: true
dns:
enable: true
";
let config = r"
rules:
- aaaaa
script1: test
";
let merge = serde_yaml::from_str::<Mapping>(merge)?;
let config = serde_yaml::from_str::<Mapping>(config)?;
let result = serde_yaml::to_string(&use_merge(
merge,
config,
vec!["tun"].iter().map(|s| s.to_string()).collect(),
))?;
println!("{result}");
Ok(())
}

View File

@ -0,0 +1,57 @@
mod field;
mod merge;
mod script;
pub(self) use self::field::*;
use self::merge::*;
use self::script::*;
use crate::core::PrfData;
use serde_yaml::Mapping;
use std::collections::HashMap;
type ResultLog = Vec<(String, String)>;
pub fn runtime_config(
clash_config: Mapping,
profile_config: Mapping,
profile_enhanced: Vec<PrfData>,
valid: Vec<String>,
// tun_enable: bool,
) -> (Mapping, HashMap<String, ResultLog>) {
let mut config = profile_config;
let mut result_map = HashMap::new();
profile_enhanced.into_iter().for_each(|data| {
if data.merge.is_some() {
config = use_merge(data.merge.unwrap(), config.to_owned(), valid.clone());
} else if data.script.is_some() {
let mut logs = vec![];
match use_script(data.script.unwrap(), config.to_owned(), valid.clone()) {
Ok((res_config, res_logs)) => {
config = res_config;
logs.extend(res_logs);
}
Err(err) => {
logs.push(("error".into(), err.to_string()));
}
}
if let Some(uid) = data.item.uid {
result_map.insert(uid, logs);
}
}
});
config = use_filter(config, use_valid_fields(valid));
for (key, value) in clash_config.into_iter() {
config.insert(key, value);
}
config = use_filter(config, use_clash_fields());
config = use_sort(config);
(config, result_map)
}

View File

@ -0,0 +1,96 @@
use super::{use_filter, use_valid_fields};
use anyhow::Result;
use serde_yaml::{self, Mapping};
pub fn use_script(
script: String,
config: Mapping,
valid: Vec<String>,
) -> Result<(Mapping, Vec<(String, String)>)> {
use rquickjs::{Context, Func, Runtime};
use std::sync::{Arc, Mutex};
let runtime = Runtime::new().unwrap();
let context = Context::full(&runtime).unwrap();
let outputs = Arc::new(Mutex::new(vec![]));
let copy_outputs = outputs.clone();
let result = context.with(|ctx| -> Result<Mapping> {
ctx.globals().set(
"__verge_log__",
Func::from(move |level: String, data: String| {
let mut out = copy_outputs.lock().unwrap();
out.push((level, data));
}),
)?;
ctx.eval(
r#"var console = Object.freeze({
log(data){__verge_log__("log",JSON.stringify(data))},
info(data){__verge_log__("info",JSON.stringify(data))},
error(data){__verge_log__("error",JSON.stringify(data))},
debug(data){__verge_log__("debug",JSON.stringify(data))},
});"#,
)?;
let config_str = serde_json::to_string(&config)?;
let code = format!("\n{script}\n;\nJSON.stringify(main({config_str})||'')");
let result: String = ctx.eval(code.as_str())?;
if result == "\"\"" {
anyhow::bail!("main function should return object");
}
Ok(serde_json::from_str::<Mapping>(result.as_str())?)
});
let mut out = outputs.lock().unwrap();
match result {
Ok(config) => {
let valid = use_valid_fields(valid);
let config = use_filter(config, valid);
Ok((config, out.to_vec()))
}
Err(err) => {
out.push(("error".into(), err.to_string()));
Ok((config, out.to_vec()))
}
}
}
#[test]
fn test_script() {
let script = r#"
function main(config) {
if (Array.isArray(config.rules)) {
config.rules = [...config.rules, "add"];
}
console.log(config);
config.proxies = ["111"];
return config;
}
"#;
let config = r#"
rules:
- 111
- 222
tun:
enable: false
dns:
enable: false
"#;
let config = serde_yaml::from_str(config).unwrap();
let (config, results) = use_script(
script.into(),
config,
vec!["tun"].iter().map(|s| s.to_string()).collect(),
)
.unwrap();
let config_str = serde_yaml::to_string(&config).unwrap();
println!("{config_str}");
dbg!(results);
}

View File

@ -237,70 +237,70 @@ impl Clash {
config config
} }
/// only 5 default fields available (clash config fields) // /// only 5 default fields available (clash config fields)
/// convert to lowercase // /// convert to lowercase
pub fn strict_filter(config: Mapping) -> Mapping { // pub fn strict_filter(config: Mapping) -> Mapping {
// Only the following fields are allowed: // // Only the following fields are allowed:
// proxies/proxy-providers/proxy-groups/rule-providers/rules // // proxies/proxy-providers/proxy-groups/rule-providers/rules
let valid_keys = vec![ // let valid_keys = vec![
"proxies", // "proxies",
"proxy-providers", // "proxy-providers",
"proxy-groups", // "proxy-groups",
"rules", // "rules",
"rule-providers", // "rule-providers",
]; // ];
let mut new_config = Mapping::new(); // let mut new_config = Mapping::new();
for (key, value) in config.into_iter() { // for (key, value) in config.into_iter() {
key.as_str().map(|key_str| { // key.as_str().map(|key_str| {
// change to lowercase // // change to lowercase
let mut key_str = String::from(key_str); // let mut key_str = String::from(key_str);
key_str.make_ascii_lowercase(); // key_str.make_ascii_lowercase();
// filter // // filter
if valid_keys.contains(&&*key_str) { // if valid_keys.contains(&&*key_str) {
new_config.insert(Value::String(key_str), value); // new_config.insert(Value::String(key_str), value);
} // }
}); // });
} // }
new_config // new_config
} // }
/// more clash config fields available // /// more clash config fields available
/// convert to lowercase // /// convert to lowercase
pub fn loose_filter(config: Mapping) -> Mapping { // pub fn loose_filter(config: Mapping) -> Mapping {
// all of these can not be revised by script or merge // // all of these can not be revised by script or merge
// http/https/socks port should be under control // // http/https/socks port should be under control
let not_allow = vec![ // let not_allow = vec![
"port", // "port",
"socks-port", // "socks-port",
"mixed-port", // "mixed-port",
"allow-lan", // "allow-lan",
"mode", // "mode",
"external-controller", // "external-controller",
"secret", // "secret",
"log-level", // "log-level",
]; // ];
let mut new_config = Mapping::new(); // let mut new_config = Mapping::new();
for (key, value) in config.into_iter() { // for (key, value) in config.into_iter() {
key.as_str().map(|key_str| { // key.as_str().map(|key_str| {
// change to lowercase // // change to lowercase
let mut key_str = String::from(key_str); // let mut key_str = String::from(key_str);
key_str.make_ascii_lowercase(); // key_str.make_ascii_lowercase();
// filter // // filter
if !not_allow.contains(&&*key_str) { // if !not_allow.contains(&&*key_str) {
new_config.insert(Value::String(key_str), value); // new_config.insert(Value::String(key_str), value);
} // }
}); // });
} // }
new_config // new_config
} // }
} }
impl Default for Clash { impl Default for Clash {

View File

@ -1,8 +1,7 @@
use super::prfitem::PrfItem; use super::prfitem::PrfItem;
use crate::utils::{config, dirs}; use crate::utils::{config, dirs};
use anyhow::Result;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_yaml::{self, Mapping, Sequence, Value}; use serde_yaml::Mapping;
use std::fs; use std::fs;
#[derive(Default, Debug, Clone, Serialize, Deserialize)] #[derive(Default, Debug, Clone, Serialize, Deserialize)]
@ -27,13 +26,13 @@ pub struct PrfEnhancedResult {
#[derive(Default, Debug, Clone, Serialize, Deserialize)] #[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct PrfData { pub struct PrfData {
item: PrfItem, pub item: PrfItem,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
merge: Option<Mapping>, pub merge: Option<Mapping>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
script: Option<String>, pub script: Option<String>,
} }
impl PrfData { impl PrfData {
@ -65,210 +64,3 @@ impl PrfData {
} }
} }
} }
fn get_valid_list(valid: Vec<String>) -> Vec<String> {
let mut valid_list: Vec<String> = vec![
"rules",
"proxies",
"proxy-groups",
"proxy-providers",
"rule-providers",
]
.iter()
.map(|s| s.to_string())
.collect();
valid_list.extend(valid);
valid_list
}
fn use_valid_filter(config: Mapping, valid: Vec<String>) -> Mapping {
let valid = get_valid_list(valid);
let mut new_config = Mapping::new();
valid.iter().for_each(|k| {
let k = Value::from(k.clone());
if let Some(value) = config.get(&k) {
new_config.insert(k, value.clone());
}
});
new_config
}
pub fn use_merge(merge: Mapping, config: Mapping, valid: Vec<String>) -> Mapping {
let valid_list = get_valid_list(valid);
let mut config = config;
valid_list.iter().for_each(|key| {
let key = Value::String(key.into());
if let Some(value) = merge.get(&key) {
config.insert(key, value.clone());
}
});
vec!["rules", "proxies", "proxy-groups"]
.iter()
.for_each(|key_str| {
let key_val = Value::from(key_str.to_string());
let mut list = Sequence::default();
list = config.get(&key_val).map_or(list.clone(), |val| {
val.as_sequence().map_or(list, |v| v.clone())
});
let pre_key = Value::from(format!("prepend-{key_str}"));
let post_key = Value::from(format!("append-{key_str}"));
if let Some(pre_val) = merge.get(&pre_key) {
if pre_val.is_sequence() {
let mut pre_val = pre_val.as_sequence().unwrap().clone();
pre_val.extend(list);
list = pre_val;
}
}
if let Some(post_val) = merge.get(&post_key) {
if post_val.is_sequence() {
list.extend(post_val.as_sequence().unwrap().clone());
}
}
config.insert(key_val, Value::from(list));
});
config
}
pub fn use_script(
script: String,
config: Mapping,
valid: Vec<String>,
) -> Result<(Mapping, Vec<(String, String)>)> {
use rquickjs::{Context, Func, Runtime};
use std::sync::{Arc, Mutex};
let runtime = Runtime::new().unwrap();
let context = Context::full(&runtime).unwrap();
let outputs = Arc::new(Mutex::new(vec![]));
let copy_outputs = outputs.clone();
let result = context.with(|ctx| -> Result<Mapping> {
ctx.globals().set(
"__verge_log__",
Func::from(move |level: String, data: String| {
let mut out = copy_outputs.lock().unwrap();
out.push((level, data));
}),
)?;
ctx.eval(
r#"var console = Object.freeze({
log(data){__verge_log__("log",JSON.stringify(data))},
info(data){__verge_log__("info",JSON.stringify(data))},
error(data){__verge_log__("error",JSON.stringify(data))},
debug(data){__verge_log__("debug",JSON.stringify(data))},
});"#,
)?;
let config_str = serde_json::to_string(&config)?;
let code = format!("\n{script}\n;\nJSON.stringify(main({config_str})||'')");
let result: String = ctx.eval(code.as_str())?;
if result == "\"\"" {
anyhow::bail!("main function should return object");
}
Ok(serde_json::from_str::<Mapping>(result.as_str())?)
});
let mut out = outputs.lock().unwrap();
match result {
Ok(config) => {
let config = use_valid_filter(config, valid);
Ok((config, out.to_vec()))
}
Err(err) => {
out.push(("error".into(), err.to_string()));
Ok((config, out.to_vec()))
}
}
}
#[test]
fn test_merge() -> Result<()> {
let merge = r"
prepend-rules:
- prepend
- 1123123
append-rules:
- append
prepend-proxies:
- 9999
append-proxies:
- 1111
rules:
- replace
proxy-groups:
- 123781923810
tun:
enable: true
dns:
enable: true
";
let config = r"
rules:
- aaaaa
script: test
";
let merge = serde_yaml::from_str::<Mapping>(merge)?;
let config = serde_yaml::from_str::<Mapping>(config)?;
let result = serde_yaml::to_string(&use_merge(
merge,
config,
vec!["tun"].iter().map(|s| s.to_string()).collect(),
))?;
println!("{result}");
Ok(())
}
#[test]
fn test_script() {
let script = r#"
function main(config) {
if (Array.isArray(config.rules)) {
config.rules = [...config.rules, "add"];
}
console.log(config);
config.proxies = ["111"];
return config;
}
"#;
let config = r#"
rules:
- 111
- 222
tun:
enable: false
dns:
enable: false
"#;
let config = serde_yaml::from_str(config).unwrap();
let (config, results) = use_script(
script.into(),
config,
vec!["tun"].iter().map(|s| s.to_string()).collect(),
)
.unwrap();
let config_str = serde_yaml::to_string(&config).unwrap();
println!("{config_str}");
dbg!(results);
}

View File

@ -1,6 +1,7 @@
use self::notice::Notice; use self::notice::Notice;
use self::sysopt::Sysopt; use self::sysopt::Sysopt;
use self::timer::Timer; use self::timer::Timer;
use crate::config::runtime_config;
use crate::core::enhance::PrfEnhancedResult; use crate::core::enhance::PrfEnhancedResult;
use crate::log_if_err; use crate::log_if_err;
use crate::utils::help; use crate::utils::help;
@ -24,6 +25,7 @@ mod timer;
mod verge; mod verge;
pub use self::clash::*; pub use self::clash::*;
pub use self::enhance::*;
pub use self::prfitem::*; pub use self::prfitem::*;
pub use self::profiles::*; pub use self::profiles::*;
pub use self::service::*; pub use self::service::*;
@ -114,12 +116,12 @@ impl Core {
log_if_err!(self.update_systray(&app_handle)); log_if_err!(self.update_systray(&app_handle));
log_if_err!(self.update_systray_clash(&app_handle)); log_if_err!(self.update_systray_clash(&app_handle));
// wait the window setup during resolve app // // wait the window setup during resolve app
let core = self.clone(); // let core = self.clone();
tauri::async_runtime::spawn(async move { // tauri::async_runtime::spawn(async move {
sleep(Duration::from_secs(2)).await; // sleep(Duration::from_secs(2)).await;
log_if_err!(core.activate_enhanced(true)); // log_if_err!(core.activate_enhanced(true));
}); // });
// timer initialize // timer initialize
let mut timer = self.timer.lock(); let mut timer = self.timer.lock();
@ -139,8 +141,8 @@ impl Core {
service.restart()?; service.restart()?;
drop(service); drop(service);
self.activate()?; self.activate()
self.activate_enhanced(true) // self.activate_enhanced(true)
} }
/// change the clash core /// change the clash core
@ -164,8 +166,8 @@ impl Core {
service.start()?; service.start()?;
drop(service); drop(service);
self.activate()?; self.activate()
self.activate_enhanced(true) // self.activate_enhanced(true)
} }
/// Patch Clash /// Patch Clash
@ -184,7 +186,7 @@ impl Core {
drop(service); drop(service);
self.activate()?; self.activate()?;
self.activate_enhanced(true)?; // self.activate_enhanced(true)?;
let mut sysopt = self.sysopt.lock(); let mut sysopt = self.sysopt.lock();
let verge = self.verge.lock(); let verge = self.verge.lock();
@ -219,7 +221,8 @@ impl Core {
service.start()?; service.start()?;
drop(service); drop(service);
self.activate_enhanced(false)?; // self.activate_enhanced(false)?;
self.activate()?;
} }
} }
@ -257,7 +260,8 @@ impl Core {
} }
if tun_mode.is_some() { if tun_mode.is_some() {
self.activate_enhanced(false)?; // self.activate_enhanced(false)?;
self.activate()?;
} }
Ok(()) Ok(())
@ -341,127 +345,130 @@ impl Core {
/// activate the profile /// activate the profile
/// auto activate enhanced profile /// auto activate enhanced profile
pub fn activate(&self) -> Result<()> { pub fn activate(&self) -> Result<()> {
let data = { let profiles = self.profiles.lock();
let profiles = self.profiles.lock(); let profile_config = profiles.gen_activate()?;
let data = profiles.gen_activate()?; let profile_enhanced = profiles.gen_enhanced("".into())?;
Clash::strict_filter(data) drop(profiles);
};
let mut clash = self.clash.lock();
let mut config = clash.config.clone();
let info = clash.info.clone();
for (key, value) in data.into_iter() {
config.insert(key, value);
}
let config = {
let verge = self.verge.lock();
let tun_mode = verge.enable_tun_mode.unwrap_or(false);
Clash::_tun_mode(config, tun_mode)
};
let notice = {
let window = self.window.lock();
Notice::from(window.clone())
};
clash.set_running_config(&config);
drop(clash);
let service = self.service.lock();
service.set_config(info, config, notice)
}
/// Enhanced
/// enhanced profiles mode
pub fn activate_enhanced(&self, skip: bool) -> Result<()> {
let window = self.window.lock();
if window.is_none() {
bail!("failed to get the main window");
}
let event_name = help::get_uid("e");
let event_name = format!("enhanced-cb-{event_name}");
// generate the payload
let payload = {
let profiles = self.profiles.lock();
profiles.gen_enhanced(event_name.clone())?
};
// do not run enhanced
if payload.chain.len() == 0 {
if skip {
return Ok(());
}
drop(window);
return self.activate();
}
let tun_mode = { let tun_mode = {
let verge = self.verge.lock(); let verge = self.verge.lock();
verge.enable_tun_mode.unwrap_or(false) verge.enable_tun_mode.unwrap_or(false)
}; };
let info = { let mut clash = self.clash.lock();
let clash = self.clash.lock(); let clash_config = clash.config.clone();
clash.info.clone()
let (config, result) = runtime_config(
clash_config,
profile_config,
profile_enhanced.chain,
profile_enhanced.valid,
);
dbg!(result);
let info = clash.info.clone();
clash.set_running_config(&config);
drop(clash);
let notice = {
let window = self.window.lock();
Notice::from(window.clone())
}; };
let notice = Notice::from(window.clone()); let service = self.service.lock();
let service = self.service.clone(); service.set_config(info, config, notice)
let window = window.clone().unwrap();
window.once(&event_name, move |event| {
let result = event.payload();
if result.is_none() {
log::warn!(target: "app", "event payload result is none");
return;
}
let result = result.unwrap();
let result: PrfEnhancedResult = serde_json::from_str(result).unwrap();
if let Some(data) = result.data {
let mut config = Clash::read_config();
let filter_data = Clash::loose_filter(data); // loose filter
for (key, value) in filter_data.into_iter() {
config.insert(key, value);
}
let config = Clash::_tun_mode(config, tun_mode);
let service = service.lock();
log_if_err!(service.set_config(info, config, notice));
log::info!(target: "app", "profile enhanced status {}", result.status);
}
result.error.map(|err| log::error!(target: "app", "{err}"));
});
let verge = self.verge.lock();
let silent_start = verge.enable_silent_start.clone();
let closable = unsafe { WINDOW_CLOSABLE };
if silent_start.unwrap_or(false) && closable {
unsafe {
WINDOW_CLOSABLE = false;
}
window.emit("script-handler-close", payload).unwrap();
} else {
window.emit("script-handler", payload).unwrap();
}
Ok(())
} }
// /// Enhanced
// /// enhanced profiles mode
// pub fn activate_enhanced(&self, skip: bool) -> Result<()> {
// let window = self.window.lock();
// if window.is_none() {
// bail!("failed to get the main window");
// }
// let event_name = help::get_uid("e");
// let event_name = format!("enhanced-cb-{event_name}");
// // generate the payload
// let payload = {
// let profiles = self.profiles.lock();
// profiles.gen_enhanced(event_name.clone())?
// };
// // do not run enhanced
// if payload.chain.len() == 0 {
// if skip {
// return Ok(());
// }
// drop(window);
// return self.activate();
// }
// let tun_mode = {
// let verge = self.verge.lock();
// verge.enable_tun_mode.unwrap_or(false)
// };
// let info = {
// let clash = self.clash.lock();
// clash.info.clone()
// };
// let notice = Notice::from(window.clone());
// let service = self.service.clone();
// let window = window.clone().unwrap();
// window.once(&event_name, move |event| {
// let result = event.payload();
// if result.is_none() {
// log::warn!(target: "app", "event payload result is none");
// return;
// }
// let result = result.unwrap();
// let result: PrfEnhancedResult = serde_json::from_str(result).unwrap();
// if let Some(data) = result.data {
// let mut config = Clash::read_config();
// let filter_data = Clash::loose_filter(data); // loose filter
// for (key, value) in filter_data.into_iter() {
// config.insert(key, value);
// }
// let config = Clash::_tun_mode(config, tun_mode);
// let service = service.lock();
// log_if_err!(service.set_config(info, config, notice));
// log::info!(target: "app", "profile enhanced status {}", result.status);
// }
// result.error.map(|err| log::error!(target: "app", "{err}"));
// });
// let verge = self.verge.lock();
// let silent_start = verge.enable_silent_start.clone();
// let closable = unsafe { WINDOW_CLOSABLE };
// if silent_start.unwrap_or(false) && closable {
// unsafe {
// WINDOW_CLOSABLE = false;
// }
// window.emit("script-handler-close", payload).unwrap();
// } else {
// window.emit("script-handler", payload).unwrap();
// }
// Ok(())
// }
} }
impl Core { impl Core {
@ -482,7 +489,8 @@ impl Core {
// reactivate the config // reactivate the config
if Some(uid) == profiles.get_current() { if Some(uid) == profiles.get_current() {
drop(profiles); drop(profiles);
return core.activate_enhanced(false); // return core.activate_enhanced(false);
return core.activate();
} }
return Ok(()); return Ok(());
@ -505,7 +513,8 @@ impl Core {
// reactivate the profile // reactivate the profile
if Some(uid) == profiles.get_current() { if Some(uid) == profiles.get_current() {
drop(profiles); drop(profiles);
core.activate_enhanced(false)?; // core.activate_enhanced(false)?;
core.activate()?;
} }
Ok(()) Ok(())

View File

@ -4,6 +4,7 @@
)] )]
mod cmds; mod cmds;
mod config;
mod core; mod core;
mod utils; mod utils;