Merge branch 'dev' into chore/i18n
This commit is contained in:
@@ -234,4 +234,15 @@ suspicious_operation_groupings = "deny"
|
||||
string_lit_as_bytes = "deny"
|
||||
significant_drop_tightening = "deny"
|
||||
significant_drop_in_scrutinee = "deny"
|
||||
redundant_clone = "deny"
|
||||
redundant_clone = "deny"
|
||||
# option_if_let_else = "deny" // 过于激进,暂时不开启
|
||||
needless_pass_by_ref_mut = "deny"
|
||||
needless_collect = "deny"
|
||||
missing_const_for_fn = "deny"
|
||||
iter_with_drain = "deny"
|
||||
iter_on_single_items = "deny"
|
||||
iter_on_empty_collections = "deny"
|
||||
# fallible_impl_from = "deny" // 过于激进,暂时不开启
|
||||
equatable_if_let = "deny"
|
||||
collection_is_never_read = "deny"
|
||||
branches_sharing_code = "deny"
|
||||
@@ -189,7 +189,6 @@ pub async fn apply_dns_config(apply: bool) -> CmdResult {
|
||||
})?;
|
||||
|
||||
logging!(info, Type::Config, "DNS config successfully applied");
|
||||
handle::Handle::refresh_clash();
|
||||
} else {
|
||||
// 当关闭DNS设置时,重新生成配置(不加载DNS配置文件)
|
||||
logging!(
|
||||
@@ -212,9 +211,9 @@ pub async fn apply_dns_config(apply: bool) -> CmdResult {
|
||||
})?;
|
||||
|
||||
logging!(info, Type::Config, "Config regenerated successfully");
|
||||
handle::Handle::refresh_clash();
|
||||
}
|
||||
|
||||
handle::Handle::refresh_clash();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -13,19 +13,23 @@ pub(super) async fn check_youtube_premium(client: &Client) -> UnlockItem {
|
||||
Ok(response) => {
|
||||
if let Ok(body) = response.text().await {
|
||||
let body_lower = body.to_lowercase();
|
||||
let mut status = "Failed";
|
||||
let mut region = None;
|
||||
|
||||
if body_lower.contains("youtube premium is not available in your country") {
|
||||
return UnlockItem {
|
||||
name: "Youtube Premium".to_string(),
|
||||
status: "No".to_string(),
|
||||
region: None,
|
||||
check_time: Some(get_local_date_string()),
|
||||
};
|
||||
}
|
||||
|
||||
if body_lower.contains("ad-free") {
|
||||
let re = match Regex::new(r#"id="country-code"[^>]*>([^<]+)<"#) {
|
||||
Ok(re) => re,
|
||||
status = "No";
|
||||
} else if body_lower.contains("ad-free") {
|
||||
match Regex::new(r#"id="country-code"[^>]*>([^<]+)<"#) {
|
||||
Ok(re) => {
|
||||
if let Some(caps) = re.captures(&body)
|
||||
&& let Some(m) = caps.get(1)
|
||||
{
|
||||
let country_code = m.as_str().trim();
|
||||
let emoji = country_code_to_emoji(country_code);
|
||||
region = Some(format!("{emoji}{country_code}"));
|
||||
status = "Yes";
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
logging!(
|
||||
error,
|
||||
@@ -33,34 +37,14 @@ pub(super) async fn check_youtube_premium(client: &Client) -> UnlockItem {
|
||||
"Failed to compile YouTube Premium regex: {}",
|
||||
e
|
||||
);
|
||||
return UnlockItem {
|
||||
name: "Youtube Premium".to_string(),
|
||||
status: "Failed".to_string(),
|
||||
region: None,
|
||||
check_time: Some(get_local_date_string()),
|
||||
};
|
||||
}
|
||||
};
|
||||
let region = re.captures(&body).and_then(|caps| {
|
||||
caps.get(1).map(|m| {
|
||||
let country_code = m.as_str().trim();
|
||||
let emoji = country_code_to_emoji(country_code);
|
||||
format!("{emoji}{country_code}")
|
||||
})
|
||||
});
|
||||
|
||||
return UnlockItem {
|
||||
name: "Youtube Premium".to_string(),
|
||||
status: "Yes".to_string(),
|
||||
region,
|
||||
check_time: Some(get_local_date_string()),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
UnlockItem {
|
||||
name: "Youtube Premium".to_string(),
|
||||
status: "Failed".to_string(),
|
||||
region: None,
|
||||
status: status.to_string(),
|
||||
region,
|
||||
check_time: Some(get_local_date_string()),
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -17,7 +17,7 @@ mod platform {
|
||||
mod platform {
|
||||
use super::CmdResult;
|
||||
|
||||
pub fn invoke_uwp_tool() -> CmdResult {
|
||||
pub const fn invoke_uwp_tool() -> CmdResult {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -611,6 +611,6 @@ impl PrfItem {
|
||||
}
|
||||
|
||||
// 向前兼容,默认为订阅启用自动更新
|
||||
fn default_allow_auto_update() -> Option<bool> {
|
||||
const fn default_allow_auto_update() -> Option<bool> {
|
||||
Some(true)
|
||||
}
|
||||
|
||||
@@ -102,12 +102,12 @@ impl IProfiles {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_current(&self) -> Option<&String> {
|
||||
pub const fn get_current(&self) -> Option<&String> {
|
||||
self.current.as_ref()
|
||||
}
|
||||
|
||||
/// get items ref
|
||||
pub fn get_items(&self) -> Option<&Vec<PrfItem>> {
|
||||
pub const fn get_items(&self) -> Option<&Vec<PrfItem>> {
|
||||
self.items.as_ref()
|
||||
}
|
||||
|
||||
|
||||
@@ -531,7 +531,7 @@ impl IVerge {
|
||||
patch!(enable_external_controller);
|
||||
}
|
||||
|
||||
pub fn get_singleton_port() -> u16 {
|
||||
pub const fn get_singleton_port() -> u16 {
|
||||
crate::constants::network::ports::SINGLETON_SERVER
|
||||
}
|
||||
|
||||
|
||||
@@ -347,11 +347,12 @@ impl AsyncProxyQuery {
|
||||
&mut buffer_size,
|
||||
);
|
||||
|
||||
let mut proxy_server = String::new();
|
||||
if server_result == 0 && value_type == REG_SZ && buffer_size > 0 {
|
||||
let proxy_server = if server_result == 0 && value_type == REG_SZ && buffer_size > 0 {
|
||||
let end_pos = buffer.iter().position(|&x| x == 0).unwrap_or(buffer.len());
|
||||
proxy_server = String::from_utf16_lossy(&buffer[..end_pos]);
|
||||
}
|
||||
String::from_utf16_lossy(&buffer[..end_pos])
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
// 读取代理绕过列表
|
||||
let proxy_override_name = "ProxyOverride\0".encode_utf16().collect::<Vec<u16>>();
|
||||
@@ -368,14 +369,16 @@ impl AsyncProxyQuery {
|
||||
&mut bypass_buffer_size,
|
||||
);
|
||||
|
||||
let mut bypass_list = String::new();
|
||||
if override_result == 0 && bypass_value_type == REG_SZ && bypass_buffer_size > 0 {
|
||||
let end_pos = bypass_buffer
|
||||
.iter()
|
||||
.position(|&x| x == 0)
|
||||
.unwrap_or(bypass_buffer.len());
|
||||
bypass_list = String::from_utf16_lossy(&bypass_buffer[..end_pos]);
|
||||
}
|
||||
let bypass_list =
|
||||
if override_result == 0 && bypass_value_type == REG_SZ && bypass_buffer_size > 0 {
|
||||
let end_pos = bypass_buffer
|
||||
.iter()
|
||||
.position(|&x| x == 0)
|
||||
.unwrap_or(bypass_buffer.len());
|
||||
String::from_utf16_lossy(&bypass_buffer[..end_pos])
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
RegCloseKey(hkey);
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ enum Operation {
|
||||
}
|
||||
|
||||
impl Operation {
|
||||
fn timeout(&self) -> u64 {
|
||||
const fn timeout(&self) -> u64 {
|
||||
match self {
|
||||
Self::Upload => TIMEOUT_UPLOAD,
|
||||
Self::Download => TIMEOUT_DOWNLOAD,
|
||||
|
||||
@@ -84,7 +84,7 @@ impl fmt::Display for SystemHotkey {
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
impl SystemHotkey {
|
||||
pub fn function(self) -> HotkeyFunction {
|
||||
pub const fn function(self) -> HotkeyFunction {
|
||||
match self {
|
||||
Self::CmdQ => HotkeyFunction::Quit,
|
||||
Self::CmdW => HotkeyFunction::Hide,
|
||||
|
||||
@@ -137,7 +137,7 @@ impl CoreManager {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_connection_io_error(kind: std::io::ErrorKind) -> bool {
|
||||
const fn is_connection_io_error(kind: std::io::ErrorKind) -> bool {
|
||||
matches!(
|
||||
kind,
|
||||
std::io::ErrorKind::ConnectionAborted
|
||||
|
||||
@@ -136,7 +136,7 @@ async fn uninstall_service() -> Result<()> {
|
||||
let elevator = crate::utils::help::linux_elevator();
|
||||
let status = match get_effective_uid() {
|
||||
0 => StdCommand::new(uninstall_shell).status()?,
|
||||
_ => StdCommand::new(elevator.clone())
|
||||
_ => StdCommand::new(elevator)
|
||||
.arg("sh")
|
||||
.arg("-c")
|
||||
.arg(uninstall_shell)
|
||||
@@ -177,7 +177,7 @@ async fn install_service() -> Result<()> {
|
||||
let elevator = crate::utils::help::linux_elevator();
|
||||
let status = match get_effective_uid() {
|
||||
0 => StdCommand::new(install_shell).status()?,
|
||||
_ => StdCommand::new(elevator.clone())
|
||||
_ => StdCommand::new(elevator)
|
||||
.arg("sh")
|
||||
.arg("-c")
|
||||
.arg(install_shell)
|
||||
@@ -449,7 +449,7 @@ impl ServiceManager {
|
||||
Self(ServiceStatus::Unavailable("Need Checks".into()))
|
||||
}
|
||||
|
||||
pub fn config() -> Option<clash_verge_service_ipc::IpcConfig> {
|
||||
pub const fn config() -> Option<clash_verge_service_ipc::IpcConfig> {
|
||||
Some(clash_verge_service_ipc::IpcConfig {
|
||||
default_timeout: Duration::from_millis(30),
|
||||
retry_delay: Duration::from_millis(250),
|
||||
|
||||
@@ -252,8 +252,8 @@ impl Timer {
|
||||
// Now perform async operations without holding locks
|
||||
for (uid, tid, interval) in operations_to_add {
|
||||
// Re-acquire locks for individual operations
|
||||
let mut delay_timer = self.delay_timer.write();
|
||||
if let Err(e) = self.add_task(&mut delay_timer, uid.clone(), tid, interval) {
|
||||
let delay_timer = self.delay_timer.write();
|
||||
if let Err(e) = self.add_task(&delay_timer, uid.clone(), tid, interval) {
|
||||
logging_error!(Type::Timer, "Failed to add task for uid {}: {}", uid, e);
|
||||
|
||||
// Rollback on failure - remove from timer_map
|
||||
@@ -370,7 +370,7 @@ impl Timer {
|
||||
/// Add a timer task with better error handling
|
||||
fn add_task(
|
||||
&self,
|
||||
delay_timer: &mut DelayTimer,
|
||||
delay_timer: &DelayTimer,
|
||||
uid: String,
|
||||
tid: TaskID,
|
||||
minutes: u64,
|
||||
|
||||
@@ -16,7 +16,7 @@ pub struct CoreConfigValidator {
|
||||
}
|
||||
|
||||
impl CoreConfigValidator {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
is_processing: AtomicBool::new(false),
|
||||
}
|
||||
|
||||
@@ -351,23 +351,21 @@ pub fn run() {
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn handle_window_destroyed() {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
use crate::core::hotkey::SystemHotkey;
|
||||
AsyncHandler::spawn(move || async move {
|
||||
let _ = hotkey::Hotkey::global().unregister_system_hotkey(SystemHotkey::CmdQ);
|
||||
let _ = hotkey::Hotkey::global().unregister_system_hotkey(SystemHotkey::CmdW);
|
||||
let is_enable_global_hotkey = Config::verge()
|
||||
.await
|
||||
.latest_arc()
|
||||
.enable_global_hotkey
|
||||
.unwrap_or(true);
|
||||
if !is_enable_global_hotkey {
|
||||
let _ = hotkey::Hotkey::global().reset();
|
||||
}
|
||||
});
|
||||
}
|
||||
use crate::core::hotkey::SystemHotkey;
|
||||
AsyncHandler::spawn(move || async move {
|
||||
let _ = hotkey::Hotkey::global().unregister_system_hotkey(SystemHotkey::CmdQ);
|
||||
let _ = hotkey::Hotkey::global().unregister_system_hotkey(SystemHotkey::CmdW);
|
||||
let is_enable_global_hotkey = Config::verge()
|
||||
.await
|
||||
.latest_arc()
|
||||
.enable_global_hotkey
|
||||
.unwrap_or(true);
|
||||
if !is_enable_global_hotkey {
|
||||
let _ = hotkey::Hotkey::global().reset();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,6 +445,7 @@ pub fn run() {
|
||||
tauri::WindowEvent::Focused(focused) => {
|
||||
event_handlers::handle_window_focus(focused);
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
tauri::WindowEvent::Destroyed => {
|
||||
event_handlers::handle_window_destroyed();
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ fn main() {
|
||||
console_subscriber::init();
|
||||
|
||||
// Check for --no-tray command line argument
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
if args.contains(&"--no-tray".into()) {
|
||||
#[cfg(target_os = "linux")]
|
||||
if std::env::args().any(|x| x == "--no-tray") {
|
||||
unsafe {
|
||||
std::env::set_var("CLASH_VERGE_DISABLE_TRAY", "1");
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ impl From<u8> for LightweightState {
|
||||
}
|
||||
|
||||
impl LightweightState {
|
||||
fn as_u8(self) -> u8 {
|
||||
const fn as_u8(self) -> u8 {
|
||||
self as u8
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ impl Drop for CommandChildGuard {
|
||||
}
|
||||
|
||||
impl CommandChildGuard {
|
||||
pub fn new(child: CommandChild) -> Self {
|
||||
pub const fn new(child: CommandChild) -> Self {
|
||||
Self(Some(child))
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ use crate::{
|
||||
use anyhow::Result;
|
||||
use async_trait::async_trait;
|
||||
use once_cell::sync::OnceCell;
|
||||
#[cfg(unix)]
|
||||
use std::iter;
|
||||
use std::{fs, path::PathBuf};
|
||||
use tauri::Manager;
|
||||
|
||||
@@ -226,8 +228,7 @@ pub fn get_encryption_key() -> Result<Vec<u8>> {
|
||||
|
||||
#[cfg(unix)]
|
||||
pub fn ensure_mihomo_safe_dir() -> Option<PathBuf> {
|
||||
["/tmp"]
|
||||
.iter()
|
||||
iter::once("/tmp")
|
||||
.map(PathBuf::from)
|
||||
.find(|path| path.exists())
|
||||
.or_else(|| {
|
||||
|
||||
@@ -506,7 +506,7 @@ pub fn init_scheme() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn init_scheme() -> Result<()> {
|
||||
pub const fn init_scheme() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ struct IntelGpuDetection {
|
||||
}
|
||||
|
||||
impl IntelGpuDetection {
|
||||
fn should_disable_dmabuf(&self) -> bool {
|
||||
const fn should_disable_dmabuf(&self) -> bool {
|
||||
self.intel_is_primary || self.inconclusive
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ enum NvidiaDmabufDisableReason {
|
||||
}
|
||||
|
||||
impl NvidiaGpuDetection {
|
||||
fn disable_reason(&self, session: &SessionEnv) -> Option<NvidiaDmabufDisableReason> {
|
||||
const fn disable_reason(&self, session: &SessionEnv) -> Option<NvidiaDmabufDisableReason> {
|
||||
if !session.is_wayland {
|
||||
return None;
|
||||
}
|
||||
@@ -144,11 +144,11 @@ impl DmabufOverrides {
|
||||
}
|
||||
}
|
||||
|
||||
fn has_env_override(&self) -> bool {
|
||||
const fn has_env_override(&self) -> bool {
|
||||
self.dmabuf_override.is_some()
|
||||
}
|
||||
|
||||
fn should_override_env(&self, decision: &DmabufDecision) -> bool {
|
||||
const fn should_override_env(&self, decision: &DmabufDecision) -> bool {
|
||||
if self.user_preference.is_some() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ pub struct HttpResponse {
|
||||
}
|
||||
|
||||
impl HttpResponse {
|
||||
pub fn new(status: StatusCode, headers: HeaderMap, body: String) -> Self {
|
||||
pub const fn new(status: StatusCode, headers: HeaderMap, body: String) -> Self {
|
||||
Self {
|
||||
status,
|
||||
headers,
|
||||
@@ -34,11 +34,11 @@ impl HttpResponse {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn status(&self) -> StatusCode {
|
||||
pub const fn status(&self) -> StatusCode {
|
||||
self.status
|
||||
}
|
||||
|
||||
pub fn headers(&self) -> &HeaderMap {
|
||||
pub const fn headers(&self) -> &HeaderMap {
|
||||
&self.headers
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ pub async fn check_singleton() -> Result<()> {
|
||||
let client = ClientBuilder::new()
|
||||
.timeout(Duration::from_millis(500))
|
||||
.build()?;
|
||||
// 需要确保 Send
|
||||
#[allow(clippy::needless_collect)]
|
||||
let argvs: Vec<std::string::String> = std::env::args().collect();
|
||||
if argvs.len() > 1 {
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
|
||||
Reference in New Issue
Block a user