mirror of
https://github.com/Grasscutters/Cultivation.git
synced 2025-12-14 16:14:48 +01:00
Compare commits
24 Commits
v1.0.3-alp
...
v1.0.4-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc20fe5916 | ||
|
|
1a6ed38f8f | ||
|
|
d23d5e3806 | ||
|
|
365a4f2888 | ||
|
|
e270c886db | ||
|
|
18a1b0e94c | ||
|
|
3799ec648d | ||
|
|
8ff06f6d29 | ||
|
|
6ff1ef932c | ||
|
|
9e29135376 | ||
|
|
109f98db66 | ||
|
|
69201bc8b1 | ||
|
|
656fa2cfe3 | ||
|
|
1588bee5a3 | ||
|
|
75b79d0202 | ||
|
|
6d9f1af134 | ||
|
|
d38459bb8a | ||
|
|
c7954d2294 | ||
|
|
adbb8e380d | ||
|
|
4ff9e88185 | ||
|
|
27a10c58ca | ||
|
|
44b148f2a4 | ||
|
|
6434814d1d | ||
|
|
043f3e7ce4 |
30
README.md
30
README.md
@@ -1,4 +1,4 @@
|
|||||||
# Cient Patching Notice
|
# Client Patching Notice
|
||||||
For game versions 2.8 and above, Cultivation automatically makes a small patch to your game client when launching using Grasscutter, and restores it upon closing the game. In theory, you should still be totally safe, however it would be dishonest to not explicitly state that **modifying the game client could, theoretically, lead to a ban if you connect to official servers with it**. It is extremely unlikely AND there are no instances known of it happening, but the possibility exists.
|
For game versions 2.8 and above, Cultivation automatically makes a small patch to your game client when launching using Grasscutter, and restores it upon closing the game. In theory, you should still be totally safe, however it would be dishonest to not explicitly state that **modifying the game client could, theoretically, lead to a ban if you connect to official servers with it**. It is extremely unlikely AND there are no instances known of it happening, but the possibility exists.
|
||||||
|
|
||||||
# Cultivation
|
# Cultivation
|
||||||
@@ -12,8 +12,12 @@ Please do **NOT install, download, or use pre-compiled versions of Cultivation f
|
|||||||
* [Developer Quick-start](#developer-quickstart)
|
* [Developer Quick-start](#developer-quickstart)
|
||||||
* [Setup](#setup)
|
* [Setup](#setup)
|
||||||
* [Building](#building)
|
* [Building](#building)
|
||||||
* [Troubleshooting](#troubleshooting)
|
* [Code Formatting and Linting](#code-formatting-and-linting)
|
||||||
|
* [Generating Update Artifacts](#generating-update-artifacts)
|
||||||
* [Theming](#theming)
|
* [Theming](#theming)
|
||||||
|
* [Screenshots](#screenshots)
|
||||||
|
* [Credits](#credits)
|
||||||
|
|
||||||
|
|
||||||
# Download
|
# Download
|
||||||
[Find release builds here!](https://github.com/Grasscutters/Cultivation/releases)
|
[Find release builds here!](https://github.com/Grasscutters/Cultivation/releases)
|
||||||
@@ -24,28 +28,28 @@ Once downloaded, extract somewhere and open as administrator.
|
|||||||
|
|
||||||
### Setup
|
### Setup
|
||||||
* Install [NodeJS >12](https://nodejs.org/en/)
|
* Install [NodeJS >12](https://nodejs.org/en/)
|
||||||
* Install [yarn](https://classic.yarnpkg.com/lang/en/docs/install/#debian-stable) (cry about it `npm` lovers)
|
* Install [yarn](https://classic.yarnpkg.com/lang/en/docs/install) (cry about it `npm` lovers)
|
||||||
* Install [Cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html) & [Rust compiler](https://www.rust-lang.org/tools/install)
|
* Install [Rust](https://www.rust-lang.org/tools/install)
|
||||||
* `yarn install`
|
* `yarn install`
|
||||||
* `yarn start:dev`
|
* `yarn start:dev`
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
`npm run build` or `yarn build`
|
For a release build,
|
||||||
|
- `yarn build`
|
||||||
|
|
||||||
Add `--release` or `--debug` depending on what release you are creating. This defaults to `--release`
|
For a debug build,
|
||||||
|
- `yarn build --debug`
|
||||||
|
|
||||||
### Code Formatting and Linting
|
### Code Formatting and Linting
|
||||||
|
- `yarn format`
|
||||||
|
- `yarn lint`
|
||||||
|
|
||||||
Format the code with `npm format` or `yarn format`. Run the lints with `npm lint` or `yarn lint`.
|
### Generating Update Artifacts
|
||||||
|
|
||||||
### Updating
|
|
||||||
* Add the `TAURI_PRIVATE_KEY` as an environment variable with a path to your private key.
|
* Add the `TAURI_PRIVATE_KEY` as an environment variable with a path to your private key.
|
||||||
* Add the `TAURI_KEY_PASSWORD` as an environment variable with the password for your private key.
|
* Add the `TAURI_KEY_PASSWORD` as an environment variable with the password for your private key.
|
||||||
* Run `npm run update` or `yarn build`
|
* `yarn build`
|
||||||
* The update will be in `src-tauri/target/(release|debug)/msi/Cultivation_X.X.X_x64_xx-XX.msi.zip`
|
|
||||||
|
|
||||||
# Troubleshooting
|
The update will be at `src-tauri/target/(release|debug)/msi/Cultivation_X.X.X_x64_xx-XX.msi.zip`
|
||||||
TODO. Collect common issues before updating.
|
|
||||||
|
|
||||||
# Theming
|
# Theming
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "cultivation",
|
"name": "cultivation",
|
||||||
"version": "1.0.3",
|
"version": "1.0.4",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "^1.0.0-rc.5",
|
"@tauri-apps/api": "^1.0.0-rc.5",
|
||||||
"@testing-library/jest-dom": "^5.14.1",
|
"@testing-library/jest-dom": "^5.14.1",
|
||||||
"@testing-library/react": "^13.0.0",
|
"@testing-library/react": "^13.0.0",
|
||||||
"@testing-library/user-event": "^13.2.1",
|
"@testing-library/user-event": "^14.2.6",
|
||||||
"@types/jest": "^27.0.1",
|
"@types/jest": "^28.1.6",
|
||||||
"@types/node": "^16.7.13",
|
"@types/node": "^18.0.6",
|
||||||
"@types/react": "^18.0.0",
|
"@types/react": "^18.0.0",
|
||||||
"@types/react-dom": "^18.0.0",
|
"@types/react-dom": "^18.0.0",
|
||||||
"react": "^18.1.0",
|
"react": "^18.1.0",
|
||||||
|
|||||||
148
src-tauri/Cargo.lock
generated
148
src-tauri/Cargo.lock
generated
@@ -506,9 +506,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "concurrent-queue"
|
name = "concurrent-queue"
|
||||||
version = "1.2.2"
|
version = "1.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3"
|
checksum = "83827793632c72fa4f73c2edb31e7a997527dd8ffe7077344621fc62c5478157"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cache-padded",
|
"cache-padded",
|
||||||
]
|
]
|
||||||
@@ -657,9 +657,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-common"
|
name = "crypto-common"
|
||||||
version = "0.1.4"
|
version = "0.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5999502d32b9c48d492abe66392408144895020ec4709e549e840799f3bb74c0"
|
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
"typenum",
|
"typenum",
|
||||||
@@ -721,7 +721,7 @@ dependencies = [
|
|||||||
"is_elevated",
|
"is_elevated",
|
||||||
"libloading",
|
"libloading",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"open 2.1.3",
|
"open",
|
||||||
"rcgen",
|
"rcgen",
|
||||||
"regex",
|
"regex",
|
||||||
"registry",
|
"registry",
|
||||||
@@ -784,9 +784,9 @@ checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dbus"
|
name = "dbus"
|
||||||
version = "0.9.5"
|
version = "0.9.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "de0a745c25b32caa56b82a3950f5fec7893a960f4c10ca3b02060b0c38d8c2ce"
|
checksum = "6f8bcdd56d2e5c4ed26a529c5a9029f5db8290d433497506f958eae3be148eb6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"libdbus-sys",
|
"libdbus-sys",
|
||||||
@@ -1239,15 +1239,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generator"
|
name = "generator"
|
||||||
version = "0.7.0"
|
version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c1d9279ca822891c1a4dae06d185612cf8fc6acfe5dff37781b41297811b12ee"
|
checksum = "cc184cace1cea8335047a471cc1da80f18acf8a76f3bab2028d499e328948ec7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"winapi",
|
"windows 0.32.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1463,9 +1463,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.12.2"
|
version = "0.12.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "607c8a29735385251a339424dd462993c0fed8fa09d378f259377df08c126022"
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
@@ -1948,9 +1948,9 @@ checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mac-notification-sys"
|
name = "mac-notification-sys"
|
||||||
version = "0.5.2"
|
version = "0.5.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "042f74a606175d72ca483e14e0873fe0f6c003f7af45865b17b16fdaface7203"
|
checksum = "fff231a88fe2e9985f9d159a2f02986fe46daa0f6af976a0d934be4870cc9d02"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"dirs-next",
|
"dirs-next",
|
||||||
@@ -2336,19 +2336,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "open"
|
name = "open"
|
||||||
version = "2.1.3"
|
version = "3.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f2423ffbf445b82e58c3b1543655968923dd06f85432f10be2bb4f1b7122f98c"
|
checksum = "f23a407004a1033f53e93f9b45580d14de23928faad187384f891507c9b0c045"
|
||||||
dependencies = [
|
|
||||||
"pathdiff",
|
|
||||||
"windows-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "open"
|
|
||||||
version = "3.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "360bcc8316bf6363aa3954c3ccc4de8add167b087e0259190a043c9514f910fe"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pathdiff",
|
"pathdiff",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
@@ -2356,9 +2346,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl"
|
name = "openssl"
|
||||||
version = "0.10.40"
|
version = "0.10.41"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e"
|
checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
@@ -2388,9 +2378,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.74"
|
version = "0.9.75"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "835363342df5fba8354c5b453325b110ffd54044e588c539cf2f20a8014e4cb1"
|
checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"cc",
|
"cc",
|
||||||
@@ -2546,9 +2536,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pem"
|
name = "pem"
|
||||||
version = "1.0.2"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e9a3b09a20e374558580a4914d3b7d89bd61b954a5a5e1dcbea98753addb1947"
|
checksum = "03c64931a1a212348ec4f3b4362585eca7159d0d09cbdf4a7f74f02173596fd4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
]
|
]
|
||||||
@@ -2977,9 +2967,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rcgen"
|
name = "rcgen"
|
||||||
version = "0.9.2"
|
version = "0.9.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7fa2d386df8533b02184941c76ae2e0d0c1d053f5d43339169d80f21275fc5e"
|
checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pem",
|
"pem",
|
||||||
"ring",
|
"ring",
|
||||||
@@ -3184,9 +3174,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.7"
|
version = "1.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a0a5f7c728f5d284929a1cccb5bc19884422bfe6ef4d6c409da2c41838983fcf"
|
checksum = "24c8ad4f0c00e1eb5bc7614d236a7f1300e3dbd76b68cac8e06fb00b015ad8d8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
@@ -3322,18 +3312,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.138"
|
version = "1.0.139"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1578c6245786b9d168c5447eeacfb96856573ca56c9d68fdcf394be134882a47"
|
checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.138"
|
version = "1.0.139"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "023e9b1467aef8a10fb88f25611870ada9800ef7e22afce356bb0d2387b6f27c"
|
checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -3789,9 +3779,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri"
|
name = "tauri"
|
||||||
version = "1.0.3"
|
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 = "d61fc211e0bd2c04c0aecd202d2cd72dd797a89da02989a39e1b9691462386d6"
|
checksum = "827f61bd3dd40276694be5c7ffc40d65b94ab00d9f8c1a4a4db07f2cdc306c83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"attohttpc",
|
"attohttpc",
|
||||||
@@ -3810,7 +3800,7 @@ dependencies = [
|
|||||||
"notify-rust",
|
"notify-rust",
|
||||||
"objc",
|
"objc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"open 3.0.1",
|
"open",
|
||||||
"os_info",
|
"os_info",
|
||||||
"os_pipe 1.0.1",
|
"os_pipe 1.0.1",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
@@ -3842,9 +3832,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-build"
|
name = "tauri-build"
|
||||||
version = "1.0.3"
|
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 = "2f2b32e551ec810ba4ab2ad735de5e3576e54bf0322ab0f4b7ce41244bc65ecf"
|
checksum = "acafb1c515c5d14234a294461bd43c723639a84891a45f6a250fd3441ad2e8ed"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cargo_toml",
|
"cargo_toml",
|
||||||
@@ -3858,9 +3848,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-codegen"
|
name = "tauri-codegen"
|
||||||
version = "1.0.3"
|
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 = "f6f1f7928dd040fc03c94207adfad506c0cf5b152982fd1dc0a621f7fd777e22"
|
checksum = "16d62a3c8790d6cba686cea6e3f7f569d12c662c3274c2d165a4fd33e3871b72"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"brotli",
|
"brotli",
|
||||||
@@ -3884,9 +3874,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-macros"
|
name = "tauri-macros"
|
||||||
version = "1.0.3"
|
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 = "e50b9f52871c088857360319a37472d59f4644f1ed004489599d62831a1b6996"
|
checksum = "7296fa17996629f43081e1c66d554703900187ed900c5bf46f97f0bcfb069278"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.4.0",
|
"heck 0.4.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -4068,10 +4058,11 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.19.2"
|
version = "1.20.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439"
|
checksum = "57aec3cfa4c296db7255446efb4928a6be304b431a806216105542a67b6ca82e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
"memchr",
|
"memchr",
|
||||||
@@ -4107,9 +4098,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-tungstenite"
|
name = "tokio-tungstenite"
|
||||||
version = "0.17.1"
|
version = "0.17.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06cda1232a49558c46f8a504d5b93101d42c0bf7f911f12a105ba48168f821ae"
|
checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"log",
|
"log",
|
||||||
@@ -4236,9 +4227,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tungstenite"
|
name = "tungstenite"
|
||||||
version = "0.17.2"
|
version = "0.17.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d96a2dea40e7570482f28eb57afbe42d97551905da6a9400acc5c328d24004f5"
|
checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
@@ -4284,9 +4275,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.1"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
|
checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-normalization"
|
name = "unicode-normalization"
|
||||||
@@ -4690,6 +4681,19 @@ dependencies = [
|
|||||||
"windows_x86_64_msvc 0.24.0",
|
"windows_x86_64_msvc 0.24.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fbedf6db9096bc2364adce0ae0aa636dcd89f3c3f2cd67947062aaf0ca2a10ec"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_msvc 0.32.0",
|
||||||
|
"windows_i686_gnu 0.32.0",
|
||||||
|
"windows_i686_msvc 0.32.0",
|
||||||
|
"windows_x86_64_gnu 0.32.0",
|
||||||
|
"windows_x86_64_msvc 0.32.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows"
|
name = "windows"
|
||||||
version = "0.37.0"
|
version = "0.37.0"
|
||||||
@@ -4749,6 +4753,12 @@ version = "0.37.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3263d25f1170419995b78ff10c06b949e8a986c35c208dc24333c64753a87169"
|
checksum = "3263d25f1170419995b78ff10c06b949e8a986c35c208dc24333c64753a87169"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
@@ -4767,6 +4777,12 @@ version = "0.24.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0866510a3eca9aed73a077490bbbf03e5eaac4e1fd70849d89539e5830501fd"
|
checksum = "c0866510a3eca9aed73a077490bbbf03e5eaac4e1fd70849d89539e5830501fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
@@ -4785,6 +4801,12 @@ version = "0.24.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bf0ffed56b7e9369a29078d2ab3aaeceea48eb58999d2cff3aa2494a275b95c6"
|
checksum = "bf0ffed56b7e9369a29078d2ab3aaeceea48eb58999d2cff3aa2494a275b95c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
@@ -4803,6 +4825,12 @@ version = "0.24.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "384a173630588044205a2993b6864a2f56e5a8c1e7668c07b93ec18cf4888dc4"
|
checksum = "384a173630588044205a2993b6864a2f56e5a8c1e7668c07b93ec18cf4888dc4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
@@ -4821,6 +4849,12 @@ version = "0.24.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9bd8f062d8ca5446358159d79a90be12c543b3a965c847c8f3eedf14b321d399"
|
checksum = "9bd8f062d8ca5446358159d79a90be12c543b3a965c847c8f3eedf14b321d399"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.36.1"
|
version = "0.36.1"
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ zip = "0.6.2"
|
|||||||
once_cell = "1.13.0"
|
once_cell = "1.13.0"
|
||||||
|
|
||||||
# Program opener.
|
# Program opener.
|
||||||
open = "2.1.2"
|
open = "3.0.2"
|
||||||
duct = "0.13.5"
|
duct = "0.13.5"
|
||||||
|
|
||||||
# Serialization.
|
# Serialization.
|
||||||
|
|||||||
@@ -2,17 +2,14 @@ fn main() {
|
|||||||
cc::Build::new()
|
cc::Build::new()
|
||||||
.include("mhycrypto")
|
.include("mhycrypto")
|
||||||
.cpp(true)
|
.cpp(true)
|
||||||
|
|
||||||
.file("mhycrypto/memecrypto.cpp")
|
.file("mhycrypto/memecrypto.cpp")
|
||||||
.file("mhycrypto/metadata.cpp")
|
.file("mhycrypto/metadata.cpp")
|
||||||
.file("mhycrypto/metadatastringdec.cpp")
|
.file("mhycrypto/metadatastringdec.cpp")
|
||||||
|
|
||||||
.compile("mhycrypto");
|
.compile("mhycrypto");
|
||||||
|
|
||||||
cc::Build::new()
|
cc::Build::new()
|
||||||
.include("mhycrypto")
|
.include("mhycrypto")
|
||||||
.file("mhycrypto/aes.c")
|
.file("mhycrypto/aes.c")
|
||||||
|
|
||||||
.compile("mhycrypto-aes");
|
.compile("mhycrypto-aes");
|
||||||
|
|
||||||
tauri_build::build()
|
tauri_build::build()
|
||||||
|
|||||||
@@ -23,7 +23,9 @@
|
|||||||
"grasscutter_with_game": "Automatically launch Grasscutter with game",
|
"grasscutter_with_game": "Automatically launch Grasscutter with game",
|
||||||
"language": "Select Language",
|
"language": "Select Language",
|
||||||
"background": "Set Custom Background (link or image file)",
|
"background": "Set Custom Background (link or image file)",
|
||||||
"theme": "Set Theme"
|
"theme": "Set Theme",
|
||||||
|
"patch_metadata": "Automatically Patch Metadata",
|
||||||
|
"use_proxy": "Use Internal Proxy"
|
||||||
},
|
},
|
||||||
"downloads": {
|
"downloads": {
|
||||||
"grasscutter_stable_data": "Download Grasscutter Stable Data",
|
"grasscutter_stable_data": "Download Grasscutter Stable Data",
|
||||||
@@ -64,6 +66,7 @@
|
|||||||
"resources": "These are also required to run a Grasscutter server. This button will be grey if you have an existing resources folder with contents inside"
|
"resources": "These are also required to run a Grasscutter server. This button will be grey if you have an existing resources folder with contents inside"
|
||||||
},
|
},
|
||||||
"swag": {
|
"swag": {
|
||||||
"akebi": "Set Akebi Executable"
|
"akebi": "Set Akebi Executable",
|
||||||
|
"migoto": "Set 3dMigoto Executable"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
69
src-tauri/lang/es.json
Normal file
69
src-tauri/lang/es.json
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"lang_name": "Español",
|
||||||
|
"main": {
|
||||||
|
"title": "Cultivation",
|
||||||
|
"launch_button": "Launch",
|
||||||
|
"gc_enable": "Conectar Via Grasscutter",
|
||||||
|
"https_enable": "Usar HTTPS",
|
||||||
|
"ip_placeholder": "Dirección del servidor...",
|
||||||
|
"port_placeholder": "Puerto...",
|
||||||
|
"files_downloading": "Archivos Descargandose: ",
|
||||||
|
"files_extracting": "Archivos Extrayendose: "
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"enabled": "Activado",
|
||||||
|
"disabled": "Desactivado",
|
||||||
|
"game_path": "Ruta de instalación del juego",
|
||||||
|
"game_executable": "Establecer ejecutable del juego",
|
||||||
|
"recover_metadata": "Recuperación de Metadatos de Emergencia",
|
||||||
|
"grasscutter_jar": "Establecer JAR de Grasscutter",
|
||||||
|
"toggle_encryption": "Alternar Cifrado",
|
||||||
|
"install_certificate": "Instalar Certificado Proxie",
|
||||||
|
"java_path": "Establecer Ruta Personalizada de Java",
|
||||||
|
"grasscutter_with_game": "Iniciar automáticamente Grasscutter con el juego",
|
||||||
|
"language": "Seleccionar Idioma",
|
||||||
|
"background": "Establecer Fondo Personalizado (link o archivo de imagen)",
|
||||||
|
"theme": "Establecer Tema"
|
||||||
|
},
|
||||||
|
"downloads": {
|
||||||
|
"grasscutter_stable_data": "Descargar Datos Estables de Grasscutter",
|
||||||
|
"grasscutter_latest_data": "Descargar Datos más Recientes de Grasscutter",
|
||||||
|
"grasscutter_stable_data_update": "Actualizar Datos Estables de Grasscutter",
|
||||||
|
"grasscutter_latest_data_update": "Actualizar Datos más Recientes de Grasscutter",
|
||||||
|
"grasscutter_stable": "Descargar Grasscutter Estable",
|
||||||
|
"grasscutter_latest": "Descargar Grasscutter más reciente",
|
||||||
|
"grasscutter_stable_update": "Actualizar Grasscutter Estable",
|
||||||
|
"grasscutter_latest_update": "Actualizar Grasscutter más reciente",
|
||||||
|
"resources": "Descargar Recursos de Grasscutter",
|
||||||
|
"game": "Descarga el juego"
|
||||||
|
},
|
||||||
|
"download_status": {
|
||||||
|
"downloading": "Descargando",
|
||||||
|
"extracting": "Extrayendo",
|
||||||
|
"error": "Error",
|
||||||
|
"finished": "Finalizado",
|
||||||
|
"stopped": "Detenido"
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"select_file": "Seleccionar el archivo o carpeta...",
|
||||||
|
"select_folder": "Seleccionar la carpeta...",
|
||||||
|
"download": "Descargar",
|
||||||
|
"install": "Instalar"
|
||||||
|
},
|
||||||
|
"news": {
|
||||||
|
"latest_commits": "Commits Recientes",
|
||||||
|
"latest_version": "Ultima versión"
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"port_help_text": "Asegúrese de que este sea el Dispatch server port, no el Game server port. Este es casi siempre '443'.",
|
||||||
|
"game_help_text": "No necesitas usar una copia separada para jugar con Grasscutter. Esto es para cambiar a 2.6 o si no tienes el juego instalado.",
|
||||||
|
"gc_stable_jar": "Descargue la versión Estable actual de Grasscutter, que incluye el archivo jar y los archivos de datos.",
|
||||||
|
"gc_dev_jar": "Descargue la última versión de Desarrollo de Grasscutter, que incluye archivos jar y archivos de datos.",
|
||||||
|
"gc_stable_data": "Descargue los archivos de Datos Estables actuales de Grasscutter, que no vienen con un archivo jar. Esto es útil para actualizar.",
|
||||||
|
"gc_dev_data": "Descargue los últimos archivos de Datos de Desarrollo de Grasscutter, que no vienen con un archivo jar. Esto es útil para actualizar.",
|
||||||
|
"resources": "Estos también son necesarios para ejecutar un servidor Grasscutter. Este botón estará gris si tiene una carpeta de recursos existente con contenido dentro."
|
||||||
|
},
|
||||||
|
"swag": {
|
||||||
|
"akebi": "Establecer el ejecutable de Akebi"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,7 +43,7 @@ bool gen_global_metadata_key(uint8_t* src, size_t srcn) {
|
|||||||
|
|
||||||
uint64_t* key = (uint64_t*)src;
|
uint64_t* key = (uint64_t*)src;
|
||||||
|
|
||||||
for (int i = 0; i < srcn / sizeof(uint64_t); i++)
|
for (size_t i = 0; i < srcn / sizeof(uint64_t); i++)
|
||||||
key[i] = rand();
|
key[i] = rand();
|
||||||
|
|
||||||
*(uint16_t *) (src + 0xc8) = 0xfc2e; // Magic
|
*(uint16_t *) (src + 0xc8) = 0xfc2e; // Magic
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::fs;
|
|
||||||
use file_diff::diff;
|
use file_diff::diff;
|
||||||
use std::{io::{Read, Write}};
|
use std::fs;
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn rename(path: String, new_name: String) {
|
pub fn rename(path: String, new_name: String) {
|
||||||
@@ -21,6 +21,11 @@ pub fn rename(path: String, new_name: String) {
|
|||||||
fs::rename(path, &path_replaced).unwrap();
|
fs::rename(path, &path_replaced).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn dir_create(path: String) {
|
||||||
|
fs::create_dir_all(path).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn dir_exists(path: &str) -> bool {
|
pub fn dir_exists(path: &str) -> bool {
|
||||||
let path_buf = std::path::PathBuf::from(path);
|
let path_buf = std::path::PathBuf::from(path);
|
||||||
@@ -133,20 +138,12 @@ pub fn write_file(path: String, contents: String) {
|
|||||||
let path_buf = std::path::PathBuf::from(&path);
|
let path_buf = std::path::PathBuf::from(&path);
|
||||||
|
|
||||||
// Create file if it exists, otherwise just open and rewrite
|
// Create file if it exists, otherwise just open and rewrite
|
||||||
let mut file = match fs::File::open(&path_buf) {
|
let mut file = match fs::File::create(&path_buf) {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Failed to open file: {}", e);
|
println!("Failed to open file: {}", e);
|
||||||
|
|
||||||
// attempt to create file. otherwise return
|
|
||||||
match fs::File::create(&path_buf) {
|
|
||||||
Ok(file) => file,
|
|
||||||
Err(e) => {
|
|
||||||
println!("Failed to create file: {}", e);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Write contents to file
|
// Write contents to file
|
||||||
@@ -154,7 +151,6 @@ pub fn write_file(path: String, contents: String) {
|
|||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Failed to write to file: {}", e);
|
println!("Failed to write to file: {}", e);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,12 +13,12 @@ use sysinfo::{System, SystemExt};
|
|||||||
mod downloader;
|
mod downloader;
|
||||||
mod file_helpers;
|
mod file_helpers;
|
||||||
mod lang;
|
mod lang;
|
||||||
|
mod metadata_patcher;
|
||||||
mod proxy;
|
mod proxy;
|
||||||
mod structs;
|
mod structs;
|
||||||
mod system_helpers;
|
mod system_helpers;
|
||||||
mod unzip;
|
mod unzip;
|
||||||
mod web;
|
mod web;
|
||||||
mod metadata_patcher;
|
|
||||||
|
|
||||||
static WATCH_GAME_PROCESS: Lazy<Mutex<String>> = Lazy::new(|| Mutex::new(String::new()));
|
static WATCH_GAME_PROCESS: Lazy<Mutex<String>> = Lazy::new(|| Mutex::new(String::new()));
|
||||||
|
|
||||||
@@ -42,6 +42,7 @@ fn main() {
|
|||||||
proxy::generate_ca_files,
|
proxy::generate_ca_files,
|
||||||
unzip::unzip,
|
unzip::unzip,
|
||||||
file_helpers::rename,
|
file_helpers::rename,
|
||||||
|
file_helpers::dir_create,
|
||||||
file_helpers::dir_exists,
|
file_helpers::dir_exists,
|
||||||
file_helpers::dir_is_empty,
|
file_helpers::dir_is_empty,
|
||||||
file_helpers::dir_delete,
|
file_helpers::dir_delete,
|
||||||
|
|||||||
@@ -4,19 +4,25 @@ use std::fs::OpenOptions;
|
|||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
fn decrypt_global_metadata(data: *mut u8, size: u64);
|
fn decrypt_global_metadata(data: *mut u8, size: u64);
|
||||||
fn encrypt_global_metadata(data: *mut u8, size: u64);
|
fn encrypt_global_metadata(data: *mut u8, size: u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dll_decrypt_global_metadata(data : *mut u8, size : u64) -> Result<bool, Box<dyn std::error::Error>> {
|
fn dll_decrypt_global_metadata(
|
||||||
|
data: *mut u8,
|
||||||
|
size: u64,
|
||||||
|
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
decrypt_global_metadata(data, size);
|
decrypt_global_metadata(data, size);
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dll_encrypt_global_metadata(data : *mut u8, size : u64) -> Result<bool, Box<dyn std::error::Error>> {
|
fn dll_encrypt_global_metadata(
|
||||||
|
data: *mut u8,
|
||||||
|
size: u64,
|
||||||
|
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
encrypt_global_metadata(data, size);
|
encrypt_global_metadata(data, size);
|
||||||
Ok(true)
|
Ok(true)
|
||||||
@@ -46,7 +52,11 @@ pub fn patch_metadata(metadata_folder: &str) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//write encrypted to file
|
//write encrypted to file
|
||||||
let mut file = match OpenOptions::new().create(true).write(true).open(&(metadata_folder.to_owned() + "\\global-metadata-patched.dat")) {
|
let mut file = match OpenOptions::new()
|
||||||
|
.create(true)
|
||||||
|
.write(true)
|
||||||
|
.open(&(metadata_folder.to_owned() + "\\global-metadata-patched.dat"))
|
||||||
|
{
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Failed to open global-metadata: {}", e);
|
println!("Failed to open global-metadata: {}", e);
|
||||||
@@ -88,9 +98,7 @@ fn decrypt_metadata(file_path: &str) -> Vec<u8> {
|
|||||||
println!("Failed to decrypt global-metadata: {}", e);
|
println!("Failed to decrypt global-metadata: {}", e);
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
Vec::new()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace_keys(data: &[u8]) -> Vec<u8> {
|
fn replace_keys(data: &[u8]) -> Vec<u8> {
|
||||||
@@ -151,9 +159,7 @@ fn encrypt_metadata(old_data: &[u8]) -> Vec<u8> {
|
|||||||
println!("Failed to encrypt global-metadata: {}", e);
|
println!("Failed to encrypt global-metadata: {}", e);
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
Vec::new()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_vecs_match<T: PartialEq>(a: &Vec<T>, b: &Vec<T>) -> bool {
|
fn do_vecs_match<T: PartialEq>(a: &Vec<T>, b: &Vec<T>) -> bool {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "Cultivation",
|
"productName": "Cultivation",
|
||||||
"version": "1.0.3"
|
"version": "1.0.4"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": {
|
"allowlist": {
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ class App extends React.Component<IProps, IState> {
|
|||||||
|
|
||||||
// Emitted for metadata replacing-purposes
|
// Emitted for metadata replacing-purposes
|
||||||
listen('game_closed', async () => {
|
listen('game_closed', async () => {
|
||||||
|
const wasPatched = await getConfigOption('patch_metadata')
|
||||||
|
|
||||||
|
if (wasPatched) {
|
||||||
const unpatched = await unpatchGame()
|
const unpatched = await unpatchGame()
|
||||||
|
|
||||||
console.log(`unpatched game? ${unpatched}`)
|
console.log(`unpatched game? ${unpatched}`)
|
||||||
@@ -70,6 +73,7 @@ class App extends React.Component<IProps, IState> {
|
|||||||
if (!unpatched) {
|
if (!unpatched) {
|
||||||
alert(`Could not unpatch game! (You should be able to find your metadata backup in ${await dataDir()}\\cultivation\\)`)
|
alert(`Could not unpatch game! (You should be able to find your metadata backup in ${await dataDir()}\\cultivation\\)`)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
let min = false
|
let min = false
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ export default class ServerLaunchSection extends React.Component<{}, IState> {
|
|||||||
this.toggleGrasscutter = this.toggleGrasscutter.bind(this)
|
this.toggleGrasscutter = this.toggleGrasscutter.bind(this)
|
||||||
this.playGame = this.playGame.bind(this)
|
this.playGame = this.playGame.bind(this)
|
||||||
this.launchAkebi = this.launchAkebi.bind(this)
|
this.launchAkebi = this.launchAkebi.bind(this)
|
||||||
|
this.launch3dm = this.launch3dm.bind(this)
|
||||||
this.setIp = this.setIp.bind(this)
|
this.setIp = this.setIp.bind(this)
|
||||||
this.setPort = this.setPort.bind(this)
|
this.setPort = this.setPort.bind(this)
|
||||||
this.toggleHttps = this.toggleHttps.bind(this)
|
this.toggleHttps = this.toggleHttps.bind(this)
|
||||||
@@ -100,12 +101,14 @@ export default class ServerLaunchSection extends React.Component<{}, IState> {
|
|||||||
|
|
||||||
// Connect to proxy
|
// Connect to proxy
|
||||||
if (config.toggle_grasscutter) {
|
if (config.toggle_grasscutter) {
|
||||||
|
if (config.patch_metadata) {
|
||||||
const patched = await patchGame()
|
const patched = await patchGame()
|
||||||
|
|
||||||
if (!patched) {
|
if (!patched) {
|
||||||
alert('Could not patch game!')
|
alert('Could not patch game!')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const game_exe = await getGameExecutable()
|
const game_exe = await getGameExecutable()
|
||||||
|
|
||||||
@@ -113,14 +116,16 @@ export default class ServerLaunchSection extends React.Component<{}, IState> {
|
|||||||
await setConfigOption('last_ip', this.state.ip)
|
await setConfigOption('last_ip', this.state.ip)
|
||||||
await setConfigOption('last_port', this.state.port)
|
await setConfigOption('last_port', this.state.port)
|
||||||
|
|
||||||
// Set IP
|
|
||||||
await invoke('set_proxy_addr', { addr: (this.state.httpsEnabled ? 'https':'http') + '://' + this.state.ip + ':' + this.state.port })
|
|
||||||
await invoke('enable_process_watcher', {
|
await invoke('enable_process_watcher', {
|
||||||
process: proc_name || game_exe
|
process: proc_name || game_exe
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (config.use_internal_proxy) {
|
||||||
|
// Set IP
|
||||||
|
await invoke('set_proxy_addr', { addr: (this.state.httpsEnabled ? 'https':'http') + '://' + this.state.ip + ':' + this.state.port })
|
||||||
// Connect to proxy
|
// Connect to proxy
|
||||||
await invoke('connect', { port: 8365, certificatePath: await dataDir() + '\\cultivation\\ca' })
|
await invoke('connect', { port: 8365, certificatePath: await dataDir() + '\\cultivation\\ca' })
|
||||||
|
}
|
||||||
|
|
||||||
// Open server as well if the options are set
|
// Open server as well if the options are set
|
||||||
if (config.grasscutter_with_game) {
|
if (config.grasscutter_with_game) {
|
||||||
@@ -184,6 +189,18 @@ export default class ServerLaunchSection extends React.Component<{}, IState> {
|
|||||||
await this.playGame(config.akebi_path, gameExec)
|
await this.playGame(config.akebi_path, gameExec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async launch3dm() {
|
||||||
|
const config = await getConfig()
|
||||||
|
|
||||||
|
// First launch 3dm
|
||||||
|
invoke('run_program', {
|
||||||
|
path: config.migoto_path
|
||||||
|
})
|
||||||
|
|
||||||
|
// Then play the game as normal
|
||||||
|
await this.playGame()
|
||||||
|
}
|
||||||
|
|
||||||
setIp(text: string) {
|
setIp(text: string) {
|
||||||
this.setState({
|
this.setState({
|
||||||
ip: text
|
ip: text
|
||||||
@@ -236,9 +253,15 @@ export default class ServerLaunchSection extends React.Component<{}, IState> {
|
|||||||
<BigButton onClick={this.playGame} id="officialPlay">{this.state.buttonLabel}</BigButton>
|
<BigButton onClick={this.playGame} id="officialPlay">{this.state.buttonLabel}</BigButton>
|
||||||
{
|
{
|
||||||
this.state.swag && (
|
this.state.swag && (
|
||||||
|
<>
|
||||||
<BigButton onClick={this.launchAkebi} id="akebiLaunch">
|
<BigButton onClick={this.launchAkebi} id="akebiLaunch">
|
||||||
<img className="AkebiIcon" id="akebiIcon" src={Akebi} />
|
<img className="AkebiIcon" id="akebiIcon" src={Akebi} />
|
||||||
</BigButton>
|
</BigButton>
|
||||||
|
<BigButton onClick={this.launch3dm} id="serverLaunch">
|
||||||
|
3DM
|
||||||
|
</BigButton>
|
||||||
|
</>
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
<BigButton onClick={this.launchServer} id="serverLaunch">
|
<BigButton onClick={this.launchServer} id="serverLaunch">
|
||||||
|
|||||||
@@ -31,10 +31,13 @@ interface IState {
|
|||||||
themes: string[]
|
themes: string[]
|
||||||
theme: string
|
theme: string
|
||||||
encryption: boolean
|
encryption: boolean
|
||||||
|
patch_metadata: boolean
|
||||||
|
use_internal_proxy: boolean
|
||||||
swag: boolean
|
swag: boolean
|
||||||
|
|
||||||
// Swag stuff
|
// Swag stuff
|
||||||
akebi_path: string
|
akebi_path: string
|
||||||
|
migoto_path: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Options extends React.Component<IProps, IState> {
|
export default class Options extends React.Component<IProps, IState> {
|
||||||
@@ -52,20 +55,26 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
themes: ['default'],
|
themes: ['default'],
|
||||||
theme: '',
|
theme: '',
|
||||||
encryption: false,
|
encryption: false,
|
||||||
|
patch_metadata: false,
|
||||||
|
use_internal_proxy: false,
|
||||||
swag: false,
|
swag: false,
|
||||||
|
|
||||||
// Swag stuff
|
// Swag stuff
|
||||||
akebi_path: '',
|
akebi_path: '',
|
||||||
|
migoto_path: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setGameExecutable = this.setGameExecutable.bind(this)
|
this.setGameExecutable = this.setGameExecutable.bind(this)
|
||||||
this.setGrasscutterJar = this.setGrasscutterJar.bind(this)
|
this.setGrasscutterJar = this.setGrasscutterJar.bind(this)
|
||||||
this.setJavaPath = this.setJavaPath.bind(this)
|
this.setJavaPath = this.setJavaPath.bind(this)
|
||||||
this.setAkebi = this.setAkebi.bind(this)
|
this.setAkebi = this.setAkebi.bind(this)
|
||||||
|
this.setMigoto = this.setMigoto.bind(this)
|
||||||
this.toggleGrasscutterWithGame = this.toggleGrasscutterWithGame.bind(this)
|
this.toggleGrasscutterWithGame = this.toggleGrasscutterWithGame.bind(this)
|
||||||
this.setCustomBackground = this.setCustomBackground.bind(this)
|
this.setCustomBackground = this.setCustomBackground.bind(this)
|
||||||
this.toggleEncryption = this.toggleEncryption.bind(this)
|
this.toggleEncryption = this.toggleEncryption.bind(this)
|
||||||
this.restoreMetadata = this.restoreMetadata.bind(this)
|
this.restoreMetadata = this.restoreMetadata.bind(this)
|
||||||
|
this.toggleMetadata = this.toggleMetadata.bind(this)
|
||||||
|
this.toggleProxy = this.toggleProxy.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
@@ -88,6 +97,8 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
themes: (await getThemeList()).map((t) => t.name),
|
themes: (await getThemeList()).map((t) => t.name),
|
||||||
theme: config.theme || 'default',
|
theme: config.theme || 'default',
|
||||||
encryption: await translate(encEnabled ? 'options.enabled' : 'options.disabled'),
|
encryption: await translate(encEnabled ? 'options.enabled' : 'options.disabled'),
|
||||||
|
patch_metadata: config.patch_metadata || false,
|
||||||
|
use_internal_proxy: config.use_internal_proxy || false,
|
||||||
swag: config.swag_mode || false,
|
swag: config.swag_mode || false,
|
||||||
|
|
||||||
// Swag stuff
|
// Swag stuff
|
||||||
@@ -129,6 +140,14 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setMigoto(value: string) {
|
||||||
|
setConfigOption('migoto_path', value)
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
migoto_path: value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async setLanguage(value: string) {
|
async setLanguage(value: string) {
|
||||||
await setConfigOption('language', value)
|
await setConfigOption('language', value)
|
||||||
window.location.reload()
|
window.location.reload()
|
||||||
@@ -205,6 +224,26 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async toggleMetadata() {
|
||||||
|
const changedVal = !(await getConfigOption('patch_metadata'))
|
||||||
|
|
||||||
|
await setConfigOption('patch_metadata', changedVal)
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
patch_metadata: changedVal,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async toggleProxy() {
|
||||||
|
const changedVal = !(await getConfigOption('use_internal_proxy'))
|
||||||
|
|
||||||
|
await setConfigOption('use_internal_proxy', changedVal)
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
use_internal_proxy: changedVal,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Menu closeFn={this.props.closeFn} className="Options" heading="Options">
|
<Menu closeFn={this.props.closeFn} className="Options" heading="Options">
|
||||||
@@ -226,6 +265,33 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
</BigButton>
|
</BigButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="OptionSection" id="menuOptionsContainerPatchMeta">
|
||||||
|
<div className="OptionLabel" id="menuOptionsLabelPatchMeta">
|
||||||
|
<Tr text="options.patch_metadata" />
|
||||||
|
</div>
|
||||||
|
<div className="OptionValue" id="menuOptionsCheckboxPatchMeta">
|
||||||
|
<Checkbox
|
||||||
|
onChange={this.toggleMetadata}
|
||||||
|
checked={this.state?.patch_metadata}
|
||||||
|
id="patchMeta"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="OptionSection" id="menuOptionsContainerUseProxy">
|
||||||
|
<div className="OptionLabel" id="menuOptionsLabelUseProxy">
|
||||||
|
<Tr text="options.use_proxy" />
|
||||||
|
</div>
|
||||||
|
<div className="OptionValue" id="menuOptionsCheckboxUseProxy">
|
||||||
|
<Checkbox
|
||||||
|
onChange={this.toggleProxy}
|
||||||
|
checked={this.state?.use_internal_proxy}
|
||||||
|
id="useProxy"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
|
||||||
<div className='OptionSection' id="menuOptionsContainerGCJar">
|
<div className='OptionSection' id="menuOptionsContainerGCJar">
|
||||||
<div className='OptionLabel' id="menuOptionsLabelGCJar">
|
<div className='OptionLabel' id="menuOptionsLabelGCJar">
|
||||||
<Tr text="options.grasscutter_jar" />
|
<Tr text="options.grasscutter_jar" />
|
||||||
@@ -266,6 +332,14 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
<DirInput onChange={this.setAkebi} value={this.state?.akebi_path} extensions={['exe']} />
|
<DirInput onChange={this.setAkebi} value={this.state?.akebi_path} extensions={['exe']} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='OptionSection' id="menuOptionsContainerMigoto">
|
||||||
|
<div className='OptionLabel' id="menuOptionsLabelMigoto">
|
||||||
|
<Tr text="swag.migoto" />
|
||||||
|
</div>
|
||||||
|
<div className='OptionValue' id="menuOptionsDirMigoto">
|
||||||
|
<DirInput onChange={this.setMigoto} value={this.state?.migoto_path} extensions={['exe']} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ let defaultConfig: Configuration
|
|||||||
cert_generated: false,
|
cert_generated: false,
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
https_enabled: false,
|
https_enabled: false,
|
||||||
debug_enabled: false
|
debug_enabled: false,
|
||||||
|
patch_metadata: true,
|
||||||
|
use_internal_proxy: true,
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|
||||||
@@ -43,10 +45,13 @@ export interface Configuration {
|
|||||||
theme: string
|
theme: string
|
||||||
https_enabled: boolean
|
https_enabled: boolean
|
||||||
debug_enabled: boolean
|
debug_enabled: boolean
|
||||||
|
patch_metadata: boolean
|
||||||
|
use_internal_proxy: boolean
|
||||||
swag_mode?: boolean
|
swag_mode?: boolean
|
||||||
|
|
||||||
// Swag stuff
|
// Swag stuff
|
||||||
akebi_path?: string
|
akebi_path?: string
|
||||||
|
migoto_path?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function setConfigOption<K extends keyof Configuration>(key: K, value: Configuration[K]): Promise<void> {
|
export async function setConfigOption<K extends keyof Configuration>(key: K, value: Configuration[K]): Promise<void> {
|
||||||
@@ -60,7 +65,7 @@ export async function getConfigOption<K extends keyof Configuration>(key: K): Pr
|
|||||||
const config = await getConfig()
|
const config = await getConfig()
|
||||||
const defaults = defaultConfig
|
const defaults = defaultConfig
|
||||||
|
|
||||||
return config[key] || defaults[key]
|
return config[key] === null || config[key] === undefined ? defaults[key] : config[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getConfig() {
|
export async function getConfig() {
|
||||||
|
|||||||
@@ -70,6 +70,20 @@ export async function patchGame() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do we have a patch already?
|
||||||
|
const patchedExists = await invoke('dir_exists', {
|
||||||
|
path: await getBackupMetadataPath() + '\\global-metadata-patched.dat'
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!patchedExists) {
|
||||||
|
// No patch found? Patching creates one
|
||||||
|
const patched = await patchMetadata()
|
||||||
|
|
||||||
|
if (!patched) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Are we already patched? If so, that's fine, just continue as normal
|
// Are we already patched? If so, that's fine, just continue as normal
|
||||||
const gameIsPatched = await invoke('are_files_identical', {
|
const gameIsPatched = await invoke('are_files_identical', {
|
||||||
path1: await getBackupMetadataPath() + '\\global-metadata-patched.dat',
|
path1: await getBackupMetadataPath() + '\\global-metadata-patched.dat',
|
||||||
@@ -142,22 +156,6 @@ export async function unpatchGame() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
const metaPatched = await invoke('are_files_identical', {
|
|
||||||
path1: await getBackupMetadataPath() + '\\global-metadata-patched.dat',
|
|
||||||
path2: await getGameMetadataPath() + '\\global-metadata.dat'
|
|
||||||
})
|
|
||||||
|
|
||||||
const metaExists = await invoke('dir_exists', {
|
|
||||||
path: await getGameMetadataPath() + '\\global-metadata.dat'
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!metaPatched && metaExists) {
|
|
||||||
// Game isn't patched
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Replacing patched game metadata with unpatched metadata')
|
|
||||||
|
|
||||||
const replaced = await invoke('copy_file_with_new_name', {
|
const replaced = await invoke('copy_file_with_new_name', {
|
||||||
path: await getBackupMetadataPath() + '\\global-metadata-unpatched.dat',
|
path: await getBackupMetadataPath() + '\\global-metadata-unpatched.dat',
|
||||||
newPath: await getGameMetadataPath(),
|
newPath: await getGameMetadataPath(),
|
||||||
@@ -201,26 +199,27 @@ export async function globalMetadataLink() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function restoreMetadata(manager: DownloadHandler) {
|
export async function restoreMetadata(manager: DownloadHandler) {
|
||||||
const backupExists = await invoke('dir_exists', {
|
|
||||||
path: await getBackupMetadataPath() + '\\global-metadata-unpatched.dat'
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!backupExists) {
|
|
||||||
console.log('No backup found! Replacing with global metadata link')
|
|
||||||
|
|
||||||
const metaLink = await globalMetadataLink()
|
const metaLink = await globalMetadataLink()
|
||||||
|
|
||||||
if (!metaLink) {
|
if (!metaLink) {
|
||||||
console.log('Coudl not get global metadata link!')
|
console.log('Could not get global metadata link!')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Should make sure metadata path exists since the user may have deleted it
|
||||||
|
await invoke('dir_create', {
|
||||||
|
path: await getBackupMetadataPath()
|
||||||
|
})
|
||||||
|
|
||||||
|
// It is possible the unpatched backup is mistakenly patched
|
||||||
|
await invoke('delete_file', {
|
||||||
|
path: await getBackupMetadataPath() + '\\global-metadata-unpatched.dat'
|
||||||
|
})
|
||||||
|
|
||||||
// Download the file
|
// Download the file
|
||||||
manager.addDownload(metaLink, await getBackupMetadataPath() + '\\global-metadata-unpatched.dat', () => {
|
manager.addDownload(metaLink, await getBackupMetadataPath() + '\\global-metadata-unpatched.dat', () => {
|
||||||
unpatchGame()
|
unpatchGame()
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Restoring backedup metadata')
|
console.log('Restoring backedup metadata')
|
||||||
|
|
||||||
await unpatchGame()
|
await unpatchGame()
|
||||||
|
|||||||
Reference in New Issue
Block a user