diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 18cb931..7dec717 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -1,4 +1,4 @@ -name: Build rustii +name: Build rustwii on: push: @@ -19,18 +19,18 @@ jobs: # Not sure if this is the best choice, but I'm building in release mode to produce more effective nightly binaries. - name: Update Toolchain run: rustup update - - name: Build rustii + - name: Build rustwii run: cargo build --verbose --release - - name: Package rustii for Upload + - name: Package rustwii for Upload run: | - mv target/release/rustii ~/rustii + mv target/release/rustwii ~/rustwii cd ~ - tar cvf rustii.tar rustii - - name: Upload rustii + tar cvf rustwii.tar rustwii + - name: Upload rustwii uses: actions/upload-artifact@v4 with: - path: ~/rustii.tar - name: rustii-Linux-bin + path: ~/rustwii.tar + name: rustwii-Linux-bin build-macos-arm64: @@ -42,18 +42,18 @@ jobs: run: rustup update - name: Add ARM64 Target run: rustup target add aarch64-apple-darwin - - name: Build rustii + - name: Build rustwii run: cargo build --verbose --release --target aarch64-apple-darwin - - name: Package rustii for Upload + - name: Package rustwii for Upload run: | - mv target/aarch64-apple-darwin/release/rustii ~/rustii + mv target/aarch64-apple-darwin/release/rustwii ~/rustwii cd ~ - tar cvf rustii.tar rustii - - name: Upload rustii + tar cvf rustwii.tar rustwii + - name: Upload rustwii uses: actions/upload-artifact@v4 with: - path: ~/rustii.tar - name: rustii-macOS-arm64-bin + path: ~/rustwii.tar + name: rustwii-macOS-arm64-bin build-macos-x86_64: @@ -65,18 +65,18 @@ jobs: run: rustup update - name: Add x86_64 Target run: rustup target add x86_64-apple-darwin - - name: Build rustii + - name: Build rustwii run: cargo build --verbose --release --target x86_64-apple-darwin - - name: Package rustii for Upload + - name: Package rustwii for Upload run: | - mv target/x86_64-apple-darwin/release/rustii ~/rustii + mv target/x86_64-apple-darwin/release/rustwii ~/rustwii cd ~ - tar cvf rustii.tar rustii - - name: Upload rustii + tar cvf rustwii.tar rustwii + - name: Upload rustwii uses: actions/upload-artifact@v4 with: - path: ~/rustii.tar - name: rustii-macOS-x86_64-bin + path: ~/rustwii.tar + name: rustwii-macOS-x86_64-bin build-windows-x86_64: @@ -86,12 +86,12 @@ jobs: - uses: actions/checkout@v4 - name: Update Toolchain run: rustup update - - name: Build rustii + - name: Build rustwii run: cargo build --verbose --release - - name: Upload rustii + - name: Upload rustwii uses: actions/upload-artifact@v4 with: - path: D:\a\rustii\rustii\target\release\rustii.exe - name: rustii-Windows-bin + path: D:\a\rustwii\rustwii\target\release\rustwii.exe + name: rustwii-Windows-bin diff --git a/src/archive/ash.rs b/src/archive/ash.rs index 3f85328..9e2c761 100644 --- a/src/archive/ash.rs +++ b/src/archive/ash.rs @@ -45,7 +45,7 @@ fn ash_bit_reader_feed_word(reader: &mut ASHBitReader) -> Result<(), ASHError> { Ok(()) } -fn ash_bit_reader_init(src: &[u8], size: u32, startpos: u32) -> Result { +fn ash_bit_reader_init(src: &'_ [u8], size: u32, startpos: u32) -> Result, ASHError> { // Load data into a bit reader, then have it read its first word. let mut reader = ASHBitReader { src, diff --git a/src/bin/rustwii/info.rs b/src/bin/rustwii/info.rs index 0875cab..64d655e 100644 --- a/src/bin/rustwii/info.rs +++ b/src/bin/rustwii/info.rs @@ -20,8 +20,8 @@ fn print_tid(title_id: [u8; 8]) -> Result<()> { } else { None }; - if ascii_tid.is_some() { - println!(" Title ID: {} ({})", hex::encode(title_id).to_uppercase(), ascii_tid.unwrap()); + if let Some(ascii_tid) = ascii_tid { + println!(" Title ID: {} ({})", hex::encode(title_id).to_uppercase(), ascii_tid); } else { println!(" Title ID: {}", hex::encode(title_id).to_uppercase()); } @@ -74,7 +74,7 @@ fn print_tmd_info(tmd: tmd::TMD, cert: Option) -> Result<()> println!(" Certificate Info: {} (Unknown)", signature_issuer); } let region = if hex::encode(tmd.title_id()).eq("0000000100000002") { - match versions::dec_to_standard(tmd.title_version(), &hex::encode(tmd.title_id()), Some(tmd.is_vwii() != false)) + match versions::dec_to_standard(tmd.title_version(), &hex::encode(tmd.title_id()), Some(tmd.is_vwii())) .unwrap_or_default().chars().last() { Some('U') => "USA", Some('E') => "EUR", @@ -89,11 +89,11 @@ fn print_tmd_info(tmd: tmd::TMD, cert: Option) -> Result<()> }; println!(" Region: {}", region); println!(" Title Type: {}", tmd.title_type()?); - println!(" vWii Title: {}", tmd.is_vwii() != false); + println!(" vWii Title: {}", tmd.is_vwii()); println!(" DVD Video Access: {}", tmd.check_access_right(tmd::AccessRight::DVDVideo)); println!(" AHB Access: {}", tmd.check_access_right(tmd::AccessRight::AHB)); - if cert.is_some() { - let signing_str = match cert::verify_tmd(&cert.unwrap(), &tmd) { + if let Some(cert) = cert { + let signing_str = match cert::verify_tmd(&cert, &tmd) { Ok(result) => match result { true => "Valid (Unmodified TMD)", false => { @@ -161,8 +161,8 @@ fn print_ticket_info(ticket: ticket::Ticket, cert: Option) -> println!(" Decryption Key: {}", key); println!(" Title Key (Encrypted): {}", hex::encode(ticket.title_key())); println!(" Title Key (Decrypted): {}", hex::encode(ticket.title_key_dec())); - if cert.is_some() { - let signing_str = match cert::verify_ticket(&cert.unwrap(), &ticket) { + if let Some(cert) = cert { + let signing_str = match cert::verify_ticket(&cert, &ticket) { Ok(result) => match result { true => "Valid (Unmodified Ticket)", false => { diff --git a/src/bin/rustwii/nand/emunand.rs b/src/bin/rustwii/nand/emunand.rs index 10c52ea..2690fef 100644 --- a/src/bin/rustwii/nand/emunand.rs +++ b/src/bin/rustwii/nand/emunand.rs @@ -162,8 +162,8 @@ pub fn info(emunand: &str) -> Result<()> { } else { None }; - if ascii_tid.is_some() { - println!(" {} ({})", title.to_uppercase(), ascii_tid.unwrap()); + if let Some(ascii_tid) = ascii_tid { + println!(" {} ({})", title.to_uppercase(), ascii_tid); } else { println!(" {}", title.to_uppercase()); } @@ -192,8 +192,8 @@ pub fn info(emunand: &str) -> Result<()> { } else { None }; - if ascii_tid.is_some() { - println!(" {} ({})", title.to_uppercase(), ascii_tid.unwrap()); + if let Some(ascii_tid) = ascii_tid { + println!(" {} ({})", title.to_uppercase(), ascii_tid); } else { println!(" {}", title.to_uppercase()); } diff --git a/src/bin/rustwii/title/nus.rs b/src/bin/rustwii/title/nus.rs index f36774e..4b3f9e1 100644 --- a/src/bin/rustwii/title/nus.rs +++ b/src/bin/rustwii/title/nus.rs @@ -214,7 +214,7 @@ pub fn download_title(tid: &str, version: &Option, output: &TitleOutputType bail!("The specified Title ID is invalid!"); } if version.is_some() { - println!("Downloading title {} v{}, please wait...", tid, version.clone().unwrap()); + println!("Downloading title {} v{}, please wait...", tid, version.unwrap()); } else { println!("Downloading title {} vLatest, please wait...", tid); } @@ -245,9 +245,9 @@ pub fn download_title(tid: &str, version: &Option, output: &TitleOutputType let content_region = content::ContentRegion::from_contents(contents, tmd.content_records().clone())?; println!(" - Building certificate chain..."); let cert_chain = cert::CertificateChain::from_bytes(&nus::download_cert_chain(true).with_context(|| "Certificate chain could not be built.")?)?; - if tik.is_some() { + if let Some(tik) = tik { // If we have a Ticket, then build a Title and jump to the output method. - let title = title::Title::from_parts(cert_chain, None, tik.unwrap(), tmd, content_region, None)?; + let title = title::Title::from_parts(cert_chain, None, tik, tmd, content_region, None)?; if output.wad.is_some() { download_title_wad(title, output.wad.clone().unwrap())?; } else { diff --git a/src/bin/rustwii/title/wad.rs b/src/bin/rustwii/title/wad.rs index a3c8511..10b4d0a 100644 --- a/src/bin/rustwii/title/wad.rs +++ b/src/bin/rustwii/title/wad.rs @@ -327,8 +327,8 @@ pub fn edit_wad(input: &str, output: &Option, edits: &WadModifications) let new_tid: Vec = tid_high.iter().chain(&tid_low).copied().collect(); title.set_title_id(new_tid.try_into().unwrap())?; } - if edits.ios.is_some() { - let new_ios = edits.ios.unwrap(); + if let Some(ios) = edits.ios { + let new_ios = ios; if new_ios < 3 { bail!("The specified IOS version is not valid! The new IOS version must be between 3 and 255.") } @@ -428,12 +428,12 @@ pub fn remove_wad(input: &str, output: &Option, identifier: &ContentIden let mut title = title::Title::from_bytes(&fs::read(in_path)?).with_context(|| "The provided WAD file could not be parsed, and is likely invalid.")?; // Parse the identifier passed to choose how to find and remove the target. // ...maybe don't take the above comment out of context - if identifier.index.is_some() { - title.content.remove_content(identifier.index.unwrap()).with_context(|| "The specified index does not exist in the provided WAD!")?; + if let Some(index) = identifier.index { + title.content.remove_content(index).with_context(|| "The specified index does not exist in the provided WAD!")?; println!("{:?}", title.tmd); title.fakesign().with_context(|| "An unknown error occurred while fakesigning the modified WAD.")?; fs::write(&out_path, title.to_wad()?.to_bytes()?).with_context(|| "Could not open output file for writing.")?; - println!("Successfully removed content at index {} in WAD file \"{}\".", identifier.index.unwrap(), out_path.display()); + println!("Successfully removed content at index {} in WAD file \"{}\".", index, out_path.display()); } else if identifier.cid.is_some() { let cid = u32::from_str_radix(identifier.cid.clone().unwrap().as_str(), 16).with_context(|| "The specified Content ID is invalid!")?; let index = match title.content.get_index_from_cid(cid) { @@ -476,8 +476,8 @@ pub fn set_wad(input: &str, content: &str, output: &Option, identifier: }; } // Parse the identifier passed to choose how to do the find and replace. - if identifier.index.is_some() { - match title.set_content(&new_content, identifier.index.unwrap(), None, target_type) { + if let Some(index) = identifier.index { + match title.set_content(&new_content, index, None, target_type) { Err(title::TitleError::Content(content::ContentError::IndexOutOfRange { index, max })) => { bail!("The specified index {} does not exist in this WAD! The maximum index is {}.", index, max) }, diff --git a/src/title/content.rs b/src/title/content.rs index 049e442..c45e462 100644 --- a/src/title/content.rs +++ b/src/title/content.rs @@ -81,9 +81,9 @@ impl ContentRegion { return Err(ContentError::MissingContents { required: content_records.len(), found: contents.len()}); } let mut content_region = Self::new(content_records)?; - for i in 0..contents.len() { - let target_index = content_region.content_records[i].index; - content_region.load_enc_content(&contents[i], target_index as usize)?; + for (index, content) in contents.iter().enumerate() { + let target_index = content_region.content_records[index].index; + content_region.load_enc_content(content, target_index as usize)?; } Ok(content_region) } @@ -213,15 +213,15 @@ impl ContentRegion { } self.content_records[index].content_size = content_size; self.content_records[index].content_hash = content_hash; - if cid.is_some() { + if let Some(cid) = cid { // Make sure that the new CID isn't already in use. - if self.content_records.iter().any(|record| record.content_id == cid.unwrap()) { - return Err(ContentError::CIDAlreadyExists(cid.unwrap())); + if self.content_records.iter().any(|record| record.content_id == cid) { + return Err(ContentError::CIDAlreadyExists(cid)); } - self.content_records[index].content_id = cid.unwrap(); + self.content_records[index].content_id = cid; } - if content_type.is_some() { - self.content_records[index].content_type = content_type.unwrap(); + if let Some(content_type) = content_type { + self.content_records[index].content_type = content_type; } self.contents[index] = content.to_vec(); Ok(()) @@ -320,12 +320,18 @@ pub struct SharedContentMap { pub records: Vec, } +impl Default for SharedContentMap { + fn default() -> Self { + Self::new() + } +} + impl SharedContentMap { /// Creates a new SharedContentMap instance from the binary data of a content.map file. pub fn from_bytes(data: &[u8]) -> Result { // The uid.sys file must be divisible by a multiple of 28, or something is wrong, since each // entry is 28 bytes long. - if (data.len() % 28) != 0 { + if !data.len().is_multiple_of(28) { return Err(ContentError::InvalidSharedContentMapLength); } let record_count = data.len() / 28; diff --git a/src/title/mod.rs b/src/title/mod.rs index c3c84f4..46cd5ea 100644 --- a/src/title/mod.rs +++ b/src/title/mod.rs @@ -190,8 +190,8 @@ impl Title { /// Sets a new Title ID for the Title. This will re-encrypt the Title Key in the Ticket, since /// the Title ID is used as the IV for decrypting the Title Key. pub fn set_title_id(&mut self, title_id: [u8; 8]) -> Result<(), TitleError> { - self.tmd.set_title_id(title_id)?; - self.ticket.set_title_id(title_id)?; + self.tmd.set_title_id(title_id); + self.ticket.set_title_id(title_id); Ok(()) } diff --git a/src/title/nus.rs b/src/title/nus.rs index d07eb2d..9d86b6e 100644 --- a/src/title/nus.rs +++ b/src/title/nus.rs @@ -126,8 +126,8 @@ pub fn download_tmd(title_id: [u8; 8], title_version: Option, wiiu_endpoint } else { WII_NUS_ENDPOINT.to_owned() }; - let tmd_url = if title_version.is_some() { - format!("{}{}/tmd.{}", endpoint_url, &hex::encode(title_id), title_version.unwrap()) + let tmd_url = if let Some(title_version) = title_version { + format!("{}{}/tmd.{}", endpoint_url, &hex::encode(title_id), title_version) } else { format!("{}{}/tmd", endpoint_url, &hex::encode(title_id)) }; diff --git a/src/title/ticket.rs b/src/title/ticket.rs index d55a7ee..d6d5ab6 100644 --- a/src/title/ticket.rs +++ b/src/title/ticket.rs @@ -320,10 +320,9 @@ impl Ticket { /// Sets a new Title ID for the Ticket. This will re-encrypt the Title Key, since the Title ID /// is used as the IV for decrypting the Title Key. - pub fn set_title_id(&mut self, title_id: [u8; 8]) -> Result<(), TicketError> { + pub fn set_title_id(&mut self, title_id: [u8; 8]) { let new_enc_title_key = crypto::encrypt_title_key(self.title_key_dec(), self.common_key_index, title_id, self.is_dev()); self.title_key = new_enc_title_key; self.title_id = title_id; - Ok(()) } } diff --git a/src/title/tmd.rs b/src/title/tmd.rs index d8464f0..4eda914 100644 --- a/src/title/tmd.rs +++ b/src/title/tmd.rs @@ -322,8 +322,8 @@ impl TMD { } /// Sets the content records in the TMD. - pub fn set_content_records(&mut self, content_records: &Vec) { - self.content_records = content_records.clone() + pub fn set_content_records(&mut self, content_records: &[ContentRecord]) { + self.content_records = content_records.to_vec(); } /// Gets whether a TMD is fakesigned using the strncmp (trucha) bug or not. @@ -449,9 +449,8 @@ impl TMD { } /// Sets a new Title ID for a TMD. - pub fn set_title_id(&mut self, title_id: [u8; 8]) -> Result<(), TMDError> { + pub fn set_title_id(&mut self, title_id: [u8; 8]) { self.title_id = title_id; - Ok(()) } /// Gets the Title ID of the IOS required by a TMD.