Add support for titles without FST.

This commit is contained in:
Maschell 2019-04-14 14:50:01 +02:00
parent 1698acb3f6
commit 151ad6e2a6
3 changed files with 41 additions and 2 deletions

View File

@ -27,6 +27,9 @@ import de.mas.wiiu.jnus.entities.TMD;
import de.mas.wiiu.jnus.entities.Ticket;
import de.mas.wiiu.jnus.entities.content.Content;
import de.mas.wiiu.jnus.entities.fst.FST;
import de.mas.wiiu.jnus.entities.fst.FSTEntry;
import de.mas.wiiu.jnus.implementations.FSTDataProviderNUSTitle;
import de.mas.wiiu.jnus.interfaces.FSTDataProvider;
import de.mas.wiiu.jnus.interfaces.NUSDataProvider;
import de.mas.wiiu.jnus.utils.StreamUtils;
import de.mas.wiiu.jnus.utils.cryptography.AESDecryption;
@ -63,12 +66,22 @@ public class NUSTitleLoader {
}
result.setTicket(ticket);
// If we have just content, we don't have a FST.
if (tmd.getAllContents().size() == 1) {
// The only way to check if the key is right, is by trying to decrypt the whole thing.
FSTDataProvider dp = new FSTDataProviderNUSTitle(result);
for (FSTEntry children : dp.getRoot().getChildren()) {
dp.readFile(children);
}
return result;
}
// If we have more than one content, the index 0 is the FST.
Content fstContent = tmd.getContentByIndex(0);
InputStream fstContentEncryptedStream = dataProvider.getInputStreamFromContent(fstContent, 0, Optional.of(fstContent.getEncryptedFileSize()));
byte[] fstBytes = StreamUtils.getBytesFromStream(fstContentEncryptedStream, (int) fstContent.getEncryptedFileSize());
if (fstContent.isEncrypted()) {
AESDecryption aesDecryption = new AESDecryption(ticket.getDecryptedKey(), new byte[0x10]);
if (fstBytes.length % 0x10 != 0) {

View File

@ -88,6 +88,16 @@ public class FSTEntry {
param.setDir(true);
return new FSTEntry(param);
}
public static FSTEntry createFSTEntry(FSTEntry parent, String filename, Content content) {
FSTEntryParam param = new FSTEntryParam();
param.setFileNameSupplier(() -> filename);
param.setFileSize(content.getDecryptedFileSize());
param.setContent(content);
param.setDir(false);
param.setParent(parent);
return new FSTEntry(param);
}
public String getFilename() {
if (filename == null) {

View File

@ -21,9 +21,11 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Optional;
import java.util.stream.Collectors;
import de.mas.wiiu.jnus.NUSTitle;
import de.mas.wiiu.jnus.entities.content.Content;
import de.mas.wiiu.jnus.entities.fst.FST;
import de.mas.wiiu.jnus.entities.fst.FSTEntry;
import de.mas.wiiu.jnus.interfaces.FSTDataProvider;
import de.mas.wiiu.jnus.interfaces.HasNUSTitle;
@ -38,16 +40,30 @@ import lombok.extern.java.Log;
@Log
public class FSTDataProviderNUSTitle implements FSTDataProvider, HasNUSTitle {
private final NUSTitle title;
private final FSTEntry rootEntry;
@Getter @Setter private String name;
public FSTDataProviderNUSTitle(NUSTitle title) {
this.title = title;
this.name = String.format("%016X", title.getTMD().getTitleID());
FST fst = title.getFST();
if (fst != null) {
rootEntry = title.getFST().getRoot();
} else if (title.getTMD().getContentCount() == 1) {
// If the tmd has only one content file, it has not FST. We have to create our own FST.
Content c = title.getTMD().getAllContents().values().stream().collect(Collectors.toList()).get(0);
FSTEntry root = FSTEntry.getRootFSTEntry();
FSTEntry.createFSTEntry(root, "data.bin", c); // Will add this title root.
rootEntry = root;
} else {
rootEntry = null;
}
}
@Override
public FSTEntry getRoot() {
return title.getFST().getRoot();
return rootEntry;
}
@Override