2016-02-02 19:38:53 +01:00
|
|
|
package de.mas.jnustool;
|
|
|
|
|
2016-03-02 19:48:04 +01:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
|
|
|
|
|
|
import de.mas.jnustool.util.Downloader;
|
|
|
|
import de.mas.jnustool.util.Settings;
|
2016-02-02 19:38:53 +01:00
|
|
|
import de.mas.jnustool.util.Util;
|
2016-04-11 12:48:21 +02:00
|
|
|
/**
|
|
|
|
* Content file of the NUSTitle. Holds the encrpyted files
|
|
|
|
*
|
|
|
|
* Thanks to crediar for the offsets in CDecrypt
|
|
|
|
* @author Maschell
|
|
|
|
*
|
|
|
|
*/
|
2016-02-01 20:54:01 +01:00
|
|
|
public class Content {
|
2016-04-11 12:48:21 +02:00
|
|
|
/**
|
|
|
|
* TODO: make it simpler
|
|
|
|
*/
|
2016-02-01 20:54:01 +01:00
|
|
|
int ID; // 0 0xB04
|
|
|
|
short index; // 4 0xB08
|
|
|
|
short type; // 6 0xB0A
|
|
|
|
long size; // 8 0xB0C
|
|
|
|
byte[] SHA2 = new byte[32]; // 16 0xB14
|
2016-03-02 19:48:04 +01:00
|
|
|
TitleMetaData tmd;
|
2016-04-11 12:48:21 +02:00
|
|
|
AtomicInteger error_output_done = new AtomicInteger(0);
|
2016-02-01 20:54:01 +01:00
|
|
|
|
2016-03-02 19:48:04 +01:00
|
|
|
public Content(int ID, short index, short type, long size, byte[] SHA2,TitleMetaData tmd) {
|
2016-02-01 20:54:01 +01:00
|
|
|
this.ID = ID;
|
|
|
|
this.index = index;
|
|
|
|
this.type = type;
|
|
|
|
this.size = size;
|
|
|
|
this.SHA2 = SHA2;
|
2016-03-02 19:48:04 +01:00
|
|
|
this.tmd = tmd;
|
2016-02-01 20:54:01 +01:00
|
|
|
}
|
2016-03-02 19:48:04 +01:00
|
|
|
|
2016-04-11 12:48:21 +02:00
|
|
|
/**
|
|
|
|
* Downloads the content files (encrypted)
|
|
|
|
* @param progress: A progress object can be used to get informations of the progress. Will be ignored when null is used.
|
|
|
|
* @throws IOException
|
|
|
|
*/
|
|
|
|
public void download(Progress progress) throws IOException{
|
2016-03-02 19:48:04 +01:00
|
|
|
String tmpPath = tmd.getContentPath();
|
2016-04-11 12:48:21 +02:00
|
|
|
|
2016-03-02 19:48:04 +01:00
|
|
|
File f = new File(tmpPath + "/" + String.format("%08X", ID ) + ".app");
|
|
|
|
if(f.exists()){
|
|
|
|
if(f.length() == size){
|
|
|
|
Logger.log("Skipping Content: " + String.format("%08X", ID));
|
|
|
|
progress.addCurrent((int) size);
|
2016-04-11 12:48:21 +02:00
|
|
|
return;
|
2016-03-02 19:48:04 +01:00
|
|
|
}else{
|
2016-04-11 12:48:21 +02:00
|
|
|
if(Settings.downloadWhenCachedFilesMissingOrBroken){
|
2016-03-02 19:48:04 +01:00
|
|
|
Logger.log("Content " +String.format("%08X", ID) + " is broken. Downloading it again.");
|
|
|
|
Downloader.getInstance().downloadContent(tmd.titleID,ID,tmpPath,progress);
|
|
|
|
}else{
|
|
|
|
if(Settings.skipBrokenFiles){
|
|
|
|
Logger.log("Content " +String.format("%08X", ID) + " is broken. Ignoring it.");
|
|
|
|
}else{
|
|
|
|
Logger.log("Content " +String.format("%08X", ID) + " is broken. Downloading not allowed.");
|
|
|
|
System.exit(2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
Logger.log("Download Content: " + String.format("%08X", ID));
|
|
|
|
Downloader.getInstance().downloadContent(tmd.titleID,ID,tmpPath,progress);
|
|
|
|
}
|
2016-04-11 12:48:21 +02:00
|
|
|
if ((type & 0x02) == 0x02){
|
|
|
|
Downloader.getInstance().downloadContentH3(tmd.titleID,ID,tmpPath,null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString(){
|
|
|
|
return "ID: " + ID +" index: " + index + " type: " + type + " size: " + size + " SHA2: " + Util.ByteArrayToString(SHA2);
|
2016-03-02 19:48:04 +01:00
|
|
|
}
|
2016-02-01 20:54:01 +01:00
|
|
|
}
|