Extract contents in parallel if supported.

This commit is contained in:
Maschell 2018-12-06 16:48:36 +01:00
parent 31becf6c8b
commit 8ef84f48dd
3 changed files with 44 additions and 13 deletions

View File

@ -22,10 +22,14 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
import de.mas.wiiu.jnus.entities.content.Content; import de.mas.wiiu.jnus.entities.content.Content;
import de.mas.wiiu.jnus.implementations.NUSDataProvider; import de.mas.wiiu.jnus.implementations.NUSDataProvider;
import de.mas.wiiu.jnus.utils.FileUtils; import de.mas.wiiu.jnus.utils.FileUtils;
import de.mas.wiiu.jnus.utils.Parallelizable;
import de.mas.wiiu.jnus.utils.Utils; import de.mas.wiiu.jnus.utils.Utils;
import lombok.Getter; import lombok.Getter;
import lombok.extern.java.Log; import lombok.extern.java.Log;
@ -36,6 +40,8 @@ public final class ExtractionService {
@Getter private final NUSTitle NUSTitle; @Getter private final NUSTitle NUSTitle;
private boolean parallelizable = false;
public static ExtractionService getInstance(NUSTitle nustitle) { public static ExtractionService getInstance(NUSTitle nustitle) {
if (!instances.containsKey(nustitle)) { if (!instances.containsKey(nustitle)) {
instances.put(nustitle, new ExtractionService(nustitle)); instances.put(nustitle, new ExtractionService(nustitle));
@ -44,6 +50,9 @@ public final class ExtractionService {
} }
private ExtractionService(NUSTitle nustitle) { private ExtractionService(NUSTitle nustitle) {
if (nustitle.getDataProvider() instanceof Parallelizable) {
parallelizable = true;
}
this.NUSTitle = nustitle; this.NUSTitle = nustitle;
} }
@ -75,15 +84,32 @@ public final class ExtractionService {
extractEncryptedContentFilesTo(new ArrayList<Content>(getNUSTitle().getTMD().getAllContents().values()), outputFolder, true); extractEncryptedContentFilesTo(new ArrayList<Content>(getNUSTitle().getTMD().getAllContents().values()), outputFolder, true);
} }
public void extractEncryptedContentTo(Content content, String outputFolder, boolean withHashes) throws IOException {
NUSDataProvider dataProvider = getDataProvider();
if (withHashes) {
dataProvider.saveEncryptedContentWithH3Hash(content, outputFolder);
} else {
dataProvider.saveEncryptedContent(content, outputFolder);
}
}
public void extractEncryptedContentFilesTo(List<Content> list, String outputFolder, boolean withHashes) throws IOException { public void extractEncryptedContentFilesTo(List<Content> list, String outputFolder, boolean withHashes) throws IOException {
Utils.createDir(outputFolder); Utils.createDir(outputFolder);
NUSDataProvider dataProvider = getDataProvider(); if (parallelizable) {
for (Content c : list) { try {
log.info("Saving " + c.getFilename()); CompletableFuture.allOf(list.stream().map((Content c) -> CompletableFuture.runAsync(() -> {
if (withHashes) { try {
dataProvider.saveEncryptedContentWithH3Hash(c, outputFolder); extractEncryptedContentTo(c, outputFolder, withHashes);
} else { } catch (IOException e) {
dataProvider.saveEncryptedContent(c, outputFolder); throw new CompletionException(e);
}
})).toArray(CompletableFuture[]::new)).get();
} catch (InterruptedException | ExecutionException e) {
throw new IOException(e);
}
} else {
for (Content c : list) {
extractEncryptedContentTo(c, outputFolder, withHashes);
} }
} }
} }
@ -102,18 +128,18 @@ public final class ExtractionService {
FileUtils.saveByteArrayToFile(tmd_path, rawTMD); FileUtils.saveByteArrayToFile(tmd_path, rawTMD);
} }
public void extractTicketTo(String output) throws IOException { public boolean extractTicketTo(String output) throws IOException {
Utils.createDir(output); Utils.createDir(output);
byte[] rawTicket = getDataProvider().getRawTicket(); byte[] rawTicket = getDataProvider().getRawTicket();
if (rawTicket == null || rawTicket.length == 0) { if (rawTicket == null || rawTicket.length == 0) {
log.info("Couldn't write Ticket: No Ticket loaded"); log.info("Couldn't write Ticket: No Ticket loaded");
return; return false;
} }
String ticket_path = output + File.separator + Settings.TICKET_FILENAME; String ticket_path = output + File.separator + Settings.TICKET_FILENAME;
log.info("Extracting Ticket to: " + ticket_path); log.info("Extracting Ticket to: " + ticket_path);
FileUtils.saveByteArrayToFile(ticket_path, rawTicket); return FileUtils.saveByteArrayToFile(ticket_path, rawTicket);
} }
public void extractCertTo(String output) throws IOException { public void extractCertTo(String output) throws IOException {
@ -132,6 +158,7 @@ public final class ExtractionService {
public void extractAll(String outputFolder) throws IOException { public void extractAll(String outputFolder) throws IOException {
Utils.createDir(outputFolder); Utils.createDir(outputFolder);
extractAllEncryptedContentFilesWithHashesTo(outputFolder); extractAllEncryptedContentFilesWithHashesTo(outputFolder);
extractCertTo(outputFolder); extractCertTo(outputFolder);
extractTMDTo(outputFolder); extractTMDTo(outputFolder);

View File

@ -17,19 +17,18 @@
package de.mas.wiiu.jnus.implementations; package de.mas.wiiu.jnus.implementations;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.logging.Logger;
import de.mas.wiiu.jnus.NUSTitle; import de.mas.wiiu.jnus.NUSTitle;
import de.mas.wiiu.jnus.Settings; import de.mas.wiiu.jnus.Settings;
import de.mas.wiiu.jnus.entities.TMD; import de.mas.wiiu.jnus.entities.TMD;
import de.mas.wiiu.jnus.entities.content.Content; import de.mas.wiiu.jnus.entities.content.Content;
import de.mas.wiiu.jnus.utils.Parallelizable;
import de.mas.wiiu.jnus.utils.download.NUSDownloadService; import de.mas.wiiu.jnus.utils.download.NUSDownloadService;
import lombok.Getter; import lombok.Getter;
public class NUSDataProviderRemote extends NUSDataProvider { public class NUSDataProviderRemote extends NUSDataProvider implements Parallelizable {
@Getter private final int version; @Getter private final int version;
@Getter private final long titleID; @Getter private final long titleID;

View File

@ -0,0 +1,5 @@
package de.mas.wiiu.jnus.utils;
public interface Parallelizable {
}