mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 17:15:38 +08:00
refactor: wip
This commit is contained in:
@@ -1,10 +1,7 @@
|
||||
use crate::utils::{config, dirs};
|
||||
use anyhow::Result;
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::Mutex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use std::{net::SocketAddr, sync::Arc};
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct IClashTemp(pub Mapping);
|
||||
@@ -33,69 +30,6 @@ impl IClashTemp {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[deprecated]
|
||||
pub struct ClashN {
|
||||
/// maintain the clash config
|
||||
pub config: Arc<Mutex<Mapping>>,
|
||||
/// some info
|
||||
pub info: Arc<Mutex<ClashInfoN>>,
|
||||
}
|
||||
|
||||
impl ClashN {
|
||||
pub fn global() -> &'static ClashN {
|
||||
static DATA: OnceCell<ClashN> = OnceCell::new();
|
||||
|
||||
DATA.get_or_init(|| {
|
||||
let config = ClashN::read_config();
|
||||
let info = ClashInfoN::from(&config);
|
||||
|
||||
ClashN {
|
||||
config: Arc::new(Mutex::new(config)),
|
||||
info: Arc::new(Mutex::new(info)),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// get clash config
|
||||
pub fn read_config() -> Mapping {
|
||||
config::read_merge_mapping(dirs::clash_path())
|
||||
}
|
||||
|
||||
/// save the clash config
|
||||
pub fn save_config(&self) -> Result<()> {
|
||||
let config = self.config.lock();
|
||||
|
||||
config::save_yaml(
|
||||
dirs::clash_path(),
|
||||
&*config,
|
||||
Some("# Default Config For ClashN Core\n\n"),
|
||||
)
|
||||
}
|
||||
|
||||
/// 返回旧值
|
||||
pub fn patch_info(&self, info: ClashInfoN) -> Result<ClashInfoN> {
|
||||
let mut old_info = self.info.lock();
|
||||
let old = (*old_info).to_owned();
|
||||
*old_info = info;
|
||||
Ok(old)
|
||||
}
|
||||
|
||||
/// patch update the clash config
|
||||
/// if the port is changed then return true
|
||||
pub fn patch_config(&self, patch: Mapping) -> Result<()> {
|
||||
let mut config = self.config.lock();
|
||||
|
||||
for (key, value) in patch.into_iter() {
|
||||
config.insert(key, value);
|
||||
}
|
||||
|
||||
drop(config);
|
||||
|
||||
self.save_config()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct ClashInfoN {
|
||||
/// clash sidecar status
|
||||
@@ -245,21 +179,3 @@ pub struct IClashFallbackFilter {
|
||||
pub ipcidr: Option<Vec<String>>,
|
||||
pub domain: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let socket = SocketAddr::new("127.0.0.1".parse().unwrap(), 9090);
|
||||
|
||||
let s = "[::]:8080".parse::<SocketAddr>();
|
||||
|
||||
dbg!(s);
|
||||
|
||||
// match "::8080".parse::<SocketAddr>() {
|
||||
// Ok(_) => {}
|
||||
// Err(err) => {
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
// assert_eq!(":8080".parse(), Ok(socket));
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
use super::{Draft, IClashTemp, IProfiles, IVerge};
|
||||
use crate::config::ClashN;
|
||||
use once_cell::sync::OnceCell;
|
||||
use serde_yaml::Mapping;
|
||||
|
||||
pub struct Config {
|
||||
clash_config: Draft<IClashTemp>,
|
||||
@@ -20,18 +18,6 @@ impl Config {
|
||||
})
|
||||
}
|
||||
|
||||
// pub fn clash<'a>() -> MappedMutexGuard<'a, IClash> {
|
||||
// Self::global().clash_config.latest()
|
||||
// }
|
||||
|
||||
// pub fn verge<'a>() -> MappedMutexGuard<'a, IVerge> {
|
||||
// Self::global().verge_config.latest()
|
||||
// }
|
||||
|
||||
// pub fn profiles<'a>() -> MappedMutexGuard<'a, IProfiles> {
|
||||
// Self::global().profiles_config.latest()
|
||||
// }
|
||||
|
||||
pub fn clash() -> Draft<IClashTemp> {
|
||||
Self::global().clash_config.clone()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use super::{IClash, IClashTemp, IProfiles, IVerge};
|
||||
use super::{IClashTemp, IProfiles, IVerge};
|
||||
use parking_lot::{MappedMutexGuard, Mutex, MutexGuard};
|
||||
use serde_yaml::Mapping;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -64,10 +63,10 @@ macro_rules! draft_define {
|
||||
};
|
||||
}
|
||||
|
||||
draft_define!(IClash);
|
||||
// draft_define!(IClash);
|
||||
draft_define!(IClashTemp);
|
||||
draft_define!(IVerge);
|
||||
draft_define!(Mapping);
|
||||
// draft_define!(Mapping);
|
||||
draft_define!(IProfiles);
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -6,6 +6,8 @@ use serde_yaml::Mapping;
|
||||
use std::fs;
|
||||
use sysproxy::Sysproxy;
|
||||
|
||||
use super::Config;
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct PrfItem {
|
||||
pub uid: Option<String>,
|
||||
@@ -192,9 +194,9 @@ impl PrfItem {
|
||||
|
||||
// 使用软件自己的代理
|
||||
if self_proxy {
|
||||
let clash = super::ClashN::global();
|
||||
let port = clash.info.lock().port.clone();
|
||||
let port = Config::clash().data().get_info()?.port;
|
||||
let port = port.ok_or(anyhow::anyhow!("failed to get clash info port"))?;
|
||||
|
||||
let proxy_scheme = format!("http://127.0.0.1:{port}");
|
||||
|
||||
if let Ok(proxy) = reqwest::Proxy::http(&proxy_scheme) {
|
||||
|
||||
@@ -1,82 +1,25 @@
|
||||
use super::{prfitem::PrfItem, ChainItem, PrfOption};
|
||||
use crate::{
|
||||
core::CoreManager,
|
||||
utils::{config, dirs, help},
|
||||
};
|
||||
use super::{prfitem::PrfItem, ChainItem};
|
||||
use crate::utils::{config, dirs, help};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::Mutex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::Mapping;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::{fs, io::Write};
|
||||
|
||||
#[deprecated]
|
||||
pub struct ProfilesN {
|
||||
pub config: Arc<Mutex<IProfiles>>,
|
||||
}
|
||||
|
||||
impl ProfilesN {
|
||||
pub fn global() -> &'static ProfilesN {
|
||||
static PROFILES: OnceCell<ProfilesN> = OnceCell::new();
|
||||
|
||||
PROFILES.get_or_init(|| ProfilesN {
|
||||
config: Arc::new(Mutex::new(IProfiles::read_file())),
|
||||
})
|
||||
}
|
||||
|
||||
/// 更新单个配置
|
||||
pub async fn update_item(&self, uid: String, option: Option<PrfOption>) -> Result<()> {
|
||||
let url_opt = {
|
||||
let profiles = self.config.lock();
|
||||
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 mut profiles = self.config.lock();
|
||||
profiles.update_item(uid.clone(), item)?;
|
||||
|
||||
Some(uid) == profiles.get_current()
|
||||
}
|
||||
None => true,
|
||||
};
|
||||
|
||||
if should_update {
|
||||
CoreManager::global().activate_config().await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Define the `profiles.yaml` schema
|
||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct IProfiles {
|
||||
/// same as PrfConfig.current
|
||||
current: Option<String>,
|
||||
pub current: Option<String>,
|
||||
|
||||
/// same as PrfConfig.chain
|
||||
chain: Option<Vec<String>>,
|
||||
pub chain: Option<Vec<String>>,
|
||||
|
||||
/// record valid fields for clash
|
||||
valid: Option<Vec<String>>,
|
||||
pub valid: Option<Vec<String>>,
|
||||
|
||||
/// profile list
|
||||
items: Option<Vec<PrfItem>>,
|
||||
pub items: Option<Vec<PrfItem>>,
|
||||
}
|
||||
|
||||
macro_rules! patch {
|
||||
@@ -134,7 +77,7 @@ impl IProfiles {
|
||||
|
||||
if items.iter().find(|&each| each.uid == some_uid).is_some() {
|
||||
self.current = some_uid;
|
||||
return self.save_file();
|
||||
return self.save_file(); // todo remove
|
||||
}
|
||||
|
||||
bail!("invalid uid \"{uid}\"");
|
||||
|
||||
@@ -1,53 +1,6 @@
|
||||
use crate::utils::{config, dirs};
|
||||
use anyhow::Result;
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::Mutex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[deprecated]
|
||||
pub struct VergeN {
|
||||
pub config: Arc<Mutex<IVerge>>,
|
||||
}
|
||||
|
||||
impl VergeN {
|
||||
pub fn global() -> &'static VergeN {
|
||||
static DATA: OnceCell<VergeN> = OnceCell::new();
|
||||
|
||||
DATA.get_or_init(|| {
|
||||
let config = config::read_yaml::<IVerge>(dirs::verge_path());
|
||||
VergeN {
|
||||
config: Arc::new(Mutex::new(config)),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Save IVerge App Config
|
||||
pub fn save_file(&self) -> Result<()> {
|
||||
self.config.lock().save_file()
|
||||
}
|
||||
|
||||
/// patch verge config
|
||||
/// only save to file
|
||||
pub fn patch_config(&self, patch: IVerge) -> Result<()> {
|
||||
{
|
||||
self.config.lock().patch_config(patch);
|
||||
}
|
||||
self.save_file()
|
||||
}
|
||||
|
||||
/// 在初始化前尝试拿到单例端口的值
|
||||
pub fn get_singleton_port() -> u16 {
|
||||
let config = config::read_yaml::<IVerge>(dirs::verge_path());
|
||||
|
||||
#[cfg(not(feature = "verge-dev"))]
|
||||
const SERVER_PORT: u16 = 33331;
|
||||
#[cfg(feature = "verge-dev")]
|
||||
const SERVER_PORT: u16 = 11233;
|
||||
|
||||
config.app_singleton_port.unwrap_or(SERVER_PORT)
|
||||
}
|
||||
}
|
||||
|
||||
/// ### `verge.yaml` schema
|
||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
||||
@@ -177,4 +130,16 @@ impl IVerge {
|
||||
patch!(auto_close_connection);
|
||||
patch!(default_latency_test);
|
||||
}
|
||||
|
||||
/// 在初始化前尝试拿到单例端口的值
|
||||
pub fn get_singleton_port() -> u16 {
|
||||
let config = config::read_yaml::<IVerge>(dirs::verge_path());
|
||||
|
||||
#[cfg(not(feature = "verge-dev"))]
|
||||
const SERVER_PORT: u16 = 33331;
|
||||
#[cfg(feature = "verge-dev")]
|
||||
const SERVER_PORT: u16 = 11233;
|
||||
|
||||
config.app_singleton_port.unwrap_or(SERVER_PORT)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user