[feat] listen to steam user changes

This commit is contained in:
2025-11-05 11:32:43 +08:00
parent 6710fe1754
commit c19adcc3f8
7 changed files with 274 additions and 3 deletions

162
src-tauri/Cargo.lock generated
View File

@@ -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"

View File

@@ -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"

View File

@@ -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!(

View File

@@ -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,

View File

@@ -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;

View 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 文件");
}
}
}
}