diff --git a/bun.lockb b/bun.lockb index 3fd6beb..372e016 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 2d7348b..c672361 100644 --- a/package.json +++ b/package.json @@ -23,44 +23,44 @@ "@reactuses/core": "6.0.1", "@supabase/ssr": "0.6.1", "@tauri-apps/api": "2.4.0", - "@tauri-apps/plugin-autostart": "^2.2.0", - "@tauri-apps/plugin-cli": "~2", + "@tauri-apps/plugin-autostart": "^2.3.0", + "@tauri-apps/plugin-cli": "~2.2.0", "@tauri-apps/plugin-clipboard-manager": "2.2.2", - "@tauri-apps/plugin-deep-link": "~2.2.0", - "@tauri-apps/plugin-dialog": "~2.2.0", + "@tauri-apps/plugin-deep-link": "~2.2.1", + "@tauri-apps/plugin-dialog": "~2.2.1", "@tauri-apps/plugin-fs": "2.2.0", "@tauri-apps/plugin-global-shortcut": "2.2.0", "@tauri-apps/plugin-http": "2.4.2", "@tauri-apps/plugin-notification": "2.2.2", "@tauri-apps/plugin-os": "2.2.1", "@tauri-apps/plugin-process": "2.2.0", - "@tauri-apps/plugin-shell": "2.2.0", + "@tauri-apps/plugin-shell": "~2.2.1", "@tauri-apps/plugin-store": "^2.2.0", "@tauri-store/valtio": "2.1.1", "@types/throttle-debounce": "^5.0.2", "ahooks": "^3.8.4", - "framer-motion": "^12.5.0", - "next": "15.2.4", + "framer-motion": "^12.6.3", + "next": "15.2.3", "next-themes": "^0.4.6", - "react": "^19.0.0", - "react-dom": "^19.0.0", + "react": "^19.1.0", + "react-dom": "^19.1.0", "react-markdown": "^10.1.0", "remark-gfm": "^4.0.1", "swr": "^2.3.3", "tauri-plugin-system-info-api": "^2.0.10" }, "devDependencies": { - "@tauri-apps/cli": "^2.4.0", + "@tauri-apps/cli": "^2.4.1", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.2.0", "@testing-library/user-event": "^14.6.1", "@types/jest": "^29.5.14", - "@types/node": "^22.13.13", + "@types/node": "^22.13.17", "@types/react": "19.0.10", "@types/react-dom": "19.0.4", - "@typescript-eslint/eslint-plugin": "^8.28.0", - "@typescript-eslint/parser": "^8.28.0", + "@typescript-eslint/eslint-plugin": "^8.29.0", + "@typescript-eslint/parser": "^8.29.0", "autoprefixer": "^10.4.21", "clsx": "^2.1.1", "cross-env": "^7.0.3", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 0690a5e..8cee61d 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -41,7 +41,7 @@ tauri-plugin-fs = "2.2.0" tauri-plugin-dialog = "2.2.0" tauri-plugin-os = "2.2.1" tauri-plugin-clipboard-manager = "2.2.2" -tauri-plugin-shell = "2.2.0" +tauri-plugin-shell = "2" tauri-plugin-http = "2.4.2" tauri-plugin-notification = "2.2.2" tauri-plugin-valtio = "2.1.1" diff --git a/src-tauri/capabilities/desktop.json b/src-tauri/capabilities/desktop.json index a09f320..0e759ef 100644 --- a/src-tauri/capabilities/desktop.json +++ b/src-tauri/capabilities/desktop.json @@ -28,6 +28,8 @@ "autostart:default", "autostart:allow-enable", "autostart:allow-disable", - "cli:default" + "cli:default", + "fs:allow-read-text-file", + "fs:allow-resource-read-recursive" ] } \ No newline at end of file diff --git a/src-tauri/gen/schemas/capabilities.json b/src-tauri/gen/schemas/capabilities.json index 0ed4170..885c09f 100644 --- a/src-tauri/gen/schemas/capabilities.json +++ b/src-tauri/gen/schemas/capabilities.json @@ -1 +1 @@ -{"desktop-capability":{"identifier":"desktop-capability","description":"","local":true,"windows":["main"],"permissions":["global-shortcut:default","theme:default","store:default","store:allow-set","store:allow-get-store","store:allow-has","store:allow-delete","store:allow-clear","store:allow-values","store:allow-save","store:allow-load","store:allow-reset","store:allow-entries","deep-link:default","deep-link:allow-register","deep-link:allow-get-current","autostart:default","autostart:allow-enable","autostart:allow-disable","cli:default"],"platforms":["macOS","windows","linux"]},"migrated":{"identifier":"migrated","description":"permissions that were migrated from v1","local":true,"windows":["main"],"permissions":["core:default","fs:allow-read-file","fs:allow-write-file","fs:allow-read-dir","fs:allow-copy-file","fs:allow-mkdir","fs:allow-remove","fs:allow-remove","fs:allow-rename","fs:allow-exists","core:window:allow-create","core:window:allow-center","core:window:allow-request-user-attention","core:window:allow-set-resizable","core:window:allow-set-maximizable","core:window:allow-set-minimizable","core:window:allow-set-closable","core:window:allow-set-title","core:window:allow-maximize","core:window:allow-unmaximize","core:window:allow-minimize","core:window:allow-unminimize","core:window:allow-show","core:window:allow-hide","core:window:allow-close","core:window:allow-set-decorations","core:window:allow-set-always-on-top","core:window:allow-set-content-protected","core:window:allow-set-size","core:window:allow-set-min-size","core:window:allow-set-max-size","core:window:allow-set-position","core:window:allow-set-fullscreen","core:window:allow-set-focus","core:window:allow-set-icon","core:window:allow-set-skip-taskbar","core:window:allow-set-cursor-grab","core:window:allow-set-cursor-visible","core:window:allow-set-cursor-icon","core:window:allow-set-cursor-position","core:window:allow-set-ignore-cursor-events","core:window:allow-start-dragging","core:webview:allow-print","shell:allow-execute","shell:allow-open","dialog:allow-open","dialog:allow-save","dialog:allow-message","dialog:allow-ask","dialog:allow-confirm","http:default","notification:default","global-shortcut:allow-is-registered","global-shortcut:allow-register","global-shortcut:allow-register-all","global-shortcut:allow-unregister","global-shortcut:allow-unregister-all","os:allow-platform","os:allow-version","os:allow-os-type","os:allow-family","os:allow-arch","os:allow-exe-extension","os:allow-locale","os:allow-hostname","process:allow-restart","process:allow-exit","clipboard-manager:allow-read-text","clipboard-manager:allow-write-text","core:app:allow-app-show","core:app:allow-app-hide","core:app:allow-set-app-theme","process:default","fs:default","dialog:default","os:default","clipboard-manager:default"]},"system-info":{"identifier":"system-info","description":"","local":true,"windows":["*"],"permissions":["system-info:allow-all"]},"valtio":{"identifier":"valtio","description":"","local":true,"windows":["*"],"permissions":["valtio:default","core:event:default"]}} \ No newline at end of file +{"desktop-capability":{"identifier":"desktop-capability","description":"","local":true,"windows":["main"],"permissions":["global-shortcut:default","theme:default","store:default","store:allow-set","store:allow-get-store","store:allow-has","store:allow-delete","store:allow-clear","store:allow-values","store:allow-save","store:allow-load","store:allow-reset","store:allow-entries","deep-link:default","deep-link:allow-register","deep-link:allow-get-current","autostart:default","autostart:allow-enable","autostart:allow-disable","cli:default","fs:allow-read-text-file","fs:allow-resource-read-recursive"],"platforms":["macOS","windows","linux"]},"migrated":{"identifier":"migrated","description":"permissions that were migrated from v1","local":true,"windows":["main"],"permissions":["core:default","fs:allow-read-file","fs:allow-write-file","fs:allow-read-dir","fs:allow-copy-file","fs:allow-mkdir","fs:allow-remove","fs:allow-remove","fs:allow-rename","fs:allow-exists","core:window:allow-create","core:window:allow-center","core:window:allow-request-user-attention","core:window:allow-set-resizable","core:window:allow-set-maximizable","core:window:allow-set-minimizable","core:window:allow-set-closable","core:window:allow-set-title","core:window:allow-maximize","core:window:allow-unmaximize","core:window:allow-minimize","core:window:allow-unminimize","core:window:allow-show","core:window:allow-hide","core:window:allow-close","core:window:allow-set-decorations","core:window:allow-set-always-on-top","core:window:allow-set-content-protected","core:window:allow-set-size","core:window:allow-set-min-size","core:window:allow-set-max-size","core:window:allow-set-position","core:window:allow-set-fullscreen","core:window:allow-set-focus","core:window:allow-set-icon","core:window:allow-set-skip-taskbar","core:window:allow-set-cursor-grab","core:window:allow-set-cursor-visible","core:window:allow-set-cursor-icon","core:window:allow-set-cursor-position","core:window:allow-set-ignore-cursor-events","core:window:allow-start-dragging","core:webview:allow-print","shell:allow-execute","shell:allow-open","dialog:allow-open","dialog:allow-save","dialog:allow-message","dialog:allow-ask","dialog:allow-confirm","http:default","notification:default","global-shortcut:allow-is-registered","global-shortcut:allow-register","global-shortcut:allow-register-all","global-shortcut:allow-unregister","global-shortcut:allow-unregister-all","os:allow-platform","os:allow-version","os:allow-os-type","os:allow-family","os:allow-arch","os:allow-exe-extension","os:allow-locale","os:allow-hostname","process:allow-restart","process:allow-exit","clipboard-manager:allow-read-text","clipboard-manager:allow-write-text","core:app:allow-app-show","core:app:allow-app-hide","core:app:allow-set-app-theme","process:default","fs:default","dialog:default","os:default","clipboard-manager:default"]},"system-info":{"identifier":"system-info","description":"","local":true,"windows":["*"],"permissions":["system-info:allow-all"]},"valtio":{"identifier":"valtio","description":"","local":true,"windows":["*"],"permissions":["valtio:default","core:event:default"]}} \ No newline at end of file diff --git a/src-tauri/resources/csda.exe b/src-tauri/resources/csda.exe new file mode 100644 index 0000000..5c1a7b3 Binary files /dev/null and b/src-tauri/resources/csda.exe differ diff --git a/src-tauri/src/cmds.rs b/src-tauri/src/cmds.rs index 8264f72..fc34809 100644 --- a/src-tauri/src/cmds.rs +++ b/src-tauri/src/cmds.rs @@ -4,6 +4,12 @@ use crate::vdf::preset; use crate::vdf::preset::VideoConfig; use crate::wrap_err; use anyhow::Result; +use std::fs::File; +use std::fs; +use tauri::path::BaseDirectory; +use tauri::Manager; + +// use tauri_plugin_shell::ShellExt; // pub type Result = Result; @@ -16,7 +22,17 @@ pub fn greet(name: &str) -> Result { #[tauri::command] pub fn launch_game(steam_path: &str, launch_option: &str, server: &str) -> Result { - wrap_err!(steam::launch_game(steam_path, launch_option, server)); + 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 {}", @@ -111,3 +127,64 @@ pub fn set_cs2_video_config( 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()) +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index a76a2fc..f8dd822 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -134,6 +134,7 @@ fn main() { cmds::get_cs2_video_config, cmds::set_cs2_video_config, cmds::check_path, + cmds::analyze_replay, on_button_clicked ]) .run(ctx) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 51d1056..f7fc72c 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -12,6 +12,9 @@ "copyright": "", "targets": "all", "externalBin": [], + "resources": [ + "resources/csda.exe" + ], "icon": [ "icons/32x32.png", "icons/128x128.png", @@ -32,7 +35,6 @@ "providerShortName": null, "signingIdentity": null }, - "resources": [], "shortDescription": "", "linux": { "deb": { @@ -42,7 +44,7 @@ }, "productName": "CS工具箱", "mainBinaryName": "cstb", - "version": "0.0.6-beta.1", + "version": "0.0.6-beta.2", "identifier": "upup.cool", "plugins": { "deep-link": { diff --git a/src/app/(main)/movie/page.tsx b/src/app/(main)/movie/page.tsx index b58f138..0bfe20b 100644 --- a/src/app/(main)/movie/page.tsx +++ b/src/app/(main)/movie/page.tsx @@ -1,4 +1,66 @@ "use client" + +import { Card, CardBody, CardHeader, CardIcon, CardTool } from "@/components/window/Card" +import { MovieBoard } from "@icon-park/react" +import { ToolButton } from "@/components/window/ToolButton" +import { invoke } from "@tauri-apps/api/core" +import path from "path" +import { useSteamStore } from "@/store/steam" +import { addToast } from "@heroui/react" +// import { Command } from "@tauri-apps/plugin-shell" + export default function Page() { - return
Movie
+ const steam = useSteamStore() + const testDemo = async (demo_name: string) => { + const res = await invoke("analyze_replay", { + path: path.resolve( + steam.cs2BaseDir(), + "game", + "csgo", + "replays", + "test.dem" + ), + }) + console.log("test.dem", "→", res) + // const demo_path = path.resolve( + // '"', + // steam.cs2BaseDir(), + // "game", + // "csgo", + // "replays", + // demo_name, + // '"' + // ) + // const command = Command.sidecar("bin/csda", [ + // "-demo-path", + // "D:\\Programs\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\game\\csgo\\replays", + // "-format", + // "json", + // "-minify", + // ]) + // const output = await command.execute() + // console.log("output", output) + addToast({ title: "解析成功" }) + } + return ( +
+ + + + 录像 + + + { + await testDemo("test.dem") + }} + > + 读取 + + + + 录像 + +
+ ) } diff --git a/src/app/(main)/users/layout.tsx b/src/app/(main)/users/layout.tsx index d68f9e3..485121c 100644 --- a/src/app/(main)/users/layout.tsx +++ b/src/app/(main)/users/layout.tsx @@ -10,7 +10,7 @@ export default function PreferenceLayout({ // const pathname = usePathname() return ( -
+
{/* ("tray://launch_game", async (event) => { await invoke("launch_game", { - steamPath: `${steam.state.steamDir}/steam.exe`, - launchOption: tool.state.launchOptions[tool.state.launchIndex].option || "", + steamPath: `${steamStore.state.steamDir}\\steam.exe`, + launchOption: toolStore.state.launchOptions[toolStore.state.launchIndex].option || "", server: event.payload || "worldwide", }) - addToast({ title: "启动国服成功" }) + addToast({ title: `启动${event.payload === "worldwide" ? "国际服" : "国服"}成功` }) }) void listen("tray://kill_steam", async () => { @@ -38,7 +38,7 @@ export default function RootLayout({ children }: { children: React.ReactNode }) }) void listen("tray://set_powerplan", async (event) => { - if (typeof(event.payload) === "number" && event.payload <= 0 && event.payload > 4) return + if (typeof event.payload === "number" && event.payload <= 0 && event.payload > 4) return await invoke("set_powerplan", { plan: event.payload }) const current = await invoke("get_powerplan") tool.setPowerPlan(current) diff --git a/src/components/cstb/SteamUsers.tsx b/src/components/cstb/SteamUsers.tsx index 1a5fa6f..19fa97b 100644 --- a/src/components/cstb/SteamUsers.tsx +++ b/src/components/cstb/SteamUsers.tsx @@ -20,7 +20,7 @@ const SteamUsers = ({ className }: { className?: string }) => { } return ( - + Steam用户 @@ -32,8 +32,11 @@ const SteamUsers = ({ className }: { className?: string }) => { - -
    + +
      {steam.state.users.map((user, id) => (
    • { const [hide, setHide] = useState(false) @@ -253,6 +254,17 @@ const VideoSetting = () => { void tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0) }, []) + const debounceCurrentUserId = useDebounce(steam.currentUser()?.steam_id32, { + wait: 500, + leading: false, + trailing: true, + maxWait: 2500, + }) + useEffect(() => { + if (steam.state.steamDirValid && steam.currentUser()) + void tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0) + }, [debounceCurrentUserId]) + return ( diff --git a/src/store/tool.ts b/src/store/tool.ts index ea1570f..7850bc7 100644 --- a/src/store/tool.ts +++ b/src/store/tool.ts @@ -4,6 +4,7 @@ import { DEFAULT_STORE_CONFIG } from "./config" import { emit } from "@tauri-apps/api/event" import { invoke } from "@tauri-apps/api/core" import VideoSetting from "@/components/cstb/VideoSetting" +import { useSteamStore } from "./steam" interface LaunchOption { option: string