Quellcode durchsuchen

feat: disable running with admin permission and check service mode

MystiPanda vor 1 Jahr
Ursprung
Commit
a0f9fb90ee

+ 46 - 9
src-tauri/src/feat.rs

@@ -88,16 +88,37 @@ pub fn toggle_system_proxy() {
 pub fn toggle_tun_mode() {
     let enable = Config::verge().data().enable_tun_mode;
     let enable = enable.unwrap_or(false);
-
     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}"),
+        if !enable {
+            if let Ok(res) = service::check_service().await {
+                if res.code == 0 {
+                    match patch_verge(IVerge {
+                        enable_tun_mode: Some(!enable),
+                        ..IVerge::default()
+                    })
+                    .await
+                    {
+                        Ok(_) => handle::Handle::refresh_verge(),
+                        Err(err) => log::error!(target: "app", "{err}"),
+                    }
+                    return;
+                }
+            }
+            tauri::api::dialog::message(
+                None::<&tauri::Window>,
+                "Please install and enable service mode",
+                "Service mode is required for Tun mode",
+            );
+        } else {
+            match patch_verge(IVerge {
+                enable_tun_mode: Some(!enable),
+                ..IVerge::default()
+            })
+            .await
+            {
+                Ok(_) => handle::Handle::refresh_verge(),
+                Err(err) => log::error!(target: "app", "{err}"),
+            }
         }
     });
 }
@@ -403,3 +424,19 @@ pub async fn test_delay(url: String) -> Result<u32> {
         }
     }
 }
+
+pub fn check_permission() -> Result<()> {
+    #[cfg(target_os = "windows")]
+    {
+        let hklm = winreg::RegKey::predef(winreg::enums::HKEY_LOCAL_MACHINE);
+
+        if let Ok(reg) = hklm.open_subkey_with_flags(
+            "SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run",
+            winreg::enums::KEY_SET_VALUE,
+        ) {
+            reg.delete_value("Clash Verge").unwrap_or_default();
+            return Ok(());
+        }
+    }
+    Err(anyhow::anyhow!("permission denied"))
+}

+ 10 - 0
src-tauri/src/main.rs

@@ -19,6 +19,16 @@ fn main() -> std::io::Result<()> {
         println!("app exists");
         return Ok(());
     }
+    // 权限检测
+    if feat::check_permission().is_ok() {
+        println!("please do not run with admin permission");
+        tauri::api::dialog::blocking::message(
+            None::<&tauri::Window>,
+            "Please do not run with admin permission",
+            "If you want to use Tun mode, please enable service mode instead",
+        );
+        return Ok(());
+    }
 
     #[cfg(target_os = "linux")]
     std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1");

+ 24 - 63
src/components/setting/mods/stack-mode-switch.tsx

