From afa7355f4d9489e7d6833fe289830257cc319271 Mon Sep 17 00:00:00 2001 From: purp1e Date: Thu, 27 Mar 2025 11:30:03 +0800 Subject: [PATCH] testing video parse --- .gitignore | 5 +- src-tauri/gen/schemas/macOS-schema.json | 15 +++ src-tauri/src/cmds.rs | 2 +- src-tauri/src/tool/common.rs | 19 +++- src-tauri/src/tool/powerplan.rs | 17 ++++ src-tauri/src/vdf/parse.rs | 122 ++++++++++++++++++------ src-tauri/src/vdf/preset.rs | 63 ++++++++++++ 7 files changed, 211 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index df9ac71..b913fe1 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,7 @@ yarn-error.log* *.tsbuildinfo .env -.env.* \ No newline at end of file +.env.* + +temp/ +log/ \ No newline at end of file diff --git a/src-tauri/gen/schemas/macOS-schema.json b/src-tauri/gen/schemas/macOS-schema.json index 5d1e84d..5a259ba 100644 --- a/src-tauri/gen/schemas/macOS-schema.json +++ b/src-tauri/gen/schemas/macOS-schema.json @@ -2039,6 +2039,21 @@ "type": "string", "const": "autostart:deny-is-enabled" }, + { + "description": "Allows reading the CLI matches", + "type": "string", + "const": "cli:default" + }, + { + "description": "Enables the cli_matches command without any pre-configured scope.", + "type": "string", + "const": "cli:allow-cli-matches" + }, + { + "description": "Denies the cli_matches command without any pre-configured scope.", + "type": "string", + "const": "cli:deny-cli-matches" + }, { "description": "No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n", "type": "string", diff --git a/src-tauri/src/cmds.rs b/src-tauri/src/cmds.rs index 45d4dd9..454540e 100644 --- a/src-tauri/src/cmds.rs +++ b/src-tauri/src/cmds.rs @@ -55,7 +55,7 @@ pub fn get_powerplan() -> Result { let powerplan = powerplan::get_powerplan()?; #[cfg(not(target_os = "windows"))] - let powerplan = powerplan::PowerPlanMode::Other.into(); + let powerplan = powerplan::PowerPlanMode::Other as i32; Ok(powerplan) } diff --git a/src-tauri/src/tool/common.rs b/src-tauri/src/tool/common.rs index 0427f1c..86b26ec 100644 --- a/src-tauri/src/tool/common.rs +++ b/src-tauri/src/tool/common.rs @@ -1,10 +1,12 @@ -use std::os::windows::process::CommandExt; use std::process::Command; +#[cfg(windows)] +use std::os::windows::process::CommandExt; const CREATE_NO_WINDOW: u32 = 0x08000000; // const DETACHED_PROCESS: u32 = 0x00000008; pub fn kill(name: &str) -> String { + #[cfg(windows)] Command::new("taskkill") .args(&["/IM", name, "/F"]) .creation_flags(CREATE_NO_WINDOW) @@ -15,10 +17,16 @@ pub fn kill(name: &str) -> String { } pub fn run_steam() -> std::io::Result { + #[cfg(target_os = "windows")] Command::new("cmd") .args(&["/C", "start", "steam://run"]) .creation_flags(CREATE_NO_WINDOW) - .output() + .output(); + + #[cfg(target_os = "macos")] + Command::new("open") + .args(&["-a", "Steam"]) + .output() } pub fn get_exe_path(name: &str) -> Result { @@ -30,11 +38,17 @@ pub fn get_exe_path(name: &str) -> Result { // 进程路径 let command = format!("Get-Process {} | Select-Object path", name); let args = command.split_whitespace().collect::>(); + #[cfg(windows)] let output = Command::new("powershell.exe") .args(&args) .creation_flags(CREATE_NO_WINDOW) .output()?; + #[cfg(target_os = "macos")] + let output = Command::new("osascript") + .args(&["-e", &format!("tell application \"{}\" to get path to me", name)]) + .output()?; + let out = String::from_utf8_lossy(&output.stdout).to_string(); if out.contains("Path") { @@ -54,6 +68,7 @@ pub fn get_exe_path(name: &str) -> Result { pub fn open_path(path: &str) -> Result<(), std::io::Error> { // path中所有/ 转换为 \ let path = path.replace("/", "\\"); + #[cfg(windows)] Command::new("cmd.exe") .args(["/c", "start", "", &path]) .creation_flags(CREATE_NO_WINDOW) diff --git a/src-tauri/src/tool/powerplan.rs b/src-tauri/src/tool/powerplan.rs index 36bc362..c6c8395 100644 --- a/src-tauri/src/tool/powerplan.rs +++ b/src-tauri/src/tool/powerplan.rs @@ -39,6 +39,7 @@ impl PowerPlan { .get(&mode) .ok_or("Invalid power plan number (expect from 1 to 4)")?; + #[cfg(target_os = "windows")] let output = Command::new("powercfg") .arg("/S") .arg(guid) @@ -46,6 +47,14 @@ impl PowerPlan { .output() .map_err(|e| format!("Failed to execute powercfg command: {}", e))?; + #[cfg(target_os = "macos")] + let output = Command::new("pmset") + .arg("-g") + .arg("plan") + .output() + .map_err(|e| format!("Failed to execute pmset command: {}", e))?; + + if !output.status.success() { return Err(format!( "Powercfg command failed: {}", @@ -57,12 +66,20 @@ impl PowerPlan { } pub fn get(&self) -> Result { + #[cfg(windows)] let output = Command::new("powercfg") .arg("/L") .creation_flags(CREATE_NO_WINDOW) .output() .map_err(|e| format!("Failed to execute powercfg command: {}", e))?; + #[cfg(target_os = "macos")] + let output = Command::new("pmset") + .arg("-g") + .arg("plan") + .output() + .map_err(|e| format!("Failed to execute pmset command: {}", e))?; + let output_str = String::from_utf8_lossy(&output.stdout); let re = regex::Regex::new(r"GUID:\s+(\S+)\s+\(\S+\)\s+\*") .map_err(|e| format!("Failed to compile regex: {}", e))?; diff --git a/src-tauri/src/vdf/parse.rs b/src-tauri/src/vdf/parse.rs index 35c994e..c95f805 100644 --- a/src-tauri/src/vdf/parse.rs +++ b/src-tauri/src/vdf/parse.rs @@ -40,40 +40,98 @@ pub fn to_json(vdf_data: &str) -> String { json_data } +pub fn to_vdf(json_data: &str) -> String { + let json_value: serde_json::Value = serde_json::from_str(json_data).unwrap(); + let mut vdf_data = String::new(); + build_vdf(&json_value, &mut vdf_data, 0); + vdf_data +} + +fn build_vdf(json_value: &serde_json::Value, vdf_data: &mut String, indent_level: usize) { + match json_value { + serde_json::Value::Object(obj) => { + for (key, value) in obj { + vdf_data.push_str(&"\t".repeat(indent_level)); + vdf_data.push_str(&format!("\"{}\"\n", key)); + vdf_data.push_str(&"\t".repeat(indent_level)); + vdf_data.push_str("{\n"); + build_vdf(value, vdf_data, indent_level + 1); + vdf_data.push_str(&"\t".repeat(indent_level)); + vdf_data.push_str("}\n"); + } + } + serde_json::Value::String(s) => { + vdf_data.push_str(&"\t".repeat(indent_level)); + vdf_data.push_str(&format!("\"{}\"\t\t\"{}\"\n", s, s)); + } + _ => { + vdf_data.push_str(&"\t".repeat(indent_level)); + vdf_data.push_str(&format!("\"{}\"\t\t\"{}\"\n", json_value, json_value)); + } + } +} + mod tests { use super::*; + static VDF_DATA: &str = r#"\"users\" + { + \"76561198315078806\" + { + \"AccountName\" \"_jerry_dota2\" + \"PersonaName\" \"Rop紫(已黑化)\" + \"RememberPassword\" \"1\" + \"WantsOfflineMode\" \"0\" + \"SkipOfflineModeWarning\" \"0\" + \"AllowAutoLogin\" \"1\" + \"MostRecent\" \"1\" + \"Timestamp\" \"1742706884\" + } + \"76561198107125441\" + { + \"AccountName\" \"_im_ai_\" + \"PersonaName\" \"Buongiorno\" + \"RememberPassword\" \"1\" + \"WantsOfflineMode\" \"0\" + \"SkipOfflineModeWarning\" \"0\" + \"AllowAutoLogin\" \"1\" + \"MostRecent\" \"0\" + \"Timestamp\" \"1739093763\" + } + } + "#; + + static JSON_DATA: &str = r#"{ + "users": { + "76561198315078806": { + "AccountName": "_jerry_dota2", + "PersonaName": "Rop紫(已黑化)", + "RememberPassword": "1", + "WantsOfflineMode": "0", + "SkipOfflineModeWarning": "0", + "AllowAutoLogin": "1", + "MostRecent": "1", + "Timestamp": "1742706884" + }, + "76561198107125441": { + "AccountName": "_im_ai_", + "PersonaName": "Buongiorno", + "RememberPassword": "1", + "WantsOfflineMode": "0", + "SkipOfflineModeWarning": "0", + "AllowAutoLogin": "1", + "MostRecent": "0", + "Timestamp": "1739093763" + } + } + }"#; + + #[test] fn test_to_json() { - let vdf_data = "\"users\" - { - \"76561198315078806\" - { - \"AccountName\" \"_jerry_dota2\" - \"PersonaName\" \"Rop紫(已黑化)\" - \"RememberPassword\" \"1\" - \"WantsOfflineMode\" \"0\" - \"SkipOfflineModeWarning\" \"0\" - \"AllowAutoLogin\" \"1\" - \"MostRecent\" \"1\" - \"Timestamp\" \"1742706884\" - } - \"76561198107125441\" - { - \"AccountName\" \"_im_ai_\" - \"PersonaName\" \"Buongiorno\" - \"RememberPassword\" \"1\" - \"WantsOfflineMode\" \"0\" - \"SkipOfflineModeWarning\" \"0\" - \"AllowAutoLogin\" \"1\" - \"MostRecent\" \"0\" - \"Timestamp\" \"1739093763\" - } - } -"; - // let expected_json = r#"{"key1": "value1","key2": "value2","subkey": {"key3": "value3"}}"#; - let json_data = to_json(vdf_data); + let json_data = to_json(VDF_DATA); + println!("{}", json_data); // 解析json let json_value: serde_json::Value = serde_json::from_str(&json_data).unwrap(); @@ -81,4 +139,12 @@ mod tests { println!("{}", json_value) // assert_eq!(to_json(vdf_data), expected_json); } + + #[test] + fn test_to_vdf() { + // let json_data = r#"{"key1": "value1","key2": "value2","subkey": {"key3": "value3"}}"#; + let vdf_data = to_vdf(JSON_DATA); + + println!("{}", vdf_data); + } } diff --git a/src-tauri/src/vdf/preset.rs b/src-tauri/src/vdf/preset.rs index 37e9932..88b3590 100644 --- a/src-tauri/src/vdf/preset.rs +++ b/src-tauri/src/vdf/preset.rs @@ -44,6 +44,42 @@ pub struct LocalUser { avatar_key: String, } +#[derive(Serialize, Deserialize, Debug)] +pub struct VideoConfig { + version: String, + vendor_id: String, + device_id: String, + setting_cpu_level: String, + setting_gpu_mem_level: String, + setting_gpu_level: String, + setting_knowndevice: String, + setting_defaultres: String, + setting_defaultresheight: String, + setting_refreshrate_numerator: String, + setting_refreshrate_denominator: String, + setting_fullscreen: String, + setting_coop_fullscreen: String, + setting_nowindowborder: String, + setting_mat_vsync: String, + setting_fullscreen_min_on_focus_loss: String, + setting_high_dpi: String, + auto_config: String, + setting_shaderquality: String, + setting_r_texturefilteringquality: String, + setting_msaa_samples: String, + setting_r_csgo_cmaa_enable: String, + setting_videocfg_shadow_quality: String, + setting_videocfg_dynamic_shadows: String, + setting_videocfg_texture_detail: String, + setting_videocfg_particle_detail: String, + setting_videocfg_ao_detail: String, + setting_videocfg_hdr_detail: String, + setting_videocfg_fsr_detail: String, + setting_monitor_index: String, + setting_r_low_latency: String, + setting_aspectratiomode: String, +} + pub fn parse_login_users(steam_dir: &str) -> Result> { let t_path = Path::new(steam_dir).join("config/loginusers.vdf"); if !t_path.exists() { @@ -270,6 +306,20 @@ fn read_avatar(steam_dir: &str, steam_id64: &str) -> Option { } } +pub fn get_cs2_video(file_path: &str) -> Result> { + let data = fs::read_to_string(file_path)?; + let json_data = super::parse::to_json(&data); + let kv: HashMap = serde_json::from_str(&json_data)?; + Ok(kv) +} + +pub fn set_cs2_video(file_path: &str, data: HashMap) -> Result<()> { + let json_data = serde_json::to_string(&data)?; + let vdf_data = super::parse::to_vdf(&json_data); + fs::write(file_path, vdf_data)?; + Ok(()) +} + #[cfg(test)] mod tests { use super::*; @@ -279,4 +329,17 @@ mod tests { let users = get_users("D:\\Programs\\Steam").unwrap(); println!("{:?}", users); } + + #[test] + fn test_get_cs2_video() { + let video_config = get_cs2_video("src-tauri/src/vdf/tests/cs2_video.txt").unwrap(); + println!("{:?}", video_config); + } + + #[test] + fn test_set_cs2_video() { + let mut video_config = HashMap::new(); + video_config.insert("setting.fullscreen".to_string(), "0".to_string()); + set_cs2_video("temp/cs2_video.txt", video_config).unwrap(); + } }