use crate::steam; use crate::tool::*; use crate::tool::updater::{check_update, download_update, install_update, UpdateInfo}; use crate::vdf::preset; use crate::vdf::preset::VideoConfig; use crate::wrap_err; use anyhow::Result; use std::fs::File; use std::fs; use std::path::Path; use std::io::{BufRead, BufReader}; use tauri::path::BaseDirectory; use tauri::Manager; // use tauri_plugin_shell::ShellExt; // pub type Result = Result; #[tauri::command] pub fn greet(name: &str) -> Result { Ok(format!("Hello, {}! You've been greeted from Rust!", name)) } // 工具 #[tauri::command] pub fn launch_game(steam_path: &str, launch_option: &str, server: &str) -> Result { println!( "{}: launching game on server: {}, with launch Option {}", steam_path, server, launch_option ); // wrap_err!(steam::launch_game(steam_path, launch_option, server)); // 如果有错误,打印出来 if let Err(e) = steam::launch_game(steam_path, launch_option, server) { println!("Error: {}", e); return Err(e.to_string()); } // steam::launch_game(steam_path, launch_option, server); Ok(format!( "Launching game on server: {}, with launch Option {}", server, launch_option )) } #[tauri::command] pub fn kill_game() -> Result { Ok(common::kill("cs2.exe")) } #[tauri::command] pub fn check_process_running(process_name: &str) -> Result { Ok(common::check_process_running(process_name)) } #[tauri::command] pub fn kill_steam() -> Result { Ok(common::kill("steam.exe")) } // Steam #[tauri::command] pub fn get_steam_path() -> Result { wrap_err!(steam::path::get_steam_path()) } #[tauri::command] pub fn get_cs_path(name: &str, steam_dir: &str) -> Result { wrap_err!(steam::path::get_cs_path(name, steam_dir)) } #[tauri::command] pub fn open_path(path: &str) -> Result<(), String> { wrap_err!(common::open_path(path)) } #[tauri::command] pub fn get_powerplan() -> Result { #[cfg(target_os = "windows")] let powerplan = powerplan::get_powerplan()?; #[cfg(not(target_os = "windows"))] let powerplan = powerplan::PowerPlanMode::Other as i32; Ok(powerplan) } #[tauri::command] pub fn set_powerplan(plan: i32) -> Result<(), String> { #[cfg(target_os = "windows")] powerplan::set_powerplan(plan)?; Ok(()) } #[tauri::command] pub fn get_steam_users(steam_dir: &str) -> Result, String> { wrap_err!(preset::get_users(steam_dir)) } #[tauri::command] pub fn set_auto_login_user(user: &str) -> Result { #[cfg(target_os = "windows")] steam::reg::set_auto_login_user(user)?; 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()) } ///// 录像 #[tauri::command] pub async fn analyze_replay(app: tauri::AppHandle, path: &str) -> Result { // 检测文件是否存在 if !std::path::Path::new(&path).exists() { return Err("文件不存在".to_string()); } // 获取应用配置目录 let config_dir = app .path() .resolve("metadata", BaseDirectory::AppConfig) .expect("无法获取配置目录"); // 确保 metadata 文件夹存在 if !config_dir.exists() { fs::create_dir_all(&config_dir).expect("无法创建 metadata 文件夹"); } // 提取文件名部分 let file_name = std::path::Path::new(path) .file_name() .and_then(|name| name.to_str()) .unwrap_or("default_filename"); // 拼接输出文件路径 let output_path = config_dir.join(format!("{}.json", file_name)); // 确保输出文件存在,如果不存在则创建空文件 if !output_path.exists() { File::create(&output_path).expect("无法创建输出文件"); } // 调用项目绑定cli程序 let cli_path = app .path() .resolve("resources/csda", BaseDirectory::Resource) .expect("analyzer not found"); println!("cli path: {}", cli_path.display()); let output = std::process::Command::new(cli_path) .arg("-demo-path") .arg(path) .arg("-format") .arg("json") .arg("-minify") .arg("-output") .arg(output_path.to_str().expect("路径转换失败")) .output() .expect("Failed to execute command"); // 获取输出 let output_str = String::from_utf8_lossy(&output.stdout); // 打印输出 println!("{}", output_str); // 返回结果 Ok(output_str.to_string()) } // 帧数测试相关 #[tauri::command] pub fn get_console_log_path(cs_path: &str) -> Result { // cs_path 是类似 "game\bin\win64" 的路径,需要向上找到 game\csgo\console.log let path = Path::new(cs_path); // 向上找到 game 目录 if let Some(game_dir) = path.ancestors().find(|p| { p.file_name() .and_then(|n| n.to_str()) .map(|n| n == "game") .unwrap_or(false) }) { let console_log_path = game_dir.join("csgo").join("console.log"); Ok(console_log_path.to_string_lossy().to_string()) } else { Err("无法找到 game 目录".to_string()) } } #[tauri::command] pub fn read_vprof_report(console_log_path: &str) -> Result { let path = Path::new(console_log_path); if !path.exists() { return Err("console.log 文件不存在".to_string()); } let file = File::open(path).map_err(|e| format!("无法打开文件: {}", e))?; let reader = BufReader::new(file); let mut vprof_lines = Vec::new(); let mut in_vprof_section = false; let mut empty_line_count = 0; for line_result in reader.lines() { let line = line_result.map_err(|e| format!("读取行错误: {}", e))?; // 检测 [VProf] 标记 if line.contains("[VProf]") { in_vprof_section = true; empty_line_count = 0; vprof_lines.push(line.clone()); } else if in_vprof_section { // 如果在 VProf 部分中 if line.trim().is_empty() { empty_line_count += 1; // 如果遇到两个连续的空行,结束 VProf 部分 if empty_line_count >= 2 { break; } vprof_lines.push(line.clone()); } else { empty_line_count = 0; vprof_lines.push(line.clone()); } } } if vprof_lines.is_empty() { return Err("未找到 [VProf] 报告".to_string()); } Ok(vprof_lines.join("\n")) } // 更新相关命令 /// 检查更新 #[tauri::command] pub async fn check_app_update( app: tauri::AppHandle, custom_endpoint: Option, github_repo: Option, ) -> Result, String> { let current_version = app.package_info().version.to_string(); wrap_err!(check_update( custom_endpoint.as_deref(), github_repo.as_deref(), ¤t_version ).await) } /// 下载更新 #[tauri::command] pub async fn download_app_update( app: tauri::AppHandle, download_url: String, ) -> Result { let path = wrap_err!(download_update( &app, &download_url, None // 可以添加进度回调 ).await)?; Ok(path.to_string_lossy().to_string()) } /// 安装更新 #[tauri::command] pub fn install_app_update(installer_path: String) -> Result<(), String> { wrap_err!(install_update(&installer_path)) }