JNUSTool/src/de/mas/jnustool/NUSTitle.java
Maschell 0e03adf10f Added a lot of things!
Added a settings class! (no runtime configuration atm)
added decryption from files
added download to files
2016-02-02 22:55:33 +01:00

214 lines
6.0 KiB
Java

package de.mas.jnustool;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import de.mas.jnustool.util.Decryption;
import de.mas.jnustool.util.Downloader;
import de.mas.jnustool.util.ExitException;
import de.mas.jnustool.util.Settings;
public class NUSTitle {
private TitleMetaData tmd;
private TIK ticket;
private FST fst;
private long titleID;
public NUSTitle(long titleId,String key) throws ExitException{
setTitleID(titleId);
try {
if(Settings.downloadContent){
File f = new File(getContentPath());
if(!f.exists())f.mkdir();
}
if(Settings.downloadContent){
File f = new File(getContentPath() + "/" + "tmd");
if(!(f.exists() && Settings.skipExistingTMDTICKET)){
System.out.println("Downloading TMD");
Downloader.getInstance().downloadTMD(titleId,getContentPath());
}else{
System.out.println("Skipped download of TMD. Already existing");
}
f = new File(getContentPath() + "/" + "cetk");
if(!(f.exists() && Settings.skipExistingTMDTICKET)){
if(key == null){
System.out.print("Downloading Ticket");
Downloader.getInstance().downloadTicket(titleId,getContentPath());
}
}else{
System.out.println("Skipped download of ticket. Already existing");
}
}
if(Settings.useCachedFiles){
File f = new File(getContentPath() + "/" + "tmd");
if(f.exists()){
System.out.println("Using cached TMD.");
tmd = new TitleMetaData(f);
}else{
System.out.println("No cached TMD found.");
}
}
if(tmd == null){
if(Settings.downloadWhenCachedFilesMissingOrBroken){
if(Settings.useCachedFiles) System.out.println("Getting missing tmd from Server!");
tmd = new TitleMetaData(Downloader.getInstance().downloadTMDToByteArray(titleId));
}else{
System.out.println("Downloading of missing files is not enabled. Exiting");
throw new ExitException("TMD missing.");
}
}
if(key != null){
System.out.println("Using ticket from parameter.");
ticket = new TIK(key,titleId);
}else{
if(Settings.useCachedFiles){
File f = new File(getContentPath() + "/" + "cetk");
if(f.exists()){
System.out.println("Using cached cetk.");
ticket = new TIK(f,titleId);
}else{
System.out.println("No cached ticket found.");
}
}
if(ticket == null){
if(Settings.downloadWhenCachedFilesMissingOrBroken){
if(Settings.useCachedFiles) System.out.println("getting missing ticket");
ticket = new TIK(Downloader.getInstance().downloadTicketToByteArray(titleId),tmd.titleID);
}else{
System.out.println("Downloading of missing files is not enabled. Exiting");
throw new ExitException("Ticket missing.");
}
}
}
if(Settings.downloadContent){
File f = new File(getContentPath() + "/" + String.format("%08x", tmd.contents[0].ID) + ".app");
if(!(f.exists() && Settings.skipExistingFiles)){
System.out.println("Downloading FST (" + String.format("%08x", tmd.contents[0].ID) + ")");
Downloader.getInstance().downloadContent(titleId,tmd.contents[0].ID,getContentPath());
}else{
if(f.length() != tmd.contents[0].size){
if(Settings.downloadWhenCachedFilesMissingOrBroken){
System.out.println("FST already existing, but broken. Downloading it again.");
Downloader.getInstance().downloadContent(titleId,tmd.contents[0].ID,getContentPath());
}else{
System.out.println("FST already existing, but broken. No download allowed.");
throw new ExitException("FST missing.");
}
}else{
System.out.println("Skipped download of FST. Already existing");
}
}
}
Decryption decryption = new Decryption(ticket.getDecryptedKey(),0);
byte[] encryptedFST = null;
if(Settings.useCachedFiles){
String path = getContentPath() + "/" + String.format("%08x", tmd.contents[0].ID) + ".app";
File f = new File(path);
if(f.exists()){
System.out.println("Using cached FST");
Path file = Paths.get(path);
encryptedFST = Files.readAllBytes(file);
}else{
System.out.println("No cached FST (" + String.format("%08x", tmd.contents[0].ID) + ") found.");
}
}
if(encryptedFST == null){
if(Settings.downloadWhenCachedFilesMissingOrBroken){
if(Settings.useCachedFiles)System.out.println("Getting FST from server.");
encryptedFST = Downloader.getInstance().downloadContentToByteArray(titleId,tmd.contents[0].ID);
}else{
System.out.println("Downloading of missing files is not enabled. Exiting");
throw new ExitException("");
}
}
byte[] decryptedFST = decryption.decrypt(encryptedFST);
fst = new FST(decryptedFST,tmd);
tmd.setNUSTitle(this);
if(Settings.downloadContent){
tmd.downloadContents();
}
System.out.println("Total Size of Content Files: " + ((int)((getTotalContentSize()/1024.0/1024.0)*100))/100.0 +" MB");
System.out.println("Total Size of Decrypted Files: " + ((int)((fst.getTotalContentSizeInNUS()/1024.0/1024.0)*100))/100.0 +" MB");
System.out.println("Entries: " + fst.getTotalEntries());
System.out.println("Entries: " + fst.getFileCount());
System.out.println("Files in NUSTitle: " + fst.getFileCountInNUS());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public FST getFst() {
return fst;
}
public void setFst(FST fst) {
this.fst = fst;
}
public TitleMetaData getTmd() {
return tmd;
}
public void setTmd(TitleMetaData tmd) {
this.tmd = tmd;
}
public TIK getTicket() {
return ticket;
}
public void setTicket(TIK ticket) {
this.ticket = ticket;
}
public long getTotalContentSize() {
return tmd.getTotalContentSize();
}
public String getContentPath() {
return getContentPathPrefix() + String.format("%016X", getTitleID());
}
public String getContentPathPrefix() {
return "tmp_";
}
private long getTitleID() {
return titleID;
}
private void setTitleID(long titleId) {
this.titleID = titleId;
}
}