mirror of
https://github.com/Maschell/JNUSTool.git
synced 2025-01-05 21:08:18 +01:00
-Fixed creating title.cert
-Fixed downloading .h3 files -Improves logging
This commit is contained in:
parent
6e54967dd5
commit
6e595b9305
BIN
jar/JNUSTool.jar
BIN
jar/JNUSTool.jar
Binary file not shown.
BIN
release.zip
BIN
release.zip
Binary file not shown.
@ -47,12 +47,16 @@ public class Content {
|
||||
if(f.exists()){
|
||||
if(f.length() == size){
|
||||
Logger.log("Skipping Content: " + String.format("%08X", ID));
|
||||
progress.addCurrent((int) size);
|
||||
return;
|
||||
if(progress != null){
|
||||
progress.addCurrent((int) size);
|
||||
}
|
||||
}else{
|
||||
if(Settings.downloadWhenCachedFilesMissingOrBroken){
|
||||
Logger.log("Content " +String.format("%08X", ID) + " is broken. Downloading it again.");
|
||||
Downloader.getInstance().downloadContent(tmd.titleID,ID,tmpPath,progress);
|
||||
Logger.log("Content " +String.format("%08X", ID) + " has a different filesize and may be broken. Downloading it again.");
|
||||
new File(tmpPath).delete();
|
||||
Logger.log("Downloading Content: " + String.format("%08X", ID));
|
||||
Downloader.getInstance().downloadContent(tmd.titleID,ID,tmpPath,progress);
|
||||
|
||||
}else{
|
||||
if(Settings.skipBrokenFiles){
|
||||
Logger.log("Content " +String.format("%08X", ID) + " is broken. Ignoring it.");
|
||||
@ -63,11 +67,17 @@ public class Content {
|
||||
}
|
||||
}
|
||||
}else{
|
||||
Logger.log("Download Content: " + String.format("%08X", ID));
|
||||
Downloader.getInstance().downloadContent(tmd.titleID,ID,tmpPath,progress);
|
||||
Logger.log("Downloading Content: " + String.format("%08X", ID));
|
||||
Downloader.getInstance().downloadContent(tmd.titleID,ID,tmpPath,progress);
|
||||
}
|
||||
if ((type & 0x02) == 0x02){
|
||||
Downloader.getInstance().downloadContentH3(tmd.titleID,ID,tmpPath,null);
|
||||
f = new File(tmpPath + "/" + String.format("%08X", ID ) + ".h3");
|
||||
if(!f.exists()){
|
||||
Logger.log("Downloading H3: " + String.format("%08X.h3", ID));
|
||||
Downloader.getInstance().downloadContentH3(tmd.titleID,ID,tmpPath,null);
|
||||
}else{
|
||||
Logger.log("Skipping H3: " + String.format("%08X.h3", ID));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,12 @@ public class ContentDownloader implements Callable<Integer>
|
||||
|
||||
@Override
|
||||
public Integer call() throws Exception {
|
||||
this.content.download(progress);
|
||||
try{
|
||||
this.content.download(progress);
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -2,30 +2,35 @@ package de.mas.jnustool;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class FEntryDownloader implements Callable<Integer>
|
||||
{
|
||||
FEntry f;
|
||||
public class FEntryDownloader implements Callable<Integer>{
|
||||
FEntry f;
|
||||
Progress progress = null;
|
||||
|
||||
public void setTitle(FEntry f){
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
public FEntryDownloader(FEntry f,Progress fatherProgress){
|
||||
setTitle(f);
|
||||
createProgressListener(fatherProgress);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void createProgressListener(Progress fatherProgress) {
|
||||
if(fatherProgress != null){
|
||||
progress = new Progress();
|
||||
fatherProgress.add(progress);
|
||||
progress.addTotal(f.getFileLength());
|
||||
|
||||
progress.addTotal(f.getFileLength());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer call() throws Exception {
|
||||
f.downloadAndDecrypt(progress);
|
||||
try{
|
||||
f.downloadAndDecrypt(progress);
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -83,11 +83,7 @@ public class FST {
|
||||
private void parse(byte[] decrypteddata, TitleMetaData tmd) throws IOException {
|
||||
|
||||
if(!Arrays.equals(Arrays.copyOfRange(decrypteddata, 0, 3), new byte[]{0x46,0x53,0x54})){
|
||||
Logger.log(Util.ByteArrayToString(Arrays.copyOfRange(decrypteddata, 0, 3)));
|
||||
|
||||
System.err.println("Not a FST. Maybe a wrong key?");
|
||||
throw new IllegalArgumentException("File not a FST");
|
||||
|
||||
throw new IllegalArgumentException("Not a FST. Maybe a wrong key? Don't worry if you only want to download encrypted files!");
|
||||
}
|
||||
this.totalContentCount = Util.getIntFromBytes(decrypteddata, 8);
|
||||
int base_offset = 0x20+totalContentCount*0x20;
|
||||
|
@ -220,34 +220,63 @@ public class NUSTitle {
|
||||
}
|
||||
}
|
||||
|
||||
public void downloadEncryptedFiles(Progress progress) throws IOException {
|
||||
|
||||
public void downloadEncryptedFiles(Progress progress) throws IOException {
|
||||
Util.createSubfolder(getContentPath());
|
||||
|
||||
Downloader.getInstance().downloadTMD(titleID,version,getContentPath());
|
||||
Logger.log("---Downloading encrypted files---");
|
||||
Downloader.getInstance().downloadTMD(titleID,version,getContentPath());
|
||||
Logger.log("Downloaded title.tmd");
|
||||
tmd.downloadContents(progress);
|
||||
try{
|
||||
File f = new File(getContentPath() + "/" + "title.tik");
|
||||
if(!f.exists()){
|
||||
Logger.log("Downloaded content files");
|
||||
|
||||
File f = new File(getContentPath() + "/" + "title.tik");
|
||||
if(!f.exists()){
|
||||
try{
|
||||
Downloader.getInstance().downloadTicket(titleID,getContentPath());
|
||||
Logger.log("Downloaded title.tik");
|
||||
}catch(Exception e){
|
||||
Logger.log("!!!Missing file: title.tik. You need to add it manually before you can install this title.!!!");
|
||||
}
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(getContentPath() + "/title.cert");
|
||||
fos.write(ticket.cert0);
|
||||
fos.write(tmd.cert);
|
||||
fos.write(ticket.cert1);
|
||||
fos.close();
|
||||
if(version > 0 && Settings.DL_ALL_VERSIONS){
|
||||
fos = new FileOutputStream(getContentPath() + "/title.cert." + version);
|
||||
fos.write(ticket.cert0);
|
||||
fos.write(tmd.cert);
|
||||
fos.write(ticket.cert1);
|
||||
fos.close();
|
||||
}
|
||||
}else{
|
||||
Logger.log("Skipped title.tik");
|
||||
}
|
||||
|
||||
f = new File(getContentPath() + "/" + "title.tik");
|
||||
byte[] defaultcert = null;
|
||||
|
||||
Logger.log("Trying to create title.cert");
|
||||
if(!f.exists()){
|
||||
try{
|
||||
defaultcert = Util.getDefaultCert();
|
||||
}catch(Exception e){
|
||||
Logger.log("Failed to get missing cert from OSv10 cetk =(. Couldn't create title.cert");
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
Logger.log("Got missing cert from OSv10 title");
|
||||
}else{
|
||||
defaultcert = ticket.cert1;
|
||||
}
|
||||
|
||||
try{
|
||||
FileOutputStream fos = new FileOutputStream(getContentPath() + "/title.cert");
|
||||
fos.write(tmd.cert1);
|
||||
fos.write(tmd.cert2);
|
||||
fos.write(defaultcert);
|
||||
fos.close();
|
||||
if(version > 0 && Settings.DL_ALL_VERSIONS){
|
||||
fos = new FileOutputStream(getContentPath() + "/title.cert." + version);
|
||||
fos.write(tmd.cert1);
|
||||
fos.write(tmd.cert2);
|
||||
fos.write(defaultcert);
|
||||
fos.close();
|
||||
}
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
Logger.log("Error while creating ticket files.");
|
||||
}
|
||||
Logger.log("Created title.cert");
|
||||
Logger.log("---Successfully downloaded encrypted files---");
|
||||
}
|
||||
|
||||
public NUSTitleInformation readMeta(InputStream bis) {
|
||||
|
@ -25,7 +25,7 @@ public class Starter {
|
||||
private static String updateCSVPath;
|
||||
|
||||
public static void main(String[] args) {
|
||||
Logger.log("JNUSTool 0.0.8 - alpha - by Maschell");
|
||||
Logger.log("JNUSTool 0.0.8b - alpha - by Maschell");
|
||||
Logger.log("");
|
||||
try {
|
||||
readConfig();
|
||||
|
@ -37,7 +37,8 @@ public class TitleMetaData {
|
||||
byte[] SHA2 = new byte[32]; // 0x1E4
|
||||
ContentInfo[] contentInfos = new ContentInfo[64]; // 0x1E4
|
||||
Content[] contents; // 0x1E4
|
||||
byte[] cert = new byte[0x300];
|
||||
byte[] cert1 = new byte[0x400];
|
||||
byte[] cert2 = new byte[0x300];
|
||||
|
||||
private NUSTitle nus;
|
||||
|
||||
@ -130,8 +131,11 @@ public class TitleMetaData {
|
||||
this.contents[i] = new Content(ID,index,type,size,buffer,this);
|
||||
}
|
||||
|
||||
if(f.read(cert,0, 0x300) != 0x300){
|
||||
Logger.log("Error reading TMD cert");
|
||||
if(f.read(cert2,0, 0x300) != 0x300){
|
||||
Logger.log("Error reading TMD cert2");
|
||||
}
|
||||
if(f.read(cert1,0, 0x400) != 0x400){
|
||||
Logger.log("Error reading TMD cert1");
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
@ -155,7 +159,8 @@ public class TitleMetaData {
|
||||
sb.append("contentCount: " + contentCount +"\n");
|
||||
sb.append("bootIndex: " + bootIndex +"\n");
|
||||
sb.append("SHA2: " + Util.ByteArrayToString(SHA2) +"\n");
|
||||
sb.append("cert: " + Util.ByteArrayToString(cert) +"\n");
|
||||
sb.append("cert1: " + Util.ByteArrayToString(cert1) +"\n");
|
||||
sb.append("cert2: " + Util.ByteArrayToString(cert2) +"\n");
|
||||
sb.append("contentInfos: \n");
|
||||
|
||||
for(int i = 0; i<contents.length-1;i++){
|
||||
|
@ -22,7 +22,6 @@ public class Util {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
public static String ByteArrayToString(byte[] ba)
|
||||
{
|
||||
if(ba == null) return null;
|
||||
@ -133,4 +132,9 @@ public class Util {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] getDefaultCert() throws IOException {
|
||||
byte [] ticket = Downloader.getInstance().downloadTicketToByteArray(0x000500101000400AL); //Downloading cetk from OSv10
|
||||
return Arrays.copyOfRange(ticket, 0x350, 0x350+0x300);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user