diff --git a/Cargo.lock b/Cargo.lock index f483d69..f27f0e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,11 +33,33 @@ dependencies = [ "serde", "serde_json", "sha1_smol", + "simple-log", "steamlocate", "tokio", "winres", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "arc-swap" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dabe5a181f83789739c194cbe5a897dde195078fac08568d09221fd6137a7ba8" + [[package]] name = "autocfg" version = "1.1.0" @@ -116,6 +138,20 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.4", +] + [[package]] name = "colored" version = "2.1.0" @@ -139,6 +175,12 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "convert_case" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8" + [[package]] name = "core-foundation" version = "0.9.3" @@ -179,6 +221,15 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -277,6 +328,16 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -407,13 +468,19 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", "tracing", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.14.3" @@ -466,6 +533,15 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] + [[package]] name = "hyper" version = "1.2.0" @@ -522,6 +598,29 @@ dependencies = [ "tracing", ] +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "idna" version = "0.4.0" @@ -532,6 +631,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + [[package]] name = "indexmap" version = "2.2.6" @@ -539,7 +648,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.3", ] [[package]] @@ -570,6 +679,12 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is_debug" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06d198e9919d9822d5f7083ba8530e04de87841eaf21ead9af8f2304efd57c89" + [[package]] name = "itoa" version = "1.0.6" @@ -619,6 +734,12 @@ version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.4.5" @@ -626,10 +747,53 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] -name = "log" -version = "0.4.18" +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +dependencies = [ + "serde", +] + +[[package]] +name = "log-mdc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7" + +[[package]] +name = "log4rs" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e1ad45e4584824d760c35d71868dd7e6e5acd8f5195a9573743b369fc86cd6" +dependencies = [ + "arc-swap", + "chrono", + "flate2", + "fnv", + "humantime", + "libc", + "log", + "log-mdc", + "parking_lot", + "serde", + "serde-value", + "serde_derive", + "serde_json", + "serde_yaml", + "thread-id", + "winapi", +] [[package]] name = "memchr" @@ -692,6 +856,15 @@ dependencies = [ "tempfile", ] +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.16.0" @@ -783,6 +956,40 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "ordered-float" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3305af35278dd29f46fcdd139e0b1fbfae2153f0e5928b39b035542dd31e37b7" +dependencies = [ + "num-traits", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + [[package]] name = "percent-encoding" version = "2.3.0" @@ -892,6 +1099,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.35" @@ -931,6 +1144,12 @@ dependencies = [ "getrandom", ] +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + [[package]] name = "redox_syscall" version = "0.2.16" @@ -1047,6 +1266,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "security-framework" version = "2.9.2" @@ -1096,6 +1321,16 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-value" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a65a7291a8a568adcae4c10a677ebcedbc6c9cec91c054dee2ce40b0e3290eb" +dependencies = [ + "ordered-float", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.197" @@ -1130,6 +1365,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_yaml" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" +dependencies = [ + "indexmap 1.9.3", + "ryu", + "serde", + "yaml-rust", +] + [[package]] name = "sha1_smol" version = "1.0.0" @@ -1147,6 +1394,20 @@ dependencies = [ "digest", ] +[[package]] +name = "simple-log" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "110feefe2a808cadb7fe8c07c615ac82e899f1795fec063ed2fb1d72de5d417b" +dependencies = [ + "convert_case", + "is_debug", + "log", + "log4rs", + "once_cell", + "serde", +] + [[package]] name = "slab" version = "0.4.9" @@ -1257,6 +1518,17 @@ dependencies = [ "syn", ] +[[package]] +name = "thread-id" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" +dependencies = [ + "libc", + "redox_syscall 0.1.57", + "winapi", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -1553,6 +1825,37 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.4", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -1601,6 +1904,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.0", ] +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -1613,6 +1931,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -1625,6 +1949,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -1637,6 +1967,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -1649,6 +1985,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -1661,6 +2003,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -1673,6 +2021,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -1685,6 +2039,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + [[package]] name = "winreg" version = "0.50.0" @@ -1713,3 +2073,12 @@ checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" dependencies = [ "toml", ] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] diff --git a/Cargo.toml b/Cargo.toml index d9ba8d9..cb1513b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ reqwest = { version = "0.12.2", features = ["stream"] } futures-util = "0.3.30" indicatif = "0.17.8" tokio = {version="1.36.0", features = ["rt-multi-thread", "macros"]} +simple-log = "1.5.1" [target.'cfg(unix)'.dependencies] openssl = { version = "0.10.64", default-features = false, features = ["vendored"] } diff --git a/src/config.rs b/src/config.rs index 136341a..373c26b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -23,7 +23,7 @@ pub fn save(config_path: PathBuf, config: Config) { fs::create_dir_all(config_path.parent().unwrap()).unwrap(); save(config_path, config); } - _ => println!("Could not save config file, got:\n{}\n", e), + _ => crate::println_error!("Error while saving config {}", e.to_string()), }, } } diff --git a/src/http_async.rs b/src/http_async.rs index 35b6b8d..3b5504d 100644 --- a/src/http_async.rs +++ b/src/http_async.rs @@ -33,12 +33,14 @@ pub async fn download_file_progress( // Fix for CF shenanigans let total_size = res.content_length().unwrap_or(size); pb.set_length(total_size); - pb.println(format!( - "[{}] {} ({})", + let msg = format!( + "{} {} ({})", "Downloading".bright_yellow(), misc::cute_path(path), misc::human_readable_bytes(total_size) - )); + ); + pb.println(&msg); + info!("{}", msg); pb.set_message(path.file_name().unwrap().to_str().unwrap().to_string()); let mut file = @@ -81,10 +83,7 @@ pub async fn download_file(url: &str, path: &PathBuf) -> Result<(), String> { Ok(()) } Err(e) => { - misc::fatal_error(&format!( - "Could not download file from {}, got:\n{}", - url, e - )); + misc::fatal_error(&e.to_string()); Err("Could not download file".to_string()) } } @@ -106,16 +105,12 @@ pub async fn get_body(url: &str) -> Result, String> { .await { Ok(res) => { - println!( - "[DEBUG] {} {}", - res.status().to_string().bright_yellow(), - url.bright_yellow() - ); + debug!("{} {}", res.status().to_string(), url); let body = res.bytes().await.or(Err("Failed to get body"))?; Ok(body.to_vec()) } Err(e) => { - misc::fatal_error(&format!("Could not get body from {}, got:\n{}", url, e)); + misc::fatal_error(&e.to_string()); Err("Could not get body".to_string()) } } diff --git a/src/iw4x.rs b/src/iw4x.rs index d9f2f25..f01ae26 100644 --- a/src/iw4x.rs +++ b/src/iw4x.rs @@ -23,18 +23,18 @@ pub async fn update(dir: &Path) { let local = local_revision(dir); if remote <= local && dir.join("iw4x.dll").exists() { - println!( + crate::println_info!( "[{}] No files to download for IW4x", "Info".bright_magenta(), ); return; } - println!( + crate::println_info!( "[{}] Downloading outdated or missing files for IW4x", "Info".bright_magenta() ); - println!( + crate::println_info!( "[{}] {}", "Downloading".bright_yellow(), misc::cute_path(&dir.join("iw4x.dll")) diff --git a/src/main.rs b/src/main.rs index 499ae93..6330e3a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,10 +10,14 @@ mod structs; use global::*; use structs::*; +#[macro_use] +extern crate simple_log; + use colored::*; use indicatif::ProgressBar; #[cfg(windows)] use mslnk::ShellLink; +use simple_log::LogConfigBuilder; use std::{borrow::Cow, collections::HashMap, env, fs, path::Path, path::PathBuf}; #[cfg(windows)] use steamlocate::SteamDir; @@ -26,7 +30,7 @@ fn get_installed_games(games: &Vec) -> Vec<(u32, PathBuf)> { let steamdir = match steamdir_result { Ok(steamdir) => steamdir, Err(error) => { - println!("Error locating Steam: {}", error); + crate::println_error!("Error locating Steam: {}", error); return installed_games; } }; @@ -51,17 +55,17 @@ fn create_shortcut(path: &Path, target: &Path, icon: String, args: String) { sl.set_arguments(Some(args)); sl.set_icon_location(Some(icon)); sl.create_lnk(path).unwrap_or_else(|error| { - println!("Error creating shortcut.\n{:#?}", error); + crate::println_error!("Error creating shortcut.\n{:#?}", error); }); } else { - println!("Error creating shortcut."); + crate::println_error!("Error creating shortcut."); } } #[cfg(windows)] fn setup_client_links(game: &Game, game_dir: &Path) { if game.client.len() > 1 { - println!("Multiple clients installed, use the shortcuts (launch-.lnk in the game directory or on the desktop) to launch a specific client."); + crate::println_error!("Multiple clients installed, use the shortcuts (launch-.lnk in the game directory or on the desktop) to launch a specific client."); } for c in game.client.iter() { @@ -107,7 +111,7 @@ async fn auto_install(path: &Path, game: &Game<'_>, master_url: &String) { #[cfg(windows)] async fn windows_launcher_install(games: &Vec>, master_url: &String) { - println!( + crate::println_info!( "{}", "No game specified/found. Checking for installed Steam games..".yellow() ); @@ -117,11 +121,11 @@ async fn windows_launcher_install(games: &Vec>, master_url: &String) { let current_dir = env::current_dir().unwrap(); for (id, path) in installed_games.iter() { if current_dir.starts_with(path) { - println!("Found game in current directory."); - println!("Installing AlterWare client for {}.", id); + crate::println_info!("Found game in current directory."); + crate::println_info!("Installing AlterWare client for {}.", id); let game = games.iter().find(|&g| g.app_id == *id).unwrap(); auto_install(path, game, master_url).await; - println!("Installation complete. Please run the launcher again or use a shortcut to launch the game."); + crate::println_info!("Installation complete. Please run the launcher again or use a shortcut to launch the game."); std::io::stdin().read_line(&mut String::new()).unwrap(); std::process::exit(0); } @@ -145,10 +149,10 @@ async fn windows_launcher_install(games: &Vec>, master_url: &String) { if launcher_path != target_path { fs::copy(launcher_path, target_path).unwrap(); - println!("Launcher copied to {}", path.display()); + crate::println_info!("Launcher copied to {}", path.display()); } auto_install(path, game, master_url).await; - println!("Installation complete. Please run the launcher again or use a shortcut to launch the game."); + crate::println_info!("Installation complete. Please run the launcher again or use a shortcut to launch the game."); std::io::stdin().read_line(&mut String::new()).unwrap(); break; } @@ -233,11 +237,13 @@ async fn update_dir( if sha1_local != sha1_remote { files_to_download.push(file.clone()); } else { - pb.println(format!( + let msg = format!( "[{}] {}", "Checked".bright_blue(), misc::cute_path(&file_path) - )); + ); + pb.println(&msg); + info!("{}", msg); hashes.insert(file_name.to_owned(), file.hash.to_lowercase()); } } else { @@ -246,19 +252,23 @@ async fn update_dir( } if files_to_download.is_empty() { - pb.println(format!( + let msg = format!( "[{}] No files to download for {}", "Info".bright_magenta(), remote_dir - )); + ); + pb.println(&msg); + info!("{}", msg); return; } - pb.println(format!( + let msg = format!( "[{}] Downloading outdated or missing files for {}, {}", "Info".bright_magenta(), remote_dir, misc::human_readable_bytes(total_download_size(&files_to_download, remote_dir)) - )); + ); + pb.println(&msg); + info!("{}", msg); misc::pb_style_download(pb, true); let client = reqwest::Client::new(); @@ -362,14 +372,14 @@ async fn update( continue 'outer; } - println!( + crate::println_info!( "[{}] {}", "Removed".bright_red(), misc::cute_path(&file_path) ); if fs::remove_file(&file_path).is_err() { - println!( + crate::println_error!( "[{}] Couldn't delete {}", "Error".bright_red(), misc::cute_path(&file_path) @@ -452,7 +462,7 @@ async fn update( fn launch(file_path: &PathBuf, args: &str) { println!("\n\nJoin the AlterWare Discord server:\nhttps://discord.gg/2ETE8engZM\n\n"); - println!("Launching {} {}", file_path.display(), args); + crate::println_info!("Launching {} {}", file_path.display(), args); std::process::Command::new(file_path) .args(args.trim().split(' ')) .current_dir(file_path.parent().unwrap()) @@ -465,7 +475,7 @@ fn launch(file_path: &PathBuf, args: &str) { #[cfg(windows)] fn setup_env() { colored::control::set_virtual_terminal(true).unwrap_or_else(|error| { - println!("{:#?}", error); + crate::println_error!("{:#?}", error); colored::control::SHOULD_COLORIZE.set_override(false); }); @@ -475,9 +485,9 @@ fn setup_env() { if let Ok(current_exe) = env::current_exe() { if let Some(parent) = current_exe.parent() { if let Err(error) = env::set_current_dir(parent) { - eprintln!("{:#?}", error); + crate::println_error!("{:#?}", error); } else { - println!("Running from the system directory. Changed working directory to the executable location."); + crate::println_info!("Running from the system directory. Changed working directory to the executable location."); } } } @@ -512,8 +522,25 @@ fn arg_remove_value(args: &mut Vec, arg: &str) { #[tokio::main] async fn main() { + let log_file = env::current_exe() + .unwrap_or(PathBuf::from("alterware-launcher")) + .with_extension("log"); + if log_file.exists() { + if fs::remove_file(&log_file).is_err() { + println!("Couldn't clear log file, make sure target directory is writable."); + } + } + let logger_config = LogConfigBuilder::builder() + .path(log_file.to_str().unwrap()) + .time_format("%Y-%m-%d %H:%M:%S.%f") + .level("debug") + .output_file() + .build(); + let _ = simple_log::new(logger_config); + #[cfg(windows)] setup_env(); + let mut args: Vec = env::args().collect(); if arg_bool(&args, "--help") { @@ -613,8 +640,7 @@ async fn main() { .await .unwrap(); let games: Vec = serde_json::from_str(&games_json).unwrap_or_else(|error| { - println!("Error parsing games.json: {:#?}", error); - fs::write("alterware-launcher-error.txt", &games_json).unwrap(); + crate::println_error!("Error parsing games.json: {:#?}", error); misc::stdin(); std::process::exit(1); }); @@ -708,7 +734,7 @@ async fn main() { #[cfg(windows)] windows_launcher_install(&games, &master_url).await; - println!("{}", "Game not found!".bright_red()); + crate::println_error!("{}", "Game not found!".bright_red()); println!("Place the launcher in the game folder, if that doesn't work specify the client on the command line (ex. alterware-launcher.exe iw4-sp)"); println!("Press enter to exit..."); std::io::stdin().read_line(&mut String::new()).unwrap(); diff --git a/src/misc.rs b/src/misc.rs index 8a82a41..6344906 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -26,7 +26,7 @@ pub fn rev_to_int(rev: &str) -> u16 { } pub fn fatal_error(error: &str) { - println!("\n\n{}:\n{}", "Error".bright_red(), error); + crate::println_error!("{}: {}", "Error".bright_red(), error); stdin(); std::process::exit(1); } @@ -56,3 +56,19 @@ pub fn pb_style_download(pb: &ProgressBar, state: bool) { pub fn cute_path(path: &Path) -> String { path.to_str().unwrap().replace('\\', "/") } + +#[macro_export] +macro_rules! println_info { + ($($arg:tt)*) => {{ + println!($($arg)*); + info!($($arg)*); + }} +} + +#[macro_export] +macro_rules! println_error { + ($($arg:tt)*) => {{ + eprintln!($($arg)*); + error!($($arg)*); + }} +} diff --git a/src/self_update.rs b/src/self_update.rs index 6ddbf93..3cef6fa 100644 --- a/src/self_update.rs +++ b/src/self_update.rs @@ -13,8 +13,8 @@ pub async fn self_update_available() -> bool { #[cfg(not(windows))] pub async fn run(_update_only: bool) { if self_update_available().await { - println!("A new version of the AlterWare launcher is available."); - println!( + crate::println_info!("A new version of the AlterWare launcher is available."); + crate::println_info!( "Download it at {}", github::latest_release_url(GH_OWNER, GH_REPO) ); @@ -55,13 +55,13 @@ pub async fn run(update_only: bool) { || file_name.contains(".__selfdelete__.exe")) { fs::remove_file(file.path()).unwrap_or_else(|_| { - println!("Failed to remove old launcher file."); + crate::println_error!("Failed to remove old launcher file."); }); } } if self_update_available().await { - println!("Performing launcher self-update."); + crate::println_info!("Performing launcher self-update."); println!( "If you run into any issues, please download the latest version at {}", github::latest_release_url(GH_OWNER, GH_REPO) @@ -92,7 +92,7 @@ pub async fn run(update_only: bool) { .unwrap(); if !file_path.exists() { - println!("Failed to download launcher update."); + crate::println_error!("Failed to download launcher update."); return; } @@ -102,7 +102,7 @@ pub async fn run(update_only: bool) { // restarting spawns a new console, automation should manually restart on exit code 201 if !update_only { let restart_error = restart().to_string(); - println!("Failed to restart launcher: {}", restart_error); + crate::println_error!("Failed to restart launcher: {}", restart_error); println!("Please restart the launcher manually."); misc::stdin(); } diff --git a/src/structs.rs b/src/structs.rs index 939b542..60808d2 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -23,7 +23,7 @@ impl<'a> Game<'a> { for required_file in &self.required { let file_path = dir.join(required_file); if !file_path.exists() { - println!("Required file {} does not exist", file_path.display()); + crate::println_error!("Required file {} does not exist", file_path.display()); return false; } }