[feat] listen to steam user changes
This commit is contained in:
162
src-tauri/Cargo.lock
generated
162
src-tauri/Cargo.lock
generated
@@ -10,6 +10,7 @@ dependencies = [
|
||||
"base64 0.22.1",
|
||||
"futures-util",
|
||||
"log",
|
||||
"notify",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"serde",
|
||||
@@ -1288,6 +1289,18 @@ dependencies = [
|
||||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"libredox",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.4"
|
||||
@@ -1367,6 +1380,15 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fsevent-sys"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futf"
|
||||
version = "0.1.5"
|
||||
@@ -2204,6 +2226,26 @@ dependencies = [
|
||||
"cfb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"inotify-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify-sys"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.11.0"
|
||||
@@ -2348,6 +2390,26 @@ dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kqueue"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a"
|
||||
dependencies = [
|
||||
"kqueue-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kqueue-sys"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kuchikiki"
|
||||
version = "0.8.8-speedreader"
|
||||
@@ -2430,6 +2492,7 @@ checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2572,6 +2635,18 @@ dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi 0.11.1+wasi-snapshot-preview1",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.1.0"
|
||||
@@ -2708,6 +2783,25 @@ dependencies = [
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "6.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"crossbeam-channel",
|
||||
"filetime",
|
||||
"fsevent-sys",
|
||||
"inotify",
|
||||
"kqueue",
|
||||
"libc",
|
||||
"log",
|
||||
"mio 0.8.11",
|
||||
"walkdir",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify-rust"
|
||||
version = "4.11.7"
|
||||
@@ -5450,7 +5544,7 @@ checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"mio 1.1.0",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
@@ -6433,6 +6527,15 @@ dependencies = [
|
||||
"windows-targets 0.42.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
@@ -6484,6 +6587,21 @@ dependencies = [
|
||||
"windows_x86_64_msvc 0.42.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
@@ -6541,6 +6659,12 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
@@ -6559,6 +6683,12 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
@@ -6577,6 +6707,12 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
@@ -6607,6 +6743,12 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
@@ -6625,6 +6767,12 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
@@ -6643,6 +6791,12 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
@@ -6661,6 +6815,12 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
|
||||
@@ -52,6 +52,7 @@ tauri-plugin-autostart = "2.5.1"
|
||||
tauri-plugin-single-instance = { version = "2.3.6", features = ["deep-link"] }
|
||||
tauri-plugin-deep-link = "2.4.5"
|
||||
anyhow = "1.0.100"
|
||||
notify = "6.1.1"
|
||||
[target.'cfg(windows)'.dependencies] # Windows Only
|
||||
winreg = "0.55.0"
|
||||
|
||||
|
||||
@@ -106,6 +106,11 @@ pub fn set_auto_login_user(user: &str) -> Result<String, String> {
|
||||
Ok(format!("Set auto login user to {}", user))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn start_watch_loginusers(app: tauri::AppHandle, steam_dir: String) -> Result<(), String> {
|
||||
wrap_err!(steam::watch::start_watch_loginusers(app, steam_dir))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_cs2_video_config(steam_dir: &str, steam_id32: u32) -> Result<VideoConfig, String> {
|
||||
let p = format!(
|
||||
|
||||
@@ -129,6 +129,7 @@ fn main() {
|
||||
cmds::set_powerplan,
|
||||
cmds::get_steam_users,
|
||||
cmds::set_auto_login_user,
|
||||
cmds::start_watch_loginusers,
|
||||
cmds::get_cs2_video_config,
|
||||
cmds::set_cs2_video_config,
|
||||
cmds::check_path,
|
||||
|
||||
@@ -3,6 +3,7 @@ pub mod id;
|
||||
pub mod path;
|
||||
pub mod reg;
|
||||
pub mod user;
|
||||
pub mod watch;
|
||||
|
||||
// common steam utils
|
||||
use anyhow::Result;
|
||||
|
||||
76
src-tauri/src/steam/watch.rs
Normal file
76
src-tauri/src/steam/watch.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use anyhow::Result;
|
||||
use notify::{Config, Event, EventKind, RecommendedWatcher, RecursiveMode, Watcher};
|
||||
use std::path::Path;
|
||||
use std::sync::{Mutex, OnceLock};
|
||||
use tauri::{AppHandle, Emitter};
|
||||
|
||||
// 全局 watcher 存储,用于管理文件监听器的生命周期
|
||||
static WATCHER: OnceLock<Mutex<Option<RecommendedWatcher>>> = OnceLock::new();
|
||||
|
||||
/// 启动监听 loginusers.vdf 文件的变化
|
||||
pub fn start_watch_loginusers(app: AppHandle, steam_dir: String) -> Result<()> {
|
||||
// 停止之前的监听
|
||||
stop_watch_loginusers();
|
||||
|
||||
let loginusers_path = Path::new(&steam_dir).join("config/loginusers.vdf");
|
||||
let config_dir = Path::new(&steam_dir).join("config");
|
||||
|
||||
// 如果 config 目录不存在,不进行监听
|
||||
if !config_dir.exists() {
|
||||
log::warn!("config 目录不存在,跳过监听: {:?}", config_dir);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let app_clone = app.clone();
|
||||
|
||||
let mut watcher = RecommendedWatcher::new(
|
||||
move |result: Result<Event, notify::Error>| {
|
||||
match result {
|
||||
Ok(event) => {
|
||||
// 检查是否是 loginusers.vdf 文件的变化
|
||||
if let EventKind::Modify(_) | EventKind::Create(_) = event.kind {
|
||||
for path in &event.paths {
|
||||
if path.ends_with("loginusers.vdf") {
|
||||
log::info!("检测到 loginusers.vdf 文件变化: {:?}", path);
|
||||
// 延迟一小段时间,确保文件写入完成
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
// 发送事件到前端
|
||||
if let Err(e) = app_clone.emit("steam://loginusers_changed", ()) {
|
||||
log::error!("发送 loginusers 变化事件失败: {}", e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("文件监听错误: {}", e);
|
||||
}
|
||||
}
|
||||
},
|
||||
Config::default(),
|
||||
)?;
|
||||
|
||||
// 监听 config 目录(而不是单个文件),因为某些文件系统可能不会直接监听单个文件
|
||||
watcher.watch(&config_dir, RecursiveMode::NonRecursive)?;
|
||||
log::info!("开始监听 loginusers.vdf 文件: {:?}", loginusers_path);
|
||||
|
||||
// 保存 watcher 到全局变量
|
||||
let watcher_store = WATCHER.get_or_init(|| Mutex::new(None));
|
||||
*watcher_store.lock().unwrap() = Some(watcher);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 停止监听 loginusers.vdf 文件
|
||||
pub fn stop_watch_loginusers() {
|
||||
if let Some(watcher_store) = WATCHER.get() {
|
||||
if let Ok(mut watcher_guard) = watcher_store.lock() {
|
||||
if let Some(watcher) = watcher_guard.take() {
|
||||
drop(watcher);
|
||||
log::info!("已停止监听 loginusers.vdf 文件");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { toolStore, useToolStore } from "@/store/tool"
|
||||
import { addToast } from "@heroui/react"
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
import { listen } from "@tauri-apps/api/event"
|
||||
import { useDebounce } from "ahooks"
|
||||
import { useDebounce, useThrottleFn } from "ahooks"
|
||||
import { useEffect } from "react"
|
||||
import "./globals.css"
|
||||
import Providers from "./providers"
|
||||
@@ -75,8 +75,35 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
||||
useEffect(() => {
|
||||
if (debounceSteamDirValid) {
|
||||
void steam.getUsers()
|
||||
// 启动文件监听
|
||||
void invoke("start_watch_loginusers", { steamDir: steam.state.steamDir })
|
||||
}
|
||||
}, [debounceSteamDirValid])
|
||||
}, [debounceSteamDirValid, steam.state.steamDir])
|
||||
|
||||
// 节流获取用户列表函数,3秒间隔,trailing模式
|
||||
const { run: throttledGetUsers } = useThrottleFn(
|
||||
async () => {
|
||||
if (steam.state.steamDirValid) {
|
||||
await steam.getUsers()
|
||||
}
|
||||
},
|
||||
{
|
||||
wait: 3000,
|
||||
leading: false,
|
||||
trailing: true,
|
||||
}
|
||||
)
|
||||
|
||||
// 监听 loginusers.vdf 文件变化事件
|
||||
useEffect(() => {
|
||||
const unlisten = listen("steam://loginusers_changed", async () => {
|
||||
// 文件变化时使用节流函数重新获取用户列表
|
||||
throttledGetUsers()
|
||||
})
|
||||
return () => {
|
||||
void unlisten.then((fn) => fn())
|
||||
}
|
||||
}, [steam.state.steamDirValid, throttledGetUsers])
|
||||
|
||||
return (
|
||||
<html lang="en">
|
||||
|
||||
Reference in New Issue
Block a user