diff --git a/.gitignore b/.gitignore index 82c9537..e18d350 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,22 @@ -# Generated by Cargo -# will have compiled files and executables -debug/ -target/ -.idea/ - -# These are backup files generated by rustfmt -**/*.rs.bk - -# Error / Debug Logging -*.log - -# MSVC Windows builds of rustc generate these, which store debugging information -*.pdb - - -# RustRover -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ +.idea/ + +# These are backup files generated by rustfmt +**/*.rs.bk + +# Error / Debug Logging +*.log + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + + +# RustRover +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ \ No newline at end of file diff --git a/LICENSE b/LICENSE index 9ca3c19..5841512 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2025 Yuhki - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +MIT License + +Copyright (c) 2025 Yuhki + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 61dd0b6..d66d12a 100644 --- a/README.md +++ b/README.md @@ -1,77 +1,77 @@ -# 🌊 Wuthering Waves Downloader - -*A high-performance, reliable downloader for Wuthering Waves with multi-CDN support and verification* - -> Feel free to open Pull requests if you want to contribute with improvements! - -[![Rust](https://img.shields.io/badge/Rust-1.87.0--nightly-orange?logo=rust)](https://www.rust-lang.org/) -[![License](https://img.shields.io/badge/License-MIT-blue)](LICENSE) - -## 📦 Requirements -- **Rust nightly toolchain** - 1.87.0-nightly or newer -- **Windows** - for full console feature support - -### 🛠️ Installation & Usage -- **Install the nightly toolchain:** -```bash -rustup toolchain install nightly -rustup default nightly -``` - -- **Clone the repository:** -```bash -git clone https://github.com/yuhkix/wuwa-downloader.git -cd wuwa-downloader -``` - -- **Build the project:** -```bash -cargo build --release -``` - -## 🌟 Key Features - -### 🚀 Download Management -- **Multi-CDN Fallback** - Automatically tries all available CDN mirrors - -- **Version Selection** - Interactive menu for Live/Beta versions - -- **Verified Downloads** - MD5 checksum validation for every file - -- **Smart Retry Logic** - 3 retry attempts per CDN with timeout protection - -- **GZIP Support** - Handles compressed responses efficiently - -### 🛡️ Reliability -- **Atomic Operations** - Thread-safe progress tracking - -- **Graceful Interrupt** - CTRL-C handling with summary display - -- **Comprehensive Logging** - Detailed error logging with timestamps - -- **Validation Failures** - Auto-removes files with checksum mismatches - -### 📂 File Management -- **Smart Path Handling** - Cross-platform path support - -- **Auto-directory Creation** - Builds full directory trees as needed - -- **Clean Failed Downloads** - Removes corrupted files automatically - -### 💻 User Interface -- **Color-coded Output** - Clear visual feedback (success/warning/error) - -- **Dynamic Title Updates** - Real-time progress in window title - -- **Clean Progress Display** - Simplified download status without clutter - -- **Formatted Duration** - Clear elapsed time display (HH:MM:SS) - -### ⚙️ Technical Details -- **Streaming Downloads** - Memory-efficient chunked transfers - -- **HEAD Request Verification** - Pre-checks file availability - -- **Multi-threaded** - Safe concurrent progress tracking - -- **Configurable Timeouts** - 30s for metadata, 10000s for downloads +# 🌊 Wuthering Waves Downloader + +*A high-performance, reliable downloader for Wuthering Waves with multi-CDN support and verification* + +> Feel free to open Pull requests if you want to contribute with improvements! + +[![Rust](https://img.shields.io/badge/Rust-1.87.0--nightly-orange?logo=rust)](https://www.rust-lang.org/) +[![License](https://img.shields.io/badge/License-MIT-blue)](LICENSE) + +## 📦 Requirements +- **Rust nightly toolchain** - 1.87.0-nightly or newer +- **Windows** - for full console feature support + +### 🛠️ Installation & Usage +- **Install the nightly toolchain:** +```bash +rustup toolchain install nightly +rustup default nightly +``` + +- **Clone the repository:** +```bash +git clone https://github.com/yuhkix/wuwa-downloader.git +cd wuwa-downloader +``` + +- **Build the project:** +```bash +cargo build --release +``` + +## 🌟 Key Features + +### 🚀 Download Management +- **Multi-CDN Fallback** - Automatically tries all available CDN mirrors + +- **Version Selection** - Interactive menu for Live/Beta versions + +- **Verified Downloads** - MD5 checksum validation for every file + +- **Smart Retry Logic** - 3 retry attempts per CDN with timeout protection + +- **GZIP Support** - Handles compressed responses efficiently + +### 🛡️ Reliability +- **Atomic Operations** - Thread-safe progress tracking + +- **Graceful Interrupt** - CTRL-C handling with summary display + +- **Comprehensive Logging** - Detailed error logging with timestamps + +- **Validation Failures** - Auto-removes files with checksum mismatches + +### 📂 File Management +- **Smart Path Handling** - Cross-platform path support + +- **Auto-directory Creation** - Builds full directory trees as needed + +- **Clean Failed Downloads** - Removes corrupted files automatically + +### 💻 User Interface +- **Color-coded Output** - Clear visual feedback (success/warning/error) + +- **Dynamic Title Updates** - Real-time progress in window title + +- **Clean Progress Display** - Simplified download status without clutter + +- **Formatted Duration** - Clear elapsed time display (HH:MM:SS) + +### ⚙️ Technical Details +- **Streaming Downloads** - Memory-efficient chunked transfers + +- **HEAD Request Verification** - Pre-checks file availability + +- **Multi-threaded** - Safe concurrent progress tracking + +- **Configurable Timeouts** - 30s for metadata, 10000s for downloads diff --git a/build.rs b/build.rs index 5bfc5cc..5266d85 100644 --- a/build.rs +++ b/build.rs @@ -1,8 +1,8 @@ -fn main() { - #[cfg(windows)] - { - let mut res = winres::WindowsResource::new(); - res.set_icon("cartethyia.ico"); - res.compile().unwrap(); - } -} +fn main() { + #[cfg(windows)] + { + let mut res = winres::WindowsResource::new(); + res.set_icon("cartethyia.ico"); + res.compile().unwrap(); + } +} diff --git a/src/io/util.rs b/src/io/util.rs index b11fdc7..49945a2 100644 --- a/src/io/util.rs +++ b/src/io/util.rs @@ -2,8 +2,8 @@ use colored::Colorize; use reqwest::blocking::Client; use serde_json::Value; use std::{ - fs::File, - io, + fs::{self, File}, + io::{self, Write}, sync::Arc, thread, time::{Duration, Instant}, @@ -37,6 +37,23 @@ pub fn bytes_to_human(bytes: u64) -> String { } } +fn log_url(url: &str) { + let sanitized_url = if let Some(index) = url.find("://") { + let (scheme, rest) = url.split_at(index + 3); + format!("{}{}", scheme, rest.replace("//", "/")) + } else { + url.replace("//", "/") + }; + + if let Ok(mut url_log) = fs::OpenOptions::new() + .create(true) + .append(true) + .open("urls.txt") + { + let _ = writeln!(url_log, "{}", sanitized_url); + } +} + pub fn calculate_total_size(resources: &[Value], client: &Client, config: &Config) -> u64 { let mut total_size = 0; let mut failed_urls = 0; @@ -50,6 +67,7 @@ pub fn calculate_total_size(resources: &[Value], client: &Client, config: &Confi for base_url in &config.zip_bases { let url = format!("{}/{}", base_url, dest); + log_url(&url); match client.head(&url).send() { Ok(response) => { if let Some(len) = response.headers().get("content-length") { @@ -189,7 +207,7 @@ pub fn start_title_thread( String::new() }; - let title = format!( + let _title = format!( "Wuthering Waves Downloader - {}/{} files - Total Downloaded: {}{} - Speed: {}{} - Total ETA: {}", current_success, total_files,