-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cleaned main a bit, prepared for diffage
- Loading branch information
1 parent
f8b114e
commit 1afb648
Showing
1 changed file
with
107 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,84 +1,140 @@ | ||
use std::{collections::HashMap, ffi::OsStr, fs::File, io::{Read, Write}, path::Path}; | ||
use std::{ | ||
collections::HashMap, | ||
ffi::OsStr, | ||
fs::File, | ||
io::{Read, Write}, | ||
path::Path, | ||
string, | ||
}; | ||
|
||
use msbt::msbt; | ||
use ::msbt::msbt::MSBTString; | ||
use clap::Parser; | ||
use bytestream::ByteOrder; | ||
use clap::{Parser, ValueEnum}; | ||
use msbt::msbt; | ||
use serde::{Deserialize, Serialize}; | ||
use toml; | ||
|
||
#[derive(Parser, Debug)] | ||
#[command(author, version, about, long_about = None)] | ||
struct Args { | ||
/// Name of the file to open | ||
filename: String | ||
/// Command | ||
#[arg(value_enum)] | ||
action: Actions, | ||
|
||
/// File to extract, or to use as a base for diffing. | ||
original: String, | ||
|
||
/// Files to use for diffing. | ||
edited: Vec<String>, | ||
} | ||
#[derive(ValueEnum, Clone, Debug)] | ||
enum Actions { | ||
EXTRACT, | ||
CREATE, | ||
DIFF, | ||
PATCH, | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Clone)] | ||
struct SerMsbt { | ||
is_big_endian:bool, | ||
has_attributes:bool, | ||
strings:HashMap<String, String> | ||
is_big_endian: bool, | ||
has_attributes: bool, | ||
strings: HashMap<String, String>, | ||
} | ||
|
||
fn main() -> ::msbt::Result<()> { | ||
let cli = Args::parse(); | ||
let arg_filename = cli.filename.clone(); | ||
let args = Args::parse(); | ||
match args.action { | ||
Actions::EXTRACT => return extract_msbt(args), | ||
Actions::CREATE => return create_msbt(args), | ||
Actions::DIFF => todo!(), | ||
Actions::PATCH => todo!(), | ||
} | ||
} | ||
|
||
fn extract_msbt(args: Args) -> ::msbt::Result<()> { | ||
let arg_filename = args.original.clone(); | ||
let path = Path::new(&arg_filename); | ||
let extension = path.extension().unwrap().to_str().unwrap().to_lowercase(); | ||
let filename = path.file_stem().unwrap().to_str().unwrap(); | ||
let filepath = path.parent().unwrap(); | ||
let mut file = File::open(cli.filename)?; | ||
if extension == "msbt" { | ||
let filename = path.file_stem().unwrap().to_str().unwrap(); | ||
let filepath = path.parent().unwrap(); | ||
let mut file = File::open(args.original)?; | ||
|
||
let mut output_map = HashMap::new(); | ||
let msbt = msbt::from_binary(&mut file)?; | ||
let strings = msbt::get_strings(msbt.clone())?; | ||
for string in strings { | ||
let mut parsed_string = ::msbt::structs::TXT2::parse_binary(string.string, msbt.endianness); | ||
parsed_string.truncate(parsed_string.len()-1); | ||
let mut parsed_string = | ||
::msbt::structs::TXT2::parse_binary(string.string, msbt.endianness); | ||
parsed_string.truncate(parsed_string.len() - 1); | ||
output_map.insert(string.label, parsed_string); | ||
} | ||
let order = match msbt.endianness { | ||
bytestream::ByteOrder::BigEndian => true, | ||
bytestream::ByteOrder::LittleEndian => false, | ||
}; | ||
let msbt_json = SerMsbt{is_big_endian: order, has_attributes:msbt.has_attributes, strings: output_map}; | ||
let msbt_json = SerMsbt { | ||
is_big_endian: order, | ||
has_attributes: msbt.has_attributes, | ||
strings: output_map, | ||
}; | ||
let serialized = toml::ser::to_string_pretty(&msbt_json).unwrap(); | ||
let mut result = File::create(filepath.join(filename.to_owned()+".toml"))?; | ||
let mut result = File::create(filepath.join(filename.to_owned() + ".toml"))?; | ||
result.write(serialized.as_bytes())?; | ||
} else if extension == "toml" { | ||
let mut toml_string = "".to_owned(); | ||
let _ = file.read_to_string(&mut toml_string); | ||
let json:SerMsbt = toml::de::from_str(toml_string.as_str())?; | ||
let mut strings = Vec::<MSBTString>::new(); | ||
let mut i = 0; | ||
let order = match json.is_big_endian { | ||
true => bytestream::ByteOrder::BigEndian, | ||
false => bytestream::ByteOrder::LittleEndian, | ||
}; | ||
println!("Parsing {} string(s)...", json.strings.len()); | ||
for (label, string) in json.strings{ | ||
let corrected_string = string+"\0"; | ||
strings.push(MSBTString{ index: i, label: label, string: ::msbt::structs::TXT2::parse_string(&corrected_string, order).unwrap() }); | ||
i += 1; | ||
} | ||
println!("Parsed {} string(s).", strings.len()); | ||
let new_msbt = msbt::to_binary(strings, order)?; | ||
let mut result = File::create(filepath.join(filename.to_owned()+".msbt"))?; | ||
result.write(&new_msbt)?; | ||
Ok(()) | ||
} else { | ||
Err(::msbt::Error::NotMSBT) | ||
} | ||
|
||
//Clappy Trio | ||
// let string = [0x0E, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xCD, 0x50, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x20, 0x00, 0x00, 0xE0, 0x20, 0x00, 0x66, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x69, 0x00, 0x72, 0x00, 0x64, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x70, 0x00, 0x2E, 0x00, 0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x0E, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0xCD, 0x0E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x3B, 0xDB, 0x3E, 0xFF, 0x54, 0x00, 0x61, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x20, 0x00, 0x66, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x69, 0x00, 0x72, 0x00, 0x64, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x70, 0x00, 0x2E, 0x00, 0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00]; | ||
//Quiz Show | ||
// let string: [u8;118] = [0x54,0x00,0x68,0x00,0x65,0x00,0x20,0x00,0x6B,0x00,0x65,0x00,0x79,0x00,0x20,0x00,0x68,0x00,0x65,0x00,0x72,0x00,0x65,0x00,0x20,0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x74,0x00,0x6F,0x00,0x20,0x00,0x0E,0x00,0x00,0x00,0x03,0x00,0x04,0x00,0xE4,0x00,0x00,0xFF,0x75,0x00,0x73,0x00,0x65,0x00,0x0A,0x00,0x74,0x00,0x68,0x00,0x65,0x00,0x20,0x00,0x72,0x00,0x68,0x00,0x79,0x00,0x74,0x00,0x68,0x00,0x6D,0x00,0x20,0x00,0x74,0x00,0x6F,0x00,0x20,0x00,0x72,0x00,0x65,0x00,0x6D,0x00,0x65,0x00,0x6D,0x00,0x62,0x00,0x65,0x00,0x72,0x00,0x0E,0x00,0x00,0x00,0x03,0x00,0x04,0x00,0x00,0x00,0x00,0xFF,0x21,0x00,0x00,0x00]; | ||
// let constructed_string = ::msbt::structs::TXT2::parse_binary(string.to_vec(), bytestream::ByteOrder::LittleEndian); | ||
// println!("{}", constructed_string); | ||
|
||
// let string = "[RawCmd 4.0 00CD]Press [!A_button_3DS] for the third clap.[/RawCmd 4.0][RawCmd 4.1]\n[RawCmd 4.0 01CD][RawCmd 0.3 3BDB3EFF]Tap[RawCmd 0.3 000000FF] for the third clap.[/RawCmd 4.0]"; | ||
// let constructed_string = ::msbt::structs::TXT2::parse_string(string, bytestream::ByteOrder::LittleEndian); | ||
} | ||
|
||
// let code = "[/RawCmd 4.0]".to_string(); | ||
// let raw_code = ::msbt::structs::TXT2::convert_control_code_close(&code, bytestream::ByteOrder::LittleEndian); | ||
// println!("{:02X?}", raw_code); | ||
fn create_msbt(args: Args) -> ::msbt::Result<()> { | ||
let arg_filename = args.original.clone(); | ||
let path = Path::new(&arg_filename); | ||
let filename = path.file_stem().unwrap().to_str().unwrap(); | ||
let filepath = path.parent().unwrap(); | ||
let mut file = File::open(args.original)?; | ||
let toml = get_toml(file)?; | ||
let strings = get_strings_toml(&toml)?; | ||
let order = get_endianness_toml(&toml)?; | ||
let new_msbt = msbt::to_binary(strings, order)?; | ||
let mut result = File::create(filepath.join(filename.to_owned() + ".msbt"))?; | ||
result.write(&new_msbt)?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
fn get_toml(mut file: File) -> ::msbt::Result<SerMsbt>{ | ||
let mut toml_string = "".to_owned(); | ||
let _ = file.read_to_string(&mut toml_string); | ||
Ok(toml::de::from_str(toml_string.as_str())?) | ||
} | ||
|
||
fn get_endianness_toml(toml: &SerMsbt) -> ::msbt::Result<bytestream::ByteOrder> { | ||
let mut strings = Vec::<MSBTString>::new(); | ||
let mut i = 0; | ||
match toml.is_big_endian { | ||
true => Ok(bytestream::ByteOrder::BigEndian), | ||
false => Ok(bytestream::ByteOrder::LittleEndian), | ||
} | ||
} | ||
|
||
fn get_strings_toml(toml: &SerMsbt) -> ::msbt::Result<Vec<MSBTString>>{ | ||
let mut strings = Vec::<MSBTString>::new(); | ||
let mut i = 0; | ||
let order = match toml.is_big_endian { | ||
true => bytestream::ByteOrder::BigEndian, | ||
false => bytestream::ByteOrder::LittleEndian, | ||
}; | ||
println!("Parsing {} string(s)...", toml.strings.len()); | ||
for (label, string) in &toml.strings { | ||
let corrected_string = string.to_owned() + "\0"; | ||
strings.push(MSBTString { | ||
index: i, | ||
label: label.to_string(), | ||
string: ::msbt::structs::TXT2::parse_string(&corrected_string, order).unwrap(), | ||
}); | ||
i += 1; | ||
} | ||
println!("Parsed {} string(s).", strings.len()); | ||
Ok(strings) | ||
} |