From afa7355f4d9489e7d6833fe289830257cc319271 Mon Sep 17 00:00:00 2001 From: purp1e Date: Thu, 27 Mar 2025 11:30:03 +0800 Subject: [PATCH 01/10] 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(); + } } -- 2.49.1 From 93cda8dc85b854a2a266e102b98447c798ac7ea6 Mon Sep 17 00:00:00 2001 From: Purp1e <47248616+Purple-CSGO@users.noreply.github.com> Date: Thu, 27 Mar 2025 13:32:30 +0800 Subject: [PATCH 02/10] [feat] read video config is ok --- .gitignore | 1 + src-tauri/.gitignore | 2 +- src-tauri/src/cmds.rs | 26 ++ src-tauri/src/main.rs | 2 + src-tauri/src/tool/common.rs | 2 +- src-tauri/src/vdf/parse.rs | 80 +++--- src-tauri/src/vdf/preset.rs | 334 ++++++++++++++++++++++--- src/components/cstb/VideoSetting.tsx | 356 ++++++++++++++++++--------- src/store/tool.ts | 90 +++++-- 9 files changed, 675 insertions(+), 218 deletions(-) diff --git a/.gitignore b/.gitignore index b913fe1..45fe8c3 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,5 @@ yarn-error.log* .env.* temp/ +src-tauri/temp/ log/ \ No newline at end of file diff --git a/src-tauri/.gitignore b/src-tauri/.gitignore index fd29446..f8248e3 100644 --- a/src-tauri/.gitignore +++ b/src-tauri/.gitignore @@ -1,3 +1,3 @@ # Generated by Cargo # will have compiled files and executables -/target/ +/target/ \ No newline at end of file diff --git a/src-tauri/src/cmds.rs b/src-tauri/src/cmds.rs index 454540e..8264f72 100644 --- a/src-tauri/src/cmds.rs +++ b/src-tauri/src/cmds.rs @@ -1,6 +1,7 @@ use crate::steam; use crate::tool::*; use crate::vdf::preset; +use crate::vdf::preset::VideoConfig; use crate::wrap_err; use anyhow::Result; @@ -81,6 +82,31 @@ pub fn set_auto_login_user(user: &str) -> Result { Ok(format!("Set auto login user to {}", user)) } +#[tauri::command] +pub fn get_cs2_video_config(steam_dir: &str, steam_id32: u32) -> Result { + let p = format!( + "{}/userdata/{}/730/local/cfg/cs2_video.txt", + steam_dir, steam_id32 + ); + let video = preset::get_cs2_video(p.as_str()).map_err(|e| e.to_string())?; + Ok(video) +} + +#[tauri::command] +pub fn set_cs2_video_config( + steam_dir: &str, + steam_id32: u32, + video_config: VideoConfig, +) -> Result<(), String> { + let p = format!( + "{}/userdata/{}/730/local/cfg/cs2_video.txt", + steam_dir, steam_id32 + ); + preset::set_cs2_video(p.as_str(), video_config).map_err(|e| e.to_string())?; + + Ok(()) +} + #[tauri::command] pub fn check_path(path: &str) -> Result { Ok(std::path::Path::new(&path).exists()) diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index b66574f..55a64ec 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -129,6 +129,8 @@ fn main() { cmds::set_powerplan, cmds::get_steam_users, cmds::set_auto_login_user, + cmds::get_cs2_video_config, + cmds::set_cs2_video_config, cmds::check_path, on_button_clicked ]) diff --git a/src-tauri/src/tool/common.rs b/src-tauri/src/tool/common.rs index 86b26ec..8b7d142 100644 --- a/src-tauri/src/tool/common.rs +++ b/src-tauri/src/tool/common.rs @@ -18,7 +18,7 @@ pub fn kill(name: &str) -> String { pub fn run_steam() -> std::io::Result { #[cfg(target_os = "windows")] - Command::new("cmd") + return Command::new("cmd") .args(&["/C", "start", "steam://run"]) .creation_flags(CREATE_NO_WINDOW) .output(); diff --git a/src-tauri/src/vdf/parse.rs b/src-tauri/src/vdf/parse.rs index c95f805..4e2c584 100644 --- a/src-tauri/src/vdf/parse.rs +++ b/src-tauri/src/vdf/parse.rs @@ -48,55 +48,55 @@ pub fn to_vdf(json_data: &str) -> String { } 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)); - } - } + 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\" + static VDF_DATA: &str = r#""users" { - \"76561198315078806\" + "76561198315078806" { - \"AccountName\" \"_jerry_dota2\" - \"PersonaName\" \"Rop紫(已黑化)\" - \"RememberPassword\" \"1\" - \"WantsOfflineMode\" \"0\" - \"SkipOfflineModeWarning\" \"0\" - \"AllowAutoLogin\" \"1\" - \"MostRecent\" \"1\" - \"Timestamp\" \"1742706884\" + "AccountName" "_jerry_dota2" + "PersonaName" "Rop紫(已黑化)" + "RememberPassword" "1" + "WantsOfflineMode" "0" + "SkipOfflineModeWarning" "0" + "AllowAutoLogin" "1" + "MostRecent" "1" + "Timestamp" "1742706884" } - \"76561198107125441\" + "76561198107125441" { - \"AccountName\" \"_im_ai_\" - \"PersonaName\" \"Buongiorno\" - \"RememberPassword\" \"1\" - \"WantsOfflineMode\" \"0\" - \"SkipOfflineModeWarning\" \"0\" - \"AllowAutoLogin\" \"1\" - \"MostRecent\" \"0\" - \"Timestamp\" \"1739093763\" + "AccountName" "_im_ai_" + "PersonaName" "Buongiorno" + "RememberPassword" "1" + "WantsOfflineMode" "0" + "SkipOfflineModeWarning" "0" + "AllowAutoLogin" "1" + "MostRecent" "0" + "Timestamp" "1739093763" } } "#; diff --git a/src-tauri/src/vdf/preset.rs b/src-tauri/src/vdf/preset.rs index 88b3590..9652d56 100644 --- a/src-tauri/src/vdf/preset.rs +++ b/src-tauri/src/vdf/preset.rs @@ -49,35 +49,74 @@ 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, + cpu_level: String, + gpu_mem_level: String, + gpu_level: String, + knowndevice: String, + defaultres: String, + defaultresheight: String, + refreshrate_numerator: String, + refreshrate_denominator: String, + fullscreen: String, + coop_fullscreen: String, + nowindowborder: String, + mat_vsync: String, + fullscreen_min_on_focus_loss: String, + 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, + shaderquality: String, + r_texturefilteringquality: String, + msaa_samples: String, + r_csgo_cmaa_enable: String, + videocfg_shadow_quality: String, + videocfg_dynamic_shadows: String, + videocfg_texture_detail: String, + videocfg_particle_detail: String, + videocfg_ao_detail: String, + videocfg_hdr_detail: String, + videocfg_fsr_detail: String, + monitor_index: String, + r_low_latency: String, + aspectratiomode: String, +} + +impl Default for VideoConfig { + fn default() -> Self { + VideoConfig { + version: String::new(), + vendor_id: String::new(), + device_id: String::new(), + cpu_level: String::new(), + gpu_mem_level: String::new(), + gpu_level: String::new(), + knowndevice: String::new(), + defaultres: String::new(), + defaultresheight: String::new(), + refreshrate_numerator: String::new(), + refreshrate_denominator: String::new(), + fullscreen: String::new(), + coop_fullscreen: String::new(), + nowindowborder: String::new(), + mat_vsync: String::new(), + fullscreen_min_on_focus_loss: String::new(), + high_dpi: String::new(), + auto_config: String::new(), + shaderquality: String::new(), + r_texturefilteringquality: String::new(), + msaa_samples: String::new(), + r_csgo_cmaa_enable: String::new(), + videocfg_shadow_quality: String::new(), + videocfg_dynamic_shadows: String::new(), + videocfg_texture_detail: String::new(), + videocfg_particle_detail: String::new(), + videocfg_ao_detail: String::new(), + videocfg_hdr_detail: String::new(), + videocfg_fsr_detail: String::new(), + monitor_index: String::new(), + r_low_latency: String::new(), + aspectratiomode: String::new(), + } + } } pub fn parse_login_users(steam_dir: &str) -> Result> { @@ -306,16 +345,234 @@ 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)?; +pub fn get_cs2_video(file_path: &str) -> Result { + // TODO: no kv + 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) + let video_config = VideoConfig { + version: kv.get("version").unwrap_or(&"".to_string()).to_string(), + vendor_id: kv.get("vendor_id").unwrap_or(&"".to_string()).to_string(), + device_id: kv.get("device_id").unwrap_or(&"".to_string()).to_string(), + cpu_level: kv + .get("setting.cpu_level") + .unwrap_or(&"".to_string()) + .to_string(), + gpu_mem_level: kv + .get("setting.gpu_mem_level") + .unwrap_or(&"".to_string()) + .to_string(), + gpu_level: kv + .get("setting.gpu_level") + .unwrap_or(&"".to_string()) + .to_string(), + knowndevice: kv + .get("setting.knowndevice") + .unwrap_or(&"".to_string()) + .to_string(), + defaultres: kv + .get("setting.defaultres") + .unwrap_or(&"".to_string()) + .to_string(), + defaultresheight: kv + .get("setting.defaultresheight") + .unwrap_or(&"".to_string()) + .to_string(), + refreshrate_numerator: kv + .get("setting.refreshrate_numerator") + .unwrap_or(&"".to_string()) + .to_string(), + refreshrate_denominator: kv + .get("setting.refreshrate_denominator") + .unwrap_or(&"".to_string()) + .to_string(), + fullscreen: kv + .get("setting.fullscreen") + .unwrap_or(&"".to_string()) + .to_string(), + coop_fullscreen: kv + .get("setting.coop_fullscreen") + .unwrap_or(&"".to_string()) + .to_string(), + nowindowborder: kv + .get("setting.nowindowborder") + .unwrap_or(&"".to_string()) + .to_string(), + mat_vsync: kv + .get("setting.mat_vsync") + .unwrap_or(&"".to_string()) + .to_string(), + fullscreen_min_on_focus_loss: kv + .get("setting.fullscreen_min_on_focus_loss") + .unwrap_or(&"".to_string()) + .to_string(), + high_dpi: kv + .get("setting.high_dpi") + .unwrap_or(&"".to_string()) + .to_string(), + auto_config: kv.get("auto_config").unwrap_or(&"".to_string()).to_string(), + shaderquality: kv + .get("setting.shaderquality") + .unwrap_or(&"".to_string()) + .to_string(), + r_texturefilteringquality: kv + .get("setting.r_texturefilteringquality") + .unwrap_or(&"".to_string()) + .to_string(), + msaa_samples: kv + .get("setting.msaa_samples") + .unwrap_or(&"".to_string()) + .to_string(), + r_csgo_cmaa_enable: kv + .get("setting.r_csgo_cmaa_enable") + .unwrap_or(&"".to_string()) + .to_string(), + videocfg_shadow_quality: kv + .get("setting.videocfg_shadow_quality") + .unwrap_or(&"".to_string()) + .to_string(), + videocfg_dynamic_shadows: kv + .get("setting.videocfg_dynamic_shadows") + .unwrap_or(&"".to_string()) + .to_string(), + videocfg_texture_detail: kv + .get("setting.videocfg_texture_detail") + .unwrap_or(&"".to_string()) + .to_string(), + videocfg_particle_detail: kv + .get("setting.videocfg_particle_detail") + .unwrap_or(&"".to_string()) + .to_string(), + videocfg_ao_detail: kv + .get("setting.videocfg_ao_detail") + .unwrap_or(&"".to_string()) + .to_string(), + videocfg_hdr_detail: kv + .get("setting.videocfg_hdr_detail") + .unwrap_or(&"".to_string()) + .to_string(), + videocfg_fsr_detail: kv + .get("setting.videocfg_fsr_detail") + .unwrap_or(&"".to_string()) + .to_string(), + monitor_index: kv + .get("setting.monitor_index") + .unwrap_or(&"".to_string()) + .to_string(), + r_low_latency: kv + .get("setting.r_low_latency") + .unwrap_or(&"".to_string()) + .to_string(), + aspectratiomode: kv + .get("setting.aspectratiomode") + .unwrap_or(&"".to_string()) + .to_string(), + }; + Ok(video_config) } -pub fn set_cs2_video(file_path: &str, data: HashMap) -> Result<()> { - let json_data = serde_json::to_string(&data)?; +pub fn set_cs2_video(file_path: &str, data: VideoConfig) -> Result<()> { + // TODO: no kv + let mut kv = HashMap::new(); + kv.insert("version".to_string(), data.version); + kv.insert("vendor_id".to_string(), data.vendor_id); + kv.insert("device_id".to_string(), data.device_id); + kv.insert("setting.cpu_level".to_string(), data.cpu_level); + kv.insert( + "setting.gpu_mem_level".to_string(), + data.gpu_mem_level, + ); + kv.insert("setting.gpu_level".to_string(), data.gpu_level); + kv.insert("setting.knowndevice".to_string(), data.knowndevice); + kv.insert("setting.defaultres".to_string(), data.defaultres); + kv.insert( + "setting.defaultresheight".to_string(), + data.defaultresheight, + ); + kv.insert( + "setting.refreshrate_numerator".to_string(), + data.refreshrate_numerator, + ); + kv.insert( + "setting.refreshrate_denominator".to_string(), + data.refreshrate_denominator, + ); + kv.insert("setting.fullscreen".to_string(), data.fullscreen); + kv.insert( + "setting.coop_fullscreen".to_string(), + data.coop_fullscreen, + ); + kv.insert( + "setting.nowindowborder".to_string(), + data.nowindowborder, + ); + kv.insert("setting.mat_vsync".to_string(), data.mat_vsync); + kv.insert( + "setting.fullscreen_min_on_focus_loss".to_string(), + data.fullscreen_min_on_focus_loss, + ); + kv.insert("setting.high_dpi".to_string(), data.high_dpi); + kv.insert("auto_config".to_string(), data.auto_config); + kv.insert( + "setting.shaderquality".to_string(), + data.shaderquality, + ); + kv.insert( + "setting.r_texturefilteringquality".to_string(), + data.r_texturefilteringquality, + ); + kv.insert( + "setting.msaa_samples".to_string(), + data.msaa_samples, + ); + kv.insert( + "setting.r_csgo_cmaa_enable".to_string(), + data.r_csgo_cmaa_enable, + ); + kv.insert( + "setting.videocfg_shadow_quality".to_string(), + data.videocfg_shadow_quality, + ); + kv.insert( + "setting.videocfg_dynamic_shadows".to_string(), + data.videocfg_dynamic_shadows, + ); + kv.insert( + "setting.videocfg_texture_detail".to_string(), + data.videocfg_texture_detail, + ); + kv.insert( + "setting.videocfg_particle_detail".to_string(), + data.videocfg_particle_detail, + ); + kv.insert( + "setting.videocfg_ao_detail".to_string(), + data.videocfg_ao_detail, + ); + kv.insert( + "setting.videocfg_hdr_detail".to_string(), + data.videocfg_hdr_detail, + ); + kv.insert( + "setting.videocfg_fsr_detail".to_string(), + data.videocfg_fsr_detail, + ); + kv.insert( + "setting.monitor_index".to_string(), + data.monitor_index, + ); + kv.insert( + "setting.r_low_latency".to_string(), + data.r_low_latency, + ); + kv.insert( + "setting.aspectratiomode".to_string(), + data.aspectratiomode, + ); + + let json_data = serde_json::to_string(&kv)?; let vdf_data = super::parse::to_vdf(&json_data); + // println!("{}", vdf_data); fs::write(file_path, vdf_data)?; Ok(()) } @@ -332,14 +589,17 @@ mod tests { #[test] fn test_get_cs2_video() { - let video_config = get_cs2_video("src-tauri/src/vdf/tests/cs2_video.txt").unwrap(); + let manifest_dir = env!("CARGO_MANIFEST_DIR"); + let file_path = format!("{}/src/vdf/tests/cs2_video.txt", manifest_dir); + let video_config = get_cs2_video(&file_path).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(); + let manifest_dir = env!("CARGO_MANIFEST_DIR"); + let file_path = format!("{}/temp/cs2_video.txt", manifest_dir); + let video_config = VideoConfig::default(); + set_cs2_video(&file_path, video_config).unwrap(); } } diff --git a/src/components/cstb/VideoSetting.tsx b/src/components/cstb/VideoSetting.tsx index 6934b6f..28a13d5 100644 --- a/src/components/cstb/VideoSetting.tsx +++ b/src/components/cstb/VideoSetting.tsx @@ -1,15 +1,17 @@ import { CloseSmall, Down, Edit, Plus, SettingConfig, Up } from "@icon-park/react" -import { useState } from "react" +import { useEffect, useState } from "react" import { Card, CardBody, CardHeader, CardIcon, CardTool } from "../window/Card" import { ToolButton } from "../window/ToolButton" import { addToast, NumberInput, Tab, Tabs, Tooltip } from "@heroui/react" import { motion } from "framer-motion" import { useToolStore } from "@/store/tool" +import { useSteamStore } from "@/store/steam" const VideoSetting = () => { const [hide, setHide] = useState(false) const [edit, setEdit] = useState(false) const tool = useToolStore() + const steam = useSteamStore() // const [launchOpt, setLaunchOpt] = useState(tool.state.VideoSettings[tool.state.launchIndex] || "") // useEffect(() => { @@ -18,69 +20,173 @@ const VideoSetting = () => { // 设置对应关系 // TODO Value通过实际数值映射 + const videoSettings = [ - { type: "", title: "全屏", value: "全屏", options: ["窗口", "全屏"] }, - { type: "", title: "垂直同步", value: "关闭", options: ["关闭", "开启"] }, - { type: "", title: "低延迟模式", value: "关闭", options: ["关闭", "开启"] }, - { type: "", title: "增强角色对比度", value: "禁用", options: ["禁用", "启用"] }, - { type: "", title: "CMAA2抗锯齿", value: "关闭", options: ["关闭", "开启"] }, { - type: "", + type: "fullscreen", + title: "全屏", + value: tool.state.videoSetting.fullscreen === "1" ? "全屏" : "窗口", + options: ["窗口", "全屏"], + }, + { + type: "mat_vsync", + title: "垂直同步", + value: tool.state.videoSetting.mat_vsync === "1" ? "开启" : "关闭", + options: ["关闭", "开启"], + }, + { + type: "r_low_latency", + title: "低延迟模式", + value: tool.state.videoSetting.r_low_latency === "1" ? "开启" : "关闭", + options: ["关闭", "开启"], + }, + { + type: "r_csgo_cmaa_enable", + title: "增强角色对比度", + value: tool.state.videoSetting.r_csgo_cmaa_enable === "1" ? "启用" : "禁用", + options: ["禁用", "启用"], + }, + { + type: "msaa_samples", title: "多重采样抗锯齿", - value: "2X MSAA", + value: + { + 0: "无", + 2: "2X MSAA", + 4: "4X MSAA", + 8: "8X MSAA", + }[parseInt(tool.state.videoSetting.msaa_samples)] || "无", options: ["无", "2X MSAA", "4X MSAA", "8X MSAA"], }, - { type: "", title: "全局阴影效果", value: "低", options: ["低", "中", "高", "非常高"] }, - { type: "", title: "动态阴影", value: "全部", options: ["仅限日光", "全部"] }, - { type: "", title: "模型/贴图细节", value: "中", options: ["低", "中", "高"] }, { - type: "", + type: "videocfg_shadow_quality", + title: "全局阴影效果", + value: + ["低", "中", "高", "非常高"][parseInt(tool.state.videoSetting.videocfg_shadow_quality)] || + "低", + options: ["低", "中", "高", "非常高"], + }, + { + type: "videocfg_dynamic_shadows", + title: "动态阴影", + value: + ["仅限日光", "全部"][parseInt(tool.state.videoSetting.videocfg_dynamic_shadows)] || + "仅限日光", + options: ["仅限日光", "全部"], + }, + { + type: "videocfg_texture_detail", + title: "模型/贴图细节", + value: ["低", "中", "高"][parseInt(tool.state.videoSetting.videocfg_texture_detail)] || "低", + options: ["低", "中", "高"], + }, + { + type: "r_texturefilteringquality", title: "贴图过滤模式", - value: "异向 4X", + value: + ["双线性", "三线性", "异向 2X", "异向 4X", "异向 8X", "异向 16X"][ + parseInt(tool.state.videoSetting.r_texturefilteringquality) + ] || "双线性", options: ["双线性", "三线性", "异向 2X", "异向 4X", "异向 8X", "异向 16X"], }, - { type: "", title: "光影细节", value: "低", options: ["低", "高"] }, - { type: "", title: "粒子细节", value: "低", options: ["低", "中", "高", "非常高"] }, - { type: "", title: "环境光遮蔽", value: "已禁用", options: ["已禁用", "中", "高"] }, - { type: "", title: "高动态范围", value: "性能", options: ["性能", "品质"] }, { - type: "", + type: "videocfg_hdr_detail", + title: "光影细节", + value: ["低", "高"][parseInt(tool.state.videoSetting.shaderquality)] || "低", + options: ["低", "高"], + }, + { + type: "videocfg_particle_detail", + title: "粒子细节", + value: + ["低", "中", "高", "非常高"][parseInt(tool.state.videoSetting.videocfg_particle_detail)] || + "低", + options: ["低", "中", "高", "非常高"], + }, + { + type: "videocfg_ao_detail", + title: "环境光遮蔽", + value: + ["已禁用", "中", "高"][parseInt(tool.state.videoSetting.videocfg_ao_detail)] || "已禁用", + options: ["已禁用", "中", "高"], + }, + { + type: "videocfg_fsr_detail", title: "Fidelity FX 超级分辨率", - value: "已禁用", + value: + ["已禁用", "超高品质", "品质", "均衡", "性能"][ + parseInt(tool.state.videoSetting.videocfg_fsr_detail) + ] || "性能", options: ["性能", "均衡", "品质", "超高品质", "已禁用"], }, ] + // const videoSettings = [ + // { type: "", title: "全屏", value: "全屏", options: ["窗口", "全屏"] }, + // { type: "", title: "垂直同步", value: "关闭", options: ["关闭", "开启"] }, + // { type: "", title: "低延迟模式", value: "关闭", options: ["关闭", "开启"] }, + // { type: "", title: "增强角色对比度", value: "禁用", options: ["禁用", "启用"] }, + // { type: "", title: "CMAA2抗锯齿", value: "关闭", options: ["关闭", "开启"] }, + // { + // type: "", + // title: "多重采样抗锯齿", + // value: "2X MSAA", + // options: ["无", "2X MSAA", "4X MSAA", "8X MSAA"], + // }, + // { type: "", title: "全局阴影效果", value: "低", options: ["低", "中", "高", "非常高"] }, + // { type: "", title: "动态阴影", value: "全部", options: ["仅限日光", "全部"] }, + // { type: "", title: "模型/贴图细节", value: "中", options: ["低", "中", "高"] }, + // { + // type: "", + // title: "贴图过滤模式", + // value: "异向 4X", + // options: ["双线性", "三线性", "异向 2X", "异向 4X", "异向 8X", "异向 16X"], + // }, + // { type: "", title: "光影细节", value: "低", options: ["低", "高"] }, + // { type: "", title: "粒子细节", value: "低", options: ["低", "中", "高", "非常高"] }, + // { type: "", title: "环境光遮蔽", value: "已禁用", options: ["已禁用", "中", "高"] }, + // { type: "", title: "高动态范围", value: "性能", options: ["性能", "品质"] }, + // { + // type: "", + // title: "Fidelity FX 超级分辨率", + // value: "已禁用", + // options: ["性能", "均衡", "品质", "超高品质", "已禁用"], + // }, + // ] + + // useEffect(() => { + // void tool.getVideoConfig() + // }) return ( - - - - - 视频设置 - - - {/* {tool.state.VideoSettings.map((option, index) => ( + + + + 视频设置 + + + {/* {tool.state.VideoSettings.map((option, index) => ( tool.setLaunchIndex(index)}> {index + 1} ))} */} - {edit && ( - <> - - - - 非常高 - 推荐 - { - addToast({ title: "测试中 功能完成后可应用设置到游戏" }) - }} - > - - 应用 - - - )} + {edit && ( + <> + + + + 非常高 + 推荐 + { + addToast({ title: "测试中 功能完成后可应用设置到游戏" }) + }} + > + + 应用 + + + )} + setEdit(!edit)}> {edit ? ( <> @@ -94,85 +200,93 @@ const VideoSetting = () => { )} - setHide(!hide)}> - {hide ? ( - <> - - 显示 - - ) : ( - <> - - 隐藏 - - )} - - - - {!hide && ( - + + + void tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0) + } > - -
    -
  • - 分辨率 - - { - tool.setVideoSetting({ - ...tool.state.videoSetting, - width: value, - }) - }} - radius="full" - step={10} - className="max-w-28" - classNames={{ inputWrapper: "h-10" }} - /> - { - tool.setVideoSetting({ - ...tool.state.videoSetting, - height: value, - }) - }} - radius="full" - step={10} - className="max-w-28" - classNames={{ inputWrapper: "h-10" }} - /> - + 读取 + + setHide(!hide)}> + {hide ? ( + <> + + 显示 + + ) : ( + <> + + 隐藏 + + )} + + + + {!hide && ( + + +
      +
    • + 分辨率 + + { + tool.setVideoSetting({ + ...tool.state.videoSetting, + defaultres: value.toString(), + }) + }} + radius="full" + step={10} + className="max-w-28" + classNames={{ inputWrapper: "h-10" }} + /> + { + tool.setVideoSetting({ + ...tool.state.videoSetting, + defaultresheight: value.toString(), + }) + }} + radius="full" + step={10} + className="max-w-28" + classNames={{ inputWrapper: "h-10" }} + /> + +
    • + {videoSettings.map((vid, index) => ( +
    • + {vid.title} + + {vid.options.map((opt, _) => ( + + ))} +
    • - {videoSettings.map((vid, index) => ( -
    • - {vid.title} - - {vid.options.map((opt, _) => ( - - ))} - -
    • - ))} -
    -
    -
    - )} - - + ))} +
