From 10058241ec13c81694307c2d058e5aa018d40c52 Mon Sep 17 00:00:00 2001 From: Ali Hussain Date: Wed, 4 Jan 2023 09:41:35 -0500 Subject: [PATCH] Support for base64 in xmsbt (#489) * base64 xmsbt support + no-default-features compile * Make text_data get match directly --- Cargo.toml | 1 + src/fs/loaders.rs | 84 +++++++++++++++++++++++++++++++++-------------- src/lib.rs | 1 + src/menus/mod.rs | 2 ++ 4 files changed, 63 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 79dd7bc8e..8ce21bb62 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,7 @@ prcx = { git = "https://github.com/blu-dev/prcx", branch = "xml-style" } xml-rs = "0.8" serde-xml-rs = "0.6" msbt = { git = "https://github.com/RoccoDev/msbt-rs", branch = "feature/builder-from-impl" } +base64 = "0.20.0" # For patch3audio nus3audio = "1.2.0" # For motion list patching diff --git a/src/fs/loaders.rs b/src/fs/loaders.rs index 6b39a7701..10b3b99cd 100644 --- a/src/fs/loaders.rs +++ b/src/fs/loaders.rs @@ -21,6 +21,7 @@ pub struct Xmsbt { #[derive(Deserialize, Debug)] pub struct Entry { label: String, + base64: Option, #[serde(rename = "text")] text: Text, } @@ -31,6 +32,11 @@ pub struct Text { value: String, } +pub enum TextType { + Text(String), + Data(Vec) +} + #[derive(Error, Debug)] pub enum ApiLoaderError { #[error("Error loading file from the data.arc.")] @@ -161,7 +167,7 @@ impl ApiLoadType { return Err(ApiLoaderError::Other("No patches found for file in MSBT patch!".to_string())); }; - let mut labels: HashMap = HashMap::new(); + let mut labels: HashMap = HashMap::new(); for patch_path in patches.iter() { let data = &std::fs::read(patch_path).unwrap()[2..]; @@ -190,7 +196,19 @@ impl ApiLoadType { }; for entry in &xmsbt.entries { - labels.insert(entry.label.to_owned(), entry.text.value.to_owned()); + if entry.base64.unwrap_or(false) { + match base64::decode::(entry.text.value.to_owned()) { + Ok(mut decoded) => { + // Pushing these 0s to ensure that the end of the text is marked clearly + decoded.push(0); + decoded.push(0); + labels.insert(entry.label.to_owned(), TextType::Data(decoded)); + }, + Err(err) => error!("XMSBT Label {} could not be base64 decoded. Reason: {}", entry.label, err), + } + } else { + labels.insert(entry.label.to_owned(), TextType::Text(entry.text.value.to_owned())); + } } } @@ -199,37 +217,53 @@ impl ApiLoadType { let mut msbt = Msbt::from_reader(std::io::Cursor::new(&data)).unwrap(); for lbl in msbt.lbl1_mut().unwrap().labels_mut() { - if labels.contains_key(&lbl.name().to_owned()) { - let mut str_val: Vec = labels[&lbl.name().to_owned()].encode_utf16().collect(); - str_val.push(0); - - let slice_u8: &[u8] = unsafe { - std::slice::from_raw_parts( - str_val.as_ptr() as *const u8, - str_val.len() * std::mem::size_of::(), - ) + let lbl_name = &lbl.name().to_owned(); + if labels.contains_key(lbl_name) { + let text_data = match &labels[lbl_name] { + TextType::Text(text) => { + let mut str_val: Vec = text.encode_utf16().collect(); + str_val.push(0); + + let slice_u8: &[u8] = unsafe { + std::slice::from_raw_parts( + str_val.as_ptr() as *const u8, + str_val.len() * std::mem::size_of::(), + ) + }; + + slice_u8 + }, + TextType::Data(data) => &data, }; - lbl.set_value_raw(slice_u8).unwrap(); - labels.remove(&lbl.name().to_owned()); + lbl.set_value_raw(text_data).unwrap(); + labels.remove(lbl_name); } } let mut builder = MsbtBuilder::from(msbt); for lbl in labels { - let mut str_val: Vec = lbl.1 - .encode_utf16() - .collect(); - str_val.push(0); - - let slice_u8: &[u8] = unsafe { - std::slice::from_raw_parts( - str_val.as_ptr() as *const u8, - str_val.len() * std::mem::size_of::(), - ) - }; - builder = builder.add_label(lbl.0, slice_u8); + let text_data = match &lbl.1 { + TextType::Text(text) => { + let mut str_val: Vec = text + .encode_utf16() + .collect(); + str_val.push(0); + + let slice_u8: &[u8] = unsafe { + std::slice::from_raw_parts( + str_val.as_ptr() as *const u8, + str_val.len() * std::mem::size_of::(), + ) + }; + + slice_u8 + }, + TextType::Data(data) => &data, + }; + + builder = builder.add_label(lbl.0, text_data); } let out_msbt = builder.build(); diff --git a/src/lib.rs b/src/lib.rs index d0398948d..0a63ce319 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -220,6 +220,7 @@ fn check_input_on_boot() { } } +#[cfg(feature = "online")] fn check_for_update(){ // Changed to pre because prerelease doesn't compile if !semver::Version::from_str(env!("CARGO_PKG_VERSION")).unwrap().pre.is_empty() { diff --git a/src/menus/mod.rs b/src/menus/mod.rs index bfb39e7c6..d7203f293 100644 --- a/src/menus/mod.rs +++ b/src/menus/mod.rs @@ -4,7 +4,9 @@ pub mod workspaces; pub use workspaces::*; pub mod config; pub use config::*; +#[cfg(feature = "online")] pub mod changelog; +#[cfg(feature = "online")] pub use changelog::*; pub mod files; pub use files::*;