@@ -1,12 +1,4 @@
-import { useTranslation } from "react-i18next";
-import { Button, ButtonGroup, Tooltip } from "@mui/material";
-import { checkService } from "@/services/cmds";
-import { useVerge } from "@/hooks/use-verge";
-import getSystem from "@/utils/get-system";
-import useSWR from "swr";
-import { useEffect } from "react";
-
-const isWIN = getSystem() === "windows";
+import { Button, ButtonGroup } from "@mui/material";
 
 interface Props {
   value?: string;
@@ -15,62 +7,31 @@ interface Props {
 
 export const StackModeSwitch = (props: Props) => {
   const { value, onChange } = props;
-  const { verge } = useVerge();
-  const { enable_service_mode } = verge ?? {};
-  // service mode
-  const { data: serviceStatus, mutate: mutateCheck } = useSWR(
-    isWIN ? "checkService" : null,
-    checkService,
-    {
-      revalidateIfStale: false,
-      shouldRetryOnError: false,
-    }
-  );
-
-  const { t } = useTranslation();
-
-  useEffect(() => {
-    mutateCheck();
-  }, []);
 
   return (
-    <Tooltip
-      title={
-        isWIN && (serviceStatus !== "active" || !enable_service_mode)
-          ? t("System and Mixed Can Only be Used in Service Mode")
-          : ""
-      }
-    >
-      <ButtonGroup size="small" sx={{ my: "4px" }}>
-        <Button
-          variant={value?.toLowerCase() === "system" ? "contained" : "outlined"}
-          onClick={() => onChange?.("system")}
-          disabled={
-            isWIN && (serviceStatus !== "active" || !enable_service_mode)
-          }
-          sx={{ textTransform: "capitalize" }}
-        >
-          System
-        </Button>
-        <Button
-          variant={value?.toLowerCase() === "gvisor" ? "contained" : "outlined"}
-          onClick={() => onChange?.("gvisor")}
-          sx={{ textTransform: "capitalize" }}
-        >
-          gVisor
-        </Button>
+    <ButtonGroup size="small" sx={{ my: "4px" }}>
+      <Button
+        variant={value?.toLowerCase() === "system" ? "contained" : "outlined"}
+        onClick={() => onChange?.("system")}
+        sx={{ textTransform: "capitalize" }}
+      >
+        System
+      </Button>
+      <Button
+        variant={value?.toLowerCase() === "gvisor" ? "contained" : "outlined"}
+        onClick={() => onChange?.("gvisor")}
+        sx={{ textTransform: "capitalize" }}
+      >
+        gVisor
+      </Button>
 
-        <Button
-          variant={value?.toLowerCase() === "mixed" ? "contained" : "outlined"}
-          onClick={() => onChange?.("mixed")}
-          disabled={
-            isWIN && (serviceStatus !== "active" || !enable_service_mode)
-          }
-          sx={{ textTransform: "capitalize" }}
-        >
-          Mixed
-        </Button>
-      </ButtonGroup>
-    </Tooltip>
+      <Button
+        variant={value?.toLowerCase() === "mixed" ? "contained" : "outlined"}
+        onClick={() => onChange?.("mixed")}
+        sx={{ textTransform: "capitalize" }}
+      >
+        Mixed
+      </Button>
+    </ButtonGroup>
   );
 };

+ 14 - 7
src/components/setting/setting-system.tsx

@@ -22,11 +22,15 @@ const SettingSystem = ({ onError }: Props) => {
   const { verge, mutateVerge, patchVerge } = useVerge();
 
   // service mode
-  const { data: serviceStatus } = useSWR("checkService", checkService, {
-    revalidateIfStale: false,
-    shouldRetryOnError: false,
-    focusThrottleInterval: 36e5, // 1 hour
-  });
+  const { data: serviceStatus, mutate: mutateCheck } = useSWR(
+    "checkService",
+    checkService,
+    {
+      revalidateIfStale: false,
+      shouldRetryOnError: false,
+      focusThrottleInterval: 36e5, // 1 hour
+    }
+  );
 
   const serviceRef = useRef<DialogRef>(null);
   const sysproxyRef = useRef<DialogRef>(null);
@@ -84,7 +88,7 @@ const SettingSystem = ({ onError }: Props) => {
           onChange={(e) => onChangeData({ enable_tun_mode: e })}
           onGuard={(e) => patchVerge({ enable_tun_mode: e })}
         >
-          <Switch edge="end" />
+          <Switch disabled={serviceStatus !== "active"} edge="end" />
         </GuardState>
       </SettingItem>
 
@@ -109,7 +113,10 @@ const SettingSystem = ({ onError }: Props) => {
           onCatch={onError}
           onFormat={onSwitchFormat}
           onChange={(e) => onChangeData({ enable_service_mode: e })}
-          onGuard={(e) => patchVerge({ enable_service_mode: e })}
+          onGuard={(e) => {
+            setTimeout(() => mutateCheck(), 1000);
+            return patchVerge({ enable_service_mode: e });
+          }}
         >
           <Switch
             edge="end"