+
+
+ )} +
) } diff --git a/src/store/tool.ts b/src/store/tool.ts index 42018e0..cc1e032 100644 --- a/src/store/tool.ts +++ b/src/store/tool.ts @@ -2,7 +2,8 @@ import { store } from "@tauri-store/valtio" import { useSnapshot } from "valtio" import { DEFAULT_STORE_CONFIG } from "./config" import { emit } from "@tauri-apps/api/event" -import { send } from "process" +import { invoke } from "@tauri-apps/api/core" +import { steamStore, useSteamStore } from "./steam" interface LaunchOption { option: string @@ -10,22 +11,38 @@ interface LaunchOption { } export interface VideoSetting { - width: number; // 分辨率宽度 - height: number; // 分辨率高度 + version: string; // 版本 + vendor_id: string; // 供应商ID + device_id: string; // 设备ID + cpu_level: string; // CPU等级 + gpu_mem_level: string; // GPU内存等级 + gpu_level: string; // GPU等级 + knowndevice: string; // 已知设备 + defaultres: string; // 默认分辨率宽度 + defaultresheight: string; // 默认分辨率高度 + refreshrate_numerator: string; // 刷新率分子 + refreshrate_denominator: string; // 刷新率分母 fullscreen: string; // 全屏 - vsync: string; // 垂直同步 - enhanceCharacterContrast: string; // 增强角色对比度 - cmaa2AntiAliasing: string; // CMAA2抗锯齿 - msaaAntiAliasing: string; // 多重采样抗锯齿 - globalShadowQuality: string; // 全局阴影效果 - dynamicShadows: string; // 动态阴影 - modelTextureDetail: string; // 模型/贴图细节 - textureFilteringMode: string; // 贴图过滤模式 - lightShadowDetail: string; // 光影细节 - particleDetail: string; // 粒子细节 - ambientOcclusion: string; // 环境光遮蔽 - hdr: string; // 高动态范围 - fidelityFxSuperResolution: string; // Fidelity FX 超级分辨率 + coop_fullscreen: string; // 合作模式全屏 + nowindowborder: string; // 无窗口边框 + mat_vsync: string; // 垂直同步 + fullscreen_min_on_focus_loss: string; // 失去焦点时最小化全屏 + high_dpi: string; // 高DPI + auto_config: string; // 自动配置 + shaderquality: string; // 着色器质量 + r_texturefilteringquality: string; // 纹理过滤质量 + msaa_samples: string; // 多重采样抗锯齿样本数 + r_csgo_cmaa_enable: string; // CMAA抗锯齿启用 + videocfg_shadow_quality: string; // 阴影质量 + videocfg_dynamic_shadows: string; // 动态阴影 + videocfg_texture_detail: string; // 纹理细节 + videocfg_particle_detail: string; // 粒子细节 + videocfg_ao_detail: string; // 环境光遮蔽细节 + videocfg_hdr_detail: string; // 高动态范围细节 + videocfg_fsr_detail: string; // FSR细节 + monitor_index: string; // 显示器索引 + r_low_latency: string; // 低延迟 + aspectratiomode: string; // 宽高比模式 } const defaultValue = { @@ -37,8 +54,38 @@ const defaultValue = { launchIndex: 0, powerPlan: 0, videoSetting: { - width: 1920, - height: 1080 + version: "1.0", + vendor_id: "0x0000", + device_id: "0x0000", + cpu_level: "3", + gpu_mem_level: "3", + gpu_level: "3", + knowndevice: "Unknown", + defaultres: "1920", + defaultresheight: "1080", + refreshrate_numerator: "144", + refreshrate_denominator: "1", + fullscreen: "1", + coop_fullscreen: "0", + nowindowborder: "1", + mat_vsync: "0", + fullscreen_min_on_focus_loss: "1", + high_dpi: "0", + auto_config: "2", + shaderquality: "0", + r_texturefilteringquality: "3", + msaa_samples: "2", + r_csgo_cmaa_enable: "0", + videocfg_shadow_quality: "0", + videocfg_dynamic_shadows: "1", + videocfg_texture_detail: "1", + videocfg_particle_detail: "0", + videocfg_ao_detail: "0", + videocfg_hdr_detail: "3", + videocfg_fsr_detail: "0", + monitor_index: "0", + r_low_latency: "1", + aspectratiomode: "0", } as VideoSetting, } @@ -67,6 +114,7 @@ export const useToolStore = () => { setLaunchIndex, setPowerPlan, setVideoSetting, + getVideoConfig, addLaunchOption, resetToolStore, } @@ -104,6 +152,12 @@ const setVideoSetting = (setting: VideoSetting) => { toolStore.state.videoSetting = setting } +const getVideoConfig = async (steam_dir: string, steam_id32: number) => { + const video = await invoke("get_cs2_video_config", { steamDir: steam_dir, steamId32: steam_id32 }) + // console.log(video) + setVideoSetting(video) +} + const addLaunchOption = (option: LaunchOption) => { // 限制最高10个 if (toolStore.state.launchOptions.length >= 10) { -- 2.49.1 From 114def0b962f7cdf5e52d003b597c79262ab96e0 Mon Sep 17 00:00:00 2001 From: purp1e Date: Thu, 27 Mar 2025 15:29:12 +0800 Subject: [PATCH 03/10] [feat] set video config --- src-tauri/src/vdf/mod.rs | 2 +- src-tauri/src/vdf/parse.rs | 68 +++++------ src-tauri/src/vdf/preset.rs | 221 ++++++++++++++---------------------- src/store/tool.ts | 8 +- 4 files changed, 126 insertions(+), 173 deletions(-) diff --git a/src-tauri/src/vdf/mod.rs b/src-tauri/src/vdf/mod.rs index 28ac29e..294d73f 100644 --- a/src-tauri/src/vdf/mod.rs +++ b/src-tauri/src/vdf/mod.rs @@ -1,2 +1,2 @@ pub mod parse; -pub mod preset; +pub mod preset; \ No newline at end of file diff --git a/src-tauri/src/vdf/parse.rs b/src-tauri/src/vdf/parse.rs index 4e2c584..1173a2c 100644 --- a/src-tauri/src/vdf/parse.rs +++ b/src-tauri/src/vdf/parse.rs @@ -1,11 +1,12 @@ pub fn to_json(vdf_data: &str) -> String { let linebreak = match std::env::consts::OS { - "macos" => "\r", + "macos" => "\n", //"\r", "windows" => "\n", "linux" => "\n", _ => "\n", }; + // NOTE: 这样会跳过顶层{} let startpoint = vdf_data.find('{').unwrap_or(0); let vdf_data = &vdf_data[startpoint..]; @@ -31,13 +32,15 @@ pub fn to_json(vdf_data: &str) -> String { json_data.push_str(&line); } + // let json_str = json_data json_data = json_data .replace(",}", "}") .trim_start_matches(": ") .trim_end_matches(',') .to_string(); + // json_data = format!("{{{}}}", json_str); - json_data + return json_data; } pub fn to_vdf(json_data: &str) -> String { @@ -48,33 +51,33 @@ pub fn to_vdf(json_data: &str) -> String { } 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)); - } - } + 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" + static VDF_DATA: &str = r#""users" { "76561198315078806" { @@ -101,7 +104,7 @@ mod tests { } "#; - static JSON_DATA: &str = r#"{ + static JSON_DATA: &str = r#"{ "users": { "76561198315078806": { "AccountName": "_jerry_dota2", @@ -126,12 +129,11 @@ mod tests { } }"#; - #[test] fn test_to_json() { // let expected_json = r#"{"key1": "value1","key2": "value2","subkey": {"key3": "value3"}}"#; let json_data = to_json(VDF_DATA); - println!("{}", json_data); + println!("{}", json_data); // 解析json let json_value: serde_json::Value = serde_json::from_str(&json_data).unwrap(); @@ -140,11 +142,11 @@ mod tests { // 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); + #[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); - } + println!("{}", vdf_data); + } } diff --git a/src-tauri/src/vdf/preset.rs b/src-tauri/src/vdf/preset.rs index 9652d56..7ded5a6 100644 --- a/src-tauri/src/vdf/preset.rs +++ b/src-tauri/src/vdf/preset.rs @@ -1,6 +1,7 @@ use anyhow::Result; use base64::engine::general_purpose::STANDARD; use base64::Engine; +use regex::Regex; use serde::{Deserialize, Serialize}; use serde_json::Value; use std::collections::HashMap; @@ -82,40 +83,40 @@ pub struct VideoConfig { impl Default for VideoConfig { fn default() -> Self { - VideoConfig { - version: String::new(), - vendor_id: String::new(), - device_id: String::new(), - cpu_level: String::new(), - gpu_mem_level: String::new(), - gpu_level: String::new(), - knowndevice: String::new(), - defaultres: String::new(), - defaultresheight: String::new(), - refreshrate_numerator: String::new(), - refreshrate_denominator: String::new(), - fullscreen: String::new(), - coop_fullscreen: String::new(), - nowindowborder: String::new(), - mat_vsync: String::new(), - fullscreen_min_on_focus_loss: String::new(), - high_dpi: String::new(), - auto_config: String::new(), - shaderquality: String::new(), - r_texturefilteringquality: String::new(), - msaa_samples: String::new(), - r_csgo_cmaa_enable: String::new(), - videocfg_shadow_quality: String::new(), - videocfg_dynamic_shadows: String::new(), - videocfg_texture_detail: String::new(), - videocfg_particle_detail: String::new(), - videocfg_ao_detail: String::new(), - videocfg_hdr_detail: String::new(), - videocfg_fsr_detail: String::new(), - monitor_index: String::new(), - r_low_latency: String::new(), - aspectratiomode: String::new(), - } + VideoConfig { + version: "15".to_string(), + vendor_id: "0".to_string(), + device_id: "0".to_string(), + cpu_level: "3".to_string(), + gpu_mem_level: "3".to_string(), + gpu_level: "3".to_string(), + knowndevice: "0".to_string(), + defaultres: "1920".to_string(), + defaultresheight: "1080".to_string(), + refreshrate_numerator: "144".to_string(), + refreshrate_denominator: "1".to_string(), + fullscreen: "1".to_string(), + coop_fullscreen: "0".to_string(), + nowindowborder: "1".to_string(), + mat_vsync: "0".to_string(), + fullscreen_min_on_focus_loss: "1".to_string(), + high_dpi: "0".to_string(), + auto_config: "2".to_string(), + shaderquality: "0".to_string(), + r_texturefilteringquality: "3".to_string(), + msaa_samples: "2".to_string(), + r_csgo_cmaa_enable: "0".to_string(), + videocfg_shadow_quality: "0".to_string(), + videocfg_dynamic_shadows: "1".to_string(), + videocfg_texture_detail: "1".to_string(), + videocfg_particle_detail: "0".to_string(), + videocfg_ao_detail: "0".to_string(), + videocfg_hdr_detail: "3".to_string(), + videocfg_fsr_detail: "0".to_string(), + monitor_index: "0".to_string(), + r_low_latency: "1".to_string(), + aspectratiomode: "0".to_string(), + } } } @@ -226,6 +227,9 @@ pub fn parse_local_users(steam_dir: &str) -> Result> { let json_data = super::parse::to_json(&data); let kv: HashMap = serde_json::from_str(&json_data)?; + // 剥离顶层 UserLocalConfigStore + let kv = kv.get("UserLocalConfigStore").and_then(|v| v.as_object()).unwrap(); + // 获取 friends 节点 let friends = kv.get("friends").and_then(|v| v.as_object()); if friends.is_none() { @@ -472,108 +476,50 @@ pub fn get_cs2_video(file_path: &str) -> Result { } pub fn set_cs2_video(file_path: &str, data: VideoConfig) -> Result<()> { - // TODO: no kv - let mut kv = HashMap::new(); - kv.insert("version".to_string(), data.version); - kv.insert("vendor_id".to_string(), data.vendor_id); - kv.insert("device_id".to_string(), data.device_id); - kv.insert("setting.cpu_level".to_string(), data.cpu_level); - kv.insert( - "setting.gpu_mem_level".to_string(), - data.gpu_mem_level, - ); - kv.insert("setting.gpu_level".to_string(), data.gpu_level); - kv.insert("setting.knowndevice".to_string(), data.knowndevice); - kv.insert("setting.defaultres".to_string(), data.defaultres); - kv.insert( - "setting.defaultresheight".to_string(), - data.defaultresheight, - ); - kv.insert( - "setting.refreshrate_numerator".to_string(), - data.refreshrate_numerator, - ); - kv.insert( - "setting.refreshrate_denominator".to_string(), - data.refreshrate_denominator, - ); - kv.insert("setting.fullscreen".to_string(), data.fullscreen); - kv.insert( - "setting.coop_fullscreen".to_string(), - data.coop_fullscreen, - ); - kv.insert( - "setting.nowindowborder".to_string(), - data.nowindowborder, - ); - kv.insert("setting.mat_vsync".to_string(), data.mat_vsync); - kv.insert( - "setting.fullscreen_min_on_focus_loss".to_string(), - data.fullscreen_min_on_focus_loss, - ); - kv.insert("setting.high_dpi".to_string(), data.high_dpi); - kv.insert("auto_config".to_string(), data.auto_config); - kv.insert( - "setting.shaderquality".to_string(), - data.shaderquality, - ); - kv.insert( - "setting.r_texturefilteringquality".to_string(), - data.r_texturefilteringquality, - ); - kv.insert( - "setting.msaa_samples".to_string(), - data.msaa_samples, - ); - kv.insert( - "setting.r_csgo_cmaa_enable".to_string(), - data.r_csgo_cmaa_enable, - ); - kv.insert( - "setting.videocfg_shadow_quality".to_string(), - data.videocfg_shadow_quality, - ); - kv.insert( - "setting.videocfg_dynamic_shadows".to_string(), - data.videocfg_dynamic_shadows, - ); - kv.insert( - "setting.videocfg_texture_detail".to_string(), - data.videocfg_texture_detail, - ); - kv.insert( - "setting.videocfg_particle_detail".to_string(), - data.videocfg_particle_detail, - ); - kv.insert( - "setting.videocfg_ao_detail".to_string(), - data.videocfg_ao_detail, - ); - kv.insert( - "setting.videocfg_hdr_detail".to_string(), - data.videocfg_hdr_detail, - ); - kv.insert( - "setting.videocfg_fsr_detail".to_string(), - data.videocfg_fsr_detail, - ); - kv.insert( - "setting.monitor_index".to_string(), - data.monitor_index, - ); - kv.insert( - "setting.r_low_latency".to_string(), - data.r_low_latency, - ); - kv.insert( - "setting.aspectratiomode".to_string(), - data.aspectratiomode, - ); + // 读取文件内容 + let file_content = fs::read_to_string(file_path)?; - let json_data = serde_json::to_string(&kv)?; - let vdf_data = super::parse::to_vdf(&json_data); - // println!("{}", vdf_data); - fs::write(file_path, vdf_data)?; + // 定义正则表达式匹配模式 + let re = Regex::new(r#""(setting\.\w+)"\s+"\d+""#).unwrap(); + + // 替换字段值 + let updated_content = re.replace_all(&file_content, |caps: ®ex::Captures| { + let key = &caps[1]; // 捕获的键名 + let value = match key { + "setting.cpu_level" => &data.cpu_level, + "setting.gpu_mem_level" => &data.gpu_mem_level, + "setting.gpu_level" => &data.gpu_level, + "setting.knowndevice" => &data.knowndevice, + "setting.defaultres" => &data.defaultres, + "setting.defaultresheight" => &data.defaultresheight, + "setting.refreshrate_numerator" => &data.refreshrate_numerator, + "setting.refreshrate_denominator" => &data.refreshrate_denominator, + "setting.fullscreen" => &data.fullscreen, + "setting.coop_fullscreen" => &data.coop_fullscreen, + "setting.nowindowborder" => &data.nowindowborder, + "setting.mat_vsync" => &data.mat_vsync, + "setting.fullscreen_min_on_focus_loss" => &data.fullscreen_min_on_focus_loss, + "setting.high_dpi" => &data.high_dpi, + "setting.shaderquality" => &data.shaderquality, + "setting.r_texturefilteringquality" => &data.r_texturefilteringquality, + "setting.msaa_samples" => &data.msaa_samples, + "setting.r_csgo_cmaa_enable" => &data.r_csgo_cmaa_enable, + "setting.videocfg_shadow_quality" => &data.videocfg_shadow_quality, + "setting.videocfg_dynamic_shadows" => &data.videocfg_dynamic_shadows, + "setting.videocfg_texture_detail" => &data.videocfg_texture_detail, + "setting.videocfg_particle_detail" => &data.videocfg_particle_detail, + "setting.videocfg_ao_detail" => &data.videocfg_ao_detail, + "setting.videocfg_hdr_detail" => &data.videocfg_hdr_detail, + "setting.videocfg_fsr_detail" => &data.videocfg_fsr_detail, + "setting.monitor_index" => &data.monitor_index, + "setting.r_low_latency" => &data.r_low_latency, + "setting.aspectratiomode" => &data.aspectratiomode, + _ => "", // 默认情况 + }; + format!(r#""{}" "{}""#, key, value) + }); + + fs::write(file_path, updated_content.as_ref())?; Ok(()) } @@ -599,6 +545,11 @@ mod tests { fn test_set_cs2_video() { let manifest_dir = env!("CARGO_MANIFEST_DIR"); let file_path = format!("{}/temp/cs2_video.txt", manifest_dir); + fs::copy( + format!("{}/src/vdf/tests/cs2_video.txt", manifest_dir), + file_path.clone(), + ) + .unwrap(); let video_config = VideoConfig::default(); set_cs2_video(&file_path, video_config).unwrap(); } diff --git a/src/store/tool.ts b/src/store/tool.ts index cc1e032..9b2c30f 100644 --- a/src/store/tool.ts +++ b/src/store/tool.ts @@ -54,13 +54,13 @@ const defaultValue = { launchIndex: 0, powerPlan: 0, videoSetting: { - version: "1.0", - vendor_id: "0x0000", - device_id: "0x0000", + version: "15", + vendor_id: "0", + device_id: "0", cpu_level: "3", gpu_mem_level: "3", gpu_level: "3", - knowndevice: "Unknown", + knowndevice: "0", defaultres: "1920", defaultresheight: "1080", refreshrate_numerator: "144", -- 2.49.1 From 63172f12bc52fb037cf3eb75124d34439023280c Mon Sep 17 00:00:00 2001 From: purp1e Date: Thu, 27 Mar 2025 15:48:09 +0800 Subject: [PATCH 04/10] [feat] set video and template --- src/components/cstb/VideoSetting.tsx | 281 ++++++++++++--------------- src/store/tool.ts | 89 ++++++++- 2 files changed, 212 insertions(+), 158 deletions(-) diff --git a/src/components/cstb/VideoSetting.tsx b/src/components/cstb/VideoSetting.tsx index 28a13d5..7d852d2 100644 --- a/src/components/cstb/VideoSetting.tsx +++ b/src/components/cstb/VideoSetting.tsx @@ -4,7 +4,7 @@ import { Card, CardBody, CardHeader, CardIcon, CardTool } from "../window/Card" import { ToolButton } from "../window/ToolButton" import { addToast, NumberInput, Tab, Tabs, Tooltip } from "@heroui/react" import { motion } from "framer-motion" -import { useToolStore } from "@/store/tool" +import { useToolStore, VideoSetting as VideoConfig, VideoSettingTemplate } from "@/store/tool" import { useSteamStore } from "@/store/steam" const VideoSetting = () => { @@ -12,150 +12,101 @@ const VideoSetting = () => { const [edit, setEdit] = useState(false) const tool = useToolStore() const steam = useSteamStore() - // const [launchOpt, setLaunchOpt] = useState(tool.state.VideoSettings[tool.state.launchIndex] || "") + const videoSettings = (video: VideoConfig) => { + return [ + { + type: "fullscreen", + title: "全屏", + value: video.fullscreen === "1" ? "全屏" : "窗口", + options: ["窗口", "全屏"], + }, + { + type: "mat_vsync", + title: "垂直同步", + value: video.mat_vsync === "1" ? "开启" : "关闭", + options: ["关闭", "开启"], + }, + { + type: "r_low_latency", + title: "低延迟模式", + value: video.r_low_latency === "1" ? "开启" : "关闭", + options: ["关闭", "开启"], + }, + { + type: "r_csgo_cmaa_enable", + title: "增强角色对比度", + value: video.r_csgo_cmaa_enable === "1" ? "启用" : "禁用", + options: ["禁用", "启用"], + }, + { + type: "msaa_samples", + title: "多重采样抗锯齿", + value: + { + 0: "无", + 2: "2X MSAA", + 4: "4X MSAA", + 8: "8X MSAA", + }[parseInt(video.msaa_samples)] || "无", + options: ["无", "2X MSAA", "4X MSAA", "8X MSAA"], + }, + { + type: "videocfg_shadow_quality", + title: "全局阴影效果", + value: ["低", "中", "高", "非常高"][parseInt(video.videocfg_shadow_quality)] || "低", + options: ["低", "中", "高", "非常高"], + }, + { + type: "videocfg_dynamic_shadows", + title: "动态阴影", + value: ["仅限日光", "全部"][parseInt(video.videocfg_dynamic_shadows)] || "仅限日光", + options: ["仅限日光", "全部"], + }, + { + type: "videocfg_texture_detail", + title: "模型/贴图细节", + value: ["低", "中", "高"][parseInt(video.videocfg_texture_detail)] || "低", + options: ["低", "中", "高"], + }, + { + type: "r_texturefilteringquality", + title: "贴图过滤模式", + value: + ["双线性", "三线性", "异向 2X", "异向 4X", "异向 8X", "异向 16X"][ + parseInt(video.r_texturefilteringquality) + ] || "双线性", + options: ["双线性", "三线性", "异向 2X", "异向 4X", "异向 8X", "异向 16X"], + }, + { + type: "videocfg_hdr_detail", + title: "光影细节", + value: ["低", "高"][parseInt(video.shaderquality)] || "低", + options: ["低", "高"], + }, + { + type: "videocfg_particle_detail", + title: "粒子细节", + value: ["低", "中", "高", "非常高"][parseInt(video.videocfg_particle_detail)] || "低", + options: ["低", "中", "高", "非常高"], + }, + { + type: "videocfg_ao_detail", + title: "环境光遮蔽", + value: ["已禁用", "中", "高"][parseInt(video.videocfg_ao_detail)] || "已禁用", + options: ["已禁用", "中", "高"], + }, + { + type: "videocfg_fsr_detail", + title: "Fidelity FX 超级分辨率", + value: + ["已禁用", "超高品质", "品质", "均衡", "性能"][parseInt(video.videocfg_fsr_detail)] || + "性能", + options: ["性能", "均衡", "品质", "超高品质", "已禁用"], + }, + ] + } - // useEffect(() => { - // setLaunchOpt(tool.state.VideoSettings[tool.state.launchIndex] || "") - // }, [tool.state.launchIndex, tool.state.VideoSettings]) - - // 设置对应关系 - // TODO Value通过实际数值映射 - - const videoSettings = [ - { - type: "fullscreen", - title: "全屏", - value: tool.state.videoSetting.fullscreen === "1" ? "全屏" : "窗口", - options: ["窗口", "全屏"], - }, - { - type: "mat_vsync", - title: "垂直同步", - value: tool.state.videoSetting.mat_vsync === "1" ? "开启" : "关闭", - options: ["关闭", "开启"], - }, - { - type: "r_low_latency", - title: "低延迟模式", - value: tool.state.videoSetting.r_low_latency === "1" ? "开启" : "关闭", - options: ["关闭", "开启"], - }, - { - type: "r_csgo_cmaa_enable", - title: "增强角色对比度", - value: tool.state.videoSetting.r_csgo_cmaa_enable === "1" ? "启用" : "禁用", - options: ["禁用", "启用"], - }, - { - type: "msaa_samples", - title: "多重采样抗锯齿", - value: - { - 0: "无", - 2: "2X MSAA", - 4: "4X MSAA", - 8: "8X MSAA", - }[parseInt(tool.state.videoSetting.msaa_samples)] || "无", - options: ["无", "2X MSAA", "4X MSAA", "8X MSAA"], - }, - { - type: "videocfg_shadow_quality", - title: "全局阴影效果", - value: - ["低", "中", "高", "非常高"][parseInt(tool.state.videoSetting.videocfg_shadow_quality)] || - "低", - options: ["低", "中", "高", "非常高"], - }, - { - type: "videocfg_dynamic_shadows", - title: "动态阴影", - value: - ["仅限日光", "全部"][parseInt(tool.state.videoSetting.videocfg_dynamic_shadows)] || - "仅限日光", - options: ["仅限日光", "全部"], - }, - { - type: "videocfg_texture_detail", - title: "模型/贴图细节", - value: ["低", "中", "高"][parseInt(tool.state.videoSetting.videocfg_texture_detail)] || "低", - options: ["低", "中", "高"], - }, - { - type: "r_texturefilteringquality", - title: "贴图过滤模式", - value: - ["双线性", "三线性", "异向 2X", "异向 4X", "异向 8X", "异向 16X"][ - parseInt(tool.state.videoSetting.r_texturefilteringquality) - ] || "双线性", - options: ["双线性", "三线性", "异向 2X", "异向 4X", "异向 8X", "异向 16X"], - }, - { - type: "videocfg_hdr_detail", - title: "光影细节", - value: ["低", "高"][parseInt(tool.state.videoSetting.shaderquality)] || "低", - options: ["低", "高"], - }, - { - type: "videocfg_particle_detail", - title: "粒子细节", - value: - ["低", "中", "高", "非常高"][parseInt(tool.state.videoSetting.videocfg_particle_detail)] || - "低", - options: ["低", "中", "高", "非常高"], - }, - { - type: "videocfg_ao_detail", - title: "环境光遮蔽", - value: - ["已禁用", "中", "高"][parseInt(tool.state.videoSetting.videocfg_ao_detail)] || "已禁用", - options: ["已禁用", "中", "高"], - }, - { - type: "videocfg_fsr_detail", - title: "Fidelity FX 超级分辨率", - value: - ["已禁用", "超高品质", "品质", "均衡", "性能"][ - parseInt(tool.state.videoSetting.videocfg_fsr_detail) - ] || "性能", - options: ["性能", "均衡", "品质", "超高品质", "已禁用"], - }, - ] - // const videoSettings = [ - // { type: "", title: "全屏", value: "全屏", options: ["窗口", "全屏"] }, - // { type: "", title: "垂直同步", value: "关闭", options: ["关闭", "开启"] }, - // { type: "", title: "低延迟模式", value: "关闭", options: ["关闭", "开启"] }, - // { type: "", title: "增强角色对比度", value: "禁用", options: ["禁用", "启用"] }, - // { type: "", title: "CMAA2抗锯齿", value: "关闭", options: ["关闭", "开启"] }, - // { - // type: "", - // title: "多重采样抗锯齿", - // value: "2X MSAA", - // options: ["无", "2X MSAA", "4X MSAA", "8X MSAA"], - // }, - // { type: "", title: "全局阴影效果", value: "低", options: ["低", "中", "高", "非常高"] }, - // { type: "", title: "动态阴影", value: "全部", options: ["仅限日光", "全部"] }, - // { type: "", title: "模型/贴图细节", value: "中", options: ["低", "中", "高"] }, - // { - // type: "", - // title: "贴图过滤模式", - // value: "异向 4X", - // options: ["双线性", "三线性", "异向 2X", "异向 4X", "异向 8X", "异向 16X"], - // }, - // { type: "", title: "光影细节", value: "低", options: ["低", "高"] }, - // { type: "", title: "粒子细节", value: "低", options: ["低", "中", "高", "非常高"] }, - // { type: "", title: "环境光遮蔽", value: "已禁用", options: ["已禁用", "中", "高"] }, - // { type: "", title: "高动态范围", value: "性能", options: ["性能", "品质"] }, - // { - // type: "", - // title: "Fidelity FX 超级分辨率", - // value: "已禁用", - // options: ["性能", "均衡", "品质", "超高品质", "已禁用"], - // }, - // ] - - // useEffect(() => { - // void tool.getVideoConfig() - // }) + const [vconfig, setVconfig] = useState(tool.state.videoSetting) return ( @@ -171,13 +122,18 @@ const VideoSetting = () => { ))} */} {edit && ( <> - - - - 非常高 - 推荐 + setVconfig({ ...vconfig, ...VideoSettingTemplate.low })}>低 + setVconfig({ ...vconfig, ...VideoSettingTemplate.middle })}>中 + setVconfig({ ...vconfig, ...VideoSettingTemplate.high })}>高 + setVconfig({ ...vconfig, ...VideoSettingTemplate.veryhigh })}>非常高 + setVconfig({ ...vconfig, ...VideoSettingTemplate.recommend })}>推荐 { + onClick={async () => { + await tool.setVideoConfig( + steam.state.steamDir, + steam.currentUser()?.steam_id32 || 0, + vconfig + ) addToast({ title: "测试中 功能完成后可应用设置到游戏" }) }} > @@ -187,7 +143,10 @@ const VideoSetting = () => { )} - setEdit(!edit)}> + { + setVconfig(tool.state.videoSetting) + setEdit(!edit) + }}> {edit ? ( <> @@ -238,12 +197,20 @@ const VideoSetting = () => { { - tool.setVideoSetting({ - ...tool.state.videoSetting, - defaultres: value.toString(), - }) + edit + ? setVconfig({ + ...vconfig, + defaultres: value.toString(), + }) + : tool.setVideoSetting({ + ...tool.state.videoSetting, + defaultres: value.toString(), + }) }} radius="full" step={10} @@ -266,7 +233,7 @@ const VideoSetting = () => { /> - {videoSettings.map((vid, index) => ( + {videoSettings(edit ? vconfig : tool.state.videoSetting).map((vid, index) => (
  • {vid.title} { setPowerPlan, setVideoSetting, getVideoConfig, + setVideoConfig, addLaunchOption, resetToolStore, } @@ -158,6 +240,11 @@ const getVideoConfig = async (steam_dir: string, steam_id32: number) => { setVideoSetting(video) } +const setVideoConfig = async (steam_dir: string, steam_id32: number, video_config: VideoSetting) => { + await invoke("set_cs2_video_config", { steamDir: steam_dir, steamId32: steam_id32, videoConfig: video_config }) + // console.log(video) +} + const addLaunchOption = (option: LaunchOption) => { // 限制最高10个 if (toolStore.state.launchOptions.length >= 10) { -- 2.49.1 From a10cf8eddf67ffbd1668c5efb9f717641ec0ddbe Mon Sep 17 00:00:00 2001 From: Purp1e <47248616+Purple-CSGO@users.noreply.github.com> Date: Thu, 27 Mar 2025 16:11:42 +0800 Subject: [PATCH 05/10] [feat] template works but cannot edit value by clicking --- src-tauri/src/vdf/preset.rs | 2 +- src/components/cstb/VideoSetting.tsx | 32 +++++++++++++++---------- src/store/tool.ts | 36 +++++++++------------------- 3 files changed, 31 insertions(+), 39 deletions(-) diff --git a/src-tauri/src/vdf/preset.rs b/src-tauri/src/vdf/preset.rs index 7ded5a6..a290659 100644 --- a/src-tauri/src/vdf/preset.rs +++ b/src-tauri/src/vdf/preset.rs @@ -228,7 +228,7 @@ pub fn parse_local_users(steam_dir: &str) -> Result> { let kv: HashMap = serde_json::from_str(&json_data)?; // 剥离顶层 UserLocalConfigStore - let kv = kv.get("UserLocalConfigStore").and_then(|v| v.as_object()).unwrap(); + // let kv = kv.get("UserLocalConfigStore").and_then(|v| v.as_object()).unwrap(); // 获取 friends 节点 let friends = kv.get("friends").and_then(|v| v.as_object()); diff --git a/src/components/cstb/VideoSetting.tsx b/src/components/cstb/VideoSetting.tsx index 7d852d2..e3f7b2c 100644 --- a/src/components/cstb/VideoSetting.tsx +++ b/src/components/cstb/VideoSetting.tsx @@ -47,25 +47,25 @@ const VideoSetting = () => { 2: "2X MSAA", 4: "4X MSAA", 8: "8X MSAA", - }[parseInt(video.msaa_samples)] || "无", + }[parseInt(video.msaa_samples, 10)] || "无", options: ["无", "2X MSAA", "4X MSAA", "8X MSAA"], }, { type: "videocfg_shadow_quality", title: "全局阴影效果", - value: ["低", "中", "高", "非常高"][parseInt(video.videocfg_shadow_quality)] || "低", + value: ["低", "中", "高", "非常高"][parseInt(video.videocfg_shadow_quality, 10)] || "低", options: ["低", "中", "高", "非常高"], }, { type: "videocfg_dynamic_shadows", title: "动态阴影", - value: ["仅限日光", "全部"][parseInt(video.videocfg_dynamic_shadows)] || "仅限日光", + value: ["仅限日光", "全部"][parseInt(video.videocfg_dynamic_shadows, 10)] || "仅限日光", options: ["仅限日光", "全部"], }, { type: "videocfg_texture_detail", title: "模型/贴图细节", - value: ["低", "中", "高"][parseInt(video.videocfg_texture_detail)] || "低", + value: ["低", "中", "高"][parseInt(video.videocfg_texture_detail, 10)] || "低", options: ["低", "中", "高"], }, { @@ -73,33 +73,33 @@ const VideoSetting = () => { title: "贴图过滤模式", value: ["双线性", "三线性", "异向 2X", "异向 4X", "异向 8X", "异向 16X"][ - parseInt(video.r_texturefilteringquality) + parseInt(video.r_texturefilteringquality, 10) ] || "双线性", options: ["双线性", "三线性", "异向 2X", "异向 4X", "异向 8X", "异向 16X"], }, { type: "videocfg_hdr_detail", title: "光影细节", - value: ["低", "高"][parseInt(video.shaderquality)] || "低", + value: ["低", "高"][parseInt(video.shaderquality, 10)] || "低", options: ["低", "高"], }, { type: "videocfg_particle_detail", title: "粒子细节", - value: ["低", "中", "高", "非常高"][parseInt(video.videocfg_particle_detail)] || "低", + value: ["低", "中", "高", "非常高"][parseInt(video.videocfg_particle_detail, 10)] || "低", options: ["低", "中", "高", "非常高"], }, { type: "videocfg_ao_detail", title: "环境光遮蔽", - value: ["已禁用", "中", "高"][parseInt(video.videocfg_ao_detail)] || "已禁用", + value: ["已禁用", "中", "高"][parseInt(video.videocfg_ao_detail, 10)] || "已禁用", options: ["已禁用", "中", "高"], }, { type: "videocfg_fsr_detail", title: "Fidelity FX 超级分辨率", value: - ["已禁用", "超高品质", "品质", "均衡", "性能"][parseInt(video.videocfg_fsr_detail)] || + ["已禁用", "超高品质", "品质", "均衡", "性能"][parseInt(video.videocfg_fsr_detail, 10)] || "性能", options: ["性能", "均衡", "品质", "超高品质", "已禁用"], }, @@ -108,6 +108,11 @@ const VideoSetting = () => { const [vconfig, setVconfig] = useState(tool.state.videoSetting) + useEffect(() => { + console.log("讀取設置") + void tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0) + }, []) + return ( @@ -134,7 +139,9 @@ const VideoSetting = () => { steam.currentUser()?.steam_id32 || 0, vconfig ) - addToast({ title: "测试中 功能完成后可应用设置到游戏" }) + await tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0) + setEdit(false) + addToast({ title: "应用设置成功" }) }} > @@ -142,8 +149,8 @@ const VideoSetting = () => { )} - - { + { + await tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0) setVconfig(tool.state.videoSetting) setEdit(!edit) }}> @@ -159,7 +166,6 @@ const VideoSetting = () => { )} - diff --git a/src/store/tool.ts b/src/store/tool.ts index 83a22e5..114ce74 100644 --- a/src/store/tool.ts +++ b/src/store/tool.ts @@ -49,12 +49,9 @@ export interface VideoSetting { // TODO: 校准 export const VideoSettingTemplate = { veryhigh: { - cpu_level: "3", - gpu_mem_level: "3", - gpu_level: "3", - shaderquality: "0", + shaderquality: "1", r_texturefilteringquality: "3", - msaa_samples: "2", + msaa_samples: "8", r_csgo_cmaa_enable: "0", videocfg_shadow_quality: "0", videocfg_dynamic_shadows: "1", @@ -64,12 +61,9 @@ export const VideoSettingTemplate = { videocfg_hdr_detail: "3", }, high: { - cpu_level: "3", - gpu_mem_level: "3", - gpu_level: "3", shaderquality: "0", - r_texturefilteringquality: "3", - msaa_samples: "2", + r_texturefilteringquality: "2", + msaa_samples: "4", r_csgo_cmaa_enable: "0", videocfg_shadow_quality: "0", videocfg_dynamic_shadows: "1", @@ -77,13 +71,11 @@ export const VideoSettingTemplate = { videocfg_particle_detail: "0", videocfg_ao_detail: "0", videocfg_hdr_detail: "3", + videocfg_fsr_detail: "0", }, middle: { - cpu_level: "3", - gpu_mem_level: "3", - gpu_level: "3", shaderquality: "0", - r_texturefilteringquality: "3", + r_texturefilteringquality: "2", msaa_samples: "2", r_csgo_cmaa_enable: "0", videocfg_shadow_quality: "0", @@ -91,27 +83,21 @@ export const VideoSettingTemplate = { videocfg_texture_detail: "1", videocfg_particle_detail: "0", videocfg_ao_detail: "0", - videocfg_hdr_detail: "3", + videocfg_fsr_detail: "1", }, low: { - cpu_level: "3", - gpu_mem_level: "3", - gpu_level: "3", shaderquality: "0", - r_texturefilteringquality: "3", - msaa_samples: "2", + r_texturefilteringquality: "0", + msaa_samples: "0", r_csgo_cmaa_enable: "0", videocfg_shadow_quality: "0", videocfg_dynamic_shadows: "1", videocfg_texture_detail: "1", videocfg_particle_detail: "0", videocfg_ao_detail: "0", - videocfg_hdr_detail: "3", + videocfg_fsr_detail: "2", }, recommend: { - cpu_level: "3", - gpu_mem_level: "3", - gpu_level: "3", shaderquality: "0", r_texturefilteringquality: "3", msaa_samples: "2", @@ -121,7 +107,7 @@ export const VideoSettingTemplate = { videocfg_texture_detail: "1", videocfg_particle_detail: "0", videocfg_ao_detail: "0", - videocfg_hdr_detail: "3", + videocfg_fsr_detail: "0", }, } -- 2.49.1 From 0e7e6dd3baed3623e9ec52b794cb706808b6f2e1 Mon Sep 17 00:00:00 2001 From: Purp1e <47248616+Purple-CSGO@users.noreply.github.com> Date: Thu, 27 Mar 2025 17:36:04 +0800 Subject: [PATCH 06/10] [feat] enable tab switch in edit mode --- src-tauri/src/vdf/preset.rs | 12 +- src/components/cstb/VideoSetting.tsx | 232 +++++++++++++++++++++++---- src/store/tool.ts | 42 ++--- 3 files changed, 230 insertions(+), 56 deletions(-) diff --git a/src-tauri/src/vdf/preset.rs b/src-tauri/src/vdf/preset.rs index a290659..297b390 100644 --- a/src-tauri/src/vdf/preset.rs +++ b/src-tauri/src/vdf/preset.rs @@ -355,9 +355,9 @@ pub fn get_cs2_video(file_path: &str) -> Result { let json_data = super::parse::to_json(&data); let kv: HashMap = serde_json::from_str(&json_data)?; let video_config = VideoConfig { - version: kv.get("version").unwrap_or(&"".to_string()).to_string(), - vendor_id: kv.get("vendor_id").unwrap_or(&"".to_string()).to_string(), - device_id: kv.get("device_id").unwrap_or(&"".to_string()).to_string(), + version: kv.get("Version").unwrap_or(&"".to_string()).to_string(), + vendor_id: kv.get("VendorID").unwrap_or(&"".to_string()).to_string(), + device_id: kv.get("DeviceID").unwrap_or(&"".to_string()).to_string(), cpu_level: kv .get("setting.cpu_level") .unwrap_or(&"".to_string()) @@ -414,7 +414,7 @@ pub fn get_cs2_video(file_path: &str) -> Result { .get("setting.high_dpi") .unwrap_or(&"".to_string()) .to_string(), - auto_config: kv.get("auto_config").unwrap_or(&"".to_string()).to_string(), + auto_config: kv.get("AutoConfig").unwrap_or(&"".to_string()).to_string(), shaderquality: kv .get("setting.shaderquality") .unwrap_or(&"".to_string()) @@ -486,6 +486,9 @@ pub fn set_cs2_video(file_path: &str, data: VideoConfig) -> Result<()> { let updated_content = re.replace_all(&file_content, |caps: ®ex::Captures| { let key = &caps[1]; // 捕获的键名 let value = match key { + "Version" => &data.version, + "VendorID" => &data.vendor_id, + "DeviceID" => &data.device_id, "setting.cpu_level" => &data.cpu_level, "setting.gpu_mem_level" => &data.gpu_mem_level, "setting.gpu_level" => &data.gpu_level, @@ -500,6 +503,7 @@ pub fn set_cs2_video(file_path: &str, data: VideoConfig) -> Result<()> { "setting.mat_vsync" => &data.mat_vsync, "setting.fullscreen_min_on_focus_loss" => &data.fullscreen_min_on_focus_loss, "setting.high_dpi" => &data.high_dpi, + "AutoConfig" => &data.auto_config, "setting.shaderquality" => &data.shaderquality, "setting.r_texturefilteringquality" => &data.r_texturefilteringquality, "setting.msaa_samples" => &data.msaa_samples, diff --git a/src/components/cstb/VideoSetting.tsx b/src/components/cstb/VideoSetting.tsx index e3f7b2c..f6e29b0 100644 --- a/src/components/cstb/VideoSetting.tsx +++ b/src/components/cstb/VideoSetting.tsx @@ -19,24 +19,63 @@ const VideoSetting = () => { title: "全屏", value: video.fullscreen === "1" ? "全屏" : "窗口", options: ["窗口", "全屏"], + mapping: (value: string) => { + return ( + { + 窗口: "0", + 全屏: "1", + }[value] || "0" + ) + }, }, { type: "mat_vsync", title: "垂直同步", value: video.mat_vsync === "1" ? "开启" : "关闭", options: ["关闭", "开启"], + mapping: (value: string) => { + return ( + { + 关闭: "0", + 开启: "1", + }[value] || "0" + ) + }, }, { type: "r_low_latency", title: "低延迟模式", value: video.r_low_latency === "1" ? "开启" : "关闭", options: ["关闭", "开启"], + mapping: (value: string) => { + return ( + { + 关闭: "0", + 开启: "1", + }[value] || "0" + ) + }, }, + // TODO: 改选项不在 cs2_video.txt 中 + // { + // type: "r_player_visible_mode", + // title: "增强角色对比度", + // value: video.r_csgo_cmaa_enable === "1" ? "启用" : "禁用", + // options: ["禁用", "启用"], + // }, { type: "r_csgo_cmaa_enable", - title: "增强角色对比度", - value: video.r_csgo_cmaa_enable === "1" ? "启用" : "禁用", - options: ["禁用", "启用"], + title: "CMAA2抗锯齿", + value: video.r_csgo_cmaa_enable === "1" ? "开启" : "关闭", + options: ["关闭", "开启"], + mapping: (value: string) => { + return ( + { + 关闭: "0", + 开启: "1", + }[value] || "0" + ) + }, }, { type: "msaa_samples", @@ -49,24 +88,61 @@ const VideoSetting = () => { 8: "8X MSAA", }[parseInt(video.msaa_samples, 10)] || "无", options: ["无", "2X MSAA", "4X MSAA", "8X MSAA"], + mapping: (value: string) => { + return ( + { + 无: 0, + "2X MSAA": 2, + "4X MSAA": 4, + "8X MSAA": 8, + }[value] || "0" + ) + }, }, { type: "videocfg_shadow_quality", title: "全局阴影效果", value: ["低", "中", "高", "非常高"][parseInt(video.videocfg_shadow_quality, 10)] || "低", options: ["低", "中", "高", "非常高"], + mapping: (value: string) => { + return ( + { + 低: "0", + 中: "1", + 高: "2", + 非常高: "3", + }[value] || "0" + ) + }, }, { type: "videocfg_dynamic_shadows", title: "动态阴影", value: ["仅限日光", "全部"][parseInt(video.videocfg_dynamic_shadows, 10)] || "仅限日光", options: ["仅限日光", "全部"], + mapping: (value: string) => { + return ( + { + 仅限日光: "0", + 全部: "1", + }[value] || "0" + ) + }, }, { type: "videocfg_texture_detail", title: "模型/贴图细节", value: ["低", "中", "高"][parseInt(video.videocfg_texture_detail, 10)] || "低", options: ["低", "中", "高"], + mapping: (value: string) => { + return ( + { + 低: "0", + 中: "1", + 高: "2", + }[value] || "0" + ) + }, }, { type: "r_texturefilteringquality", @@ -76,24 +152,67 @@ const VideoSetting = () => { parseInt(video.r_texturefilteringquality, 10) ] || "双线性", options: ["双线性", "三线性", "异向 2X", "异向 4X", "异向 8X", "异向 16X"], + mapping: (value: string) => { + return ( + { + 双线性: "0", + 三线性: "1", + "异向 2X": "2", + "异向 4X": "3", + "异向 8X": "4", + "异向 16X": "5", + }[value] || "0" + ) + }, }, { type: "videocfg_hdr_detail", title: "光影细节", - value: ["低", "高"][parseInt(video.shaderquality, 10)] || "低", + value: + { + "3": "低", + "-1": "高", + }[parseInt(video.videocfg_hdr_detail, 10)] || "低", options: ["低", "高"], + mapping: (value: string) => { + return ( + { + 低: "3", + 高: "-1", + }[value] || "3" + ) + }, }, { type: "videocfg_particle_detail", title: "粒子细节", value: ["低", "中", "高", "非常高"][parseInt(video.videocfg_particle_detail, 10)] || "低", options: ["低", "中", "高", "非常高"], + mapping: (value: string) => { + return ( + { + 低: "0", + 中: "1", + 高: "2", + 非常高: "3", + }[value] || "低" + ) + }, }, { type: "videocfg_ao_detail", title: "环境光遮蔽", value: ["已禁用", "中", "高"][parseInt(video.videocfg_ao_detail, 10)] || "已禁用", options: ["已禁用", "中", "高"], + mapping: (value: string) => { + return ( + { + 已禁用: "0", + 中: "1", + 高: "2", + }[value] || "已禁用" + ) + }, }, { type: "videocfg_fsr_detail", @@ -102,6 +221,17 @@ const VideoSetting = () => { ["已禁用", "超高品质", "品质", "均衡", "性能"][parseInt(video.videocfg_fsr_detail, 10)] || "性能", options: ["性能", "均衡", "品质", "超高品质", "已禁用"], + mapping: (value: string) => { + return ( + { + 已禁用: "0", + 超高品质: "1", + 品质: "2", + 均衡: "3", + 性能: "4", + }[value] || "已禁用" + ) + }, }, ] } @@ -109,8 +239,8 @@ const VideoSetting = () => { const [vconfig, setVconfig] = useState(tool.state.videoSetting) useEffect(() => { - console.log("讀取設置") - void tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0) + if (steam.state.steamDirValid && steam.currentUser()) + void tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0) }, []) return ( @@ -127,11 +257,27 @@ const VideoSetting = () => { ))} */} {edit && ( <> - setVconfig({ ...vconfig, ...VideoSettingTemplate.low })}>低 - setVconfig({ ...vconfig, ...VideoSettingTemplate.middle })}>中 - setVconfig({ ...vconfig, ...VideoSettingTemplate.high })}>高 - setVconfig({ ...vconfig, ...VideoSettingTemplate.veryhigh })}>非常高 - setVconfig({ ...vconfig, ...VideoSettingTemplate.recommend })}>推荐 + setVconfig({ ...vconfig, ...VideoSettingTemplate.low })}> + 低 + + setVconfig({ ...vconfig, ...VideoSettingTemplate.middle })} + > + 中 + + setVconfig({ ...vconfig, ...VideoSettingTemplate.high })}> + 高 + + setVconfig({ ...vconfig, ...VideoSettingTemplate.veryhigh })} + > + 非常高 + + setVconfig({ ...vconfig, ...VideoSettingTemplate.recommend })} + > + 推荐 + { await tool.setVideoConfig( @@ -139,7 +285,10 @@ const VideoSetting = () => { steam.currentUser()?.steam_id32 || 0, vconfig ) - await tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0) + await tool.getVideoConfig( + steam.state.steamDir, + steam.currentUser()?.steam_id32 || 0 + ) setEdit(false) addToast({ title: "应用设置成功" }) }} @@ -149,28 +298,37 @@ const VideoSetting = () => { )} - { - await tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0) + { + if (steam.state.steamDirValid && steam.currentUser()) + await tool.getVideoConfig( + steam.state.steamDir, + steam.currentUser()?.steam_id32 || 0 + ) setVconfig(tool.state.videoSetting) setEdit(!edit) - }}> - {edit ? ( - <> - - 取消编辑 - - ) : ( - <> - - 编辑 - - )} - + }} + > + {edit ? ( + <> + + 取消编辑 + + ) : ( + <> + + 编辑 + + )} + - void tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0) - } + onClick={async () => { + if (steam.state.steamDirValid && steam.currentUser()) { + void tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0) + addToast({ title: "读取成功" }) + } else addToast({ title: "请先选择用户", color: "danger" }) + }} > 读取 @@ -243,14 +401,24 @@ const VideoSetting = () => {
  • {vid.title} { + console.log(vid.type, key) + // 修改 vconfig 名为 vid.type 的 value为 key + edit && key + ? setVconfig({ + ...vconfig, + [vid.type]: vid.mapping?.(key.toString()), + }) + : null + }} > {vid.options.map((opt, _) => ( - + ))}
  • diff --git a/src/store/tool.ts b/src/store/tool.ts index 114ce74..0b4a7d8 100644 --- a/src/store/tool.ts +++ b/src/store/tool.ts @@ -46,44 +46,44 @@ export interface VideoSetting { } // 视频设置预设模版 -// TODO: 校准 export const VideoSettingTemplate = { veryhigh: { shaderquality: "1", r_texturefilteringquality: "3", msaa_samples: "8", r_csgo_cmaa_enable: "0", - videocfg_shadow_quality: "0", + videocfg_shadow_quality: "3", videocfg_dynamic_shadows: "1", - videocfg_texture_detail: "1", - videocfg_particle_detail: "0", - videocfg_ao_detail: "0", - videocfg_hdr_detail: "3", + videocfg_texture_detail: "2", + videocfg_particle_detail: "3", + videocfg_ao_detail: "3", + videocfg_hdr_detail: "-1", + videocfg_fsr_detail: "0", }, high: { - shaderquality: "0", - r_texturefilteringquality: "2", + shaderquality: "1", + r_texturefilteringquality: "3", msaa_samples: "4", r_csgo_cmaa_enable: "0", - videocfg_shadow_quality: "0", + videocfg_shadow_quality: "2", videocfg_dynamic_shadows: "1", - videocfg_texture_detail: "1", - videocfg_particle_detail: "0", - videocfg_ao_detail: "0", - videocfg_hdr_detail: "3", + videocfg_texture_detail: "2", + videocfg_particle_detail: "2", + videocfg_ao_detail: "2", + videocfg_hdr_detail: "-1", videocfg_fsr_detail: "0", }, middle: { shaderquality: "0", - r_texturefilteringquality: "2", + r_texturefilteringquality: "1", msaa_samples: "2", r_csgo_cmaa_enable: "0", - videocfg_shadow_quality: "0", + videocfg_shadow_quality: "1", videocfg_dynamic_shadows: "1", videocfg_texture_detail: "1", - videocfg_particle_detail: "0", + videocfg_particle_detail: "1", videocfg_ao_detail: "0", - videocfg_fsr_detail: "1", + videocfg_fsr_detail: "2", }, low: { shaderquality: "0", @@ -91,11 +91,12 @@ export const VideoSettingTemplate = { msaa_samples: "0", r_csgo_cmaa_enable: "0", videocfg_shadow_quality: "0", - videocfg_dynamic_shadows: "1", - videocfg_texture_detail: "1", + videocfg_dynamic_shadows: "0", + videocfg_texture_detail: "0", videocfg_particle_detail: "0", videocfg_ao_detail: "0", - videocfg_fsr_detail: "2", + videocfg_hdr_detail: "3", + videocfg_fsr_detail: "3", }, recommend: { shaderquality: "0", @@ -107,6 +108,7 @@ export const VideoSettingTemplate = { videocfg_texture_detail: "1", videocfg_particle_detail: "0", videocfg_ao_detail: "0", + videocfg_hdr_detail: "3", videocfg_fsr_detail: "0", }, } -- 2.49.1 From dabbab9f3e204c2c873e3a2000b504bc188c31b1 Mon Sep 17 00:00:00 2001 From: Purp1e <47248616+Purple-CSGO@users.noreply.github.com> Date: Thu, 27 Mar 2025 17:39:22 +0800 Subject: [PATCH 07/10] [fix] lint errors + new version --- src-tauri/tauri.conf.json | 2 +- src/components/cstb/VideoSetting.tsx | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 45a2cc1..dedc186 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -42,7 +42,7 @@ }, "productName": "CS工具箱", "mainBinaryName": "cstb", - "version": "0.0.5-beta.4", + "version": "0.0.5-beta.5", "identifier": "upup.cool", "plugins": { "deep-link": { diff --git a/src/components/cstb/VideoSetting.tsx b/src/components/cstb/VideoSetting.tsx index f6e29b0..0739a90 100644 --- a/src/components/cstb/VideoSetting.tsx +++ b/src/components/cstb/VideoSetting.tsx @@ -325,7 +325,10 @@ const VideoSetting = () => { { if (steam.state.steamDirValid && steam.currentUser()) { - void tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0) + await tool.getVideoConfig( + steam.state.steamDir, + steam.currentUser()?.steam_id32 || 0 + ) addToast({ title: "读取成功" }) } else addToast({ title: "请先选择用户", color: "danger" }) }} @@ -366,7 +369,7 @@ const VideoSetting = () => { 10 )} onValueChange={(value) => { - edit + const _ = edit ? setVconfig({ ...vconfig, defaultres: value.toString(), @@ -407,14 +410,15 @@ const VideoSetting = () => { fullWidth selectedKey={vid.value} onSelectionChange={(key) => { - console.log(vid.type, key) + // console.log(vid.type, key) // 修改 vconfig 名为 vid.type 的 value为 key - edit && key - ? setVconfig({ - ...vconfig, - [vid.type]: vid.mapping?.(key.toString()), - }) - : null + const _ = + edit && key + ? setVconfig({ + ...vconfig, + [vid.type]: vid.mapping(key.toString()), + }) + : null }} > {vid.options.map((opt, _) => ( -- 2.49.1 From 7ec20984c4533a08d18f7893fd80babcc077e74a Mon Sep 17 00:00:00 2001 From: Purp1e <47248616+Purple-CSGO@users.noreply.github.com> Date: Thu, 27 Mar 2025 17:40:02 +0800 Subject: [PATCH 08/10] v0.0.5 --- src-tauri/tauri.conf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index dedc186..116502d 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -42,7 +42,7 @@ }, "productName": "CS工具箱", "mainBinaryName": "cstb", - "version": "0.0.5-beta.5", + "version": "0.0.5", "identifier": "upup.cool", "plugins": { "deep-link": { -- 2.49.1 From faec03afb13570a70c16fb262538112a1c3f8082 Mon Sep 17 00:00:00 2001 From: Purp1e <47248616+Purple-CSGO@users.noreply.github.com> Date: Thu, 27 Mar 2025 18:02:51 +0800 Subject: [PATCH 09/10] [fix] some vconfig not applied -> stable release --- src-tauri/src/vdf/preset.rs | 2 +- src/components/cstb/VideoSetting.tsx | 29 ++++++++++++++-------------- src/store/tool.ts | 2 +- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src-tauri/src/vdf/preset.rs b/src-tauri/src/vdf/preset.rs index 297b390..902418b 100644 --- a/src-tauri/src/vdf/preset.rs +++ b/src-tauri/src/vdf/preset.rs @@ -480,7 +480,7 @@ pub fn set_cs2_video(file_path: &str, data: VideoConfig) -> Result<()> { let file_content = fs::read_to_string(file_path)?; // 定义正则表达式匹配模式 - let re = Regex::new(r#""(setting\.\w+)"\s+"\d+""#).unwrap(); + let re = Regex::new(r#""(setting\.\w+)"\s+"-?\d+""#).unwrap(); // 替换字段值 let updated_content = re.replace_all(&file_content, |caps: ®ex::Captures| { diff --git a/src/components/cstb/VideoSetting.tsx b/src/components/cstb/VideoSetting.tsx index 0739a90..f70f7b4 100644 --- a/src/components/cstb/VideoSetting.tsx +++ b/src/components/cstb/VideoSetting.tsx @@ -91,10 +91,10 @@ const VideoSetting = () => { mapping: (value: string) => { return ( { - 无: 0, - "2X MSAA": 2, - "4X MSAA": 4, - "8X MSAA": 8, + 无: "0", + "2X MSAA": "2", + "4X MSAA": "4", + "8X MSAA": "8", }[value] || "0" ) }, @@ -168,11 +168,7 @@ const VideoSetting = () => { { type: "videocfg_hdr_detail", title: "光影细节", - value: - { - "3": "低", - "-1": "高", - }[parseInt(video.videocfg_hdr_detail, 10)] || "低", + value: video.videocfg_hdr_detail === "-1" ? "高" : "低", options: ["低", "高"], mapping: (value: string) => { return ( @@ -386,12 +382,17 @@ const VideoSetting = () => { /> { - tool.setVideoSetting({ - ...tool.state.videoSetting, - defaultresheight: value.toString(), - }) + const _ = edit + ? setVconfig({ + ...vconfig, + defaultresheight: value.toString(), + }) + : tool.setVideoSetting({ + ...tool.state.videoSetting, + defaultresheight: value.toString(), + }) }} radius="full" step={10} diff --git a/src/store/tool.ts b/src/store/tool.ts index 0b4a7d8..631d2e4 100644 --- a/src/store/tool.ts +++ b/src/store/tool.ts @@ -229,8 +229,8 @@ const getVideoConfig = async (steam_dir: string, steam_id32: number) => { } const setVideoConfig = async (steam_dir: string, steam_id32: number, video_config: VideoSetting) => { + console.log(video_config.videocfg_hdr_detail) await invoke("set_cs2_video_config", { steamDir: steam_dir, steamId32: steam_id32, videoConfig: video_config }) - // console.log(video) } const addLaunchOption = (option: LaunchOption) => { -- 2.49.1 From bbcaf8e0d1a1a6b0471ace9f0c1d72389d46f752 Mon Sep 17 00:00:00 2001 From: Purp1e <47248616+Purple-CSGO@users.noreply.github.com> Date: Thu, 27 Mar 2025 18:19:53 +0800 Subject: [PATCH 10/10] [fix] missing light(shader) setting + tray emit triggers multiple times --- src/app/layout.tsx | 2 +- src/components/cstb/VideoSetting.tsx | 24 +++++++++++++++++++----- src/store/tool.ts | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index f718222..7f92ba3 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -45,7 +45,7 @@ export default function RootLayout({ children }: { children: React.ReactNode }) addToast({ title: `电源计划已切换 → ${PowerPlans[current].title}` }) }) - }) + }, []) // 检测steam路径和游戏路径是否有效 const debounceSteamDir = useDebounce(steam.state.steamDir, { diff --git a/src/components/cstb/VideoSetting.tsx b/src/components/cstb/VideoSetting.tsx index f70f7b4..94ae728 100644 --- a/src/components/cstb/VideoSetting.tsx +++ b/src/components/cstb/VideoSetting.tsx @@ -166,16 +166,16 @@ const VideoSetting = () => { }, }, { - type: "videocfg_hdr_detail", + type: "shaderquality", title: "光影细节", - value: video.videocfg_hdr_detail === "-1" ? "高" : "低", + value: video.shaderquality === "1" ? "高" : "低", options: ["低", "高"], mapping: (value: string) => { return ( { - 低: "3", - 高: "-1", - }[value] || "3" + 低: "0", + 高: "1", + }[value] || "0" ) }, }, @@ -210,6 +210,20 @@ const VideoSetting = () => { ) }, }, + { + type: "videocfg_hdr_detail", + title: "高动态范围", + value: video.videocfg_hdr_detail === "-1" ? "品质" : "性能", + options: ["性能", "品质"], + mapping: (value: string) => { + return ( + { + 性能: "3", + 品质: "-1", + }[value] || "3" + ) + }, + }, { type: "videocfg_fsr_detail", title: "Fidelity FX 超级分辨率", diff --git a/src/store/tool.ts b/src/store/tool.ts index 631d2e4..ea1570f 100644 --- a/src/store/tool.ts +++ b/src/store/tool.ts @@ -29,7 +29,7 @@ export interface VideoSetting { fullscreen_min_on_focus_loss: string; // 失去焦点时最小化全屏 high_dpi: string; // 高DPI auto_config: string; // 自动配置 - shaderquality: string; // 着色器质量 + shaderquality: string; // 光影质量 r_texturefilteringquality: string; // 纹理过滤质量 msaa_samples: string; // 多重采样抗锯齿样本数 r_csgo_cmaa_enable: string; // CMAA抗锯齿启用 -- 2.49.1