mirror of
https://github.com/lifegpc/garbro-rs.git
synced 2026-07-08 01:32:13 +08:00
Compare commits
4 Commits
de335e6323
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 3c3ebfa894 | |||
| 81df6cc2df | |||
| b8a921022b | |||
| f213fc6d8b |
145
src-tauri/Cargo.lock
generated
145
src-tauri/Cargo.lock
generated
@@ -126,6 +126,18 @@ version = "1.0.102"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "argon2"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072"
|
||||||
|
dependencies = [
|
||||||
|
"base64ct",
|
||||||
|
"blake2",
|
||||||
|
"cpufeatures 0.2.17",
|
||||||
|
"password-hash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
@@ -321,6 +333,12 @@ version = "0.22.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64ct"
|
||||||
|
version = "1.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bit-set"
|
name = "bit-set"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
@@ -351,6 +369,15 @@ dependencies = [
|
|||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "blake2"
|
||||||
|
version = "0.10.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
|
||||||
|
dependencies = [
|
||||||
|
"digest 0.10.7",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
version = "0.10.4"
|
version = "0.10.4"
|
||||||
@@ -593,9 +620,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cedarwood"
|
name = "cedarwood"
|
||||||
version = "0.4.6"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6d910bedd62c24733263d0bed247460853c9d22e8956bd4cd964302095e04e90"
|
checksum = "c0524a528a6a0288df1863c3c20fe92c301875b4941e7b6c4b394ab08c5a4c55"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"smallvec",
|
"smallvec",
|
||||||
]
|
]
|
||||||
@@ -646,6 +673,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
|
checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"cipher",
|
||||||
"cpufeatures 0.3.0",
|
"cpufeatures 0.3.0",
|
||||||
"rand_core 0.10.0",
|
"rand_core 0.10.0",
|
||||||
]
|
]
|
||||||
@@ -657,8 +685,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
|
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
"serde",
|
||||||
|
"wasm-bindgen",
|
||||||
"windows-link 0.2.1",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -668,6 +698,7 @@ version = "0.5.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea"
|
checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"block-buffer 0.12.0",
|
||||||
"crypto-common 0.2.1",
|
"crypto-common 0.2.1",
|
||||||
"inout",
|
"inout",
|
||||||
]
|
]
|
||||||
@@ -1219,6 +1250,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer 0.10.4",
|
"block-buffer 0.10.4",
|
||||||
"crypto-common 0.1.7",
|
"crypto-common 0.1.7",
|
||||||
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1564,9 +1596,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fancy-regex"
|
name = "fancy-regex"
|
||||||
version = "0.17.0"
|
version = "0.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72cf461f865c862bb7dc573f643dd6a2b6842f7c30b07882b56bd148cc2761b8"
|
checksum = "e1e1dacd0d2082dfcf1351c4bdd566bbe89a2b263235a2b50058f1e130a47277"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit-set",
|
"bit-set",
|
||||||
"regex-automata",
|
"regex-automata",
|
||||||
@@ -1575,9 +1607,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastcdc"
|
name = "fastcdc"
|
||||||
version = "3.2.1"
|
version = "4.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bf51ceb43e96afbfe4dd5c6f6082af5dfd60e220820b8123792d61963f2ce6bc"
|
checksum = "77af40d8a8dadb92dc178569a5f5edb5f3056e98255c2de48ab5d59a52892e0c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastrand"
|
name = "fastrand"
|
||||||
@@ -2725,19 +2757,20 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jieba-macros"
|
name = "jieba-macros"
|
||||||
version = "0.8.1"
|
version = "0.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "348294e44ee7e3c42685da656490f8febc7359632544019621588902216da95c"
|
checksum = "46adade69b634535a8f495cf87710ed893cff53e1dbc9dd750c2ab81c5defb82"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"phf_codegen 0.13.1",
|
"phf_codegen 0.13.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jieba-rs"
|
name = "jieba-rs"
|
||||||
version = "0.8.1"
|
version = "0.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "766bd7012aa5ba49411ebdf4e93bddd59b182d2918e085d58dec5bb9b54b7105"
|
checksum = "11b53580aaa8ec8b713da271da434f8947409242c537a9ab3f7b76bdbb19e8a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bytecount",
|
||||||
"cedarwood",
|
"cedarwood",
|
||||||
"include-flate",
|
"include-flate",
|
||||||
"jieba-macros",
|
"jieba-macros",
|
||||||
@@ -2840,6 +2873,16 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "keccak"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9e24a010dd405bd7ed803e5253182815b41bf2e6a80cc3bfc066658e03a198aa"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures 0.3.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "keyboard-types"
|
name = "keyboard-types"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@@ -3176,16 +3219,20 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "msg_tool"
|
name = "msg_tool"
|
||||||
version = "0.3.1"
|
version = "0.4.0-alpha.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"adler",
|
"adler",
|
||||||
"aes",
|
"aes",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"argon2",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
|
"blake2",
|
||||||
"block_compression",
|
"block_compression",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
"cbc",
|
"cbc",
|
||||||
|
"chacha20",
|
||||||
|
"chrono",
|
||||||
"clap 4.6.0",
|
"clap 4.6.0",
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"crossbeam",
|
"crossbeam",
|
||||||
@@ -3197,6 +3244,7 @@ dependencies = [
|
|||||||
"fancy-regex",
|
"fancy-regex",
|
||||||
"fastcdc",
|
"fastcdc",
|
||||||
"flate2",
|
"flate2",
|
||||||
|
"hex",
|
||||||
"include-flate",
|
"include-flate",
|
||||||
"int-enum",
|
"int-enum",
|
||||||
"jieba-rs",
|
"jieba-rs",
|
||||||
@@ -3217,6 +3265,7 @@ dependencies = [
|
|||||||
"parse-size",
|
"parse-size",
|
||||||
"pelite",
|
"pelite",
|
||||||
"png 0.18.1",
|
"png 0.18.1",
|
||||||
|
"qoi",
|
||||||
"rand 0.10.1",
|
"rand 0.10.1",
|
||||||
"rust-ini",
|
"rust-ini",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -3224,6 +3273,9 @@ dependencies = [
|
|||||||
"serde_yaml_ng",
|
"serde_yaml_ng",
|
||||||
"sha1",
|
"sha1",
|
||||||
"sha2 0.11.0",
|
"sha2 0.11.0",
|
||||||
|
"sha3",
|
||||||
|
"shake",
|
||||||
|
"siphasher 1.0.2",
|
||||||
"stylua",
|
"stylua",
|
||||||
"tendril 0.5.0",
|
"tendril 0.5.0",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
@@ -3232,13 +3284,16 @@ dependencies = [
|
|||||||
"webp",
|
"webp",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
"xml5ever",
|
"xml5ever",
|
||||||
|
"xxhash-rust",
|
||||||
"zopfli",
|
"zopfli",
|
||||||
"zstd",
|
"zstd",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "msg_tool_build"
|
name = "msg_tool_build"
|
||||||
version = "0.3.1"
|
version = "0.4.0-alpha.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8386042ba7f224865098b365961d45df240b4f43ac6c8e279d16616ae25188ae"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"json",
|
"json",
|
||||||
"zstd",
|
"zstd",
|
||||||
@@ -3246,7 +3301,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "msg_tool_macro"
|
name = "msg_tool_macro"
|
||||||
version = "0.3.0"
|
version = "0.4.0-alpha.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "177ed201ff17ef103ad65d1f5a679d105e463a4e36e61a977978bdb97b5d04bc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
@@ -3254,7 +3311,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "msg_tool_xp3data"
|
name = "msg_tool_xp3data"
|
||||||
version = "0.3.1"
|
version = "0.4.0-alpha.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"msg_tool_build",
|
"msg_tool_build",
|
||||||
"zstd",
|
"zstd",
|
||||||
@@ -3648,6 +3705,17 @@ 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 = "487f2ccd1e17ce8c1bfab3a65c89525af41cfad4c8659021a1e9a2aacd73b89b"
|
checksum = "487f2ccd1e17ce8c1bfab3a65c89525af41cfad4c8659021a1e9a2aacd73b89b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "password-hash"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166"
|
||||||
|
dependencies = [
|
||||||
|
"base64ct",
|
||||||
|
"rand_core 0.6.4",
|
||||||
|
"subtle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste"
|
name = "paste"
|
||||||
version = "1.0.15"
|
version = "1.0.15"
|
||||||
@@ -4096,6 +4164,15 @@ version = "0.1.28"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b5a041e753da8b807c9255f28de81879c78c876392ff2469cde94799b2896b9d"
|
checksum = "b5a041e753da8b807c9255f28de81879c78c876392ff2469cde94799b2896b9d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "qoi"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quick-error"
|
name = "quick-error"
|
||||||
version = "2.0.1"
|
version = "2.0.1"
|
||||||
@@ -4730,6 +4807,28 @@ dependencies = [
|
|||||||
"digest 0.11.2",
|
"digest 0.11.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha3"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc9bad02c26382724b2d2692c6f179285e4b54eeecd7968f52a50059c3c11759"
|
||||||
|
dependencies = [
|
||||||
|
"digest 0.11.2",
|
||||||
|
"keccak",
|
||||||
|
"sponge-cursor",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shake"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09057cb2149ad4cbd2da1e26b351f9a4c354219421229c69c3063e6f61947c4a"
|
||||||
|
dependencies = [
|
||||||
|
"digest 0.11.2",
|
||||||
|
"keccak",
|
||||||
|
"sponge-cursor",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@@ -4854,6 +4953,12 @@ dependencies = [
|
|||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sponge-cursor"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3a0219bd7d979d58245a4f41f695e1ac9f8befdffadd7f61f1bae9e39abc6620"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stable_deref_trait"
|
name = "stable_deref_trait"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
@@ -4948,6 +5053,12 @@ dependencies = [
|
|||||||
"toml 0.8.2",
|
"toml 0.8.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subtle"
|
||||||
|
version = "2.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swift-rs"
|
name = "swift-rs"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@@ -6809,6 +6920,12 @@ dependencies = [
|
|||||||
"markup5ever 0.38.0",
|
"markup5ever 0.38.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xxhash-rust"
|
||||||
|
version = "0.8.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke"
|
name = "yoke"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use msg_tool::ext::io::MutexWrapper;
|
||||||
|
use msg_tool::ext::mutex::*;
|
||||||
use msg_tool::scripts::base::ReadSeek;
|
use msg_tool::scripts::base::ReadSeek;
|
||||||
use msg_tool::scripts::{BUILDER, ScriptBuilder};
|
use msg_tool::scripts::{BUILDER, Script, ScriptBuilder};
|
||||||
use msg_tool::types::{ExtraConfig, ImageOutputType, ScriptType};
|
use msg_tool::types::{ExtraConfig, ImageOutputType, PngCompressionLevel, ScriptType};
|
||||||
use msg_tool::utils::img::*;
|
use msg_tool::utils::img::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::{BufReader, Read};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Mutex;
|
use std::sync::{Arc, Mutex};
|
||||||
use tauri::{AppHandle, Manager};
|
use tauri::{AppHandle, Manager};
|
||||||
|
use tauri::ipc::Response;
|
||||||
|
|
||||||
const PNG_SIGNATURE: &[u8] = b"\x89PNG\r\n\x1a\n";
|
const PNG_SIGNATURE: &[u8] = b"\x89PNG\r\n\x1a\n";
|
||||||
|
|
||||||
@@ -17,12 +20,172 @@ lazy_static::lazy_static! {
|
|||||||
static ref ENTRY_TYPE_CACHE: Mutex<BTreeMap<ScriptType, EntryType>> = Mutex::new(BTreeMap::new());
|
static ref ENTRY_TYPE_CACHE: Mutex<BTreeMap<ScriptType, EntryType>> = Mutex::new(BTreeMap::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CacheEntry<'a> {
|
||||||
|
archive: Box<dyn Script + Send + Sync + 'a>,
|
||||||
|
path: String,
|
||||||
|
option: FileOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> CacheEntry<'a> {
|
||||||
|
fn new(
|
||||||
|
mut reader: Box<dyn ReadSeek + Send + Sync + 'a>,
|
||||||
|
filename: &str,
|
||||||
|
option: FileOptions,
|
||||||
|
script_type: Option<ScriptType>,
|
||||||
|
) -> Result<Self> {
|
||||||
|
let (entry_type, msg_tool_type) = if let Some(typ) = script_type {
|
||||||
|
(query_entry_type(&typ), Some(typ.clone()))
|
||||||
|
} else {
|
||||||
|
let mut buffer = [0; 1024];
|
||||||
|
let n = reader.read(&mut buffer)?;
|
||||||
|
reader.rewind()?;
|
||||||
|
detect_file_type(filename, &buffer[..n])
|
||||||
|
};
|
||||||
|
if entry_type != EntryType::Archive {
|
||||||
|
return Err(anyhow::anyhow!("不是归档文件"));
|
||||||
|
}
|
||||||
|
let script_type = msg_tool_type.ok_or_else(|| anyhow::anyhow!("无法识别的归档格式"))?;
|
||||||
|
let builder = BUILDER
|
||||||
|
.iter()
|
||||||
|
.find(|b| b.script_type() == &script_type)
|
||||||
|
.ok_or_else(|| anyhow::anyhow!("不支持的归档格式"))?;
|
||||||
|
let extra_config = option.to_extra_config();
|
||||||
|
let encoding = builder.default_encoding();
|
||||||
|
let archive_encoding = builder.default_archive_encoding().unwrap_or(encoding);
|
||||||
|
let archive = builder.build_script_from_reader(
|
||||||
|
reader,
|
||||||
|
filename,
|
||||||
|
encoding,
|
||||||
|
archive_encoding,
|
||||||
|
&extra_config,
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
Ok(CacheEntry {
|
||||||
|
archive,
|
||||||
|
path: filename.to_string(),
|
||||||
|
option,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CacheManager {
|
||||||
|
file: Option<Arc<Mutex<BufReader<File>>>>,
|
||||||
|
cache: Option<CacheEntry<'static>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CacheManager {
|
||||||
|
fn list_archive(
|
||||||
|
&mut self,
|
||||||
|
path: &str,
|
||||||
|
option: Option<&Vec<FileOptions>>,
|
||||||
|
) -> Result<Vec<Entry>> {
|
||||||
|
let paths = path.split("|").collect::<Vec<_>>();
|
||||||
|
let cache = self.get_entry(path, option)?;
|
||||||
|
if paths.len() == 1 {
|
||||||
|
let mut result = Vec::new();
|
||||||
|
let mut index = 0;
|
||||||
|
for entry in cache.archive.iter_archive_filename()? {
|
||||||
|
let name = entry?;
|
||||||
|
let mut entry = cache.archive.open_file(index)?;
|
||||||
|
let file_size = entry.size();
|
||||||
|
index += 1;
|
||||||
|
let (entry_type, msg_tool_type) = if let Some(typ) = entry.script_type() {
|
||||||
|
(query_entry_type(&typ), Some(typ.clone()))
|
||||||
|
} else {
|
||||||
|
let mut buffer = [0; 1024];
|
||||||
|
let n = entry.read(&mut buffer)?;
|
||||||
|
detect_file_type(&name, &buffer[..n])
|
||||||
|
};
|
||||||
|
// 扁平结构,不区分文件夹,前端根据路径解析出文件夹结构
|
||||||
|
result.push(Entry {
|
||||||
|
name,
|
||||||
|
is_dir: false,
|
||||||
|
entry_type,
|
||||||
|
msg_tool_type,
|
||||||
|
size: file_size,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ok(result)
|
||||||
|
} else {
|
||||||
|
let filename = path.split("|").nth(1).unwrap();
|
||||||
|
let mut entry = cache.archive.open_file_by_name(filename, false)?;
|
||||||
|
let typ = entry.script_type().map(|t| t.clone());
|
||||||
|
let entry = entry.to_data()?;
|
||||||
|
let path = path.splitn(2, "|").nth(1).unwrap();
|
||||||
|
list_archive_directory_in_archive(path, entry, filename, option, typ, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn preview_image(&mut self, path: &str, option: Option<&Vec<FileOptions>>) -> Result<Vec<u8>> {
|
||||||
|
let cache = self.get_entry(path, option)?;
|
||||||
|
let paths = path.split("|").collect::<Vec<_>>();
|
||||||
|
if paths.len() == 2 {
|
||||||
|
let filename = paths[1];
|
||||||
|
let mut entry = cache.archive.open_file_by_name(filename, false)?;
|
||||||
|
let typ = entry.script_type().map(|t| t.clone());
|
||||||
|
let entry = entry.to_data()?;
|
||||||
|
preview_image_in_directory(entry, filename, option, typ, 1)
|
||||||
|
} else {
|
||||||
|
let filename = paths[1];
|
||||||
|
let mut entry = cache.archive.open_file_by_name(filename, false)?;
|
||||||
|
let typ = entry.script_type().map(|t| t.clone());
|
||||||
|
let entry = entry.to_data()?;
|
||||||
|
let path = path.splitn(2, "|").nth(1).unwrap();
|
||||||
|
preview_image_in_archive(path, entry, filename, option, typ, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 目前只能缓存根归档文件
|
||||||
|
fn get_entry(
|
||||||
|
&mut self,
|
||||||
|
path: &str,
|
||||||
|
option: Option<&Vec<FileOptions>>,
|
||||||
|
) -> Result<&CacheEntry<'static>> {
|
||||||
|
let paths = path.split("|").collect::<Vec<_>>();
|
||||||
|
let is_hit = self.cache.as_ref().map_or(false, |cache| {
|
||||||
|
if paths[0] == cache.path {
|
||||||
|
let opt = option
|
||||||
|
.and_then(|opts| opts.get(0).cloned())
|
||||||
|
.unwrap_or_default();
|
||||||
|
if opt == cache.option {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
});
|
||||||
|
let entry = if is_hit {
|
||||||
|
self.cache.as_ref().unwrap()
|
||||||
|
} else {
|
||||||
|
// 关闭当前缓存的文件和归档
|
||||||
|
self.cache.take();
|
||||||
|
self.file.take();
|
||||||
|
let file = Arc::new(Mutex::new(BufReader::new(File::open(paths[0])?)));
|
||||||
|
let option = option
|
||||||
|
.and_then(|opts| opts.get(0).cloned())
|
||||||
|
.unwrap_or_default();
|
||||||
|
let mfile = MutexWrapper::new(file.clone(), 0);
|
||||||
|
let cache_entry = CacheEntry::new(Box::new(mfile), paths[0], option, None)?;
|
||||||
|
self.file = Some(file.clone());
|
||||||
|
self.cache = Some(cache_entry);
|
||||||
|
self.cache.as_ref().unwrap()
|
||||||
|
};
|
||||||
|
Ok(entry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static::lazy_static!(
|
||||||
|
static ref CACHE_MANAGER: Mutex<CacheManager> = Mutex::new(CacheManager {
|
||||||
|
file: None,
|
||||||
|
cache: None,
|
||||||
|
});
|
||||||
|
);
|
||||||
|
|
||||||
fn query_entry_type(script_type: &ScriptType) -> EntryType {
|
fn query_entry_type(script_type: &ScriptType) -> EntryType {
|
||||||
let mut cache = ENTRY_TYPE_CACHE.lock().unwrap();
|
let mut cache = ENTRY_TYPE_CACHE.lock().unwrap();
|
||||||
if let Some(entry_type) = cache.get(script_type) {
|
if let Some(entry_type) = cache.get(script_type) {
|
||||||
return entry_type.clone();
|
return entry_type.clone();
|
||||||
}
|
}
|
||||||
let entry_type = if script_type.is_audio() {
|
let entry_type = if matches!(script_type, ScriptType::BGIAudio | ScriptType::CircusPcm) {
|
||||||
EntryType::Audio
|
EntryType::Audio
|
||||||
} else {
|
} else {
|
||||||
let builder = BUILDER
|
let builder = BUILDER
|
||||||
@@ -35,17 +198,6 @@ fn query_entry_type(script_type: &ScriptType) -> EntryType {
|
|||||||
entry_type
|
entry_type
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 到时候可能考虑把识别写到msg_tool那里
|
|
||||||
trait ScriptTypeExt {
|
|
||||||
fn is_audio(&self) -> bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ScriptTypeExt for ScriptType {
|
|
||||||
fn is_audio(&self) -> bool {
|
|
||||||
matches!(self, ScriptType::BGIAudio | ScriptType::CircusPcm)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait ScriptBuilderExt {
|
trait ScriptBuilderExt {
|
||||||
fn entry_type(&self) -> EntryType;
|
fn entry_type(&self) -> EntryType;
|
||||||
}
|
}
|
||||||
@@ -56,7 +208,7 @@ impl<T: ScriptBuilder + ?Sized> ScriptBuilderExt for T {
|
|||||||
EntryType::Image
|
EntryType::Image
|
||||||
} else if self.is_archive() {
|
} else if self.is_archive() {
|
||||||
EntryType::Archive
|
EntryType::Archive
|
||||||
} else if self.script_type().is_audio() {
|
} else if self.is_audio() {
|
||||||
EntryType::Audio
|
EntryType::Audio
|
||||||
} else {
|
} else {
|
||||||
EntryType::Unknown
|
EntryType::Unknown
|
||||||
@@ -90,7 +242,7 @@ pub struct GameTitle {
|
|||||||
alias: Option<Vec<String>>,
|
alias: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Clone)]
|
#[derive(Debug, Default, Deserialize, Clone, PartialEq, Eq)]
|
||||||
pub struct Xp3Option {
|
pub struct Xp3Option {
|
||||||
/// 设置游戏标题,用于解密xp3文件
|
/// 设置游戏标题,用于解密xp3文件
|
||||||
game_title: Option<String>,
|
game_title: Option<String>,
|
||||||
@@ -98,7 +250,7 @@ pub struct Xp3Option {
|
|||||||
force_decrypt: bool,
|
force_decrypt: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Clone)]
|
#[derive(Debug, Default, Deserialize, Clone, PartialEq, Eq)]
|
||||||
pub struct FileOptions {
|
pub struct FileOptions {
|
||||||
xp3: Option<Xp3Option>,
|
xp3: Option<Xp3Option>,
|
||||||
}
|
}
|
||||||
@@ -199,11 +351,16 @@ fn detect_file_type(filename: &str, data: &[u8]) -> (EntryType, Option<ScriptTyp
|
|||||||
(EntryType::Unknown, None)
|
(EntryType::Unknown, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_detect_file_type<P: AsRef<std::path::Path> + ?Sized>(path: &P) -> Result<(EntryType, Option<ScriptType>)> {
|
fn try_detect_file_type<P: AsRef<std::path::Path> + ?Sized>(
|
||||||
|
path: &P,
|
||||||
|
) -> Result<(EntryType, Option<ScriptType>)> {
|
||||||
let mut file = File::open(path)?;
|
let mut file = File::open(path)?;
|
||||||
let mut buffer = [0; 1024];
|
let mut buffer = [0; 1024];
|
||||||
let n = file.read(&mut buffer)?;
|
let n = file.read(&mut buffer)?;
|
||||||
Ok(detect_file_type(&path.as_ref().to_string_lossy(), &buffer[..n]))
|
Ok(detect_file_type(
|
||||||
|
&path.as_ref().to_string_lossy(),
|
||||||
|
&buffer[..n],
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_fs_directory(path: &Path) -> Result<Vec<Entry>> {
|
fn list_fs_directory(path: &Path) -> Result<Vec<Entry>> {
|
||||||
@@ -242,64 +399,6 @@ fn list_fs_directory(path: &Path) -> Result<Vec<Entry>> {
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_archive_directory(path: &Path, option: Option<&Vec<FileOptions>>) -> Result<Vec<Entry>> {
|
|
||||||
let option = option
|
|
||||||
.and_then(|opts| opts.get(0).cloned())
|
|
||||||
.unwrap_or_default();
|
|
||||||
let mut header = [0; 1024];
|
|
||||||
let n = {
|
|
||||||
let mut file = File::open(path)?;
|
|
||||||
file.read(&mut header)?
|
|
||||||
};
|
|
||||||
let (entry_type, msg_tool_type) = detect_file_type(&path.to_string_lossy(), &header[..n]);
|
|
||||||
if entry_type != EntryType::Archive {
|
|
||||||
return Err(anyhow::anyhow!("不是归档文件"));
|
|
||||||
}
|
|
||||||
let script_type = msg_tool_type.ok_or_else(|| anyhow::anyhow!("无法识别的归档格式"))?;
|
|
||||||
let builder = BUILDER
|
|
||||||
.iter()
|
|
||||||
.find(|b| b.script_type() == &script_type)
|
|
||||||
.ok_or_else(|| anyhow::anyhow!("不支持的归档格式"))?;
|
|
||||||
let extra_config = option.to_extra_config();
|
|
||||||
let encoding = builder.default_encoding();
|
|
||||||
let archive_encoding = builder.default_archive_encoding().unwrap_or(encoding);
|
|
||||||
let archive = builder.build_script_from_file(
|
|
||||||
&path.to_string_lossy(),
|
|
||||||
encoding,
|
|
||||||
archive_encoding,
|
|
||||||
&extra_config,
|
|
||||||
None,
|
|
||||||
)?;
|
|
||||||
let mut result = Vec::new();
|
|
||||||
let mut index = 0;
|
|
||||||
for entry in archive.iter_archive_filename()? {
|
|
||||||
let name = entry?;
|
|
||||||
let mut entry = archive.open_file(index)?;
|
|
||||||
index += 1;
|
|
||||||
let (entry_type, msg_tool_type) = if let Some(typ) = entry.script_type() {
|
|
||||||
let entry_type = if typ.is_audio() {
|
|
||||||
EntryType::Audio
|
|
||||||
} else {
|
|
||||||
query_entry_type(&typ)
|
|
||||||
};
|
|
||||||
(entry_type, Some(typ.clone()))
|
|
||||||
} else {
|
|
||||||
let mut buffer = [0; 1024];
|
|
||||||
let n = entry.read(&mut buffer)?;
|
|
||||||
detect_file_type(&name, &buffer[..n])
|
|
||||||
};
|
|
||||||
// 扁平结构,不区分文件夹,前端根据路径解析出文件夹结构
|
|
||||||
result.push(Entry {
|
|
||||||
name,
|
|
||||||
is_dir: false,
|
|
||||||
entry_type,
|
|
||||||
msg_tool_type,
|
|
||||||
size: None,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn list_archive_directory_in_archive<'a>(
|
fn list_archive_directory_in_archive<'a>(
|
||||||
path: &str,
|
path: &str,
|
||||||
mut reader: Box<dyn ReadSeek + Send + Sync + 'a>,
|
mut reader: Box<dyn ReadSeek + Send + Sync + 'a>,
|
||||||
@@ -312,12 +411,7 @@ fn list_archive_directory_in_archive<'a>(
|
|||||||
.and_then(|opts| opts.get(index).cloned())
|
.and_then(|opts| opts.get(index).cloned())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let (entry_type, msg_tool_type) = if let Some(typ) = typ {
|
let (entry_type, msg_tool_type) = if let Some(typ) = typ {
|
||||||
let entry_type = if typ.is_audio() {
|
(query_entry_type(&typ), Some(typ.clone()))
|
||||||
EntryType::Audio
|
|
||||||
} else {
|
|
||||||
query_entry_type(&typ)
|
|
||||||
};
|
|
||||||
(entry_type, Some(typ.clone()))
|
|
||||||
} else {
|
} else {
|
||||||
let mut buffer = [0; 1024];
|
let mut buffer = [0; 1024];
|
||||||
let n = reader.read(&mut buffer)?;
|
let n = reader.read(&mut buffer)?;
|
||||||
@@ -363,14 +457,10 @@ fn list_archive_directory_in_archive<'a>(
|
|||||||
for entry in archive.iter_archive_filename()? {
|
for entry in archive.iter_archive_filename()? {
|
||||||
let name = entry?;
|
let name = entry?;
|
||||||
let mut entry = archive.open_file(index)?;
|
let mut entry = archive.open_file(index)?;
|
||||||
|
let file_size = entry.size();
|
||||||
index += 1;
|
index += 1;
|
||||||
let (entry_type, msg_tool_type) = if let Some(typ) = entry.script_type() {
|
let (entry_type, msg_tool_type) = if let Some(typ) = entry.script_type() {
|
||||||
let entry_type = if typ.is_audio() {
|
(query_entry_type(&typ), Some(typ.clone()))
|
||||||
EntryType::Audio
|
|
||||||
} else {
|
|
||||||
query_entry_type(&typ)
|
|
||||||
};
|
|
||||||
(entry_type, Some(typ.clone()))
|
|
||||||
} else {
|
} else {
|
||||||
let mut buffer = [0; 1024];
|
let mut buffer = [0; 1024];
|
||||||
let n = entry.read(&mut buffer)?;
|
let n = entry.read(&mut buffer)?;
|
||||||
@@ -382,7 +472,7 @@ fn list_archive_directory_in_archive<'a>(
|
|||||||
is_dir: false,
|
is_dir: false,
|
||||||
entry_type,
|
entry_type,
|
||||||
msg_tool_type,
|
msg_tool_type,
|
||||||
size: None,
|
size: file_size,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(result)
|
Ok(result)
|
||||||
@@ -415,25 +505,13 @@ pub fn list_directory(
|
|||||||
options: Option<Vec<FileOptions>>,
|
options: Option<Vec<FileOptions>>,
|
||||||
) -> Result<Vec<Entry>, ErrorMsg> {
|
) -> Result<Vec<Entry>, ErrorMsg> {
|
||||||
if path.contains("|") {
|
if path.contains("|") {
|
||||||
let filename = path.split("|").nth(0).unwrap();
|
return CACHE_MANAGER
|
||||||
let reader = Box::new(std::io::BufReader::new(File::open(filename).map_err(
|
.lock_blocking()
|
||||||
|e| ErrorMsg {
|
.list_archive(path, options.as_ref())
|
||||||
typ: ErrorType::NotFound,
|
.map_err(|e| ErrorMsg {
|
||||||
msg: format!("无法打开文件: {}", e),
|
typ: ErrorType::Other,
|
||||||
},
|
msg: e.to_string(),
|
||||||
)?));
|
});
|
||||||
return list_archive_directory_in_archive(
|
|
||||||
path,
|
|
||||||
reader,
|
|
||||||
filename,
|
|
||||||
options.as_ref(),
|
|
||||||
None,
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
.map_err(|e| ErrorMsg {
|
|
||||||
typ: ErrorType::Other,
|
|
||||||
msg: e.to_string(),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
let path = std::path::Path::new(path);
|
let path = std::path::Path::new(path);
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
@@ -446,10 +524,13 @@ pub fn list_directory(
|
|||||||
if let Some(parent) = path.parent() {
|
if let Some(parent) = path.parent() {
|
||||||
let _ = set_last_directory(&app, parent.to_string_lossy().as_ref());
|
let _ = set_last_directory(&app, parent.to_string_lossy().as_ref());
|
||||||
}
|
}
|
||||||
return list_archive_directory(path, options.as_ref()).map_err(|e| ErrorMsg {
|
return CACHE_MANAGER
|
||||||
typ: ErrorType::Other,
|
.lock_blocking()
|
||||||
msg: e.to_string(),
|
.list_archive(&path.to_string_lossy(), options.as_ref())
|
||||||
});
|
.map_err(|e| ErrorMsg {
|
||||||
|
typ: ErrorType::Other,
|
||||||
|
msg: e.to_string(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
let _ = set_last_directory(&app, path.to_string_lossy().as_ref());
|
let _ = set_last_directory(&app, path.to_string_lossy().as_ref());
|
||||||
list_fs_directory(path).map_err(|e| ErrorMsg {
|
list_fs_directory(path).map_err(|e| ErrorMsg {
|
||||||
@@ -479,12 +560,7 @@ fn preview_image_in_directory<'a>(
|
|||||||
index: usize,
|
index: usize,
|
||||||
) -> Result<Vec<u8>> {
|
) -> Result<Vec<u8>> {
|
||||||
let (entry_type, msg_tool_type) = if let Some(typ) = script_type {
|
let (entry_type, msg_tool_type) = if let Some(typ) = script_type {
|
||||||
let entry_type = if typ.is_audio() {
|
(query_entry_type(&typ), Some(typ.clone()))
|
||||||
EntryType::Audio
|
|
||||||
} else {
|
|
||||||
query_entry_type(&typ)
|
|
||||||
};
|
|
||||||
(entry_type, Some(typ.clone()))
|
|
||||||
} else {
|
} else {
|
||||||
let mut buffer = [0; 1024];
|
let mut buffer = [0; 1024];
|
||||||
let n = reader.read(&mut buffer)?;
|
let n = reader.read(&mut buffer)?;
|
||||||
@@ -503,7 +579,8 @@ fn preview_image_in_directory<'a>(
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|opts| opts.get(index).cloned())
|
.and_then(|opts| opts.get(index).cloned())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let extra_config = option.to_extra_config();
|
let mut extra_config = option.to_extra_config();
|
||||||
|
extra_config.png_compression_level = PngCompressionLevel::Fast;
|
||||||
let encoding = builder.default_encoding();
|
let encoding = builder.default_encoding();
|
||||||
let archive_encoding = builder.default_archive_encoding().unwrap_or(encoding);
|
let archive_encoding = builder.default_archive_encoding().unwrap_or(encoding);
|
||||||
let image = builder.build_script_from_reader(
|
let image = builder.build_script_from_reader(
|
||||||
@@ -538,21 +615,13 @@ fn preview_image_in_archive<'a>(
|
|||||||
.and_then(|opts| opts.get(index).cloned())
|
.and_then(|opts| opts.get(index).cloned())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let (entry_type, msg_tool_type) = if let Some(typ) = typ {
|
let (entry_type, msg_tool_type) = if let Some(typ) = typ {
|
||||||
let entry_type = if typ.is_audio() {
|
(query_entry_type(&typ), Some(typ.clone()))
|
||||||
EntryType::Audio
|
|
||||||
} else {
|
|
||||||
query_entry_type(&typ)
|
|
||||||
};
|
|
||||||
(entry_type, Some(typ.clone()))
|
|
||||||
} else {
|
} else {
|
||||||
let mut buffer = [0; 1024];
|
let mut buffer = [0; 1024];
|
||||||
let n = reader.read(&mut buffer)?;
|
let n = reader.read(&mut buffer)?;
|
||||||
reader.rewind()?;
|
reader.rewind()?;
|
||||||
detect_file_type("", &buffer[..n])
|
detect_file_type("", &buffer[..n])
|
||||||
};
|
};
|
||||||
if entry_type != EntryType::Archive {
|
|
||||||
return Err(anyhow::anyhow!("不是归档文件"));
|
|
||||||
}
|
|
||||||
let msg_tool_type = msg_tool_type.ok_or_else(|| anyhow::anyhow!("无法识别的归档格式"))?;
|
let msg_tool_type = msg_tool_type.ok_or_else(|| anyhow::anyhow!("无法识别的归档格式"))?;
|
||||||
let builder = BUILDER
|
let builder = BUILDER
|
||||||
.iter()
|
.iter()
|
||||||
@@ -570,6 +639,9 @@ fn preview_image_in_archive<'a>(
|
|||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
if path.contains("|") {
|
if path.contains("|") {
|
||||||
|
if !archive.is_archive() {
|
||||||
|
return Err(anyhow::anyhow!("不是归档文件"));
|
||||||
|
}
|
||||||
let filename = path.split("|").nth(0).unwrap();
|
let filename = path.split("|").nth(0).unwrap();
|
||||||
let mut entry = archive.open_file_by_name(filename, false)?;
|
let mut entry = archive.open_file_by_name(filename, false)?;
|
||||||
let typ = entry.script_type().map(|t| t.clone());
|
let typ = entry.script_type().map(|t| t.clone());
|
||||||
@@ -592,20 +664,16 @@ fn preview_image_in_archive<'a>(
|
|||||||
/// path: /path/to/archive.zip|image.png 预览archive.zip内的image.png,options[0] 会用于打开archive.zip, options[1] 会用于打开image.png(如果需要的话)
|
/// path: /path/to/archive.zip|image.png 预览archive.zip内的image.png,options[0] 会用于打开archive.zip, options[1] 会用于打开image.png(如果需要的话)
|
||||||
/// path: /path/to/archive.zip|inner/archive2.zip|image.png 预览archive2.zip内的image.png,options[0] 会用于打开archive.zip, options[1] 会用于打开archive2.zip, options[2] 会用于打开image.png(如果需要的话)
|
/// path: /path/to/archive.zip|inner/archive2.zip|image.png 预览archive2.zip内的image.png,options[0] 会用于打开archive.zip, options[1] 会用于打开archive2.zip, options[2] 会用于打开image.png(如果需要的话)
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn preview_image(path: &str, options: Option<Vec<FileOptions>>) -> Result<Vec<u8>, ErrorMsg> {
|
pub fn preview_image(path: &str, options: Option<Vec<FileOptions>>) -> Result<Response, ErrorMsg> {
|
||||||
if path.contains("|") {
|
if path.contains("|") {
|
||||||
let filename = path.split("|").nth(0).unwrap();
|
return CACHE_MANAGER
|
||||||
let reader = Box::new(std::io::BufReader::new(File::open(filename).map_err(
|
.lock_blocking()
|
||||||
|e| ErrorMsg {
|
.preview_image(path, options.as_ref())
|
||||||
typ: ErrorType::NotFound,
|
|
||||||
msg: format!("无法打开文件: {}", e),
|
|
||||||
},
|
|
||||||
)?));
|
|
||||||
let path = path.splitn(2, "|").nth(1).unwrap();
|
|
||||||
return preview_image_in_archive(path, reader, filename, options.as_ref(), None, 0)
|
|
||||||
.map_err(|e| ErrorMsg {
|
.map_err(|e| ErrorMsg {
|
||||||
typ: ErrorType::Other,
|
typ: ErrorType::Other,
|
||||||
msg: format!("预览图片失败: {}", e),
|
msg: e.to_string(),
|
||||||
|
}).map(|data| {
|
||||||
|
Response::new(data)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let path = std::path::Path::new(path);
|
let path = std::path::Path::new(path);
|
||||||
@@ -636,5 +704,7 @@ pub fn preview_image(path: &str, options: Option<Vec<FileOptions>>) -> Result<Ve
|
|||||||
.map_err(|e| ErrorMsg {
|
.map_err(|e| ErrorMsg {
|
||||||
typ: ErrorType::Other,
|
typ: ErrorType::Other,
|
||||||
msg: format!("预览图片失败: {}", e),
|
msg: format!("预览图片失败: {}", e),
|
||||||
|
}).map(|data| {
|
||||||
|
Response::new(data)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,5 @@ export async function listDirectory(path: string, options?: FileOptions[]): Prom
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function previewImage(path: string, options?: FileOptions[]): Promise<Uint8Array> {
|
export async function previewImage(path: string, options?: FileOptions[]): Promise<Uint8Array> {
|
||||||
const bytes: number[] = await invoke("preview_image", { path, options: options ?? null });
|
return await invoke("preview_image", { path, options: options ?? null });
|
||||||
return new Uint8Array(bytes);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user