HWID implementation
This commit is contained in:
32
src-tauri/Cargo.lock
generated
32
src-tauri/Cargo.lock
generated
@@ -1085,11 +1085,13 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"log4rs",
|
"log4rs",
|
||||||
|
"machine-uid",
|
||||||
"mihomo_api",
|
"mihomo_api",
|
||||||
"nanoid",
|
"nanoid",
|
||||||
"network-interface",
|
"network-interface",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"open",
|
"open",
|
||||||
|
"os_info",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"port_scanner",
|
"port_scanner",
|
||||||
@@ -3882,6 +3884,15 @@ dependencies = [
|
|||||||
"time",
|
"time",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "machine-uid"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f1595709b0a7386bcd56ba34d250d626e5503917d05d32cdccddcd68603e212"
|
||||||
|
dependencies = [
|
||||||
|
"winreg 0.6.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "malloc_buf"
|
name = "malloc_buf"
|
||||||
version = "0.0.6"
|
version = "0.0.6"
|
||||||
@@ -4792,6 +4803,18 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "os_info"
|
||||||
|
version = "3.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d0e1ac5fde8d43c34139135df8ea9ee9465394b2d8d20f032d38998f64afffc3"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"plist",
|
||||||
|
"serde",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_pipe"
|
name = "os_pipe"
|
||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
@@ -9299,6 +9322,15 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winreg"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winreg"
|
name = "winreg"
|
||||||
version = "0.10.1"
|
version = "0.10.1"
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ identifier = "io.github.clash-verge-rev.clash-verge-rev"
|
|||||||
tauri-build = { version = "2.3.0", features = [] }
|
tauri-build = { version = "2.3.0", features = [] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
os_info = "3.0"
|
||||||
|
machine-uid = "0.2"
|
||||||
warp = "0.3.7"
|
warp = "0.3.7"
|
||||||
anyhow = "1.0.98"
|
anyhow = "1.0.98"
|
||||||
dirs = "6.0"
|
dirs = "6.0"
|
||||||
|
|||||||
@@ -113,6 +113,9 @@ pub struct PrfOption {
|
|||||||
pub proxies: Option<String>,
|
pub proxies: Option<String>,
|
||||||
|
|
||||||
pub groups: Option<String>,
|
pub groups: Option<String>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub use_hwid: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrfOption {
|
impl PrfOption {
|
||||||
@@ -132,6 +135,7 @@ impl PrfOption {
|
|||||||
a.proxies = b.proxies.or(a.proxies);
|
a.proxies = b.proxies.or(a.proxies);
|
||||||
a.groups = b.groups.or(a.groups);
|
a.groups = b.groups.or(a.groups);
|
||||||
a.timeout_seconds = b.timeout_seconds.or(a.timeout_seconds);
|
a.timeout_seconds = b.timeout_seconds.or(a.timeout_seconds);
|
||||||
|
a.use_hwid = b.use_hwid.or(a.use_hwid);
|
||||||
Some(a)
|
Some(a)
|
||||||
}
|
}
|
||||||
t => t.0.or(t.1),
|
t => t.0.or(t.1),
|
||||||
@@ -251,6 +255,7 @@ impl PrfItem {
|
|||||||
let user_agent = opt_ref.and_then(|o| o.user_agent.clone());
|
let user_agent = opt_ref.and_then(|o| o.user_agent.clone());
|
||||||
let update_interval = opt_ref.and_then(|o| o.update_interval);
|
let update_interval = opt_ref.and_then(|o| o.update_interval);
|
||||||
let timeout = opt_ref.and_then(|o| o.timeout_seconds).unwrap_or(20);
|
let timeout = opt_ref.and_then(|o| o.timeout_seconds).unwrap_or(20);
|
||||||
|
let use_hwid = opt_ref.is_some_and(|o| o.use_hwid.unwrap_or(true));
|
||||||
let mut merge = opt_ref.and_then(|o| o.merge.clone());
|
let mut merge = opt_ref.and_then(|o| o.merge.clone());
|
||||||
let mut script = opt_ref.and_then(|o| o.script.clone());
|
let mut script = opt_ref.and_then(|o| o.script.clone());
|
||||||
let mut rules = opt_ref.and_then(|o| o.rules.clone());
|
let mut rules = opt_ref.and_then(|o| o.rules.clone());
|
||||||
@@ -274,6 +279,7 @@ impl PrfItem {
|
|||||||
Some(timeout),
|
Some(timeout),
|
||||||
user_agent.clone(),
|
user_agent.clone(),
|
||||||
accept_invalid_certs,
|
accept_invalid_certs,
|
||||||
|
use_hwid,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ pub async fn test_delay(url: String) -> anyhow::Result<u32> {
|
|||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
let response = NetworkManager::global()
|
let response = NetworkManager::global()
|
||||||
.get_with_interrupt(&url, proxy_type, Some(10), user_agent, false)
|
.get_with_interrupt(&url, proxy_type, Some(10), user_agent, false, false)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match response {
|
match response {
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ pub fn run() {
|
|||||||
.get_webview_window("main")
|
.get_webview_window("main")
|
||||||
{
|
{
|
||||||
logging!(info, Type::Window, true, "设置macOS窗口标题");
|
logging!(info, Type::Window, true, "设置macOS窗口标题");
|
||||||
let _ = window.set_title("Clash Verge");
|
let _ = window.set_title("Clash Verge Rev Lite");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,3 +10,4 @@ pub mod resolve;
|
|||||||
pub mod server;
|
pub mod server;
|
||||||
pub mod tmpl;
|
pub mod tmpl;
|
||||||
pub mod window_manager;
|
pub mod window_manager;
|
||||||
|
pub mod sys_info;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
use tokio::runtime::{Builder, Runtime};
|
use tokio::runtime::{Builder, Runtime};
|
||||||
|
|
||||||
use crate::{config::Config, logging, utils::logging::Type};
|
use crate::{config::Config, logging, utils::logging::Type, utils::sys_info};
|
||||||
|
|
||||||
// HTTP2 相关
|
// HTTP2 相关
|
||||||
const H2_CONNECTION_WINDOW_SIZE: u32 = 1024 * 1024;
|
const H2_CONNECTION_WINDOW_SIZE: u32 = 1024 * 1024;
|
||||||
@@ -248,6 +248,7 @@ impl NetworkManager {
|
|||||||
timeout_secs: Option<u64>,
|
timeout_secs: Option<u64>,
|
||||||
user_agent: Option<String>,
|
user_agent: Option<String>,
|
||||||
accept_invalid_certs: bool,
|
accept_invalid_certs: bool,
|
||||||
|
use_hwid: bool,
|
||||||
) -> RequestBuilder {
|
) -> RequestBuilder {
|
||||||
if self.should_reset_clients() {
|
if self.should_reset_clients() {
|
||||||
self.reset_clients();
|
self.reset_clients();
|
||||||
@@ -331,7 +332,18 @@ impl NetworkManager {
|
|||||||
|
|
||||||
let client = builder.build().expect("Failed to build custom HTTP client");
|
let client = builder.build().expect("Failed to build custom HTTP client");
|
||||||
|
|
||||||
client.get(url)
|
let mut request_builder = client.get(url);
|
||||||
|
|
||||||
|
if use_hwid {
|
||||||
|
let sys_info = sys_info::get_system_info();
|
||||||
|
logging!(info, Type::Network, true, "Adding HWID headers to request");
|
||||||
|
request_builder = request_builder
|
||||||
|
.header("x-hwid", &sys_info.hwid)
|
||||||
|
.header("x-device-os", &sys_info.os_type)
|
||||||
|
.header("x-ver-os", &sys_info.os_ver);
|
||||||
|
}
|
||||||
|
|
||||||
|
request_builder
|
||||||
}
|
}
|
||||||
|
|
||||||
/* /// 执行GET请求,添加错误跟踪
|
/* /// 执行GET请求,添加错误跟踪
|
||||||
@@ -378,6 +390,7 @@ impl NetworkManager {
|
|||||||
timeout_secs: Option<u64>,
|
timeout_secs: Option<u64>,
|
||||||
user_agent: Option<String>,
|
user_agent: Option<String>,
|
||||||
accept_invalid_certs: bool,
|
accept_invalid_certs: bool,
|
||||||
|
use_hwid: bool,
|
||||||
) -> Result<Response> {
|
) -> Result<Response> {
|
||||||
let request = self.create_request(
|
let request = self.create_request(
|
||||||
url,
|
url,
|
||||||
@@ -385,6 +398,7 @@ impl NetworkManager {
|
|||||||
timeout_secs,
|
timeout_secs,
|
||||||
user_agent,
|
user_agent,
|
||||||
accept_invalid_certs,
|
accept_invalid_certs,
|
||||||
|
use_hwid,
|
||||||
);
|
);
|
||||||
|
|
||||||
let timeout_duration = timeout_secs.unwrap_or(20);
|
let timeout_duration = timeout_secs.unwrap_or(20);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ use tauri::{AppHandle, Manager};
|
|||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
|
|
||||||
use tauri::Url;
|
use tauri::Url;
|
||||||
|
use crate::config::PrfOption;
|
||||||
//#[cfg(not(target_os = "linux"))]
|
//#[cfg(not(target_os = "linux"))]
|
||||||
// use window_shadows::set_shadow;
|
// use window_shadows::set_shadow;
|
||||||
|
|
||||||
@@ -549,19 +550,25 @@ pub async fn resolve_scheme(param: String) -> Result<()> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if link_parsed.scheme() == "clash" || link_parsed.scheme() == "clash-verge" {
|
if link_parsed.scheme() == "clash" || link_parsed.scheme() == "clash-verge" {
|
||||||
let name = link_parsed
|
let mut name: Option<String> = None;
|
||||||
.query_pairs()
|
let mut url_param: Option<String> = None;
|
||||||
.find(|(key, _)| key == "name")
|
let mut use_hwid = true;
|
||||||
.map(|(_, value)| value.into_owned());
|
|
||||||
|
|
||||||
let url_param = if let Some(query) = link_parsed.query() {
|
for (key, value) in link_parsed.query_pairs() {
|
||||||
let prefix = "url=";
|
match key.as_ref() {
|
||||||
if let Some(pos) = query.find(prefix) {
|
"name" => name = Some(value.into_owned()),
|
||||||
let raw_url = &query[pos + prefix.len()..];
|
"url" => url_param = Some(percent_decode_str(&value).decode_utf8_lossy().to_string()),
|
||||||
Some(percent_decode_str(raw_url).decode_utf8_lossy().to_string())
|
"hwid" => use_hwid = value == "1" || value == "true",
|
||||||
} else {
|
_ => {}
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let option = if use_hwid {
|
||||||
|
log::info!(target:"app", "HWID usage requested via deep link");
|
||||||
|
Some(PrfOption {
|
||||||
|
use_hwid: Some(true),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@@ -571,7 +578,7 @@ pub async fn resolve_scheme(param: String) -> Result<()> {
|
|||||||
log::info!(target:"app", "decoded subscription url: {url}");
|
log::info!(target:"app", "decoded subscription url: {url}");
|
||||||
|
|
||||||
create_window(false);
|
create_window(false);
|
||||||
match PrfItem::from_url(url.as_ref(), name, None, None).await {
|
match PrfItem::from_url(url.as_ref(), name, None, option).await {
|
||||||
Ok(item) => {
|
Ok(item) => {
|
||||||
let uid = item.uid.clone().unwrap();
|
let uid = item.uid.clone().unwrap();
|
||||||
let _ = wrap_err!(Config::profiles().data().append_item(item));
|
let _ = wrap_err!(Config::profiles().data().append_item(item));
|
||||||
|
|||||||
22
src-tauri/src/utils/sys_info.rs
Normal file
22
src-tauri/src/utils/sys_info.rs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug, Clone)]
|
||||||
|
pub struct SystemInfo {
|
||||||
|
pub hwid: String,
|
||||||
|
pub os_type: String,
|
||||||
|
pub os_ver: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static SYSTEM_INFO: Lazy<SystemInfo> = Lazy::new(|| {
|
||||||
|
let os_info = os_info::get();
|
||||||
|
SystemInfo {
|
||||||
|
hwid: machine_uid::get().unwrap_or_else(|_| "unknown_hwid".to_string()),
|
||||||
|
os_type: os_info.os_type().to_string(),
|
||||||
|
os_ver: os_info.version().to_string(),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pub fn get_system_info() -> &'static SystemInfo {
|
||||||
|
&SYSTEM_INFO
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user