Change the content and parent attribute of a FSTEntry to an Optional

This commit is contained in:
Maschell 2019-04-19 10:42:33 +02:00
parent 75e28a733b
commit c47c9913ac
4 changed files with 37 additions and 34 deletions

View File

@ -66,7 +66,7 @@ public final class DecryptionService {
public CompletableFuture<Void> decryptFSTEntryToAsync(boolean useFullPath, FSTEntry entry, String outputPath, boolean skipExistingFile) { public CompletableFuture<Void> decryptFSTEntryToAsync(boolean useFullPath, FSTEntry entry, String outputPath, boolean skipExistingFile) {
return CompletableFuture.runAsync(() -> { return CompletableFuture.runAsync(() -> {
try { try {
if (entry.isNotInPackage() || entry.getContent() == null) { if (entry.isNotInPackage() || !entry.getContent().isPresent()) {
return; return;
} }
@ -99,7 +99,7 @@ public final class DecryptionService {
return; return;
} }
if (targetFile.length() == entry.getFileSize()) { if (targetFile.length() == entry.getFileSize()) {
Content c = entry.getContent(); Content c = entry.getContent().get();
if (c.isHashed()) { if (c.isHashed()) {
log.info("File already exists: " + entry.getFilename()); log.info("File already exists: " + entry.getFilename());
return; return;

View File

@ -20,14 +20,14 @@ import java.io.File;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.function.Supplier; import java.util.function.Supplier;
import de.mas.wiiu.jnus.entities.content.Content; import de.mas.wiiu.jnus.entities.content.Content;
import lombok.Data; import lombok.Data;
import lombok.Getter; import lombok.Getter;
import lombok.extern.java.Log; import lombok.NonNull;
@Log
/** /**
* Represents one FST Entry * Represents one FST Entry
* *
@ -41,7 +41,7 @@ public class FSTEntry {
private String filename = null; private String filename = null;
private final Supplier<String> filenameSupplier; private final Supplier<String> filenameSupplier;
@Getter private final FSTEntry parent; @Getter private final Optional<FSTEntry> parent;
@Getter private final List<FSTEntry> children = new ArrayList<>(); @Getter private final List<FSTEntry> children = new ArrayList<>();
@ -50,7 +50,7 @@ public class FSTEntry {
@Getter private final long fileSize; @Getter private final long fileSize;
@Getter private final long fileOffset; @Getter private final long fileOffset;
@Getter private final Content content; @Getter private final Optional<Content> content;
@Getter private final boolean isDir; @Getter private final boolean isDir;
@Getter private final boolean isRoot; @Getter private final boolean isRoot;
@ -62,14 +62,14 @@ public class FSTEntry {
this.filenameSupplier = fstParam.getFileNameSupplier(); this.filenameSupplier = fstParam.getFileNameSupplier();
this.flags = fstParam.getFlags(); this.flags = fstParam.getFlags();
this.parent = fstParam.getParent(); this.parent = fstParam.getParent();
if (parent != null) { if (parent.isPresent()) {
parent.children.add(this); parent.get().children.add(this);
} }
this.fileSize = fstParam.getFileSize(); this.fileSize = fstParam.getFileSize();
this.fileOffset = fstParam.getFileOffset(); this.fileOffset = fstParam.getFileOffset();
this.content = fstParam.getContent(); this.content = fstParam.getContent();
if (content != null) { if (content.isPresent()) {
content.addEntry(this); content.get().addEntry(this);
} }
this.isDir = fstParam.isDir(); this.isDir = fstParam.isDir();
this.isRoot = fstParam.isRoot(); this.isRoot = fstParam.isRoot();
@ -88,14 +88,14 @@ public class FSTEntry {
param.setDir(true); param.setDir(true);
return new FSTEntry(param); return new FSTEntry(param);
} }
public static FSTEntry createFSTEntry(FSTEntry parent, String filename, Content content) { public static FSTEntry createFSTEntry(@NonNull FSTEntry parent, @NonNull String filename, @NonNull Content content) {
FSTEntryParam param = new FSTEntryParam(); FSTEntryParam param = new FSTEntryParam();
param.setFileNameSupplier(() -> filename); param.setFileNameSupplier(() -> filename);
param.setFileSize(content.getDecryptedFileSize()); param.setFileSize(content.getDecryptedFileSize());
param.setContent(content); param.setContent(Optional.of(content));
param.setDir(false); param.setDir(false);
param.setParent(parent); param.setParent(Optional.of(parent));
return new FSTEntry(param); return new FSTEntry(param);
} }
@ -111,8 +111,9 @@ public class FSTEntry {
} }
private StringBuilder getPathInternal() { private StringBuilder getPathInternal() {
if (parent != null) { if (parent.isPresent()) {
return parent.getPathInternal().append(parent.getFilename()).append(File.separator); FSTEntry par = parent.get();
return par.getPathInternal().append(par.getFilename()).append(File.separator);
} }
return new StringBuilder(); return new StringBuilder();
} }
@ -159,14 +160,10 @@ public class FSTEntry {
public List<FSTEntry> getFSTEntriesByContent(Content content) { public List<FSTEntry> getFSTEntriesByContent(Content content) {
List<FSTEntry> entries = new ArrayList<>(); List<FSTEntry> entries = new ArrayList<>();
if (this.content == null) { if (this.content.isPresent() && this.content.get().equals(content)) {
log.warning("Error in getFSTEntriesByContent, content null"); entries.add(this);
System.exit(0);
} else {
if (this.content.equals(content)) {
entries.add(this);
}
} }
for (FSTEntry child : getChildren()) { for (FSTEntry child : getChildren()) {
entries.addAll(child.getFSTEntriesByContent(content)); entries.addAll(child.getFSTEntriesByContent(content));
} }
@ -174,7 +171,7 @@ public class FSTEntry {
} }
public long getFileOffsetBlock() { public long getFileOffsetBlock() {
if (getContent().isHashed()) { if (getContent().isPresent() && getContent().get().isHashed()) {
return (getFileOffset() / 0xFC00) * 0x10000; return (getFileOffset() / 0xFC00) * 0x10000;
} else { } else {
return getFileOffset(); return getFileOffset();
@ -211,14 +208,14 @@ public class FSTEntry {
@Data @Data
protected static class FSTEntryParam { protected static class FSTEntryParam {
private Supplier<String> fileNameSupplier = () -> ""; private Supplier<String> fileNameSupplier = () -> "";
private FSTEntry parent = null; private Optional<FSTEntry> parent = Optional.empty();
private short flags; private short flags;
private long fileSize = 0; private long fileSize = 0;
private long fileOffset = 0; private long fileOffset = 0;
private Content content = null; private Optional<Content> content = Optional.empty();
private boolean isDir = false; private boolean isDir = false;
private boolean isRoot = false; private boolean isRoot = false;

View File

@ -20,6 +20,7 @@ import java.text.ParseException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import de.mas.wiiu.jnus.entities.content.Content; import de.mas.wiiu.jnus.entities.content.Content;
import de.mas.wiiu.jnus.entities.content.ContentFSTInfo; import de.mas.wiiu.jnus.entities.content.ContentFSTInfo;
@ -109,7 +110,7 @@ public final class FSTService {
} }
} else { } else {
// TODO: make content attribute in a fstentry optional // TODO: make content attribute in a fstentry optional
entryParam.setContent(content); entryParam.setContent(Optional.of(content));
ContentFSTInfo contentFSTInfo = contentsFSTByIndex.get((int) contentIndex); ContentFSTInfo contentFSTInfo = contentsFSTByIndex.get((int) contentIndex);
if (contentFSTInfo == null) { if (contentFSTInfo == null) {
log.warning("ContentFSTInfo for FST Entry not found"); log.warning("ContentFSTInfo for FST Entry not found");
@ -121,7 +122,7 @@ public final class FSTService {
} }
entryParam.setContentFSTID(contentIndex); entryParam.setContentFSTID(contentIndex);
entryParam.setParent(parent); entryParam.setParent(Optional.of(parent));
FSTEntry entry = new FSTEntry(entryParam); FSTEntry entry = new FSTEntry(entryParam);
fstEntryToOffsetMap.put(entryOffset, entry); fstEntryToOffsetMap.put(entryOffset, entry);

View File

@ -75,11 +75,16 @@ public class FSTDataProviderNUSTitle implements FSTDataProvider, HasNUSTitle {
@Override @Override
public void readFileToStream(OutputStream out, FSTEntry entry, long offset, Optional<Long> size) throws IOException { public void readFileToStream(OutputStream out, FSTEntry entry, long offset, Optional<Long> size) throws IOException {
if (!entry.getContent().isPresent()) {
out.close();
throw new IOException("Content for the FSTEntry not found: " + entry);
}
long fileOffset = entry.getFileOffset() + offset; long fileOffset = entry.getFileOffset() + offset;
long fileOffsetBlock = fileOffset; long fileOffsetBlock = fileOffset;
long usedSize = size.orElse(entry.getFileSize()); long usedSize = size.orElse(entry.getFileSize());
Content c = entry.getContent().get();
if (entry.getContent().isHashed()) { if (c.isHashed()) {
fileOffsetBlock = (fileOffset / 0xFC00) * 0x10000; fileOffsetBlock = (fileOffset / 0xFC00) * 0x10000;
} else { } else {
fileOffsetBlock = (fileOffset / 0x8000) * 0x8000; fileOffsetBlock = (fileOffset / 0x8000) * 0x8000;
@ -97,12 +102,12 @@ public class FSTDataProviderNUSTitle implements FSTDataProvider, HasNUSTitle {
private boolean decryptFSTEntryToStream(FSTEntry entry, OutputStream outputStream, long fileOffsetBlock, long fileOffset, long fileSize) private boolean decryptFSTEntryToStream(FSTEntry entry, OutputStream outputStream, long fileOffsetBlock, long fileOffset, long fileSize)
throws IOException, CheckSumWrongException { throws IOException, CheckSumWrongException {
if (entry.isNotInPackage() || entry.getContent() == null || !title.getTicket().isPresent()) { if (entry.isNotInPackage() || !entry.getContent().isPresent() || !title.getTicket().isPresent()) {
if (!title.getTicket().isPresent()) { if (!title.getTicket().isPresent()) {
log.info("Decryption not possible because no ticket was set."); log.info("Decryption not possible because no ticket was set.");
}else if(entry.isNotInPackage()) { } else if (entry.isNotInPackage()) {
log.info("Decryption not possible because the FSTEntry is not in this package"); log.info("Decryption not possible because the FSTEntry is not in this package");
}else if(entry.getContent() == null) { } else if (entry.getContent() == null) {
// TODO: convert it to an Optional // TODO: convert it to an Optional
log.info("Decryption not possible because the Content was null"); log.info("Decryption not possible because the Content was null");
} }
@ -110,7 +115,7 @@ public class FSTDataProviderNUSTitle implements FSTDataProvider, HasNUSTitle {
return false; return false;
} }
Content c = entry.getContent(); Content c = entry.getContent().get();
NUSDataProvider dataProvider = title.getDataProvider(); NUSDataProvider dataProvider = title.getDataProvider();
@ -124,7 +129,7 @@ public class FSTDataProviderNUSTitle implements FSTDataProvider, HasNUSTitle {
} }
return nusdecryption.decryptStreams(in, outputStream, fileSize, fileOffset, c, h3HashedOpt); return nusdecryption.decryptStreams(in, outputStream, fileSize, fileOffset, c, h3HashedOpt);
} catch (CheckSumWrongException e) { } catch (CheckSumWrongException e) {
if (entry.getContent().isUNKNWNFlag1Set()) { if (c.isUNKNWNFlag1Set()) {
log.info("Hash doesn't match. But file is optional. Don't worry."); log.info("Hash doesn't match. But file is optional. Don't worry.");
} else { } else {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();