diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 6052185..2f10ea8 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -14,6 +14,18 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", + "opaque-debug", +] + [[package]] name = "aho-corasick" version = "0.7.18" @@ -201,6 +213,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "base64ct" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" + [[package]] name = "bincode" version = "1.3.3" @@ -285,6 +303,27 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +[[package]] +name = "bzip2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "cache-padded" version = "1.2.0" @@ -421,6 +460,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + [[package]] name = "cocoa" version = "0.24.0" @@ -471,6 +519,12 @@ dependencies = [ "cache-padded", ] +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + [[package]] name = "convert_case" version = "0.4.0" @@ -653,6 +707,7 @@ dependencies = [ "tokio-rustls", "tokio-tungstenite", "tracing", + "zip", ] [[package]] @@ -796,6 +851,7 @@ checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ "block-buffer", "crypto-common", + "subtle", ] [[package]] @@ -1444,6 +1500,15 @@ dependencies = [ "libc", ] +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "html5ever" version = "0.25.2" @@ -2230,6 +2295,12 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "open" version = "2.1.2" @@ -2385,12 +2456,35 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "password-hash" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8" +dependencies = [ + "base64ct", + "rand_core 0.6.3", + "subtle", +] + [[package]] name = "pathdiff" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +[[package]] +name = "pbkdf2" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271779f35b581956db91a3e55737327a03aa051e90b1c47aeb189508533adfd7" +dependencies = [ + "digest", + "hmac", + "password-hash", + "sha2", +] + [[package]] name = "pem" version = "1.0.2" @@ -3250,6 +3344,17 @@ dependencies = [ "digest", ] +[[package]] +name = "sha1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77f4e7f65455545c2153c1253d25056825e77ee2533f0e41deb65a93a34852f" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest", +] + [[package]] name = "sha2" version = "0.10.2" @@ -3435,6 +3540,12 @@ dependencies = [ "syn", ] +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + [[package]] name = "syn" version = "1.0.92" @@ -4767,6 +4878,26 @@ dependencies = [ "time", ] +[[package]] +name = "zip" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf225bcf73bb52cbb496e70475c7bd7a3f769df699c0020f6c7bd9a96dcf0b8d" +dependencies = [ + "aes", + "byteorder", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils 0.8.8", + "flate2", + "hmac", + "pbkdf2", + "sha1", + "time", + "zstd", +] + [[package]] name = "zstd" version = "0.10.0+zstd.1.5.2" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 9316303..0bb9ce8 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -18,13 +18,18 @@ tauri-build = { version = "1.0.0-rc.8", features = [] } serde = { version = "1.0", features = ["derive"] } tauri = { version = "1.0.0-rc.9", features = ["api-all"] } +# zip library +zip = "0.6.2" + # For creating a "global" downloads list lazy_static = "1.4.0" # Access to the Windows Registry. registry = "1.2.1" + # Program opener. open = "2.1.2" + # Serialization library. serde_json = "1" diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index b7a8f8b..634d07a 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -6,6 +6,7 @@ windows_subsystem = "windows" use open; use structs::{APIQuery}; +mod unzip; mod downloader; mod lang; mod proxy; @@ -19,6 +20,7 @@ fn main() { disconnect, run_program, run_jar, + unzip::unzip, open_in_browser, req_get, get_bg_file, diff --git a/src-tauri/src/unzip.rs b/src-tauri/src/unzip.rs new file mode 100644 index 0000000..1e53a77 --- /dev/null +++ b/src-tauri/src/unzip.rs @@ -0,0 +1,33 @@ +use zip; +use std::fs::File; +use std::io::Read; + +#[tauri::command] +pub fn unzip(zipfile: &str, zippath: &str, destpath: &str) { + let mut f = match File::open(zipfile) { + Ok(f) => f, + Err(e) => { + println!("Failed to open zip file: {}", e); + return; + } + }; + + let mut reader = std::io::Cursor::new(&f); + + let mut zip = match zip::ZipArchive::new(&f) { + Ok(zip) => zip, + Err(e) => { + println!("Could not open zip file: {}", e); + return; + } + }; + + for i in 0..zip.len() + { + let mut file = zip.by_index(i).unwrap(); + + println!("Filename: {}", file.name()); + let first_byte = file.bytes().next().unwrap(); + println!("{:?}", first_byte); + } +} \ No newline at end of file diff --git a/src/ui/components/menu/Downloads.tsx b/src/ui/components/menu/Downloads.tsx index e306fc4..1a7ce61 100644 --- a/src/ui/components/menu/Downloads.tsx +++ b/src/ui/components/menu/Downloads.tsx @@ -2,6 +2,7 @@ import React from 'react' import Menu from './Menu' import Tr from '../../../utils/language' import DownloadHandler from '../../../utils/download' +import { unzip } from '../../../utils/zip_utils' import BigButton from '../common/BigButton' import './Downloads.css' @@ -20,6 +21,7 @@ interface IProps { interface IState { grasscutter_downloading: boolean resources_downloading: boolean + grasscutter_set: boolean } export default class Downloads extends React.Component { @@ -28,7 +30,8 @@ export default class Downloads extends React.Component { this.state = { grasscutter_downloading: this.props.downloadManager.downloadingJar(), - resources_downloading: this.props.downloadManager.downloadingResources() + resources_downloading: this.props.downloadManager.downloadingResources(), + grasscutter_set: false } this.getGrasscutterFolder = this.getGrasscutterFolder.bind(this) @@ -38,6 +41,15 @@ export default class Downloads extends React.Component { this.disableButtons = this.disableButtons.bind(this) } + async componentDidMount() { + const gc_path = await getConfigOption('grasscutter_path') + if (gc_path) { + this.setState({ + grasscutter_set: gc_path !== '' + }) + } + } + async getGrasscutterFolder() { const path = await getConfigOption('grasscutter_path') let folderPath @@ -67,7 +79,9 @@ export default class Downloads extends React.Component { async downloadResources() { const folder = await this.getGrasscutterFolder() - this.props.downloadManager.addDownload(RESOURCES_DOWNLOAD, folder + '\\resources.zip') + this.props.downloadManager.addDownload(RESOURCES_DOWNLOAD, folder + '\\resources.zip', () => { + unzip(folder + '\\resources.zip', 'Grasscutter_Resources/Resources/', folder + '/resources') + }) this.disableButtons() } @@ -111,7 +125,7 @@ export default class Downloads extends React.Component {
- +
diff --git a/src/utils/download.ts b/src/utils/download.ts index 61a182a..992bd1c 100644 --- a/src/utils/download.ts +++ b/src/utils/download.ts @@ -1,4 +1,3 @@ - import { invoke } from '@tauri-apps/api/tauri' import { listen } from '@tauri-apps/api/event' import { byteToString } from './string' @@ -12,6 +11,7 @@ export default class DownloadHandler { startTime: number, error?: string, speed?: string, + onFinish?: () => void, }[] // Pass tauri invoke function @@ -44,6 +44,12 @@ export default class DownloadHandler { // set status to finished const index = this.downloads.findIndex(download => download.path === filename) this.downloads[index].status = 'finished' + + // Call onFinish callback + if (this.downloads[index]?.onFinish) { + // @ts-expect-error onFinish is checked for existence before being called + this.downloads[index]?.onFinish() + } }) listen('download_error', (...payload) => { @@ -74,7 +80,7 @@ export default class DownloadHandler { return this.downloads.some(d => d.path.includes('resources')) } - addDownload(url: string, path: string) { + addDownload(url: string, path: string, onFinish?: () => void) { // Begin download from rust backend, don't add if the download addition fails invoke('download_file', { url, path }) const obj = { @@ -83,6 +89,7 @@ export default class DownloadHandler { total: 0, status: 'downloading', startTime: Date.now(), + onFinish, } this.downloads.push(obj) diff --git a/src/utils/zip_utils.ts b/src/utils/zip_utils.ts new file mode 100644 index 0000000..098dd24 --- /dev/null +++ b/src/utils/zip_utils.ts @@ -0,0 +1,9 @@ +import { invoke } from '@tauri-apps/api' + +export function unzip(file: string, zippath: string, dest: string) { + invoke('unzip', { + zipfile: file, + zippath: zippath, + destpath: dest, + }) +} \ No newline at end of file