From 9440d3f820ceb6a641cdfd370e5bc2bcbe0ed824 Mon Sep 17 00:00:00 2001 From: ByteZ1337 <0xbytez@gmail.com> Date: Sun, 4 Aug 2024 19:24:04 +0200 Subject: [PATCH] switch to tracing for logging --- Cargo.toml | 3 +++ src/command/pack.rs | 9 +++++---- src/command/patch/assets_patcher.rs | 11 ++++++----- src/command/patch/audio_patcher.rs | 4 ++-- src/command/patch/locale_patcher.rs | 5 +++-- src/command/patch/mod.rs | 5 +++-- src/command/revert.rs | 5 +++-- src/command/unpack.rs | 14 +++++++------- src/crypto.rs | 4 ++-- src/main.rs | 24 +++++++++++++++++++----- 10 files changed, 53 insertions(+), 31 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5b71ad9..2688da0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,9 @@ binrw = "0.13.3" rand = "0.8.5" roxmltree = "0.20.0" xml-rs = "0.8.20" +tracing = "0.1.40" +tracing-subscriber = { version = "0.3.18", features = ["time"] } +time = { version = "0.3.36", features = ["local-offset"] } [profile.release] strip = true diff --git a/src/command/pack.rs b/src/command/pack.rs index 4184ff7..8467bb1 100644 --- a/src/command/pack.rs +++ b/src/command/pack.rs @@ -2,6 +2,7 @@ use std::ffi::OsStr; use std::path::PathBuf; use anyhow::Context; +use tracing::{info, warn}; use walkdir::WalkDir; use crate::command::AssetMetadata; @@ -63,7 +64,7 @@ fn find_input(input: &Option) -> anyhow::Result { } fn pack_dat(art_key: &String, input: &PathBuf, output: &PathBuf) -> anyhow::Result<()> { - println!("Packing assets..."); + info!("Packing assets..."); let mut assets: Vec = Vec::new(); let mut asset_bytes: Vec = Vec::new(); let mut count = 0; @@ -94,7 +95,7 @@ fn pack_dat(art_key: &String, input: &PathBuf, output: &PathBuf) -> anyhow::Resu let mut out = Vec::new(); let header_len = header.len() as i32; if header_len > i16::MAX as i32 { - println!("!!! Header length {header_len} exceeds 2^15-1. This assets file will only work with a modded game !!!"); + warn!("!!! Header length {} exceeds {}. This assets file will only work with a modded game !!!", header_len, i16::MAX); let len_one = (header_len & 0xFFFF) as u16; // set sign bit to 1 as a marker for the modded readInt16 to read 4 bytes instead of 2 let len_two = ((header_len >> 16) as u16) | 0x8000; @@ -106,14 +107,14 @@ fn pack_dat(art_key: &String, input: &PathBuf, output: &PathBuf) -> anyhow::Resu out.append(&mut header); out.append(&mut asset_bytes); - println!("Encrypting assets..."); + info!("Encrypting assets..."); let key = art_key.clone(); let enc_key = crypto::to_key_array(key.as_str()); let enc_key = enc_key.as_slice(); crypto::encrypt(enc_key, out.as_mut_slice()); std::fs::write(output, out)?; - println!("Packed {} assets", count); + info!("Packed {} assets", count); Ok(()) } diff --git a/src/command/patch/assets_patcher.rs b/src/command/patch/assets_patcher.rs index a389065..1562ba0 100644 --- a/src/command/patch/assets_patcher.rs +++ b/src/command/patch/assets_patcher.rs @@ -7,6 +7,7 @@ use anyhow::Context; use binrw::__private::write_zeroes; use binrw::BinWrite; use binrw::io::BufReader; +use tracing::info; use walkdir::WalkDir; use crate::command::pack; @@ -29,7 +30,7 @@ pub fn patch_assets( game_dir: &PathBuf, repack_info: RepackInfo, ) -> anyhow::Result { // patched assets directory - println!("Patching assets.."); + info!("Patching assets.."); let patched_assets = temp_dir.join("patched"); let unpacked = temp_dir.join("unpacked"); std::fs::create_dir_all(&patched_assets) @@ -67,10 +68,10 @@ pub fn patch_assets( // copy over the patch file if it's a png, csv or txt file // TODO: csv and txt patching if ext == OsStr::new("png") || ext == OsStr::new("csv") || ext == OsStr::new("txt") { - println!("Copying patch file for: {}", rel_path.display()); + info!("Copying patch file for: {}", rel_path.display()); copy_file(&patch_file.as_path(), rel_path, &patched_assets)?; } else if ext == OsStr::new("xml") || ext == OsStr::new("fnt") { - println!("Patching xml file: {}", rel_path.display()); + info!("Patching xml file: {}", rel_path.display()); patch_xml(&file.path(), &patch_file, rel_path, &patched_assets)?; } else { anyhow::bail!("Unsupported file type: {}", patch_file.display()); @@ -102,7 +103,7 @@ pub fn patch_assets( // copy over the file if it doesn't exist already if !target.exists() { - println!("Adding new file: {}", rel_path.display()); + info!("Adding new file: {}", rel_path.display()); copy_file(&file.path(), rel_path, &patched_assets)?; } } @@ -225,6 +226,6 @@ fn pack_to_assets(temp_dir: &PathBuf, game_dir: &PathBuf, repack: RepackInfo) -> } } - println!("Packed {} objects", new_assets.content.objects.len()); + info!("Packed {} objects", new_assets.content.objects.len()); Ok(()) } \ No newline at end of file diff --git a/src/command/patch/audio_patcher.rs b/src/command/patch/audio_patcher.rs index 185a4fc..6d80a2e 100644 --- a/src/command/patch/audio_patcher.rs +++ b/src/command/patch/audio_patcher.rs @@ -8,7 +8,7 @@ use std::path::PathBuf; use anyhow::Context; use binrw::io::BufReader; use serde::{Deserialize, Serialize}; - +use tracing::info; use crate::command::unpack::RepackInfo; use crate::unity::audio::{AudioClip, AudioCompressionFormat, StreamedResource}; use crate::unity::util::{AlignedString, U8Bool}; @@ -55,7 +55,7 @@ pub fn patch_audio(audio_patches_path: &PathBuf, game_dir: &PathBuf, repack_info .context("Failed to get parent directory of audio patches file")?; let mut offset = 0u64; - println!("Patching {} audio clips...", audio_patches.len()); + info!("Patching {} audio clips...", audio_patches.len()); for patch in &audio_patches { if patch.patched_path.extension() != Some(OsStr::new("fsb")) { anyhow::bail!("Only FSB files are supported for audio patches."); diff --git a/src/command/patch/locale_patcher.rs b/src/command/patch/locale_patcher.rs index 6046a3b..f023245 100644 --- a/src/command/patch/locale_patcher.rs +++ b/src/command/patch/locale_patcher.rs @@ -4,12 +4,13 @@ use std::path::PathBuf; use anyhow::Context; use binrw::io::BufReader; +use tracing::info; use zip::{CompressionMethod, ZipArchive}; use zip::write::{ExtendedFileOptions, FileOptions}; pub fn patch_locale(patched: &PathBuf, game_dir: &PathBuf) -> anyhow::Result<()> { let patched = patched.join("assets"); - println!("Patching en.zip..."); + info!("Patching en.zip..."); let input = BufReader::new(File::open(game_dir.join("StreamingAssets/loc/en.zip-bak")) .context("Failed to open en.zip-bak")? @@ -43,7 +44,7 @@ pub fn patch_locale(patched: &PathBuf, game_dir: &PathBuf) -> anyhow::Result<()> writer.finish().context("Failed to finish writing")?; - println!("Patched en.zip locale with {} entries", zip.len()); + info!("Patched en.zip locale with {} entries", zip.len()); Ok(()) } \ No newline at end of file diff --git a/src/command/patch/mod.rs b/src/command/patch/mod.rs index d692941..3c32ea7 100644 --- a/src/command/patch/mod.rs +++ b/src/command/patch/mod.rs @@ -4,6 +4,7 @@ use std::path::PathBuf; use anyhow::Context; use rand::random; +use tracing::info; use unpack::unpack_assets; use crate::{I18nCompatMode, Args}; @@ -18,7 +19,7 @@ mod locale_patcher; pub mod audio_patcher; pub fn patch(args: &Args, patch: &PathBuf, locale_mode: &I18nCompatMode) -> anyhow::Result<()> { - println!("Patching assets with {:?} with locale mode {:?}", patch, locale_mode); + info!("Patching assets with {:?} with locale mode {:?}", patch, locale_mode); if !patch.is_dir() { anyhow::bail!("Patch directory {:?} does not exist", patch); @@ -43,7 +44,7 @@ pub fn patch(args: &Args, patch: &PathBuf, locale_mode: &I18nCompatMode) -> anyh patch_locale(&patched_dir, &game_files.game_dir)?; } - println!("Cleaning up..."); + info!("Cleaning up..."); fs::remove_dir_all(&temp_dir).context("Failed to remove temp directory")?; Ok(()) diff --git a/src/command/revert.rs b/src/command/revert.rs index f6440a5..c2f0ce8 100644 --- a/src/command/revert.rs +++ b/src/command/revert.rs @@ -1,4 +1,5 @@ use std::path::PathBuf; +use tracing::info; use crate::command::DATA_FOLDER_NAME; pub fn revert(game_dir: &PathBuf) -> anyhow::Result<()> { @@ -20,8 +21,8 @@ pub fn revert(game_dir: &PathBuf) -> anyhow::Result<()> { let locale = game_dir.join("StreamingAssets/loc/en.zip"); let locale_bak = game_dir.join("StreamingAssets/loc/en.zip-bak"); copy_backup(&locale, &locale_bak)?; - - println!("Reverted game files to vanilla state"); + + info!("Reverted game files to vanilla state"); Ok(()) } diff --git a/src/command/unpack.rs b/src/command/unpack.rs index 95a3e8a..a29b928 100644 --- a/src/command/unpack.rs +++ b/src/command/unpack.rs @@ -7,7 +7,7 @@ use std::path::{Path, PathBuf}; use anyhow::Context; use binrw::BinRead; use binrw::io::BufReader; - +use tracing::{info, warn}; use crate::{crypto, Args, unity}; use crate::command::{ArtHeader, DATA_FOLDER_NAME}; use crate::unity::AssetsFile; @@ -63,7 +63,7 @@ fn find_input(args: &Args, input: &Option) -> anyhow::Result { pub fn unpack_dat(args: &Args, input: &PathBuf, output: &PathBuf) -> anyhow::Result<()> { let mut data = std::fs::read(input) .context("Failed to read input file")?; - println!("Unpacking assets from: {}", input.display()); + info!("Unpacking assets from: {}", input.display()); // key can be unwrapped safely here let key = args.art_key.clone().unwrap(); @@ -93,7 +93,7 @@ pub fn unpack_dat(args: &Args, input: &PathBuf, output: &PathBuf) -> anyhow::Res if let Some(parent) = path.parent() { std::fs::create_dir_all(parent)?; if !parent.canonicalize()?.starts_with(&abs_output) { - eprintln!("Skipping asset: {} (Tried escaping output directory)", asset.name); + warn!("Skipping asset: {} (Tried escaping output directory)", asset.name); continue; } } @@ -102,7 +102,7 @@ pub fn unpack_dat(args: &Args, input: &PathBuf, output: &PathBuf) -> anyhow::Res .context(format!("Failed to write asset {} to file", asset.name))?; } - println!("Unpacked {} assets", assets.len()); + info!("Unpacked {} assets", assets.len()); Ok(()) } @@ -136,7 +136,7 @@ pub fn unpack_assets(args: &Args, input_path: &PathBuf, output: &PathBuf, proces if name == "Art.dat" { let temp = PathBuf::from("./temp-art.dat"); - println!("Found Art.dat in unity assets. Temporarily saving to: {}", temp.display()); + info!("Found Art.dat in unity assets. Temporarily saving to: {}", temp.display()); let temp_writer = File::create(&temp) .context("Failed to create temporary file")?; @@ -167,9 +167,9 @@ pub fn unpack_assets(args: &Args, input_path: &PathBuf, output: &PathBuf, proces if let Some(art_file) = art_file { unpack_dat(args, &art_file, output)?; - println!("Removing temporary file: {}", art_file.display()); + info!("Removing temporary file: {}", art_file.display()); if let Err(e) = std::fs::remove_file(art_file) { - eprintln!("Failed to remove temporary file: {}", e); + warn!("Failed to remove temporary file: {}", e); } // Any unwraps here are safe because None values would've resulted in earlier bail Ok(RepackInfo { diff --git a/src/crypto.rs b/src/crypto.rs index 9869fbe..4b46776 100644 --- a/src/crypto.rs +++ b/src/crypto.rs @@ -1,7 +1,7 @@ use std::fs::File; use std::io::{Read, Seek}; use std::slice; - +use tracing::info; use crate::command::DATA_FOLDER_NAME; use crate::Args; @@ -94,7 +94,7 @@ pub fn extract_key(args: &Args) -> anyhow::Result { let mut key = [0; 16]; file.read_exact(&mut key)?; let key = String::from_utf8(key.to_vec())?; - println!("Extracted Art.dat decryption key from global metadata"); + info!("Extracted Art.dat decryption key from global metadata"); Ok(key) } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 5bb02e8..6df0cac 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,8 @@ use std::path::PathBuf; use clap::Parser; use clap_derive::{Parser, Subcommand, ValueEnum}; - +use tracing::{error, info}; +use tracing_subscriber::fmt::time::OffsetTime; use crate::command::{pack, patch, revert, unpack}; mod crypto; @@ -81,12 +82,25 @@ enum I18nCompatMode { fn main() { + tracing_subscriber::fmt() + .compact() + .with_level(true) + .with_target(false) + .with_thread_ids(false) + .with_thread_names(false) + .with_file(false) + .with_line_number(false) + .with_timer(OffsetTime::new( + time::UtcOffset::current_local_offset().unwrap_or_else(|_| time::UtcOffset::UTC), + time::format_description::parse("[hour]:[minute]:[second]").unwrap(), + )) + .init(); let mut args = Args::parse(); - println!("papers-tools v{} by {}", env!("CARGO_PKG_VERSION"), env!("CARGO_PKG_AUTHORS")); + info!("papers-tools v{} by {}", env!("CARGO_PKG_VERSION"), env!("CARGO_PKG_AUTHORS")); if args.art_key.is_none() && args.command.needs_key() { let res = crypto::extract_key(&args); if let Err(err) = res { - eprintln!("Failed to extract key: {}", err); + error!("Failed to extract key: {}", err); return; } args.art_key = Some(res.unwrap()); @@ -109,7 +123,7 @@ fn main() { }; if let Err(err) = res { - eprintln!("An error occurred while running the command:"); - eprintln!("{err}"); + error!("An error occurred while running the command:"); + error!("{err}"); } } \ No newline at end of file