diff --git a/assets/css/main.css b/assets/css/main.css index 213669e..1078c32 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -52,4 +52,8 @@ html.dark body { .el-table { font-size: 12px!important; +} + +.el-select-dropdown__wrap { + max-height: 150px!important; } \ No newline at end of file diff --git a/package.json b/package.json index 79aca5d..c2e7166 100644 --- a/package.json +++ b/package.json @@ -36,5 +36,8 @@ "prettier": "^3.4.1", "prettier-plugin-tailwindcss": "^0.6.9", "vue-clipboard3": "^2.0.0" + }, + "dependencies": { + "@tauri-apps/plugin-dialog": "~2" } } diff --git a/pages/index.vue b/pages/index.vue index 871a9ed..ef75603 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -1049,6 +1049,7 @@ mountedShow(); // 不需要await closePrevent(); data.hasNewVersion = await checkNewVersion(); + }); onBeforeUnmount(() => { diff --git a/pages/tool.vue b/pages/tool.vue index a019c20..140211d 100644 --- a/pages/tool.vue +++ b/pages/tool.vue @@ -8,7 +8,7 @@
@@ -23,7 +23,7 @@
- + 方案2
-
+
+
+ + ForceBindIP + +
+
+ + + + + + + +
+
+ + + + 刷新 +
+
+ +
+ + 浏览 + + + 启动 + +
+
+
+
+ +
+
+ + + 方案3 + + + +
+
-
+
@@ -176,6 +263,7 @@ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8f2e7f2..992f997 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,10 @@ settings: importers: .: + dependencies: + '@tauri-apps/plugin-dialog': + specifier: ~2 + version: 2.2.0 devDependencies: '@element-plus/icons-vue': specifier: ^2.3.1 @@ -1075,6 +1079,9 @@ packages: '@tauri-apps/plugin-clipboard-manager@2.0.0': resolution: {integrity: sha512-V1sXmbjnwfXt/r48RJMwfUmDMSaP/8/YbH4CLNxt+/sf1eHlIP8PRFdFDQwLN0cNQKu2rqQVbG/Wc/Ps6cDUhw==} + '@tauri-apps/plugin-dialog@2.2.0': + resolution: {integrity: sha512-6bLkYK68zyK31418AK5fNccCdVuRnNpbxquCl8IqgFByOgWFivbiIlvb79wpSXi0O+8k8RCSsIpOquebusRVSg==} + '@tauri-apps/plugin-fs@2.2.0': resolution: {integrity: sha512-+08mApuONKI8/sCNEZ6AR8vf5vI9DXD4YfrQ9NQmhRxYKMLVhRW164vdW5BSLmMpuevftpQ2FVoL9EFkfG9Z+g==} @@ -4985,6 +4992,10 @@ snapshots: dependencies: '@tauri-apps/api': 2.1.1 + '@tauri-apps/plugin-dialog@2.2.0': + dependencies: + '@tauri-apps/api': 2.1.1 + '@tauri-apps/plugin-fs@2.2.0': dependencies: '@tauri-apps/api': 2.1.1 diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 95ed117..b256fb5 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -183,6 +183,27 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +[[package]] +name = "ashpd" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d43c03d9e36dd40cab48435be0b09646da362c278223ca535493877b2c1dee9" +dependencies = [ + "enumflags2", + "futures-channel", + "futures-util", + "rand 0.8.5", + "raw-window-handle", + "serde", + "serde_repr", + "tokio", + "url", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "zbus", +] + [[package]] name = "async-broadcast" version = "0.7.1" @@ -1166,6 +1187,15 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading", +] + [[package]] name = "dlopen2" version = "0.7.0" @@ -1189,6 +1219,12 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + [[package]] name = "dpi" version = "0.1.1" @@ -1240,6 +1276,7 @@ dependencies = [ "tauri-build", "tauri-plugin-cli", "tauri-plugin-clipboard-manager", + "tauri-plugin-dialog", "tauri-plugin-fs", "tauri-plugin-log", "tauri-plugin-shell", @@ -2788,6 +2825,7 @@ checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ "bitflags 2.6.0", "block2", + "dispatch", "libc", "objc2", ] @@ -3248,7 +3286,7 @@ checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" dependencies = [ "base64 0.22.1", "indexmap 2.6.0", - "quick-xml", + "quick-xml 0.32.0", "serde", "time", ] @@ -3390,6 +3428,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "quick-xml" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.37" @@ -3615,6 +3662,29 @@ dependencies = [ "windows-registry", ] +[[package]] +name = "rfd" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8af382a047821a08aa6bfc09ab0d80ff48d45d8726f7cd8e44891f7cb4a4278e" +dependencies = [ + "ashpd", + "block2", + "glib-sys", + "gobject-sys", + "gtk-sys", + "js-sys", + "log", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "raw-window-handle", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-sys 0.48.0", +] + [[package]] name = "ring" version = "0.17.8" @@ -3793,6 +3863,12 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -4524,6 +4600,24 @@ dependencies = [ "thiserror 1.0.64", ] +[[package]] +name = "tauri-plugin-dialog" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b59fd750551b1066744ab956a1cd6b1ea3e1b3763b0b9153ac27a044d596426" +dependencies = [ + "log", + "raw-window-handle", + "rfd", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "tauri-plugin-fs", + "thiserror 2.0.3", + "url", +] + [[package]] name = "tauri-plugin-fs" version = "2.2.0" @@ -4854,6 +4948,7 @@ dependencies = [ "pin-project-lite", "signal-hook-registry", "socket2", + "tracing", "windows-sys 0.52.0", ] @@ -5324,6 +5419,66 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wayland-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" +dependencies = [ + "cc", + "downcast-rs", + "rustix", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280" +dependencies = [ + "bitflags 2.6.0", + "rustix", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols" +version = "0.32.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" +dependencies = [ + "proc-macro2", + "quick-xml 0.36.2", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" +dependencies = [ + "dlib", + "log", + "pkg-config", +] + [[package]] name = "web-sys" version = "0.3.70" @@ -5994,6 +6149,7 @@ dependencies = [ "serde_repr", "sha1", "static_assertions", + "tokio", "tracing", "uds_windows", "windows-sys 0.52.0", @@ -6150,6 +6306,7 @@ dependencies = [ "enumflags2", "serde", "static_assertions", + "url", "zvariant_derive", ] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index bbc17f6..806e9eb 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -42,13 +42,14 @@ tauri-plugin-fs = "2.2.0" tauri-plugin-clipboard-manager = "2.0.2" rand = "0.8.5" tokio = { version = "1.41.1", features = ["process"] } +tauri-plugin-dialog = "2" # prost = "0.13" # prost-types = "0.13" [dependencies.windows] version = "0.58.0" -features = ["Win32_System_TaskScheduler", "Win32_System_Power"] +features = ["Win32_System_TaskScheduler", "Win32_System_Power", "Win32_NetworkManagement_IpHelper", "Win32_NetworkManagement_Ndis", "Win32_Networking_WinSock"] [target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies] tauri-plugin-cli = "2.2.0" diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index f40c43e..3ae5ed3 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -1,104 +1,110 @@ { - "$schema": "../gen/schemas/desktop-schema.json", - "identifier": "default", - "description": "enables the default permissions", - "windows": [ - "main", - "log", - "member", - "cidr", - "advance", - "tool", - "server" - ], - "permissions": [ - "core:default", - "core:window:allow-minimize", - "core:window:allow-unminimize", - "core:window:allow-hide", - "core:window:allow-close", - "core:window:allow-set-focus", - "core:window:allow-is-visible", - "shell:allow-open", - "core:window:allow-show", - "core:window:allow-create", - "core:window:allow-set-position", - "core:window:allow-destroy", - "core:webview:allow-create-webview-window", - "core:webview:allow-set-webview-size", - "core:webview:allow-set-webview-position", - "core:webview:allow-create-webview", - "core:webview:allow-webview-show", - "core:webview:allow-webview-hide", - "core:webview:allow-webview-close", - "core:tray:allow-get-by-id", - "core:tray:allow-set-icon", - "core:tray:allow-new", - { - "identifier": "shell:allow-spawn", - "allow": [ - { - "args": [ - "run" - ], - "cmd": "$RESOURCE/easytier/tool/WinIPBroadcast", - "name": "WinIPBroadcast" - } - ] - }, - { - "identifier": "shell:allow-execute", - "allow": [ - { - "args": [ - "run" - ], - "cmd": "$RESOURCE/easytier/tool/WinIPBroadcast", - "name": "WinIPBroadcast" - }, - { - "args": true, - "cmd": "$RESOURCE/easytier/tool/nssm", - "name": "nssm" - }, - { - "args": true, - "cmd": "explorer", - "name": "explorer" - }, - { - "args": true, - "cmd": "netsh", - "name": "netsh" - }, - { - "args": true, - "cmd": "ping", - "name": "ping" - } - ] - }, - "fs:default", - "fs:allow-read-dir", - "fs:allow-exists", - "fs:allow-open", - "fs:allow-resource-read", - "fs:allow-resource-read-recursive", - "fs:allow-resource-write", - "fs:allow-resource-write-recursive", - "clipboard-manager:allow-clear", - "clipboard-manager:allow-read-text", - "clipboard-manager:allow-write-text", - - "window-state:default", - "window-state:allow-save-window-state", - "window-state:allow-restore-state", - - - "cli:default", - "cli:allow-cli-matches", - - "log:default", - "log:allow-log" - ] -} \ No newline at end of file + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "default", + "description": "enables the default permissions", + "windows": ["main", "log", "member", "cidr", "advance", "tool", "server"], + "permissions": [ + "core:default", + "core:window:allow-minimize", + "core:window:allow-unminimize", + "core:window:allow-hide", + "core:window:allow-close", + "core:window:allow-set-focus", + "core:window:allow-is-visible", + "shell:allow-open", + "core:window:allow-show", + "core:window:allow-create", + "core:window:allow-set-position", + "core:window:allow-destroy", + "core:webview:allow-create-webview-window", + "core:webview:allow-set-webview-size", + "core:webview:allow-set-webview-position", + "core:webview:allow-create-webview", + "core:webview:allow-webview-show", + "core:webview:allow-webview-hide", + "core:webview:allow-webview-close", + "core:tray:allow-get-by-id", + "core:tray:allow-set-icon", + "core:tray:allow-new", + { + "identifier": "shell:allow-spawn", + "allow": [ + { + "args": ["run"], + "cmd": "$RESOURCE/easytier/tool/WinIPBroadcast", + "name": "WinIPBroadcast" + }, + { + "args": true, + "cmd": "$RESOURCE/easytier/tool/ForceBindIP", + "name": "ForceBindIP" + }, + { + "args": true, + "cmd": "$RESOURCE/easytier/tool/ForceBindIP64", + "name": "ForceBindIP64" + } + ] + }, + { + "identifier": "shell:allow-execute", + "allow": [ + { + "args": ["run"], + "cmd": "$RESOURCE/easytier/tool/WinIPBroadcast", + "name": "WinIPBroadcast" + }, + { + "args": true, + "cmd": "$RESOURCE/easytier/tool/ForceBindIP", + "name": "ForceBindIP" + }, + { + "args": true, + "cmd": "$RESOURCE/easytier/tool/ForceBindIP64", + "name": "ForceBindIP64" + }, + { + "args": true, + "cmd": "$RESOURCE/easytier/tool/nssm", + "name": "nssm" + }, + { + "args": true, + "cmd": "explorer", + "name": "explorer" + }, + { + "args": true, + "cmd": "netsh", + "name": "netsh" + }, + { + "args": true, + "cmd": "ping", + "name": "ping" + } + ] + }, + "fs:default", + "fs:allow-read-dir", + "fs:allow-exists", + "fs:allow-open", + "fs:allow-resource-read", + "fs:allow-resource-read-recursive", + "fs:allow-resource-write", + "fs:allow-resource-write-recursive", + "clipboard-manager:allow-clear", + "clipboard-manager:allow-read-text", + "clipboard-manager:allow-write-text", + "window-state:default", + "window-state:allow-save-window-state", + "window-state:allow-restore-state", + "cli:default", + "cli:allow-cli-matches", + "log:default", + "log:allow-log", + "dialog:default", + "dialog:allow-open" + ] +} diff --git a/src-tauri/easytier/tool/BindIP.dll b/src-tauri/easytier/tool/BindIP.dll new file mode 100644 index 0000000..5755eb2 Binary files /dev/null and b/src-tauri/easytier/tool/BindIP.dll differ diff --git a/src-tauri/easytier/tool/BindIP64.dll b/src-tauri/easytier/tool/BindIP64.dll new file mode 100644 index 0000000..3469610 Binary files /dev/null and b/src-tauri/easytier/tool/BindIP64.dll differ diff --git a/src-tauri/easytier/tool/ForceBindIP.exe b/src-tauri/easytier/tool/ForceBindIP.exe new file mode 100644 index 0000000..14433c5 Binary files /dev/null and b/src-tauri/easytier/tool/ForceBindIP.exe differ diff --git a/src-tauri/easytier/tool/ForceBindIP64.exe b/src-tauri/easytier/tool/ForceBindIP64.exe new file mode 100644 index 0000000..66f52c9 Binary files /dev/null and b/src-tauri/easytier/tool/ForceBindIP64.exe differ diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 2167214..8d301a9 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -9,6 +9,7 @@ use std::fs::{self, File}; use std::io::{BufRead, BufReader, Write}; use std::os::windows::process::CommandExt; use std::process::{Command, Stdio}; +use std::ptr; use std::sync::mpsc; use std::{path, thread}; use sysinfo::System; @@ -17,16 +18,69 @@ use tauri::Emitter; use tauri::Manager; use windows::core::{BSTR, VARIANT}; use windows::Win32::Foundation::VARIANT_BOOL; +use windows::Win32::NetworkManagement::IpHelper::{ + GetAdaptersAddresses, GAA_FLAG_INCLUDE_PREFIX, IP_ADAPTER_ADDRESSES_LH, +}; +use windows::Win32::Networking::WinSock::AF_UNSPEC; use windows::Win32::System::Com::*; use windows::Win32::System::TaskScheduler::*; +// use std::ffi::CStr; use windows::Win32::System::Power::SetThreadExecutionState; use windows::Win32::System::Power::{ ES_CONTINUOUS, ES_DISPLAY_REQUIRED, ES_SYSTEM_REQUIRED, EXECUTION_STATE, }; -use tokio::process::Command as tokioCommand; use rand::Rng; +use tokio::process::Command as tokioCommand; + +#[tauri::command(rename_all = "snake_case")] +fn get_network_adapter_guids() -> Vec<[String; 2]> { + let mut guids: Vec<[String; 2]> = Vec::new(); + unsafe { + let mut buffer_length: u32 = 0; + let mut result = GetAdaptersAddresses( + AF_UNSPEC.0.into(), + GAA_FLAG_INCLUDE_PREFIX, + Some(ptr::null_mut()), + Some(ptr::null_mut()), + &mut buffer_length, + ); + + if result != 0 { + let mut buffer: Vec = vec![0; buffer_length as usize]; + let adapter_addresses: *mut IP_ADAPTER_ADDRESSES_LH = buffer.as_mut_ptr() as *mut _; + + result = GetAdaptersAddresses( + AF_UNSPEC.0.into(), + GAA_FLAG_INCLUDE_PREFIX, + Some(ptr::null_mut()), + Some(adapter_addresses), + &mut buffer_length, + ); + + if result == 0 { + let mut current_address = adapter_addresses; + + while !current_address.is_null() { + let adapter = &*current_address; + + let guid = adapter.AdapterName.to_string().unwrap(); + let desc = adapter.Description.to_string().unwrap(); + guids.push([guid, desc]); + + current_address = adapter.Next; + } + } else { + log::error!("GetAdaptersAddresses failed with error"); + } + } else { + log::error!("GetAdaptersAddresses failed to retrieve buffer length with error"); + } + } + + return guids; +} fn generate_random_user_agent() -> String { let user_agents = vec![ @@ -664,6 +718,7 @@ pub fn run() { let context = tauri::generate_context!(); tauri::Builder::default() + .plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_cli::init()) .plugin( tauri_plugin_window_state::Builder::new() @@ -740,7 +795,8 @@ pub fn run() { spawn_autostart, autostart_is_enabled, prevent_sleep, - allow_sleep + allow_sleep, + get_network_adapter_guids ]) .run(context) .expect("error while running tauri application"); diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index e89c3d6..6790746 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -53,6 +53,10 @@ "easytier/icons/", "easytier/config_template.json", "easytier/tool/WinIPBroadcast.exe", + "easytier/tool/ForceBindIP.exe", + "easytier/tool/ForceBindIP64.exe", + "easytier/tool/BindIP.dll", + "easytier/tool/BindIP64.dll", "easytier/tool/MicrosoftEdgeWebview2Setup.exe", "easytier/easytier-cli.exe", "easytier/easytier-core.exe", diff --git a/stores/index.ts b/stores/index.ts index 468d8d1..b45d0e6 100644 --- a/stores/index.ts +++ b/stores/index.ts @@ -57,6 +57,12 @@ const store = defineStore("main", { createConfigInEasytier: false, //在easytier目录生成config.json文件吗 githubFastUrl: "https://ghproxy.cc/", + // forceBindIp配置 + forceBindIpBit: "64", + delayInjectDll: false, + forceBindInput: "", + forceBindFile: "", + winipBcPid: 0, winipBcStart: false }; @@ -117,7 +123,12 @@ const store = defineStore("main", { "configPath", "winIpBcAutoStart", "createConfigInEasytier", - "githubFastUrl" + "githubFastUrl", + + "forceBindIpBit", + "delayInjectDll", + "forceBindInput", + "forceBindFile" ] // // 除了这些,其他都要存下来 // omit: ["winipBcPid", "winipBcStart"]