Skip to content

Commit

Permalink
Support for base64 in xmsbt (#489)
Browse files Browse the repository at this point in the history
* base64 xmsbt support + no-default-features compile

* Make text_data get match directly
  • Loading branch information
Coolsonickirby authored Jan 4, 2023
1 parent fe0b3a9 commit 1005824
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 25 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
84 changes: 59 additions & 25 deletions src/fs/loaders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub struct Xmsbt {
#[derive(Deserialize, Debug)]
pub struct Entry {
label: String,
base64: Option<bool>,
#[serde(rename = "text")]
text: Text,
}
Expand All @@ -31,6 +32,11 @@ pub struct Text {
value: String,
}

pub enum TextType {
Text(String),
Data(Vec<u8>)
}

#[derive(Error, Debug)]
pub enum ApiLoaderError {
#[error("Error loading file from the data.arc.")]
Expand Down Expand Up @@ -161,7 +167,7 @@ impl ApiLoadType {
return Err(ApiLoaderError::Other("No patches found for file in MSBT patch!".to_string()));
};

let mut labels: HashMap<String, String> = HashMap::new();
let mut labels: HashMap<String, TextType> = HashMap::new();

for patch_path in patches.iter() {
let data = &std::fs::read(patch_path).unwrap()[2..];
Expand Down Expand Up @@ -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::<String>(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()));
}
}
}

Expand All @@ -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<u16> = 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::<u16>(),
)
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<u16> = 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::<u16>(),
)
};

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<u16> = 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::<u16>(),
)
};
builder = builder.add_label(lbl.0, slice_u8);
let text_data = match &lbl.1 {
TextType::Text(text) => {
let mut str_val: Vec<u16> = 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::<u16>(),
)
};

slice_u8
},
TextType::Data(data) => &data,
};

builder = builder.add_label(lbl.0, text_data);
}

let out_msbt = builder.build();
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
2 changes: 2 additions & 0 deletions src/menus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down

0 comments on commit 1005824

Please sign in to comment.