The size in the FSTDataProvider and NUSDataProvider functions are not Optional anymore

This commit is contained in:
Maschell 2019-04-26 13:44:24 +02:00
parent 9cb2eaf3be
commit 69e0c8b36a
13 changed files with 43 additions and 58 deletions

View File

@ -71,7 +71,7 @@ public class NUSTitleLoader {
// If we have more than one content, the index 0 is the FST. // If we have more than one content, the index 0 is the FST.
Content fstContent = result.getTMD().getContentByIndex(0); Content fstContent = result.getTMD().getContentByIndex(0);
InputStream fstContentEncryptedStream = dataProvider.getInputStreamFromContent(fstContent, 0, Optional.of(fstContent.getEncryptedFileSize())); InputStream fstContentEncryptedStream = dataProvider.getInputStreamFromContent(fstContent);
byte[] fstBytes = StreamUtils.getBytesFromStream(fstContentEncryptedStream, (int) fstContent.getEncryptedFileSize()); byte[] fstBytes = StreamUtils.getBytesFromStream(fstContentEncryptedStream, (int) fstContent.getEncryptedFileSize());

View File

@ -65,17 +65,15 @@ public class FSTDataProviderNUSTitle implements FSTDataProvider, HasNUSTitle {
} }
@Override @Override
public boolean readFileToStream(OutputStream out, FSTEntry entry, long offset, Optional<Long> size) throws IOException { public boolean readFileToStream(OutputStream out, FSTEntry entry, long offset, long size) throws IOException {
long usedSize = size.orElse(entry.getFileSize());
try { try {
return decryptFSTEntryToStream(entry, out, offset, usedSize); return decryptFSTEntryToStream(entry, out, offset, size);
} catch (CheckSumWrongException | NoSuchAlgorithmException e) { } catch (CheckSumWrongException | NoSuchAlgorithmException e) {
throw new IOException(e); throw new IOException(e);
} }
} }
private boolean decryptFSTEntryToStream(FSTEntry entry, OutputStream outputStream, long offset, long fileSize) private boolean decryptFSTEntryToStream(FSTEntry entry, OutputStream outputStream, long offset, long size)
throws IOException, CheckSumWrongException, NoSuchAlgorithmException { throws IOException, CheckSumWrongException, NoSuchAlgorithmException {
if (entry.isNotInPackage() || !title.getTicket().isPresent()) { if (entry.isNotInPackage() || !title.getTicket().isPresent()) {
if (!title.getTicket().isPresent()) { if (!title.getTicket().isPresent()) {
@ -93,15 +91,15 @@ public class FSTDataProviderNUSTitle implements FSTDataProvider, HasNUSTitle {
long streamOffset = payloadOffset; long streamOffset = payloadOffset;
Optional<Long> readFilesize = Optional.empty(); long streamFilesize = size;
if (c.isHashed()) { if (c.isHashed()) {
streamOffset = (payloadOffset / 0xFC00) * 0x10000; streamOffset = (payloadOffset / 0xFC00) * 0x10000;
long offsetInBlock = payloadOffset - ((streamOffset / 0x10000) * 0xFC00); long offsetInBlock = payloadOffset - ((streamOffset / 0x10000) * 0xFC00);
if (offsetInBlock + fileSize < 0xFC00) { if (offsetInBlock + size < 0xFC00) {
readFilesize = Optional.of(0x10000L); streamFilesize = 0x10000L;
} else { } else {
long curVal = 0x10000; long curVal = 0x10000;
long missing = (fileSize - (0xFC00 - offsetInBlock)); long missing = (size - (0xFC00 - offsetInBlock));
curVal += (missing / 0xFC00) * 0x10000; curVal += (missing / 0xFC00) * 0x10000;
@ -109,7 +107,7 @@ public class FSTDataProviderNUSTitle implements FSTDataProvider, HasNUSTitle {
curVal += 0x10000; curVal += 0x10000;
} }
readFilesize = Optional.of(curVal); streamFilesize = curVal;
} }
} else { } else {
streamOffset = (payloadOffset / 0x8000) * 0x8000; streamOffset = (payloadOffset / 0x8000) * 0x8000;
@ -117,11 +115,12 @@ public class FSTDataProviderNUSTitle implements FSTDataProvider, HasNUSTitle {
if (payloadOffset >= 0x8000 && payloadOffset % 0x8000 == 0) { if (payloadOffset >= 0x8000 && payloadOffset % 0x8000 == 0) {
streamOffset -= 16; streamOffset -= 16;
} }
streamFilesize = c.getEncryptedFileSize();
} }
NUSDataProvider dataProvider = title.getDataProvider(); NUSDataProvider dataProvider = title.getDataProvider();
InputStream in = dataProvider.getInputStreamFromContent(c, streamOffset, readFilesize); InputStream in = dataProvider.getInputStreamFromContent(c, streamOffset, streamFilesize);
try { try {
NUSDecryption nusdecryption = new NUSDecryption(title.getTicket().get()); NUSDecryption nusdecryption = new NUSDecryption(title.getTicket().get());

View File

@ -1,5 +1,3 @@
package de.mas.wiiu.jnus.implementations;
/**************************************************************************** /****************************************************************************
* Copyright (C) 2016-2019 Maschell * Copyright (C) 2016-2019 Maschell
* *
@ -16,10 +14,11 @@ package de.mas.wiiu.jnus.implementations;
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
package de.mas.wiiu.jnus.implementations;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Optional;
import de.mas.wiiu.jnus.entities.content.ContentFSTInfo; import de.mas.wiiu.jnus.entities.content.ContentFSTInfo;
import de.mas.wiiu.jnus.entities.fst.FSTEntry; import de.mas.wiiu.jnus.entities.fst.FSTEntry;
@ -64,24 +63,22 @@ public class FSTDataProviderWUDDataPartition implements FSTDataProvider {
} }
@Override @Override
public boolean readFileToStream(OutputStream out, FSTEntry entry, long offset, Optional<Long> size) throws IOException { public boolean readFileToStream(OutputStream out, FSTEntry entry, long offset, long size) throws IOException {
ContentFSTInfo info = FSTUtils.getFSTInfoForContent(partition.getFST(), entry.getContentIndex()) ContentFSTInfo info = FSTUtils.getFSTInfoForContent(partition.getFST(), entry.getContentIndex())
.orElseThrow(() -> new IOException("Failed to find FSTInfo")); .orElseThrow(() -> new IOException("Failed to find FSTInfo"));
long usedSize = size.orElse(entry.getFileSize());
if (titleKey == null) { if (titleKey == null) {
return discReader.readEncryptedToStream(out, partition.getPartitionOffset() + info.getOffset() + entry.getFileOffset() + offset, usedSize); return discReader.readEncryptedToStream(out, partition.getPartitionOffset() + info.getOffset() + entry.getFileOffset() + offset, size);
} }
return discReader.readDecryptedToOutputStream(out, partition.getPartitionOffset() + info.getOffset(), entry.getFileOffset() + offset, usedSize, return discReader.readDecryptedToOutputStream(out, partition.getPartitionOffset() + info.getOffset(), entry.getFileOffset() + offset, size, titleKey,
titleKey, null, false); null, false);
} }
@Override @Override
public InputStream readFileAsStream(FSTEntry entry, long offset, Optional<Long> size) throws IOException { public InputStream readFileAsStream(FSTEntry entry, long offset, long size) throws IOException {
if (titleKey == null) { if (titleKey == null) {
ContentFSTInfo info = FSTUtils.getFSTInfoForContent(partition.getFST(), entry.getContentIndex()) ContentFSTInfo info = FSTUtils.getFSTInfoForContent(partition.getFST(), entry.getContentIndex())
.orElseThrow(() -> new IOException("Failed to find FSTInfo")); .orElseThrow(() -> new IOException("Failed to find FSTInfo"));
long usedSize = size.orElse(entry.getFileSize()); return discReader.readEncryptedToStream(partition.getPartitionOffset() + info.getOffset() + entry.getFileOffset() + offset, size);
return discReader.readEncryptedToStream(partition.getPartitionOffset() + info.getOffset() + entry.getFileOffset() + offset, usedSize);
} }
return FSTDataProvider.super.readFileAsStream(entry, offset, size); return FSTDataProvider.super.readFileAsStream(entry, offset, size);

View File

@ -44,7 +44,7 @@ public class NUSDataProviderFST implements NUSDataProvider {
} }
@Override @Override
public InputStream getInputStreamFromContent(Content content, long offset, Optional<Long> size) throws IOException { public InputStream getInputStreamFromContent(Content content, long offset, long size) throws IOException {
String filename = content.getFilename(); String filename = content.getFilename();
Optional<FSTEntry> contentFileOpt = FSTUtils.getChildOfDirectory(base, filename); Optional<FSTEntry> contentFileOpt = FSTUtils.getChildOfDirectory(base, filename);
FSTEntry contentFile = contentFileOpt.orElseThrow(() -> new FileNotFoundException(filename + " was not found.")); FSTEntry contentFile = contentFileOpt.orElseThrow(() -> new FileNotFoundException(filename + " was not found."));

View File

@ -45,7 +45,7 @@ public final class NUSDataProviderLocal implements NUSDataProvider {
} }
@Override @Override
public InputStream getInputStreamFromContent(Content content, long offset, Optional<Long> size) throws IOException { public InputStream getInputStreamFromContent(Content content, long offset, long size) throws IOException {
File filepath = FileUtils.getFileIgnoringFilenameCases(getLocalPath(), content.getFilename()); File filepath = FileUtils.getFileIgnoringFilenameCases(getLocalPath(), content.getFilename());
if (filepath == null || !filepath.exists()) { if (filepath == null || !filepath.exists()) {
String errormsg = "Couldn't open \"" + getLocalPath() + File.separator + content.getFilename() + "\", file does not exist"; String errormsg = "Couldn't open \"" + getLocalPath() + File.separator + content.getFilename() + "\", file does not exist";

View File

@ -48,7 +48,7 @@ public class NUSDataProviderLocalBackup implements NUSDataProvider {
} }
@Override @Override
public InputStream getInputStreamFromContent(Content content, long offset, Optional<Long> size) throws IOException { public InputStream getInputStreamFromContent(Content content, long offset, long size) throws IOException {
File filepath = new File(getFilePathOnDisk(content)); File filepath = new File(getFilePathOnDisk(content));
if (!filepath.exists()) { if (!filepath.exists()) {
throw new FileNotFoundException(filepath.getAbsolutePath() + " was not found."); throw new FileNotFoundException(filepath.getAbsolutePath() + " was not found.");

View File

@ -37,7 +37,7 @@ public class NUSDataProviderRemote implements NUSDataProvider, Parallelizable {
} }
@Override @Override
public InputStream getInputStreamFromContent(Content content, long fileOffsetBlock, Optional<Long> size) throws IOException { public InputStream getInputStreamFromContent(Content content, long fileOffsetBlock, long size) throws IOException {
NUSDownloadService downloadService = NUSDownloadService.getDefaultInstance(); NUSDownloadService downloadService = NUSDownloadService.getDefaultInstance();
return downloadService.getInputStreamForURL(getRemoteURL(content), fileOffsetBlock, size); return downloadService.getInputStreamForURL(getRemoteURL(content), fileOffsetBlock, size);
} }

View File

@ -61,14 +61,11 @@ public class NUSDataProviderWUD implements NUSDataProvider {
} }
@Override @Override
public InputStream getInputStreamFromContent(Content content, long fileOffsetBlock, Optional<Long> size) throws IOException { public InputStream getInputStreamFromContent(Content content, long fileOffsetBlock, long size) throws IOException {
WUDDiscReader discReader = getDiscReader(); WUDDiscReader discReader = getDiscReader();
long offset = getOffsetInWUD(content) + fileOffsetBlock; long offset = getOffsetInWUD(content) + fileOffsetBlock;
long usedSize = content.getEncryptedFileSize() - fileOffsetBlock;
if (size.isPresent()) { return discReader.readEncryptedToStream(offset, size);
usedSize = size.get();
}
return discReader.readEncryptedToStream(offset, usedSize);
} }
@Override @Override

View File

@ -44,7 +44,7 @@ public class NUSDataProviderWoomy implements NUSDataProvider {
} }
@Override @Override
public InputStream getInputStreamFromContent(@NonNull Content content, long fileOffsetBlock, Optional<Long> size) throws IOException { public InputStream getInputStreamFromContent(@NonNull Content content, long fileOffsetBlock, long size) throws IOException {
WoomyZipFile zipFile = getSharedWoomyZipFile(); WoomyZipFile zipFile = getSharedWoomyZipFile();
ZipEntry entry = getWoomyInfo().getContentFiles().get(content.getFilename().toLowerCase()); ZipEntry entry = getWoomyInfo().getContentFiles().get(content.getFilename().toLowerCase());
if (entry == null) { if (entry == null) {

View File

@ -21,7 +21,6 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.PipedOutputStream; import java.io.PipedOutputStream;
import java.util.Optional;
import de.mas.wiiu.jnus.entities.fst.FSTEntry; import de.mas.wiiu.jnus.entities.fst.FSTEntry;
import de.mas.wiiu.jnus.utils.PipedInputStreamWithException; import de.mas.wiiu.jnus.utils.PipedInputStreamWithException;
@ -38,16 +37,16 @@ public interface FSTDataProvider {
default public byte[] readFile(FSTEntry entry, long offset, long size) throws IOException { default public byte[] readFile(FSTEntry entry, long offset, long size) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
readFileToStream(out, entry, offset, Optional.of(size)); readFileToStream(out, entry, offset, size);
return out.toByteArray(); return out.toByteArray();
} }
default public InputStream readFileAsStream(FSTEntry entry) throws IOException { default public InputStream readFileAsStream(FSTEntry entry) throws IOException {
return readFileAsStream(entry, 0, Optional.empty()); return readFileAsStream(entry, 0, entry.getFileSize());
} }
default public InputStream readFileAsStream(FSTEntry entry, long offset, Optional<Long> size) throws IOException { default public InputStream readFileAsStream(FSTEntry entry, long offset, long size) throws IOException {
PipedOutputStream out = new PipedOutputStream(); PipedOutputStream out = new PipedOutputStream();
PipedInputStreamWithException in = new PipedInputStreamWithException(out, 0x10000); PipedInputStreamWithException in = new PipedInputStreamWithException(out, 0x10000);
@ -64,9 +63,9 @@ public interface FSTDataProvider {
} }
default public boolean readFileToStream(OutputStream out, FSTEntry entry, long offset) throws IOException { default public boolean readFileToStream(OutputStream out, FSTEntry entry, long offset) throws IOException {
return readFileToStream(out, entry, offset, Optional.empty()); return readFileToStream(out, entry, offset, entry.getFileSize());
} }
public boolean readFileToStream(OutputStream out, FSTEntry entry, long offset, Optional<Long> size) throws IOException; public boolean readFileToStream(OutputStream out, FSTEntry entry, long offset, long size) throws IOException;
} }

View File

@ -28,22 +28,19 @@ import de.mas.wiiu.jnus.utils.StreamUtils;
public interface NUSDataProvider { public interface NUSDataProvider {
default public byte[] getChunkFromContent(Content content, long offset, int size) throws IOException { default public byte[] getChunkFromContent(Content content, long offset, int size) throws IOException {
return StreamUtils.getBytesFromStream(getInputStreamFromContent(content, offset, Optional.of((long) size)), size); return StreamUtils.getBytesFromStream(getInputStreamFromContent(content, offset, size), size);
} }
/** default public InputStream getInputStreamFromContent(Content content) throws IOException {
* return getInputStreamFromContent(content, 0);
* @param content }
* @param offset
* @return
* @throws IOException
*/
public InputStream getInputStreamFromContent(Content content, long offset, Optional<Long> size) throws IOException;
default public InputStream getInputStreamFromContent(Content content, long offset) throws IOException { default public InputStream getInputStreamFromContent(Content content, long offset) throws IOException {
return getInputStreamFromContent(content, offset, Optional.empty()); return getInputStreamFromContent(content, offset, content.getEncryptedFileSize() - offset);
} }
public InputStream getInputStreamFromContent(Content content, long offset, long size) throws IOException;
public Optional<byte[]> getContentH3Hash(Content content) throws IOException; public Optional<byte[]> getContentH3Hash(Content content) throws IOException;
public Optional<byte[]> getRawTMD() throws IOException; public Optional<byte[]> getRawTMD() throws IOException;

View File

@ -133,7 +133,7 @@ public class DataProviderUtils {
} }
Utils.createDir(outputFolder); Utils.createDir(outputFolder);
InputStream inputStream = dataProvider.getInputStreamFromContent(content, 0); InputStream inputStream = dataProvider.getInputStreamFromContent(content);
if (inputStream == null) { if (inputStream == null) {
log.warning(content.getFilename() + " Couldn't save encrypted content. Input stream was null"); log.warning(content.getFilename() + " Couldn't save encrypted content. Input stream was null");
return; return;

View File

@ -83,15 +83,11 @@ public final class NUSDownloadService extends Downloader {
return downloadFileToByteArray(URL); return downloadFileToByteArray(URL);
} }
public InputStream getInputStream(String URL, long offset, Optional<Long> size) throws IOException { public InputStream getInputStream(String URL, long offset, long size) throws IOException {
URL url_obj = new URL(URL); URL url_obj = new URL(URL);
HttpURLConnection connection = (HttpURLConnection) url_obj.openConnection(); HttpURLConnection connection = (HttpURLConnection) url_obj.openConnection();
connection.setRequestProperty("User-Agent", Settings.USER_AGENT); connection.setRequestProperty("User-Agent", Settings.USER_AGENT);
String sizeString = ""; connection.setRequestProperty("Range", "bytes=" + offset + "-" + Long.toString(size));
if (size.isPresent()) {
sizeString = Long.toString(size.get());
}
connection.setRequestProperty("Range", "bytes=" + offset + "-" + sizeString);
try { try {
connection.connect(); connection.connect();
} catch (Exception e) { } catch (Exception e) {
@ -101,7 +97,7 @@ public final class NUSDownloadService extends Downloader {
return connection.getInputStream(); return connection.getInputStream();
} }
public InputStream getInputStreamForURL(String url, long offset, Optional<Long> size) throws IOException { public InputStream getInputStreamForURL(String url, long offset, Long size) throws IOException {
String URL = URL_BASE + "/" + url; String URL = URL_BASE + "/" + url;
return getInputStream(URL, offset, size); return getInputStream(URL, offset, size);