Compare commits
18 Commits
v0.0.5-bet
...
v0.0.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6dbbf94ec | ||
|
|
bbcaf8e0d1 | ||
|
|
faec03afb1 | ||
|
|
7ec20984c4 | ||
|
|
dabbab9f3e | ||
|
|
0e7e6dd3ba | ||
|
|
a10cf8eddf | ||
|
|
63172f12bc | ||
|
|
114def0b96 | ||
|
|
93cda8dc85 | ||
|
|
afa7355f4d | ||
|
|
e29b48b98c | ||
|
|
21cdc7c32d | ||
|
|
27439593b4 | ||
|
|
ed040aadf5 | ||
|
|
8f885a5412 | ||
|
|
ee03bf0160 | ||
|
|
e0a84a0570 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -39,3 +39,7 @@ yarn-error.log*
|
|||||||
|
|
||||||
.env
|
.env
|
||||||
.env.*
|
.env.*
|
||||||
|
|
||||||
|
temp/
|
||||||
|
src-tauri/temp/
|
||||||
|
log/
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
"@supabase/ssr": "0.6.1",
|
"@supabase/ssr": "0.6.1",
|
||||||
"@tauri-apps/api": "2.4.0",
|
"@tauri-apps/api": "2.4.0",
|
||||||
"@tauri-apps/plugin-autostart": "^2.2.0",
|
"@tauri-apps/plugin-autostart": "^2.2.0",
|
||||||
|
"@tauri-apps/plugin-cli": "~2",
|
||||||
"@tauri-apps/plugin-clipboard-manager": "2.2.2",
|
"@tauri-apps/plugin-clipboard-manager": "2.2.2",
|
||||||
"@tauri-apps/plugin-deep-link": "~2.2.0",
|
"@tauri-apps/plugin-deep-link": "~2.2.0",
|
||||||
"@tauri-apps/plugin-dialog": "~2.2.0",
|
"@tauri-apps/plugin-dialog": "~2.2.0",
|
||||||
@@ -55,11 +56,11 @@
|
|||||||
"@testing-library/react": "^16.2.0",
|
"@testing-library/react": "^16.2.0",
|
||||||
"@testing-library/user-event": "^14.6.1",
|
"@testing-library/user-event": "^14.6.1",
|
||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
"@types/node": "^22.13.11",
|
"@types/node": "^22.13.13",
|
||||||
"@types/react": "19.0.10",
|
"@types/react": "19.0.10",
|
||||||
"@types/react-dom": "19.0.4",
|
"@types/react-dom": "19.0.4",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.27.0",
|
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
||||||
"@typescript-eslint/parser": "^8.27.0",
|
"@typescript-eslint/parser": "^8.28.0",
|
||||||
"autoprefixer": "^10.4.21",
|
"autoprefixer": "^10.4.21",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
|
|||||||
111
src-tauri/Cargo.lock
generated
111
src-tauri/Cargo.lock
generated
@@ -16,6 +16,7 @@ dependencies = [
|
|||||||
"tauri",
|
"tauri",
|
||||||
"tauri-build",
|
"tauri-build",
|
||||||
"tauri-plugin-autostart",
|
"tauri-plugin-autostart",
|
||||||
|
"tauri-plugin-cli",
|
||||||
"tauri-plugin-clipboard-manager",
|
"tauri-plugin-clipboard-manager",
|
||||||
"tauri-plugin-deep-link",
|
"tauri-plugin-deep-link",
|
||||||
"tauri-plugin-dialog",
|
"tauri-plugin-dialog",
|
||||||
@@ -90,6 +91,56 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "0.6.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"is_terminal_polyfill",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "3.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"once_cell",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.97"
|
version = "1.0.97"
|
||||||
@@ -691,6 +742,33 @@ dependencies = [
|
|||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.5.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.5.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clipboard-win"
|
name = "clipboard-win"
|
||||||
version = "5.4.0"
|
version = "5.4.0"
|
||||||
@@ -730,6 +808,12 @@ dependencies = [
|
|||||||
"objc",
|
"objc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "combine"
|
name = "combine"
|
||||||
version = "4.6.7"
|
version = "4.6.7"
|
||||||
@@ -2441,6 +2525,12 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is_terminal_polyfill"
|
||||||
|
version = "1.70.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
@@ -5075,6 +5165,21 @@ dependencies = [
|
|||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-plugin-cli"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5458ae16eac81bdbe8d9da2a9f3e01e8cdedbc381cc1727c01127542c8a61c5"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tauri",
|
||||||
|
"tauri-plugin",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-plugin-clipboard-manager"
|
name = "tauri-plugin-clipboard-manager"
|
||||||
version = "2.2.2"
|
version = "2.2.2"
|
||||||
@@ -6013,6 +6118,12 @@ version = "1.0.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
|
|||||||
@@ -64,5 +64,6 @@ default = [ "custom-protocol" ]
|
|||||||
custom-protocol = [ "tauri/custom-protocol" ]
|
custom-protocol = [ "tauri/custom-protocol" ]
|
||||||
|
|
||||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||||
|
tauri-plugin-cli = "2"
|
||||||
tauri-plugin-global-shortcut = "2.2.0"
|
tauri-plugin-global-shortcut = "2.2.0"
|
||||||
tauri-plugin-single-instance = "2.2.2"
|
tauri-plugin-single-instance = "2.2.2"
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
"deep-link:allow-get-current",
|
"deep-link:allow-get-current",
|
||||||
"autostart:default",
|
"autostart:default",
|
||||||
"autostart:allow-enable",
|
"autostart:allow-enable",
|
||||||
"autostart:allow-disable"
|
"autostart:allow-disable",
|
||||||
|
"cli:default"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -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"],"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"]}}
|
{"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"]}}
|
||||||
@@ -2039,6 +2039,21 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"const": "autostart:deny-is-enabled"
|
"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",
|
"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",
|
"type": "string",
|
||||||
|
|||||||
@@ -2039,6 +2039,21 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"const": "autostart:deny-is-enabled"
|
"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",
|
"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",
|
"type": "string",
|
||||||
|
|||||||
@@ -2039,6 +2039,21 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"const": "autostart:deny-is-enabled"
|
"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",
|
"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",
|
"type": "string",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use crate::steam;
|
use crate::steam;
|
||||||
use crate::tool::*;
|
use crate::tool::*;
|
||||||
use crate::vdf::preset;
|
use crate::vdf::preset;
|
||||||
|
use crate::vdf::preset::VideoConfig;
|
||||||
use crate::wrap_err;
|
use crate::wrap_err;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
@@ -54,8 +55,8 @@ pub fn get_powerplan() -> Result<i32, String> {
|
|||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
let powerplan = powerplan::get_powerplan()?;
|
let powerplan = powerplan::get_powerplan()?;
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
let powerplan = powerplan::PowerPlanMode::Other.into();
|
let powerplan = powerplan::PowerPlanMode::Other as i32;
|
||||||
|
|
||||||
Ok(powerplan)
|
Ok(powerplan)
|
||||||
}
|
}
|
||||||
@@ -70,7 +71,7 @@ pub fn set_powerplan(plan: i32) -> Result<(), String> {
|
|||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn get_steam_users(steam_dir: &str) -> Result<Vec<preset::User>, String> {
|
pub fn get_steam_users(steam_dir: &str) -> Result<Vec<preset::User>, String> {
|
||||||
wrap_err!(preset::get_users(steam_dir))
|
wrap_err!(preset::get_users(steam_dir))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -81,6 +82,31 @@ pub fn set_auto_login_user(user: &str) -> Result<String, String> {
|
|||||||
Ok(format!("Set auto login user to {}", user))
|
Ok(format!("Set auto login user to {}", user))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn get_cs2_video_config(steam_dir: &str, steam_id32: u32) -> Result<VideoConfig, String> {
|
||||||
|
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]
|
#[tauri::command]
|
||||||
pub fn check_path(path: &str) -> Result<bool, String> {
|
pub fn check_path(path: &str) -> Result<bool, String> {
|
||||||
Ok(std::path::Path::new(&path).exists())
|
Ok(std::path::Path::new(&path).exists())
|
||||||
|
|||||||
@@ -4,12 +4,14 @@
|
|||||||
)]
|
)]
|
||||||
|
|
||||||
use tauri::Manager;
|
use tauri::Manager;
|
||||||
use tauri_plugin_deep_link::DeepLinkExt;
|
|
||||||
use tauri_plugin_autostart::MacosLauncher;
|
use tauri_plugin_autostart::MacosLauncher;
|
||||||
|
use tauri_plugin_cli::CliExt;
|
||||||
|
use tauri_plugin_deep_link::DeepLinkExt;
|
||||||
|
use tauri_plugin_store::StoreExt;
|
||||||
|
|
||||||
// Window Vibrancy
|
// Window Vibrancy
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
use window_vibrancy::apply_mica;
|
use window_vibrancy::apply_acrylic;
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
use window_vibrancy::{apply_vibrancy, NSVisualEffectMaterial};
|
use window_vibrancy::{apply_vibrancy, NSVisualEffectMaterial};
|
||||||
|
|
||||||
@@ -50,7 +52,10 @@ fn main() {
|
|||||||
.plugin(tauri_plugin_store::Builder::new().build())
|
.plugin(tauri_plugin_store::Builder::new().build())
|
||||||
.plugin(tauri_plugin_theme::init(ctx.config_mut()))
|
.plugin(tauri_plugin_theme::init(ctx.config_mut()))
|
||||||
.plugin(tauri_plugin_notification::init())
|
.plugin(tauri_plugin_notification::init())
|
||||||
.plugin(tauri_plugin_autostart::init(MacosLauncher::LaunchAgent, Some(vec![]) /* arbitrary number of args to pass to your app */))
|
.plugin(tauri_plugin_autostart::init(
|
||||||
|
MacosLauncher::LaunchAgent,
|
||||||
|
Some(vec!["hidden"]), /* arbitrary number of args to pass to your app */
|
||||||
|
))
|
||||||
.plugin(tauri_plugin_http::init())
|
.plugin(tauri_plugin_http::init())
|
||||||
.plugin(tauri_plugin_shell::init())
|
.plugin(tauri_plugin_shell::init())
|
||||||
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
|
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
|
||||||
@@ -60,9 +65,29 @@ fn main() {
|
|||||||
.plugin(tauri_plugin_process::init())
|
.plugin(tauri_plugin_process::init())
|
||||||
.plugin(tauri_plugin_dialog::init())
|
.plugin(tauri_plugin_dialog::init())
|
||||||
.plugin(tauri_plugin_system_info::init())
|
.plugin(tauri_plugin_system_info::init())
|
||||||
|
.plugin(tauri_plugin_cli::init())
|
||||||
// .plugin(tauri_plugin_store::Builder::default().build())
|
// .plugin(tauri_plugin_store::Builder::default().build())
|
||||||
// .plugin(tauri_plugin_updater::Builder::new().build())
|
// .plugin(tauri_plugin_updater::Builder::new().build())
|
||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
|
// Get Window
|
||||||
|
let window = app.get_webview_window("main").unwrap();
|
||||||
|
|
||||||
|
let store = app.store("cstb.json")?;
|
||||||
|
// 获取boolean类型的hidden值,Err时设置为False
|
||||||
|
let hidden: bool = store.get("hidden").and_then(|v| v.as_bool()).unwrap_or(false);
|
||||||
|
|
||||||
|
// Vibrant Window
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
apply_vibrancy(&window, NSVisualEffectMaterial::HudWindow, None, Some(10.0))
|
||||||
|
.expect("Unsupported platform! 'apply_vibrancy' is only supported on macOS");
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
apply_acrylic(&window, None)
|
||||||
|
.expect("Unsupported platform! 'apply_acrylic' is only supported on Windows");
|
||||||
|
|
||||||
|
// apply_blur(&window, Some((18, 18, 18, 0)))
|
||||||
|
// .expect("Unsupported platform! 'apply_blur' is only supported on Windows");
|
||||||
|
|
||||||
// Deep Link
|
// Deep Link
|
||||||
#[cfg(desktop)]
|
#[cfg(desktop)]
|
||||||
app.deep_link().register("cstb")?;
|
app.deep_link().register("cstb")?;
|
||||||
@@ -74,20 +99,22 @@ fn main() {
|
|||||||
tray::create_tray(handle)?;
|
tray::create_tray(handle)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Window
|
// CLI
|
||||||
let window = app.get_webview_window("main").unwrap();
|
match app.cli().matches() {
|
||||||
|
// `matches` here is a Struct with { args, subcommand }.
|
||||||
|
// `args` is `HashMap<String, ArgData>` where `ArgData` is a struct with { value, occurrences }.
|
||||||
|
// `subcommand` is `Option<Box<SubcommandMatches>>` where `SubcommandMatches` is a struct with { name, matches }.
|
||||||
|
Ok(matches) => {
|
||||||
|
println!("{:?}", matches);
|
||||||
|
if matches.args.contains_key("hidden") && matches.args["hidden"].value == true && hidden {
|
||||||
|
window.hide().unwrap();
|
||||||
|
} else {
|
||||||
|
window.show().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => {}
|
||||||
|
}
|
||||||
|
|
||||||
// Vibrant Window
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
apply_vibrancy(&window, NSVisualEffectMaterial::HudWindow, None, Some(10.0))
|
|
||||||
.expect("Unsupported platform! 'apply_vibrancy' is only supported on macOS");
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
apply_mica(&window, Some(false))
|
|
||||||
.expect("Unsupported platform! 'apply_mica' is only supported on Windows");
|
|
||||||
|
|
||||||
// apply_blur(&window, Some((18, 18, 18, 0)))
|
|
||||||
// .expect("Unsupported platform! 'apply_blur' is only supported on Windows");
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
@@ -100,8 +127,10 @@ fn main() {
|
|||||||
cmds::open_path,
|
cmds::open_path,
|
||||||
cmds::get_powerplan,
|
cmds::get_powerplan,
|
||||||
cmds::set_powerplan,
|
cmds::set_powerplan,
|
||||||
cmds::get_steam_users,
|
cmds::get_steam_users,
|
||||||
cmds::set_auto_login_user,
|
cmds::set_auto_login_user,
|
||||||
|
cmds::get_cs2_video_config,
|
||||||
|
cmds::set_cs2_video_config,
|
||||||
cmds::check_path,
|
cmds::check_path,
|
||||||
on_button_clicked
|
on_button_clicked
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
use std::os::windows::process::CommandExt;
|
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
use std::os::windows::process::CommandExt;
|
||||||
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
||||||
// const DETACHED_PROCESS: u32 = 0x00000008;
|
// const DETACHED_PROCESS: u32 = 0x00000008;
|
||||||
|
|
||||||
pub fn kill(name: &str) -> String {
|
pub fn kill(name: &str) -> String {
|
||||||
|
#[cfg(windows)]
|
||||||
Command::new("taskkill")
|
Command::new("taskkill")
|
||||||
.args(&["/IM", name, "/F"])
|
.args(&["/IM", name, "/F"])
|
||||||
.creation_flags(CREATE_NO_WINDOW)
|
.creation_flags(CREATE_NO_WINDOW)
|
||||||
@@ -15,12 +17,17 @@ pub fn kill(name: &str) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_steam() -> std::io::Result<std::process::Output> {
|
pub fn run_steam() -> std::io::Result<std::process::Output> {
|
||||||
Command::new("cmd")
|
#[cfg(target_os = "windows")]
|
||||||
|
return Command::new("cmd")
|
||||||
.args(&["/C", "start", "steam://run"])
|
.args(&["/C", "start", "steam://run"])
|
||||||
.creation_flags(CREATE_NO_WINDOW)
|
.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<String, std::io::Error> {
|
pub fn get_exe_path(name: &str) -> Result<String, std::io::Error> {
|
||||||
// [原理]
|
// [原理]
|
||||||
@@ -31,11 +38,17 @@ pub fn get_exe_path(name: &str) -> Result<String, std::io::Error> {
|
|||||||
// 进程路径
|
// 进程路径
|
||||||
let command = format!("Get-Process {} | Select-Object path", name);
|
let command = format!("Get-Process {} | Select-Object path", name);
|
||||||
let args = command.split_whitespace().collect::<Vec<&str>>();
|
let args = command.split_whitespace().collect::<Vec<&str>>();
|
||||||
|
#[cfg(windows)]
|
||||||
let output = Command::new("powershell.exe")
|
let output = Command::new("powershell.exe")
|
||||||
.args(&args)
|
.args(&args)
|
||||||
.creation_flags(CREATE_NO_WINDOW)
|
.creation_flags(CREATE_NO_WINDOW)
|
||||||
.output()?;
|
.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();
|
let out = String::from_utf8_lossy(&output.stdout).to_string();
|
||||||
|
|
||||||
if out.contains("Path") {
|
if out.contains("Path") {
|
||||||
@@ -55,6 +68,7 @@ pub fn get_exe_path(name: &str) -> Result<String, std::io::Error> {
|
|||||||
pub fn open_path(path: &str) -> Result<(), std::io::Error> {
|
pub fn open_path(path: &str) -> Result<(), std::io::Error> {
|
||||||
// path中所有/ 转换为 \
|
// path中所有/ 转换为 \
|
||||||
let path = path.replace("/", "\\");
|
let path = path.replace("/", "\\");
|
||||||
|
#[cfg(windows)]
|
||||||
Command::new("cmd.exe")
|
Command::new("cmd.exe")
|
||||||
.args(["/c", "start", "", &path])
|
.args(["/c", "start", "", &path])
|
||||||
.creation_flags(CREATE_NO_WINDOW)
|
.creation_flags(CREATE_NO_WINDOW)
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ impl PowerPlan {
|
|||||||
.get(&mode)
|
.get(&mode)
|
||||||
.ok_or("Invalid power plan number (expect from 1 to 4)")?;
|
.ok_or("Invalid power plan number (expect from 1 to 4)")?;
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
let output = Command::new("powercfg")
|
let output = Command::new("powercfg")
|
||||||
.arg("/S")
|
.arg("/S")
|
||||||
.arg(guid)
|
.arg(guid)
|
||||||
@@ -46,6 +47,14 @@ impl PowerPlan {
|
|||||||
.output()
|
.output()
|
||||||
.map_err(|e| format!("Failed to execute powercfg command: {}", e))?;
|
.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() {
|
if !output.status.success() {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"Powercfg command failed: {}",
|
"Powercfg command failed: {}",
|
||||||
@@ -57,12 +66,20 @@ impl PowerPlan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self) -> Result<i32, String> {
|
pub fn get(&self) -> Result<i32, String> {
|
||||||
|
#[cfg(windows)]
|
||||||
let output = Command::new("powercfg")
|
let output = Command::new("powercfg")
|
||||||
.arg("/L")
|
.arg("/L")
|
||||||
.creation_flags(CREATE_NO_WINDOW)
|
.creation_flags(CREATE_NO_WINDOW)
|
||||||
.output()
|
.output()
|
||||||
.map_err(|e| format!("Failed to execute powercfg command: {}", e))?;
|
.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 output_str = String::from_utf8_lossy(&output.stdout);
|
||||||
let re = regex::Regex::new(r"GUID:\s+(\S+)\s+\(\S+\)\s+\*")
|
let re = regex::Regex::new(r"GUID:\s+(\S+)\s+\(\S+\)\s+\*")
|
||||||
.map_err(|e| format!("Failed to compile regex: {}", e))?;
|
.map_err(|e| format!("Failed to compile regex: {}", e))?;
|
||||||
|
|||||||
@@ -1,12 +1,125 @@
|
|||||||
use tauri::{
|
use tauri::{
|
||||||
menu::{Menu, MenuItem},
|
menu::{CheckMenuItem, Menu, MenuItem, PredefinedMenuItem},
|
||||||
tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent},
|
tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent},
|
||||||
Manager, Runtime,
|
Emitter, Listener, Manager, Runtime,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::tool::powerplan::PowerPlanMode;
|
||||||
|
|
||||||
pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
|
pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
|
||||||
let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?;
|
// 托盘菜单项目
|
||||||
let menu = Menu::with_items(app, &[&quit_i])?;
|
let separator = &PredefinedMenuItem::separator(app).unwrap();
|
||||||
|
|
||||||
|
let show_i = &MenuItem::with_id(app, "show", "显示主界面", true, None::<&str>)?;
|
||||||
|
let quit_i = &MenuItem::with_id(app, "quit", "退出", true, None::<&str>)?;
|
||||||
|
|
||||||
|
let kill_game_i = &MenuItem::with_id(app, "kill_game", "关闭CS2", true, None::<&str>)?;
|
||||||
|
let kill_steam_i = &MenuItem::with_id(app, "kill_steam", "关闭Steam", true, None::<&str>)?;
|
||||||
|
|
||||||
|
let launch_ww_i = &MenuItem::with_id(app, "launch_ww", "启动国际服", true, None::<&str>)?;
|
||||||
|
let launch_pw_i = &MenuItem::with_id(app, "launch_pw", "启动国服", true, None::<&str>)?;
|
||||||
|
|
||||||
|
let power_plan_extreme = CheckMenuItem::with_id(
|
||||||
|
app,
|
||||||
|
"power_plan_extreme",
|
||||||
|
"卓越性能",
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
None::<&str>,
|
||||||
|
)?;
|
||||||
|
let power_plan_high =
|
||||||
|
CheckMenuItem::with_id(app, "power_plan_high", "高性能", true, false, None::<&str>)?;
|
||||||
|
let power_plan_balanced = CheckMenuItem::with_id(
|
||||||
|
app,
|
||||||
|
"power_plan_balanced",
|
||||||
|
"平衡",
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
None::<&str>,
|
||||||
|
)?;
|
||||||
|
let power_plan_powersave = CheckMenuItem::with_id(
|
||||||
|
app,
|
||||||
|
"power_plan_powersave",
|
||||||
|
"节能",
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
None::<&str>,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
|
||||||
|
let current_launch_option = MenuItem::with_id(
|
||||||
|
app,
|
||||||
|
"current_launch_option",
|
||||||
|
"启动项档位",
|
||||||
|
true,
|
||||||
|
None::<&str>,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// 创建托盘菜单
|
||||||
|
let menu = Menu::with_items(
|
||||||
|
app,
|
||||||
|
&[
|
||||||
|
&power_plan_extreme,
|
||||||
|
&power_plan_high,
|
||||||
|
&power_plan_balanced,
|
||||||
|
&power_plan_powersave,
|
||||||
|
separator,
|
||||||
|
¤t_launch_option,
|
||||||
|
launch_ww_i,
|
||||||
|
launch_pw_i,
|
||||||
|
separator,
|
||||||
|
kill_game_i,
|
||||||
|
kill_steam_i,
|
||||||
|
separator,
|
||||||
|
show_i,
|
||||||
|
quit_i,
|
||||||
|
],
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let _ = app.listen("tray://get_powerplan", move |event| {
|
||||||
|
if let Ok(payload) = event.payload().parse::<i32>() {
|
||||||
|
match payload {
|
||||||
|
x if x == PowerPlanMode::Other as i32 => {
|
||||||
|
let _ = power_plan_powersave.set_checked(false);
|
||||||
|
let _ = power_plan_balanced.set_checked(false);
|
||||||
|
let _ = power_plan_high.set_checked(false);
|
||||||
|
let _ = power_plan_extreme.set_checked(false);
|
||||||
|
}
|
||||||
|
x if x == PowerPlanMode::PowerSaving as i32 => {
|
||||||
|
let _ = power_plan_powersave.set_checked(true);
|
||||||
|
let _ = power_plan_balanced.set_checked(false);
|
||||||
|
let _ = power_plan_high.set_checked(false);
|
||||||
|
let _ = power_plan_extreme.set_checked(false);
|
||||||
|
}
|
||||||
|
x if x == PowerPlanMode::Balanced as i32 => {
|
||||||
|
let _ = power_plan_powersave.set_checked(false);
|
||||||
|
let _ = power_plan_balanced.set_checked(true);
|
||||||
|
let _ = power_plan_high.set_checked(false);
|
||||||
|
let _ = power_plan_extreme.set_checked(false);
|
||||||
|
}
|
||||||
|
x if x == PowerPlanMode::HighPerformance as i32 => {
|
||||||
|
let _ = power_plan_powersave.set_checked(false);
|
||||||
|
let _ = power_plan_balanced.set_checked(false);
|
||||||
|
let _ = power_plan_high.set_checked(true);
|
||||||
|
let _ = power_plan_extreme.set_checked(false);
|
||||||
|
}
|
||||||
|
x if x == PowerPlanMode::Extreme as i32 => {
|
||||||
|
let _ = power_plan_powersave.set_checked(false);
|
||||||
|
let _ = power_plan_balanced.set_checked(false);
|
||||||
|
let _ = power_plan_high.set_checked(false);
|
||||||
|
let _ = power_plan_extreme.set_checked(true);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let _ = app.listen("tray://get_current_launch_option", move |event| {
|
||||||
|
let payload = event.payload();
|
||||||
|
if payload != "" {
|
||||||
|
let _ = current_launch_option.set_text("启动项档位 ".to_string() + payload);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let _ = TrayIconBuilder::with_id("tray")
|
let _ = TrayIconBuilder::with_id("tray")
|
||||||
.icon(app.default_window_icon().unwrap().clone())
|
.icon(app.default_window_icon().unwrap().clone())
|
||||||
@@ -16,7 +129,43 @@ pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
|
|||||||
"quit" => {
|
"quit" => {
|
||||||
app.exit(0);
|
app.exit(0);
|
||||||
}
|
}
|
||||||
// Add more events here
|
"show" => {
|
||||||
|
if let Some(window) = app.get_webview_window("main") {
|
||||||
|
let _ = window.show();
|
||||||
|
let _ = window.set_focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"launch_ww" => {
|
||||||
|
let _ = app.emit("tray://launch_game", "worldwide");
|
||||||
|
}
|
||||||
|
"launch_pw" => {
|
||||||
|
let _ = app.emit("tray://launch_game", "perfectworld");
|
||||||
|
}
|
||||||
|
"kill_game" => {
|
||||||
|
let _ = app.emit("tray://kill_game", None::<()>);
|
||||||
|
}
|
||||||
|
"kill_steam" => {
|
||||||
|
let _ = app.emit("tray://kill_steam", None::<()>);
|
||||||
|
}
|
||||||
|
"power_plan_extreme" => {
|
||||||
|
let _ = app.emit("tray://set_powerplan", PowerPlanMode::Extreme as i32);
|
||||||
|
// let _ = power_plan_extreme.set_checked(true);
|
||||||
|
}
|
||||||
|
"power_plan_high" => {
|
||||||
|
let _ = app.emit(
|
||||||
|
"tray://set_powerplan",
|
||||||
|
PowerPlanMode::HighPerformance as i32,
|
||||||
|
);
|
||||||
|
// let _ = power_plan_high.set_checked(true);
|
||||||
|
}
|
||||||
|
"power_plan_balanced" => {
|
||||||
|
let _ = app.emit("tray://set_powerplan", PowerPlanMode::Balanced as i32);
|
||||||
|
// let _ = power_plan_balanced.set_checked(true);
|
||||||
|
}
|
||||||
|
"power_plan_powersave" => {
|
||||||
|
let _ = app.emit("tray://set_powerplan", PowerPlanMode::PowerSaving as i32);
|
||||||
|
// let _ = power_plan_powersave.set_checked(true);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
})
|
})
|
||||||
.on_tray_icon_event(|tray, event| {
|
.on_tray_icon_event(|tray, event| {
|
||||||
@@ -37,68 +186,3 @@ pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tray Menu
|
|
||||||
// let quit = CustomMenuItem::new("quit".to_string(), "Quit");
|
|
||||||
// let hide = CustomMenuItem::new("hide".to_string(), "Hide");
|
|
||||||
// let tray_menu = SystemTrayMenu::new() // insert the menu items here
|
|
||||||
// .add_item(hide)
|
|
||||||
// .add_item(quit);
|
|
||||||
// .add_native_item(SystemTrayMenuItem::Separator)
|
|
||||||
// let toggle = MenuItemBuilder::with_id("toggle", "Toggle").build(app)?;
|
|
||||||
// let menu = MenuBuilder::new(app).items(&[&toggle]).build()?;
|
|
||||||
|
|
||||||
// Setup Tray
|
|
||||||
// let tray = tauri::tray::TrayIconBuilder::with_id("my-tray").build(app)?;
|
|
||||||
// let _ = TrayIconBuilder::new()
|
|
||||||
// .menu(&menu)
|
|
||||||
// .on_menu_event(move |_, event| {
|
|
||||||
// match event.id().as_ref() {
|
|
||||||
// "toggle" => {
|
|
||||||
// println!("toggle clicked");
|
|
||||||
// }
|
|
||||||
// _ => (),
|
|
||||||
// }
|
|
||||||
// // match event {
|
|
||||||
// // SystemTrayEvent::LeftClick { position: _, size: _, .. } => {
|
|
||||||
// // let window = app.get_window("main").unwrap();
|
|
||||||
// // window.show().unwrap();
|
|
||||||
// // window.set_focus().unwrap();
|
|
||||||
|
|
||||||
// // // thread::sleep(Duration::from_millis(100));
|
|
||||||
// // // window.set_always_on_top(false).unwrap();
|
|
||||||
// // println!("system tray received a left click");
|
|
||||||
// // }
|
|
||||||
// // SystemTrayEvent::RightClick { position: _, size: _, .. } => {
|
|
||||||
// // // let window = app.get_window("main").unwrap();
|
|
||||||
// // // window.hide().unwrap();
|
|
||||||
// // println!("system tray received a right click");
|
|
||||||
// // }
|
|
||||||
// // SystemTrayEvent::DoubleClick { position: _, size: _, .. } => {
|
|
||||||
// // println!("system tray received a double click");
|
|
||||||
// // }
|
|
||||||
// // SystemTrayEvent::MenuItemClick { id, .. } =>
|
|
||||||
// // match id.as_str() {
|
|
||||||
// // "quit" => {
|
|
||||||
// // std::process::exit(0);
|
|
||||||
// // }
|
|
||||||
// // "hide" => {
|
|
||||||
// // let window = app.get_window("main").unwrap();
|
|
||||||
// // window.hide().unwrap();
|
|
||||||
// // }
|
|
||||||
// // _ => {}
|
|
||||||
// // }
|
|
||||||
// // _ => {}
|
|
||||||
// // }
|
|
||||||
// })
|
|
||||||
// .on_tray_icon_event(|tray, event| {
|
|
||||||
// if event.click_type == ClickType::Left {
|
|
||||||
// let app = tray.app_handle();
|
|
||||||
// if let Some(webview_window) = app.get_webview_window("main") {
|
|
||||||
// let _ = webview_window.show();
|
|
||||||
// let _ = webview_window.set_focus();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// .build(app)
|
|
||||||
// .unwrap();
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
pub fn to_json(vdf_data: &str) -> String {
|
pub fn to_json(vdf_data: &str) -> String {
|
||||||
let linebreak = match std::env::consts::OS {
|
let linebreak = match std::env::consts::OS {
|
||||||
"macos" => "\r",
|
"macos" => "\n", //"\r",
|
||||||
"windows" => "\n",
|
"windows" => "\n",
|
||||||
"linux" => "\n",
|
"linux" => "\n",
|
||||||
_ => "\n",
|
_ => "\n",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// NOTE: 这样会跳过顶层{}
|
||||||
let startpoint = vdf_data.find('{').unwrap_or(0);
|
let startpoint = vdf_data.find('{').unwrap_or(0);
|
||||||
let vdf_data = &vdf_data[startpoint..];
|
let vdf_data = &vdf_data[startpoint..];
|
||||||
|
|
||||||
@@ -31,49 +32,108 @@ pub fn to_json(vdf_data: &str) -> String {
|
|||||||
json_data.push_str(&line);
|
json_data.push_str(&line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// let json_str = json_data
|
||||||
json_data = json_data
|
json_data = json_data
|
||||||
.replace(",}", "}")
|
.replace(",}", "}")
|
||||||
.trim_start_matches(": ")
|
.trim_start_matches(": ")
|
||||||
.trim_end_matches(',')
|
.trim_end_matches(',')
|
||||||
.to_string();
|
.to_string();
|
||||||
|
// json_data = format!("{{{}}}", json_str);
|
||||||
|
|
||||||
json_data
|
return 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 {
|
mod tests {
|
||||||
use super::*;
|
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]
|
#[test]
|
||||||
fn test_to_json() {
|
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 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
|
// 解析json
|
||||||
let json_value: serde_json::Value = serde_json::from_str(&json_data).unwrap();
|
let json_value: serde_json::Value = serde_json::from_str(&json_data).unwrap();
|
||||||
@@ -81,4 +141,12 @@ mod tests {
|
|||||||
println!("{}", json_value)
|
println!("{}", json_value)
|
||||||
// assert_eq!(to_json(vdf_data), expected_json);
|
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use base64::engine::general_purpose::STANDARD;
|
use base64::engine::general_purpose::STANDARD;
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
|
use regex::Regex;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@@ -44,6 +45,81 @@ pub struct LocalUser {
|
|||||||
avatar_key: String,
|
avatar_key: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct VideoConfig {
|
||||||
|
version: String,
|
||||||
|
vendor_id: String,
|
||||||
|
device_id: 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,
|
||||||
|
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: "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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse_login_users(steam_dir: &str) -> Result<Vec<LoginUser>> {
|
pub fn parse_login_users(steam_dir: &str) -> Result<Vec<LoginUser>> {
|
||||||
let t_path = Path::new(steam_dir).join("config/loginusers.vdf");
|
let t_path = Path::new(steam_dir).join("config/loginusers.vdf");
|
||||||
if !t_path.exists() {
|
if !t_path.exists() {
|
||||||
@@ -151,6 +227,9 @@ pub fn parse_local_users(steam_dir: &str) -> Result<Vec<LocalUser>> {
|
|||||||
let json_data = super::parse::to_json(&data);
|
let json_data = super::parse::to_json(&data);
|
||||||
let kv: HashMap<String, Value> = serde_json::from_str(&json_data)?;
|
let kv: HashMap<String, Value> = serde_json::from_str(&json_data)?;
|
||||||
|
|
||||||
|
// 剥离顶层 UserLocalConfigStore
|
||||||
|
// let kv = kv.get("UserLocalConfigStore").and_then(|v| v.as_object()).unwrap();
|
||||||
|
|
||||||
// 获取 friends 节点
|
// 获取 friends 节点
|
||||||
let friends = kv.get("friends").and_then(|v| v.as_object());
|
let friends = kv.get("friends").and_then(|v| v.as_object());
|
||||||
if friends.is_none() {
|
if friends.is_none() {
|
||||||
@@ -270,6 +349,184 @@ fn read_avatar(steam_dir: &str, steam_id64: &str) -> Option<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_cs2_video(file_path: &str) -> Result<VideoConfig> {
|
||||||
|
// TODO: no kv
|
||||||
|
let data = fs::read_to_string(file_path)?;
|
||||||
|
let json_data = super::parse::to_json(&data);
|
||||||
|
let kv: HashMap<String, String> = serde_json::from_str(&json_data)?;
|
||||||
|
let video_config = VideoConfig {
|
||||||
|
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())
|
||||||
|
.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("AutoConfig").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: VideoConfig) -> Result<()> {
|
||||||
|
// 读取文件内容
|
||||||
|
let file_content = fs::read_to_string(file_path)?;
|
||||||
|
|
||||||
|
// 定义正则表达式匹配模式
|
||||||
|
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 {
|
||||||
|
"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,
|
||||||
|
"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,
|
||||||
|
"AutoConfig" => &data.auto_config,
|
||||||
|
"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(())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -279,4 +536,25 @@ mod tests {
|
|||||||
let users = get_users("D:\\Programs\\Steam").unwrap();
|
let users = get_users("D:\\Programs\\Steam").unwrap();
|
||||||
println!("{:?}", users);
|
println!("{:?}", users);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_cs2_video() {
|
||||||
|
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 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
},
|
},
|
||||||
"productName": "CS工具箱",
|
"productName": "CS工具箱",
|
||||||
"mainBinaryName": "cstb",
|
"mainBinaryName": "cstb",
|
||||||
"version": "0.0.5-beta.1",
|
"version": "0.0.5",
|
||||||
"identifier": "upup.cool",
|
"identifier": "upup.cool",
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"deep-link": {
|
"deep-link": {
|
||||||
@@ -51,6 +51,15 @@
|
|||||||
"cstb"
|
"cstb"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"cli": {
|
||||||
|
"description": "CS Toolbox CLI",
|
||||||
|
"args": [
|
||||||
|
{
|
||||||
|
"name": "hidden",
|
||||||
|
"description": "hidden on start"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"app": {
|
"app": {
|
||||||
@@ -70,7 +79,8 @@
|
|||||||
"transparent": true,
|
"transparent": true,
|
||||||
"theme": null,
|
"theme": null,
|
||||||
"hiddenTitle": true,
|
"hiddenTitle": true,
|
||||||
"titleBarStyle": "Transparent"
|
"titleBarStyle": "Transparent",
|
||||||
|
"visible": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"security": {
|
"security": {
|
||||||
|
|||||||
@@ -17,6 +17,21 @@ export default function Page() {
|
|||||||
>
|
>
|
||||||
开机自启动 {app.state.autoStart ? "开" : "关"}
|
开机自启动 {app.state.autoStart ? "开" : "关"}
|
||||||
</Switch>
|
</Switch>
|
||||||
|
<Switch
|
||||||
|
isSelected={app.state.startHidden}
|
||||||
|
size="sm"
|
||||||
|
onChange={(e) => app.setStartHidden(e.target.checked)}
|
||||||
|
>
|
||||||
|
静默启动 {app.state.startHidden ? "开" : "关"}
|
||||||
|
</Switch>
|
||||||
|
{/* hiddenOnClose */}
|
||||||
|
<Switch
|
||||||
|
isSelected={app.state.hiddenOnClose}
|
||||||
|
size="sm"
|
||||||
|
onChange={(e) => app.setHiddenOnClose(e.target.checked)}
|
||||||
|
>
|
||||||
|
关闭时最小化到托盘 {app.state.hiddenOnClose ? "开" : "关"}
|
||||||
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,71 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
import { init } from "@/store"
|
||||||
import { useSteamStore } from "@/store/steam"
|
import { useSteamStore } from "@/store/steam"
|
||||||
|
import { useToolStore } from "@/store/tool"
|
||||||
|
import { addToast } from "@heroui/react"
|
||||||
|
import { invoke } from "@tauri-apps/api/core"
|
||||||
|
import { listen } from "@tauri-apps/api/event"
|
||||||
|
import { useDebounce } from "ahooks"
|
||||||
import { useEffect } from "react"
|
import { useEffect } from "react"
|
||||||
import "./globals.css"
|
import "./globals.css"
|
||||||
import Providers from "./providers"
|
import Providers from "./providers"
|
||||||
import { init } from "@/store"
|
import { PowerPlans } from "@/components/cstb/PowerPlan"
|
||||||
import { useDebounce } from "ahooks"
|
|
||||||
|
|
||||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||||
|
const steam = useSteamStore()
|
||||||
|
const tool = useToolStore()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
void init()
|
void init()
|
||||||
})
|
|
||||||
|
void listen<string>("tray://launch_game", async (event) => {
|
||||||
|
await invoke("launch_game", {
|
||||||
|
steamPath: `${steam.state.steamDir}/steam.exe`,
|
||||||
|
launchOption: tool.state.launchOptions[tool.state.launchIndex].option || "",
|
||||||
|
server: event.payload || "worldwide",
|
||||||
|
})
|
||||||
|
addToast({ title: "启动国服成功" })
|
||||||
|
})
|
||||||
|
|
||||||
|
void listen("tray://kill_steam", async () => {
|
||||||
|
await invoke("kill_steam")
|
||||||
|
addToast({ title: "已关闭Steam" })
|
||||||
|
})
|
||||||
|
|
||||||
|
void listen("tray://kill_game", async () => {
|
||||||
|
await invoke("kill_game")
|
||||||
|
addToast({ title: "已关闭CS2" })
|
||||||
|
})
|
||||||
|
|
||||||
|
void listen<number>("tray://set_powerplan", async (event) => {
|
||||||
|
if (typeof(event.payload) === "number" && event.payload <= 0 && event.payload > 4) return
|
||||||
|
await invoke("set_powerplan", { plan: event.payload })
|
||||||
|
const current = await invoke<number>("get_powerplan")
|
||||||
|
tool.setPowerPlan(current)
|
||||||
|
|
||||||
|
addToast({ title: `电源计划已切换 → ${PowerPlans[current].title}` })
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
// 检测steam路径和游戏路径是否有效
|
// 检测steam路径和游戏路径是否有效
|
||||||
const steam = useSteamStore()
|
const debounceSteamDir = useDebounce(steam.state.steamDir, {
|
||||||
const debounceSteamDir = useDebounce(steam.state.steamDir, {wait: 500, leading: true, trailing: true, maxWait: 2500})
|
wait: 500,
|
||||||
const debounceCs2Dir = useDebounce(steam.state.cs2Dir, {wait: 500, leading: true, trailing: true, maxWait: 2500})
|
leading: true,
|
||||||
const debounceSteamDirValid = useDebounce(steam.state.steamDirValid, {wait: 500, leading: true, trailing: true, maxWait: 2500})
|
trailing: true,
|
||||||
|
maxWait: 2500,
|
||||||
|
})
|
||||||
|
const debounceCs2Dir = useDebounce(steam.state.cs2Dir, {
|
||||||
|
wait: 500,
|
||||||
|
leading: true,
|
||||||
|
trailing: true,
|
||||||
|
maxWait: 2500,
|
||||||
|
})
|
||||||
|
const debounceSteamDirValid = useDebounce(steam.state.steamDirValid, {
|
||||||
|
wait: 500,
|
||||||
|
leading: true,
|
||||||
|
trailing: true,
|
||||||
|
maxWait: 2500,
|
||||||
|
})
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
void steam.checkSteamDirValid()
|
void steam.checkSteamDirValid()
|
||||||
}, [debounceSteamDir])
|
}, [debounceSteamDir])
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { Key } from "@react-types/shared"
|
|||||||
import { useToolStore } from "@/store/tool"
|
import { useToolStore } from "@/store/tool"
|
||||||
import { useEffect } from "react"
|
import { useEffect } from "react"
|
||||||
|
|
||||||
const PowerPlans = [
|
export const PowerPlans = [
|
||||||
{
|
{
|
||||||
id: "0",
|
id: "0",
|
||||||
title: "其他",
|
title: "其他",
|
||||||
|
|||||||
@@ -1,178 +1,452 @@
|
|||||||
import { CloseSmall, Down, Edit, Plus, SettingConfig, Up } from "@icon-park/react"
|
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 { Card, CardBody, CardHeader, CardIcon, CardTool } from "../window/Card"
|
||||||
import { ToolButton } from "../window/ToolButton"
|
import { ToolButton } from "../window/ToolButton"
|
||||||
import { addToast, NumberInput, Tab, Tabs, Tooltip } from "@heroui/react"
|
import { addToast, NumberInput, Tab, Tabs, Tooltip } from "@heroui/react"
|
||||||
import { motion } from "framer-motion"
|
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 = () => {
|
const VideoSetting = () => {
|
||||||
const [hide, setHide] = useState(false)
|
const [hide, setHide] = useState(false)
|
||||||
const [edit, setEdit] = useState(false)
|
const [edit, setEdit] = useState(false)
|
||||||
const tool = useToolStore()
|
const tool = useToolStore()
|
||||||
// const [launchOpt, setLaunchOpt] = useState(tool.state.VideoSettings[tool.state.launchIndex] || "")
|
const steam = useSteamStore()
|
||||||
|
const videoSettings = (video: VideoConfig) => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: "fullscreen",
|
||||||
|
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: "CMAA2抗锯齿",
|
||||||
|
value: video.r_csgo_cmaa_enable === "1" ? "开启" : "关闭",
|
||||||
|
options: ["关闭", "开启"],
|
||||||
|
mapping: (value: string) => {
|
||||||
|
return (
|
||||||
|
{
|
||||||
|
关闭: "0",
|
||||||
|
开启: "1",
|
||||||
|
}[value] || "0"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "msaa_samples",
|
||||||
|
title: "多重采样抗锯齿",
|
||||||
|
value:
|
||||||
|
{
|
||||||
|
0: "无",
|
||||||
|
2: "2X MSAA",
|
||||||
|
4: "4X MSAA",
|
||||||
|
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",
|
||||||
|
title: "贴图过滤模式",
|
||||||
|
value:
|
||||||
|
["双线性", "三线性", "异向 2X", "异向 4X", "异向 8X", "异向 16X"][
|
||||||
|
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: "shaderquality",
|
||||||
|
title: "光影细节",
|
||||||
|
value: video.shaderquality === "1" ? "高" : "低",
|
||||||
|
options: ["低", "高"],
|
||||||
|
mapping: (value: string) => {
|
||||||
|
return (
|
||||||
|
{
|
||||||
|
低: "0",
|
||||||
|
高: "1",
|
||||||
|
}[value] || "0"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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_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 超级分辨率",
|
||||||
|
value:
|
||||||
|
["已禁用", "超高品质", "品质", "均衡", "性能"][parseInt(video.videocfg_fsr_detail, 10)] ||
|
||||||
|
"性能",
|
||||||
|
options: ["性能", "均衡", "品质", "超高品质", "已禁用"],
|
||||||
|
mapping: (value: string) => {
|
||||||
|
return (
|
||||||
|
{
|
||||||
|
已禁用: "0",
|
||||||
|
超高品质: "1",
|
||||||
|
品质: "2",
|
||||||
|
均衡: "3",
|
||||||
|
性能: "4",
|
||||||
|
}[value] || "已禁用"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
// useEffect(() => {
|
const [vconfig, setVconfig] = useState<VideoConfig>(tool.state.videoSetting)
|
||||||
// setLaunchOpt(tool.state.VideoSettings[tool.state.launchIndex] || "")
|
|
||||||
// }, [tool.state.launchIndex, tool.state.VideoSettings])
|
|
||||||
|
|
||||||
// 设置对应关系
|
useEffect(() => {
|
||||||
// TODO Value通过实际数值映射
|
if (steam.state.steamDirValid && steam.currentUser())
|
||||||
const videoSettings = [
|
void tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0)
|
||||||
{ 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: ["性能", "均衡", "品质", "超高品质", "已禁用"],
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip content="功能测试中,尚未实装" showArrow={true} delay={300}>
|
<Card>
|
||||||
<Card>
|
<CardHeader>
|
||||||
<CardHeader>
|
<CardIcon>
|
||||||
<CardIcon>
|
<SettingConfig /> 视频设置
|
||||||
<SettingConfig /> 视频设置
|
</CardIcon>
|
||||||
</CardIcon>
|
<CardTool>
|
||||||
<CardTool>
|
{/* {tool.state.VideoSettings.map((option, index) => (
|
||||||
{/* {tool.state.VideoSettings.map((option, index) => (
|
|
||||||
<ToolButton key={index} onClick={() => tool.setLaunchIndex(index)}>
|
<ToolButton key={index} onClick={() => tool.setLaunchIndex(index)}>
|
||||||
{index + 1}
|
{index + 1}
|
||||||
</ToolButton>
|
</ToolButton>
|
||||||
))} */}
|
))} */}
|
||||||
{edit && (
|
{edit && (
|
||||||
|
<>
|
||||||
|
<ToolButton onClick={() => setVconfig({ ...vconfig, ...VideoSettingTemplate.low })}>
|
||||||
|
低
|
||||||
|
</ToolButton>
|
||||||
|
<ToolButton
|
||||||
|
onClick={() => setVconfig({ ...vconfig, ...VideoSettingTemplate.middle })}
|
||||||
|
>
|
||||||
|
中
|
||||||
|
</ToolButton>
|
||||||
|
<ToolButton onClick={() => setVconfig({ ...vconfig, ...VideoSettingTemplate.high })}>
|
||||||
|
高
|
||||||
|
</ToolButton>
|
||||||
|
<ToolButton
|
||||||
|
onClick={() => setVconfig({ ...vconfig, ...VideoSettingTemplate.veryhigh })}
|
||||||
|
>
|
||||||
|
非常高
|
||||||
|
</ToolButton>
|
||||||
|
<ToolButton
|
||||||
|
onClick={() => setVconfig({ ...vconfig, ...VideoSettingTemplate.recommend })}
|
||||||
|
>
|
||||||
|
推荐
|
||||||
|
</ToolButton>
|
||||||
|
<ToolButton
|
||||||
|
onClick={async () => {
|
||||||
|
await tool.setVideoConfig(
|
||||||
|
steam.state.steamDir,
|
||||||
|
steam.currentUser()?.steam_id32 || 0,
|
||||||
|
vconfig
|
||||||
|
)
|
||||||
|
await tool.getVideoConfig(
|
||||||
|
steam.state.steamDir,
|
||||||
|
steam.currentUser()?.steam_id32 || 0
|
||||||
|
)
|
||||||
|
setEdit(false)
|
||||||
|
addToast({ title: "应用设置成功" })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Plus />
|
||||||
|
应用
|
||||||
|
</ToolButton>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<ToolButton
|
||||||
|
onClick={async () => {
|
||||||
|
if (steam.state.steamDirValid && steam.currentUser())
|
||||||
|
await tool.getVideoConfig(
|
||||||
|
steam.state.steamDir,
|
||||||
|
steam.currentUser()?.steam_id32 || 0
|
||||||
|
)
|
||||||
|
setVconfig(tool.state.videoSetting)
|
||||||
|
setEdit(!edit)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{edit ? (
|
||||||
<>
|
<>
|
||||||
<ToolButton>低</ToolButton>
|
<CloseSmall />
|
||||||
<ToolButton>中</ToolButton>
|
取消编辑
|
||||||
<ToolButton>高</ToolButton>
|
</>
|
||||||
<ToolButton>非常高</ToolButton>
|
) : (
|
||||||
<ToolButton>推荐</ToolButton>
|
<>
|
||||||
<ToolButton
|
<Edit />
|
||||||
onClick={() => {
|
编辑
|
||||||
addToast({ title: "测试中 功能完成后可应用设置到游戏" })
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Plus />
|
|
||||||
应用
|
|
||||||
</ToolButton>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<ToolButton onClick={() => setEdit(!edit)}>
|
</ToolButton>
|
||||||
{edit ? (
|
|
||||||
<>
|
<ToolButton
|
||||||
<CloseSmall />
|
onClick={async () => {
|
||||||
取消编辑
|
if (steam.state.steamDirValid && steam.currentUser()) {
|
||||||
</>
|
await tool.getVideoConfig(
|
||||||
) : (
|
steam.state.steamDir,
|
||||||
<>
|
steam.currentUser()?.steam_id32 || 0
|
||||||
<Edit />
|
)
|
||||||
编辑
|
addToast({ title: "读取成功" })
|
||||||
</>
|
} else addToast({ title: "请先选择用户", color: "danger" })
|
||||||
)}
|
}}
|
||||||
</ToolButton>
|
|
||||||
<ToolButton onClick={() => setHide(!hide)}>
|
|
||||||
{hide ? (
|
|
||||||
<>
|
|
||||||
<Up />
|
|
||||||
显示
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<Down />
|
|
||||||
隐藏
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</ToolButton>
|
|
||||||
</CardTool>
|
|
||||||
</CardHeader>
|
|
||||||
{!hide && (
|
|
||||||
<motion.div
|
|
||||||
initial={{ opacity: 0 }}
|
|
||||||
animate={{ opacity: 1 }}
|
|
||||||
exit={{ opacity: 0 }}
|
|
||||||
transition={{ duration: 0.2 }}
|
|
||||||
>
|
>
|
||||||
<CardBody>
|
读取
|
||||||
<ul className="flex flex-wrap gap-3 mt-1">
|
</ToolButton>
|
||||||
<li className="flex flex-col gap-1.5">
|
<ToolButton onClick={() => setHide(!hide)}>
|
||||||
<span className="ml-2">分辨率</span>
|
{hide ? (
|
||||||
<span className="flex gap-3">
|
<>
|
||||||
<NumberInput
|
<Up />
|
||||||
aria-label="width"
|
显示
|
||||||
value={tool.state.videoSetting.width}
|
</>
|
||||||
onValueChange={(value) => {
|
) : (
|
||||||
tool.setVideoSetting({
|
<>
|
||||||
...tool.state.videoSetting,
|
<Down />
|
||||||
width: value,
|
隐藏
|
||||||
})
|
</>
|
||||||
}}
|
)}
|
||||||
radius="full"
|
</ToolButton>
|
||||||
step={10}
|
</CardTool>
|
||||||
className="max-w-28"
|
</CardHeader>
|
||||||
classNames={{ inputWrapper: "h-10" }}
|
{!hide && (
|
||||||
/>
|
<motion.div
|
||||||
<NumberInput
|
initial={{ opacity: 0 }}
|
||||||
aria-label="height"
|
animate={{ opacity: 1 }}
|
||||||
value={tool.state.videoSetting.height}
|
exit={{ opacity: 0 }}
|
||||||
onValueChange={(value) => {
|
transition={{ duration: 0.2 }}
|
||||||
tool.setVideoSetting({
|
>
|
||||||
...tool.state.videoSetting,
|
<CardBody>
|
||||||
height: value,
|
<ul className="flex flex-wrap gap-3 mt-1">
|
||||||
})
|
<li className="flex flex-col gap-1.5">
|
||||||
}}
|
<span className="ml-2">分辨率</span>
|
||||||
radius="full"
|
<span className="flex gap-3">
|
||||||
step={10}
|
<NumberInput
|
||||||
className="max-w-28"
|
aria-label="width"
|
||||||
classNames={{ inputWrapper: "h-10" }}
|
value={parseInt(
|
||||||
/>
|
edit ? vconfig.defaultres : tool.state.videoSetting.defaultres,
|
||||||
</span>
|
10
|
||||||
|
)}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
const _ = edit
|
||||||
|
? setVconfig({
|
||||||
|
...vconfig,
|
||||||
|
defaultres: value.toString(),
|
||||||
|
})
|
||||||
|
: tool.setVideoSetting({
|
||||||
|
...tool.state.videoSetting,
|
||||||
|
defaultres: value.toString(),
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
radius="full"
|
||||||
|
step={10}
|
||||||
|
className="max-w-28"
|
||||||
|
classNames={{ inputWrapper: "h-10" }}
|
||||||
|
/>
|
||||||
|
<NumberInput
|
||||||
|
aria-label="height"
|
||||||
|
value={parseInt(edit ? vconfig.defaultresheight : tool.state.videoSetting.defaultresheight, 10)}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
const _ = edit
|
||||||
|
? setVconfig({
|
||||||
|
...vconfig,
|
||||||
|
defaultresheight: value.toString(),
|
||||||
|
})
|
||||||
|
: tool.setVideoSetting({
|
||||||
|
...tool.state.videoSetting,
|
||||||
|
defaultresheight: value.toString(),
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
radius="full"
|
||||||
|
step={10}
|
||||||
|
className="max-w-28"
|
||||||
|
classNames={{ inputWrapper: "h-10" }}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
{videoSettings(edit ? vconfig : tool.state.videoSetting).map((vid, index) => (
|
||||||
|
<li className="flex flex-col gap-1.5" key={index}>
|
||||||
|
<span className="ml-2">{vid.title}</span>
|
||||||
|
<Tabs
|
||||||
|
size="md"
|
||||||
|
radius="full"
|
||||||
|
className="min-w-36"
|
||||||
|
fullWidth
|
||||||
|
selectedKey={vid.value}
|
||||||
|
onSelectionChange={(key) => {
|
||||||
|
// console.log(vid.type, key)
|
||||||
|
// 修改 vconfig 名为 vid.type 的 value为 key
|
||||||
|
const _ =
|
||||||
|
edit && key
|
||||||
|
? setVconfig({
|
||||||
|
...vconfig,
|
||||||
|
[vid.type]: vid.mapping(key.toString()),
|
||||||
|
})
|
||||||
|
: null
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{vid.options.map((opt, _) => (
|
||||||
|
<Tab key={opt} title={opt} titleValue={opt} />
|
||||||
|
))}
|
||||||
|
</Tabs>
|
||||||
</li>
|
</li>
|
||||||
{videoSettings.map((vid, index) => (
|
))}
|
||||||
<li className="flex flex-col gap-1.5" key={index}>
|
</ul>
|
||||||
<span className="ml-2">{vid.title}</span>
|
</CardBody>
|
||||||
<Tabs
|
</motion.div>
|
||||||
selectedKey={vid.value}
|
)}
|
||||||
size="md"
|
</Card>
|
||||||
radius="full"
|
|
||||||
className="min-w-36"
|
|
||||||
fullWidth
|
|
||||||
>
|
|
||||||
{vid.options.map((opt, _) => (
|
|
||||||
<Tab key={opt} title={opt} />
|
|
||||||
))}
|
|
||||||
</Tabs>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</CardBody>
|
|
||||||
</motion.div>
|
|
||||||
)}
|
|
||||||
</Card>
|
|
||||||
</Tooltip>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ import {
|
|||||||
Refresh,
|
Refresh,
|
||||||
RocketOne,
|
RocketOne,
|
||||||
Square,
|
Square,
|
||||||
SunOne,
|
SunOne
|
||||||
SurprisedFaceWithOpenBigMouth,
|
|
||||||
} from "@icon-park/react"
|
} from "@icon-park/react"
|
||||||
import { type Theme, getCurrentWindow } from "@tauri-apps/api/window"
|
import { type Theme, getCurrentWindow } from "@tauri-apps/api/window"
|
||||||
import { /* relaunch, */ exit } from "@tauri-apps/plugin-process"
|
import { /* relaunch, */ exit } from "@tauri-apps/plugin-process"
|
||||||
@@ -21,6 +20,7 @@ import { usePathname, useRouter } from "next/navigation"
|
|||||||
import { saveAllNow } from "@tauri-store/valtio"
|
import { saveAllNow } from "@tauri-store/valtio"
|
||||||
import { useSteamStore } from "@/store/steam"
|
import { useSteamStore } from "@/store/steam"
|
||||||
import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter } from "@heroui/react"
|
import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter } from "@heroui/react"
|
||||||
|
import { window } from "@tauri-apps/api"
|
||||||
|
|
||||||
const Nav = () => {
|
const Nav = () => {
|
||||||
const { theme, setTheme } = useTheme()
|
const { theme, setTheme } = useTheme()
|
||||||
@@ -29,10 +29,12 @@ const Nav = () => {
|
|||||||
await setTauriTheme(theme)
|
await setTauriTheme(theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const app = useAppStore()
|
||||||
const close = async () => {
|
const close = async () => {
|
||||||
// (await window.hideOnClose) ? getCurrent().hide() : exit();
|
|
||||||
await saveAllNow()
|
await saveAllNow()
|
||||||
await exit()
|
// await exit()
|
||||||
|
if (app.state.hiddenOnClose) await window.getCurrentWindow().hide()
|
||||||
|
else await exit()
|
||||||
}
|
}
|
||||||
|
|
||||||
const minimize = async () => {
|
const minimize = async () => {
|
||||||
@@ -52,8 +54,6 @@ const Nav = () => {
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const pathname = usePathname()
|
const pathname = usePathname()
|
||||||
|
|
||||||
const app = useAppStore()
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav className="absolute top-0 right-0 flex flex-row h-16 gap-0.5 p-4" data-tauri-drag-region>
|
<nav className="absolute top-0 right-0 flex flex-row h-16 gap-0.5 p-4" data-tauri-drag-region>
|
||||||
<Tooltip content="启动页确认设置" showArrow={true} delay={300}>
|
<Tooltip content="启动页确认设置" showArrow={true} delay={300}>
|
||||||
@@ -81,7 +81,8 @@ const Nav = () => {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip content="反馈" showArrow={true} delay={300}>
|
<Tooltip content="反馈" showArrow={true} delay={300}>
|
||||||
<Link
|
<Link
|
||||||
href="/preference"
|
href="https://docs.qq.com/form/page/DZU1ieW9SQkxWU1RF"
|
||||||
|
target="_blank"
|
||||||
className="px-2 py-0 text-black transition duration-150 rounded dark:text-white hover:bg-black/10 dark:hover:bg-zinc-100/10 active:scale-95"
|
className="px-2 py-0 text-black transition duration-150 rounded dark:text-white hover:bg-black/10 dark:hover:bg-zinc-100/10 active:scale-95"
|
||||||
>
|
>
|
||||||
<button type="button">
|
<button type="button">
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ const Avatar = () => {
|
|||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
steam.currentUser()?.avatar
|
steam.currentUser()?.avatar
|
||||||
? `data:image/png;base64,${steam.currentUser()?.avatar || ''}`
|
? `data:image/png;base64,${steam.currentUser()?.avatar || ""}`
|
||||||
: "/logo_square.png"
|
: "/logo_square.png"
|
||||||
}
|
}
|
||||||
alt="avatar"
|
alt="avatar"
|
||||||
@@ -72,9 +72,10 @@ const Avatar = () => {
|
|||||||
const SideBar = () => {
|
const SideBar = () => {
|
||||||
const app = useAppStore()
|
const app = useAppStore()
|
||||||
|
|
||||||
void getVersion().then((Value) => {
|
if (typeof window !== "undefined")
|
||||||
app.setVersion(Value)
|
void getVersion().then((Value) => {
|
||||||
})
|
app.setVersion(Value)
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { store } from "@tauri-store/valtio"
|
import { store } from "@tauri-store/valtio"
|
||||||
import { useSnapshot } from "valtio"
|
import { useSnapshot } from "valtio"
|
||||||
import { DEFAULT_STORE_CONFIG } from "./config"
|
import { DEFAULT_STORE_CONFIG } from "./config"
|
||||||
import { enable, isEnabled, disable } from "@tauri-apps/plugin-autostart"
|
import { enable, disable } from "@tauri-apps/plugin-autostart"
|
||||||
|
import { LazyStore } from '@tauri-apps/plugin-store';
|
||||||
|
|
||||||
const defaultValue = {
|
const defaultValue = {
|
||||||
version: "0.0.1",
|
version: "0.0.1",
|
||||||
@@ -10,6 +11,8 @@ const defaultValue = {
|
|||||||
notice: "",
|
notice: "",
|
||||||
useMirror: true,
|
useMirror: true,
|
||||||
autoStart: false,
|
autoStart: false,
|
||||||
|
startHidden: false,
|
||||||
|
hiddenOnClose: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const appStore = store("app", { ...defaultValue }, DEFAULT_STORE_CONFIG)
|
export const appStore = store("app", { ...defaultValue }, DEFAULT_STORE_CONFIG)
|
||||||
@@ -27,10 +30,15 @@ export const useAppStore = () => {
|
|||||||
setNotice,
|
setNotice,
|
||||||
setUseMirror,
|
setUseMirror,
|
||||||
setAutoStart,
|
setAutoStart,
|
||||||
|
setStartHidden,
|
||||||
|
setHiddenOnClose,
|
||||||
resetAppStore,
|
resetAppStore,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const launchStore = new LazyStore('cstb.json', { autoSave: true });
|
||||||
|
if (typeof window !== 'undefined') void launchStore.save()
|
||||||
|
|
||||||
const setVersion = (version: string) => {
|
const setVersion = (version: string) => {
|
||||||
appStore.state.version = version
|
appStore.state.version = version
|
||||||
}
|
}
|
||||||
@@ -56,6 +64,17 @@ const setAutoStart = (autoStart: boolean) => {
|
|||||||
appStore.state.autoStart = autoStart
|
appStore.state.autoStart = autoStart
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 同步到 launchStore 使 start hidden 生效
|
||||||
|
const setStartHidden = async (startHidden: boolean) => {
|
||||||
|
appStore.state.startHidden = startHidden;
|
||||||
|
await launchStore.set('hidden', startHidden);
|
||||||
|
await launchStore.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
const setHiddenOnClose = (hiddenOnClose: boolean) => {
|
||||||
|
appStore.state.hiddenOnClose = hiddenOnClose;
|
||||||
|
}
|
||||||
|
|
||||||
const resetAppStore = () => {
|
const resetAppStore = () => {
|
||||||
setVersion(defaultValue.version)
|
setVersion(defaultValue.version)
|
||||||
setHasUpdate(defaultValue.hasUpdate)
|
setHasUpdate(defaultValue.hasUpdate)
|
||||||
@@ -63,4 +82,6 @@ const resetAppStore = () => {
|
|||||||
setNotice(defaultValue.notice)
|
setNotice(defaultValue.notice)
|
||||||
setUseMirror(defaultValue.useMirror)
|
setUseMirror(defaultValue.useMirror)
|
||||||
setAutoStart(defaultValue.autoStart)
|
setAutoStart(defaultValue.autoStart)
|
||||||
|
void setStartHidden(defaultValue.startHidden)
|
||||||
|
setHiddenOnClose(defaultValue.hiddenOnClose)
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
import { store } from "@tauri-store/valtio"
|
import { store } from "@tauri-store/valtio"
|
||||||
import { useSnapshot } from "valtio"
|
import { useSnapshot } from "valtio"
|
||||||
import { DEFAULT_STORE_CONFIG } from "./config"
|
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"
|
||||||
|
|
||||||
interface LaunchOption {
|
interface LaunchOption {
|
||||||
option: string
|
option: string
|
||||||
@@ -8,24 +11,109 @@ interface LaunchOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface VideoSetting {
|
export interface VideoSetting {
|
||||||
width: number; // 分辨率宽度
|
version: string; // 版本
|
||||||
height: number; // 分辨率高度
|
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; // 全屏
|
fullscreen: string; // 全屏
|
||||||
vsync: string; // 垂直同步
|
coop_fullscreen: string; // 合作模式全屏
|
||||||
enhanceCharacterContrast: string; // 增强角色对比度
|
nowindowborder: string; // 无窗口边框
|
||||||
cmaa2AntiAliasing: string; // CMAA2抗锯齿
|
mat_vsync: string; // 垂直同步
|
||||||
msaaAntiAliasing: string; // 多重采样抗锯齿
|
fullscreen_min_on_focus_loss: string; // 失去焦点时最小化全屏
|
||||||
globalShadowQuality: string; // 全局阴影效果
|
high_dpi: string; // 高DPI
|
||||||
dynamicShadows: string; // 动态阴影
|
auto_config: string; // 自动配置
|
||||||
modelTextureDetail: string; // 模型/贴图细节
|
shaderquality: string; // 光影质量
|
||||||
textureFilteringMode: string; // 贴图过滤模式
|
r_texturefilteringquality: string; // 纹理过滤质量
|
||||||
lightShadowDetail: string; // 光影细节
|
msaa_samples: string; // 多重采样抗锯齿样本数
|
||||||
particleDetail: string; // 粒子细节
|
r_csgo_cmaa_enable: string; // CMAA抗锯齿启用
|
||||||
ambientOcclusion: string; // 环境光遮蔽
|
videocfg_shadow_quality: string; // 阴影质量
|
||||||
hdr: string; // 高动态范围
|
videocfg_dynamic_shadows: string; // 动态阴影
|
||||||
fidelityFxSuperResolution: string; // Fidelity FX 超级分辨率
|
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; // 宽高比模式
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 视频设置预设模版
|
||||||
|
export const VideoSettingTemplate = {
|
||||||
|
veryhigh: {
|
||||||
|
shaderquality: "1",
|
||||||
|
r_texturefilteringquality: "3",
|
||||||
|
msaa_samples: "8",
|
||||||
|
r_csgo_cmaa_enable: "0",
|
||||||
|
videocfg_shadow_quality: "3",
|
||||||
|
videocfg_dynamic_shadows: "1",
|
||||||
|
videocfg_texture_detail: "2",
|
||||||
|
videocfg_particle_detail: "3",
|
||||||
|
videocfg_ao_detail: "3",
|
||||||
|
videocfg_hdr_detail: "-1",
|
||||||
|
videocfg_fsr_detail: "0",
|
||||||
|
},
|
||||||
|
high: {
|
||||||
|
shaderquality: "1",
|
||||||
|
r_texturefilteringquality: "3",
|
||||||
|
msaa_samples: "4",
|
||||||
|
r_csgo_cmaa_enable: "0",
|
||||||
|
videocfg_shadow_quality: "2",
|
||||||
|
videocfg_dynamic_shadows: "1",
|
||||||
|
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: "1",
|
||||||
|
msaa_samples: "2",
|
||||||
|
r_csgo_cmaa_enable: "0",
|
||||||
|
videocfg_shadow_quality: "1",
|
||||||
|
videocfg_dynamic_shadows: "1",
|
||||||
|
videocfg_texture_detail: "1",
|
||||||
|
videocfg_particle_detail: "1",
|
||||||
|
videocfg_ao_detail: "0",
|
||||||
|
videocfg_fsr_detail: "2",
|
||||||
|
},
|
||||||
|
low: {
|
||||||
|
shaderquality: "0",
|
||||||
|
r_texturefilteringquality: "0",
|
||||||
|
msaa_samples: "0",
|
||||||
|
r_csgo_cmaa_enable: "0",
|
||||||
|
videocfg_shadow_quality: "0",
|
||||||
|
videocfg_dynamic_shadows: "0",
|
||||||
|
videocfg_texture_detail: "0",
|
||||||
|
videocfg_particle_detail: "0",
|
||||||
|
videocfg_ao_detail: "0",
|
||||||
|
videocfg_hdr_detail: "3",
|
||||||
|
videocfg_fsr_detail: "3",
|
||||||
|
},
|
||||||
|
recommend: {
|
||||||
|
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",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const defaultValue = {
|
const defaultValue = {
|
||||||
launchOptions: [
|
launchOptions: [
|
||||||
{ option: "-novid -high -freq 144 -fullscreen", name: "" },
|
{ option: "-novid -high -freq 144 -fullscreen", name: "" },
|
||||||
@@ -35,8 +123,38 @@ const defaultValue = {
|
|||||||
launchIndex: 0,
|
launchIndex: 0,
|
||||||
powerPlan: 0,
|
powerPlan: 0,
|
||||||
videoSetting: {
|
videoSetting: {
|
||||||
width: 1920,
|
version: "15",
|
||||||
height: 1080
|
vendor_id: "0",
|
||||||
|
device_id: "0",
|
||||||
|
cpu_level: "3",
|
||||||
|
gpu_mem_level: "3",
|
||||||
|
gpu_level: "3",
|
||||||
|
knowndevice: "0",
|
||||||
|
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,
|
} as VideoSetting,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,6 +168,13 @@ export const useToolStore = () => {
|
|||||||
void toolStore.start
|
void toolStore.start
|
||||||
const state = useSnapshot(toolStore.state)
|
const state = useSnapshot(toolStore.state)
|
||||||
|
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
setTimeout(() => {
|
||||||
|
sendCurrentLaunchOptionToTray(state.launchIndex)
|
||||||
|
sendPowerPlanToTray(state.powerPlan)
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
state,
|
state,
|
||||||
store: toolStore,
|
store: toolStore,
|
||||||
@@ -58,6 +183,8 @@ export const useToolStore = () => {
|
|||||||
setLaunchIndex,
|
setLaunchIndex,
|
||||||
setPowerPlan,
|
setPowerPlan,
|
||||||
setVideoSetting,
|
setVideoSetting,
|
||||||
|
getVideoConfig,
|
||||||
|
setVideoConfig,
|
||||||
addLaunchOption,
|
addLaunchOption,
|
||||||
resetToolStore,
|
resetToolStore,
|
||||||
}
|
}
|
||||||
@@ -77,16 +204,35 @@ const setLaunchOptions = (options: LaunchOption[]) => {
|
|||||||
|
|
||||||
const setLaunchIndex = (index: number) => {
|
const setLaunchIndex = (index: number) => {
|
||||||
toolStore.state.launchIndex = index
|
toolStore.state.launchIndex = index
|
||||||
|
sendCurrentLaunchOptionToTray(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sendCurrentLaunchOptionToTray = (index: number) => {
|
||||||
|
void emit("tray://get_current_launch_option", toolStore.state.launchOptions[index].name || index + 1)
|
||||||
|
}
|
||||||
const setPowerPlan = (plan: number) => {
|
const setPowerPlan = (plan: number) => {
|
||||||
toolStore.state.powerPlan = plan
|
toolStore.state.powerPlan = plan
|
||||||
|
sendPowerPlanToTray(plan)
|
||||||
|
}
|
||||||
|
const sendPowerPlanToTray = (plan: number) => {
|
||||||
|
void emit("tray://get_powerplan", plan)
|
||||||
}
|
}
|
||||||
|
|
||||||
const setVideoSetting = (setting: VideoSetting) => {
|
const setVideoSetting = (setting: VideoSetting) => {
|
||||||
toolStore.state.videoSetting = setting
|
toolStore.state.videoSetting = setting
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getVideoConfig = async (steam_dir: string, steam_id32: number) => {
|
||||||
|
const video = await invoke<VideoSetting>("get_cs2_video_config", { steamDir: steam_dir, steamId32: steam_id32 })
|
||||||
|
// console.log(video)
|
||||||
|
setVideoSetting(video)
|
||||||
|
}
|
||||||
|
|
||||||
|
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 })
|
||||||
|
}
|
||||||
|
|
||||||
const addLaunchOption = (option: LaunchOption) => {
|
const addLaunchOption = (option: LaunchOption) => {
|
||||||
// 限制最高10个
|
// 限制最高10个
|
||||||
if (toolStore.state.launchOptions.length >= 10) {
|
if (toolStore.state.launchOptions.length >= 10) {
|
||||||
|
|||||||
Reference in New Issue
Block a user