2022-11-18 18:18:41 +08:00
|
|
|
|
//!
|
|
|
|
|
//! feat mod 里的函数主要用于
|
|
|
|
|
//! - hotkey 快捷键
|
|
|
|
|
//! - timer 定时器
|
|
|
|
|
//! - cmds 页面调用
|
|
|
|
|
//!
|
2022-11-14 01:26:33 +08:00
|
|
|
|
use crate::config::*;
|
2022-09-14 01:19:02 +08:00
|
|
|
|
use crate::core::*;
|
2022-11-14 01:26:33 +08:00
|
|
|
|
use crate::log_err;
|
2022-11-17 17:07:13 +08:00
|
|
|
|
use anyhow::{bail, Result};
|
2022-11-14 01:26:33 +08:00
|
|
|
|
use serde_yaml::{Mapping, Value};
|
2022-09-14 01:19:02 +08:00
|
|
|
|
|
2022-10-28 00:40:29 +08:00
|
|
|
|
// 重启clash
|
|
|
|
|
pub fn restart_clash_core() {
|
2022-11-14 01:26:33 +08:00
|
|
|
|
tauri::async_runtime::spawn(async {
|
2022-11-17 20:19:40 +08:00
|
|
|
|
match CoreManager::global().run_core().await {
|
2022-11-18 18:18:41 +08:00
|
|
|
|
Ok(_) => {
|
|
|
|
|
handle::Handle::refresh_clash();
|
|
|
|
|
handle::Handle::notice_message("set_config::ok", "ok");
|
|
|
|
|
}
|
|
|
|
|
Err(err) => {
|
|
|
|
|
handle::Handle::notice_message("set_config::error", format!("{err}"));
|
|
|
|
|
log::error!(target:"app", "{err}");
|
|
|
|
|
}
|
2022-11-17 20:19:40 +08:00
|
|
|
|
}
|
2022-11-14 01:26:33 +08:00
|
|
|
|
});
|
2022-10-28 00:40:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 01:26:33 +08:00
|
|
|
|
// 切换模式 rule/global/direct/script mode
|
|
|
|
|
pub fn change_clash_mode(mode: String) {
|
|
|
|
|
let mut mapping = Mapping::new();
|
|
|
|
|
mapping.insert(Value::from("mode"), mode.clone().into());
|
|
|
|
|
|
|
|
|
|
tauri::async_runtime::spawn(async move {
|
|
|
|
|
match clash_api::patch_configs(&mapping).await {
|
|
|
|
|
Ok(_) => {
|
|
|
|
|
// 更新配置
|
2022-11-17 17:07:13 +08:00
|
|
|
|
Config::clash().data().patch_config(mapping);
|
2022-11-14 01:26:33 +08:00
|
|
|
|
|
2022-11-17 17:07:13 +08:00
|
|
|
|
if let Ok(_) = Config::clash().data().save_config() {
|
2022-11-14 01:26:33 +08:00
|
|
|
|
handle::Handle::refresh_clash();
|
|
|
|
|
log_err!(handle::Handle::update_systray_part());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Err(err) => {
|
|
|
|
|
log::error!(target: "app", "{err}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
2022-09-14 01:19:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 切换系统代理
|
2022-11-17 17:07:13 +08:00
|
|
|
|
pub fn toggle_system_proxy() {
|
|
|
|
|
let enable = Config::verge().draft().enable_system_proxy.clone();
|
|
|
|
|
let enable = enable.unwrap_or(false);
|
|
|
|
|
|
|
|
|
|
tauri::async_runtime::spawn(async move {
|
|
|
|
|
match patch_verge(IVerge {
|
|
|
|
|
enable_system_proxy: Some(!enable),
|
|
|
|
|
..IVerge::default()
|
|
|
|
|
})
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(_) => handle::Handle::refresh_verge(),
|
|
|
|
|
Err(err) => log::error!(target: "app", "{err}"),
|
|
|
|
|
}
|
|
|
|
|
});
|
2022-09-14 01:19:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 打开系统代理
|
2022-11-17 17:07:13 +08:00
|
|
|
|
pub fn enable_system_proxy() {
|
|
|
|
|
tauri::async_runtime::spawn(async {
|
|
|
|
|
match patch_verge(IVerge {
|
|
|
|
|
enable_system_proxy: Some(true),
|
|
|
|
|
..IVerge::default()
|
|
|
|
|
})
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(_) => handle::Handle::refresh_verge(),
|
|
|
|
|
Err(err) => log::error!(target: "app", "{err}"),
|
|
|
|
|
}
|
|
|
|
|
});
|
2022-09-14 01:19:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 关闭系统代理
|
2022-11-17 17:07:13 +08:00
|
|
|
|
pub fn disable_system_proxy() {
|
|
|
|
|
tauri::async_runtime::spawn(async {
|
|
|
|
|
match patch_verge(IVerge {
|
|
|
|
|
enable_system_proxy: Some(false),
|
|
|
|
|
..IVerge::default()
|
|
|
|
|
})
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(_) => handle::Handle::refresh_verge(),
|
|
|
|
|
Err(err) => log::error!(target: "app", "{err}"),
|
|
|
|
|
}
|
|
|
|
|
});
|
2022-09-14 01:19:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 切换tun模式
|
2022-11-17 17:07:13 +08:00
|
|
|
|
pub fn toggle_tun_mode() {
|
|
|
|
|
let enable = Config::verge().data().enable_tun_mode.clone();
|
|
|
|
|
let enable = enable.unwrap_or(false);
|
2022-11-14 01:26:33 +08:00
|
|
|
|
|
2022-11-17 17:07:13 +08:00
|
|
|
|
tauri::async_runtime::spawn(async move {
|
|
|
|
|
match patch_verge(IVerge {
|
|
|
|
|
enable_tun_mode: Some(!enable),
|
|
|
|
|
..IVerge::default()
|
|
|
|
|
})
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(_) => handle::Handle::refresh_verge(),
|
|
|
|
|
Err(err) => log::error!(target: "app", "{err}"),
|
|
|
|
|
}
|
|
|
|
|
});
|
2022-09-14 01:19:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 打开tun模式
|
2022-11-17 17:07:13 +08:00
|
|
|
|
pub fn enable_tun_mode() {
|
|
|
|
|
tauri::async_runtime::spawn(async {
|
|
|
|
|
match patch_verge(IVerge {
|
|
|
|
|
enable_tun_mode: Some(true),
|
|
|
|
|
..IVerge::default()
|
|
|
|
|
})
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(_) => handle::Handle::refresh_verge(),
|
|
|
|
|
Err(err) => log::error!(target: "app", "{err}"),
|
|
|
|
|
}
|
|
|
|
|
});
|
2022-09-14 01:19:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 关闭tun模式
|
2022-11-17 17:07:13 +08:00
|
|
|
|
pub fn disable_tun_mode() {
|
|
|
|
|
tauri::async_runtime::spawn(async {
|
|
|
|
|
match patch_verge(IVerge {
|
|
|
|
|
enable_tun_mode: Some(false),
|
|
|
|
|
..IVerge::default()
|
|
|
|
|
})
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(_) => handle::Handle::refresh_verge(),
|
|
|
|
|
Err(err) => log::error!(target: "app", "{err}"),
|
|
|
|
|
}
|
|
|
|
|
});
|
2022-11-14 01:26:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 修改clash的配置
|
2022-11-17 17:07:13 +08:00
|
|
|
|
pub async fn patch_clash(patch: Mapping) -> Result<()> {
|
|
|
|
|
Config::clash().draft().patch_config(patch.clone());
|
2022-11-14 01:26:33 +08:00
|
|
|
|
|
2022-11-17 17:07:13 +08:00
|
|
|
|
match {
|
|
|
|
|
let mixed_port = patch.get("mixed-port");
|
|
|
|
|
if mixed_port.is_some() {
|
|
|
|
|
let changed = mixed_port != Config::clash().data().0.get("mixed-port");
|
|
|
|
|
// 检查端口占用
|
|
|
|
|
if changed {
|
|
|
|
|
if let Some(port) = mixed_port.clone().unwrap().as_u64() {
|
|
|
|
|
if !port_scanner::local_port_available(port as u16) {
|
|
|
|
|
Config::clash().discard();
|
|
|
|
|
bail!("the port not available");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2022-11-14 01:26:33 +08:00
|
|
|
|
|
2022-11-17 17:07:13 +08:00
|
|
|
|
// 激活配置
|
2022-11-17 22:53:41 +08:00
|
|
|
|
if mixed_port.is_some()
|
|
|
|
|
|| patch.get("secret").is_some()
|
|
|
|
|
|| patch.get("external-controller").is_some()
|
|
|
|
|
{
|
2022-11-18 18:37:17 +08:00
|
|
|
|
Config::generate()?;
|
2022-11-18 18:18:41 +08:00
|
|
|
|
CoreManager::global().run_core().await?;
|
2022-11-18 18:37:17 +08:00
|
|
|
|
handle::Handle::refresh_clash();
|
2022-11-17 22:53:41 +08:00
|
|
|
|
}
|
2022-11-14 01:26:33 +08:00
|
|
|
|
|
2022-11-17 17:07:13 +08:00
|
|
|
|
// 更新系统代理
|
|
|
|
|
if mixed_port.is_some() {
|
|
|
|
|
log_err!(sysopt::Sysopt::global().init_sysproxy());
|
2022-11-14 01:26:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-17 17:07:13 +08:00
|
|
|
|
if patch.get("mode").is_some() {
|
|
|
|
|
log_err!(handle::Handle::update_systray_part());
|
|
|
|
|
}
|
2022-11-14 01:26:33 +08:00
|
|
|
|
|
2022-11-17 17:07:13 +08:00
|
|
|
|
<Result<()>>::Ok(())
|
|
|
|
|
} {
|
|
|
|
|
Ok(()) => {
|
|
|
|
|
Config::clash().apply();
|
|
|
|
|
Config::clash().data().save_config()?;
|
|
|
|
|
Ok(())
|
2022-11-14 01:26:33 +08:00
|
|
|
|
}
|
2022-11-17 17:07:13 +08:00
|
|
|
|
Err(err) => {
|
|
|
|
|
Config::clash().discard();
|
|
|
|
|
Err(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-14 01:26:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 修改verge的配置
|
|
|
|
|
/// 一般都是一个个的修改
|
2022-11-17 17:07:13 +08:00
|
|
|
|
pub async fn patch_verge(patch: IVerge) -> Result<()> {
|
|
|
|
|
Config::verge().draft().patch_config(patch.clone());
|
2022-11-14 01:26:33 +08:00
|
|
|
|
|
|
|
|
|
let tun_mode = patch.enable_tun_mode;
|
|
|
|
|
let auto_launch = patch.enable_auto_launch;
|
|
|
|
|
let system_proxy = patch.enable_system_proxy;
|
|
|
|
|
let proxy_bypass = patch.system_proxy_bypass;
|
|
|
|
|
let language = patch.language;
|
|
|
|
|
|
2022-11-17 17:07:13 +08:00
|
|
|
|
match {
|
|
|
|
|
#[cfg(target_os = "windows")]
|
2022-11-18 18:18:41 +08:00
|
|
|
|
{
|
|
|
|
|
todo!()
|
|
|
|
|
}
|
2022-11-14 01:26:33 +08:00
|
|
|
|
|
2022-11-17 17:07:13 +08:00
|
|
|
|
if tun_mode.is_some() {
|
2022-11-18 18:18:41 +08:00
|
|
|
|
update_core_config().await?;
|
2022-11-17 17:07:13 +08:00
|
|
|
|
}
|
2022-11-14 01:26:33 +08:00
|
|
|
|
|
2022-11-17 17:07:13 +08:00
|
|
|
|
if auto_launch.is_some() {
|
|
|
|
|
sysopt::Sysopt::global().update_launch()?;
|
|
|
|
|
}
|
|
|
|
|
if system_proxy.is_some() || proxy_bypass.is_some() {
|
|
|
|
|
sysopt::Sysopt::global().update_sysproxy()?;
|
|
|
|
|
sysopt::Sysopt::global().guard_proxy();
|
|
|
|
|
}
|
2022-11-14 01:26:33 +08:00
|
|
|
|
|
2022-11-17 17:07:13 +08:00
|
|
|
|
if let Some(true) = patch.enable_proxy_guard {
|
|
|
|
|
sysopt::Sysopt::global().guard_proxy();
|
|
|
|
|
}
|
2022-11-14 01:26:33 +08:00
|
|
|
|
|
2022-11-17 17:07:13 +08:00
|
|
|
|
if let Some(hotkeys) = patch.hotkeys {
|
|
|
|
|
hotkey::Hotkey::global().update(hotkeys)?;
|
|
|
|
|
}
|
2022-11-14 01:26:33 +08:00
|
|
|
|
|
2022-11-17 17:07:13 +08:00
|
|
|
|
if language.is_some() {
|
|
|
|
|
handle::Handle::update_systray()?;
|
|
|
|
|
} else if system_proxy.or(tun_mode).is_some() {
|
|
|
|
|
handle::Handle::update_systray_part()?;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<Result<()>>::Ok(())
|
|
|
|
|
} {
|
|
|
|
|
Ok(()) => {
|
|
|
|
|
Config::verge().apply();
|
|
|
|
|
Config::verge().data().save_file()?;
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
Err(err) => {
|
|
|
|
|
Config::verge().discard();
|
|
|
|
|
Err(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-14 01:26:33 +08:00
|
|
|
|
}
|
2022-11-12 11:37:23 +08:00
|
|
|
|
|
2022-11-16 01:26:41 +08:00
|
|
|
|
/// 更新某个profile
|
|
|
|
|
/// 如果更新当前配置就激活配置
|
|
|
|
|
pub async fn update_profile(uid: String, option: Option<PrfOption>) -> Result<()> {
|
2022-11-17 17:07:13 +08:00
|
|
|
|
let url_opt = {
|
|
|
|
|
let profiles = Config::profiles();
|
|
|
|
|
let profiles = profiles.latest();
|
|
|
|
|
let item = profiles.get_item(&uid)?;
|
|
|
|
|
let is_remote = item.itype.as_ref().map_or(false, |s| s == "remote");
|
|
|
|
|
|
|
|
|
|
if !is_remote {
|
|
|
|
|
None // 直接更新
|
|
|
|
|
} else if item.url.is_none() {
|
|
|
|
|
bail!("failed to get the profile item url");
|
|
|
|
|
} else {
|
|
|
|
|
Some((item.url.clone().unwrap(), item.option.clone()))
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let should_update = match url_opt {
|
|
|
|
|
Some((url, opt)) => {
|
|
|
|
|
let merged_opt = PrfOption::merge(opt, option);
|
|
|
|
|
let item = PrfItem::from_url(&url, None, None, merged_opt).await?;
|
|
|
|
|
|
|
|
|
|
let profiles = Config::profiles();
|
|
|
|
|
let mut profiles = profiles.latest();
|
|
|
|
|
profiles.update_item(uid.clone(), item)?;
|
|
|
|
|
|
|
|
|
|
Some(uid) == profiles.get_current()
|
|
|
|
|
}
|
|
|
|
|
None => true,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if should_update {
|
2022-11-18 18:18:41 +08:00
|
|
|
|
update_core_config().await?;
|
2022-11-17 17:07:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-16 01:26:41 +08:00
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2022-11-18 18:18:41 +08:00
|
|
|
|
|
|
|
|
|
/// 更新配置
|
|
|
|
|
async fn update_core_config() -> Result<()> {
|
|
|
|
|
match CoreManager::global().update_config().await {
|
|
|
|
|
Ok(_) => {
|
|
|
|
|
handle::Handle::refresh_clash();
|
|
|
|
|
handle::Handle::notice_message("set_config::ok", "ok");
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
Err(err) => {
|
|
|
|
|
handle::Handle::notice_message("set_config::error", format!("{err}"));
|
|
|
|
|
Err(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|