[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

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