mirror of
https://github.com/Maschell/JNUSTool.git
synced 2025-01-05 21:08:18 +01:00
Added multi selection and meta downloader
-added a progress function -added a meta download button -added mutli selection of titles -fixed byte[] to String function
This commit is contained in:
parent
8a597aa147
commit
626104209d
3
.gitignore
vendored
3
.gitignore
vendored
@ -50,4 +50,5 @@ bin
|
||||
/config
|
||||
/tmp*
|
||||
UpdateGrabber.java
|
||||
updatetitles.csv
|
||||
updatetitles.csv
|
||||
src/de/mas/jnustool/StarterPRIATE.java
|
BIN
jar/JNUSTool.jar
BIN
jar/JNUSTool.jar
Binary file not shown.
@ -155,13 +155,16 @@ public class FEntry {
|
||||
return folder;
|
||||
}
|
||||
|
||||
public void downloadAndDecrypt() {
|
||||
public void downloadAndDecrypt(Progress progress) {
|
||||
createFolder();
|
||||
long titleID = getTitleID();
|
||||
File f = new File(String.format("%016X", titleID) +"/" +getFullPath().substring(1, getFullPath().length()));
|
||||
if(f.exists()){
|
||||
if(f.length() == getFileLength()){
|
||||
Logger.log("Skipping: " + String.format("%8.2f MB ",getFileLength()/1024.0/1024.0) + getFullPath());
|
||||
if(progress != null){
|
||||
progress.finish();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -172,6 +175,7 @@ public class FEntry {
|
||||
if(f.length() == fst.getTmd().contents[this.getContentID()].size){
|
||||
Logger.log("Decrypting: " + String.format("%8.2f MB ", getFileLength()/1024.0/1024.0) + getFullPath());
|
||||
Decryption decrypt = new Decryption(fst.getTmd().getNUSTitle().getTicket());
|
||||
decrypt.setProgressListener(progress);
|
||||
decrypt.decrypt(this,getDownloadPath());
|
||||
return;
|
||||
}else{
|
||||
@ -203,7 +207,7 @@ public class FEntry {
|
||||
}
|
||||
}
|
||||
Logger.log("Downloading: " + String.format("%8.2f MB ", getFileLength()/1024.0/1024.0) + getFullPath());
|
||||
Downloader.getInstance().downloadAndDecrypt(this);
|
||||
Downloader.getInstance().downloadAndDecrypt(this,progress);
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
|
@ -5,17 +5,26 @@ import java.util.concurrent.Callable;
|
||||
public class FEntryDownloader implements Callable<Integer>
|
||||
{
|
||||
FEntry f;
|
||||
Progress progress = null;
|
||||
public void setTitle(FEntry f){
|
||||
this.f = f;
|
||||
}
|
||||
public FEntryDownloader(FEntry f){
|
||||
public FEntryDownloader(FEntry f,Progress fatherProgress){
|
||||
setTitle(f);
|
||||
createProgressListener(fatherProgress);
|
||||
}
|
||||
|
||||
|
||||
private void createProgressListener(Progress fatherProgress) {
|
||||
if(fatherProgress != null){
|
||||
progress = new Progress();
|
||||
progress.setTotal(f.getFileLength());
|
||||
fatherProgress.add(progress);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Integer call() throws Exception {
|
||||
f.downloadAndDecrypt();
|
||||
f.downloadAndDecrypt(progress);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ public class FST {
|
||||
int totalEntries = 0;
|
||||
int dirEntries = 0;
|
||||
public FEntry metaFENtry;
|
||||
public List<FEntry> metaFolder = new ArrayList<>();
|
||||
private Directory FSTDirectory = new Directory("root");
|
||||
|
||||
private Directory contentDirectory = new Directory("root");
|
||||
@ -165,6 +166,8 @@ public class FST {
|
||||
this.totalContentSize += fileLength;
|
||||
if(in_nus_title)this.totalContentSizeInNUS += fileLength;
|
||||
|
||||
boolean metafolder = false;
|
||||
|
||||
List<String> pathList = new ArrayList<>();
|
||||
//getting the full path of entry
|
||||
if(dir)
|
||||
@ -180,7 +183,7 @@ public class FST {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int k = 0;
|
||||
int nameoffoff,nameoff_entrypath;
|
||||
|
||||
|
||||
for( j=0; j<level; ++j )
|
||||
{
|
||||
nameoffoff = Util.getIntFromBytes(decrypteddata,base_offset+Entry[j]*0x10);
|
||||
@ -188,9 +191,11 @@ public class FST {
|
||||
nameoff_entrypath = nameOff + nameoffoff;
|
||||
while(decrypteddata[nameoff_entrypath + k] != 0){k++;}
|
||||
String tmpname = new String(Arrays.copyOfRange(decrypteddata,nameoff_entrypath, nameoff_entrypath + k));
|
||||
if(j==1 && tmpname.equals("meta")){
|
||||
metafolder = true;
|
||||
}
|
||||
if(!tmpname.equals("")){
|
||||
pathList.add(tmpname);
|
||||
|
||||
pathList.add(tmpname);
|
||||
}
|
||||
|
||||
sb.append(tmpname);
|
||||
@ -205,6 +210,9 @@ public class FST {
|
||||
if(filename.equals("meta.xml")){
|
||||
metaFENtry = tmp;
|
||||
}
|
||||
if(metafolder){
|
||||
metaFolder.add(tmp);
|
||||
}
|
||||
//Logger.log(fileEntries.get(i));
|
||||
}
|
||||
|
||||
@ -231,6 +239,10 @@ public class FST {
|
||||
this.totalContentSizeInNUS = totalContentSizeInNUS;
|
||||
}
|
||||
|
||||
public List<FEntry> getMetaFolder() {
|
||||
return metaFolder;
|
||||
}
|
||||
|
||||
|
||||
public List<FEntry> getFileEntries() {
|
||||
return fileEntries;
|
||||
|
@ -1,5 +1,8 @@
|
||||
package de.mas.jnustool;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import de.mas.jnustool.gui.NUSGUI;
|
||||
|
||||
public class Logger {
|
||||
@ -7,7 +10,12 @@ public class Logger {
|
||||
public static void log(String string) {
|
||||
NUSGUI.output.append(string + "\n");
|
||||
NUSGUI.output.setCaretPosition(NUSGUI.output.getDocument().getLength());
|
||||
//System.out.println(string);
|
||||
|
||||
}
|
||||
|
||||
public static void messageBox(String string) {
|
||||
JOptionPane.showMessageDialog(new JFrame(), string);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -214,15 +214,14 @@ public class NUSTitle {
|
||||
this.titleID = titleId;
|
||||
}
|
||||
|
||||
public void decryptFEntries(List<FEntry> list) {
|
||||
public void decryptFEntries(List<FEntry> list,Progress progress) {
|
||||
ForkJoinPool pool = ForkJoinPool.commonPool();
|
||||
List<FEntryDownloader> dlList = new ArrayList<>();
|
||||
for(FEntry f : list){
|
||||
if(!f.isDir() && f.isInNUSTitle()){
|
||||
dlList.add(new FEntryDownloader(f));
|
||||
dlList.add(new FEntryDownloader(f,progress));
|
||||
}
|
||||
}
|
||||
|
||||
pool.invokeAll(dlList);
|
||||
Logger.log("Done!");
|
||||
}
|
||||
|
92
src/de/mas/jnustool/Progress.java
Normal file
92
src/de/mas/jnustool/Progress.java
Normal file
@ -0,0 +1,92 @@
|
||||
package de.mas.jnustool;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Progress {
|
||||
private long total;
|
||||
private long current;
|
||||
private ProgressUpdateListener progressUpdateListener = null;
|
||||
List<Progress> children = new ArrayList<>();
|
||||
Progress father = null;
|
||||
|
||||
|
||||
public long getTotalOfSingle() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(long total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public long getCurrentOfSingle() {
|
||||
return current;
|
||||
}
|
||||
|
||||
public void setCurrent(long current) {
|
||||
this.current = current;
|
||||
update();
|
||||
}
|
||||
|
||||
public void addCurrent(int i) {
|
||||
if(this.current + i > getTotalOfSingle()){
|
||||
setCurrent(getTotalOfSingle());
|
||||
}else{
|
||||
setCurrent(getCurrent() + i);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void update() {
|
||||
if(father != null) father.update();
|
||||
|
||||
if(progressUpdateListener != null){
|
||||
progressUpdateListener.updatePerformed(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void add(Progress progress) {
|
||||
progress.setFather(this);
|
||||
children.add(progress);
|
||||
}
|
||||
|
||||
private void setFather(Progress progressListener) {
|
||||
this.father = progressListener;
|
||||
}
|
||||
|
||||
public long getCurrent() {
|
||||
long tmp = getCurrentOfSingle();
|
||||
for(Progress p : children){
|
||||
tmp +=p.getCurrent();
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
public long getTotal() {
|
||||
long tmp = getTotalOfSingle();
|
||||
for(Progress p : children){
|
||||
tmp +=p.getTotal();
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
public void setProgressUpdateListener(ProgressUpdateListener progressUpdateListener) {
|
||||
this.progressUpdateListener = progressUpdateListener;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
setCurrent(0);
|
||||
setTotal(0);
|
||||
children = new ArrayList<>();
|
||||
}
|
||||
|
||||
public int statusInPercent() {
|
||||
return (int) ((getCurrent()*1.0)/(getTotal()*1.0)*100);
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
setCurrent(getTotalOfSingle());
|
||||
}
|
||||
|
||||
}
|
9
src/de/mas/jnustool/ProgressUpdateListener.java
Normal file
9
src/de/mas/jnustool/ProgressUpdateListener.java
Normal file
@ -0,0 +1,9 @@
|
||||
package de.mas.jnustool;
|
||||
|
||||
public interface ProgressUpdateListener {
|
||||
/**
|
||||
* Invoked when an action occurs.
|
||||
*/
|
||||
public void updatePerformed(Progress p);
|
||||
|
||||
}
|
@ -6,6 +6,10 @@ import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ForkJoinTask;
|
||||
|
||||
import de.mas.jnustool.gui.NUSGUI;
|
||||
import de.mas.jnustool.gui.UpdateChooser;
|
||||
@ -37,23 +41,37 @@ public class Starter {
|
||||
if( args.length > 1 && args[1].length() == 32){
|
||||
key = args[1].substring(0, 32);
|
||||
}
|
||||
if(titleID != 0){
|
||||
NUSGUI m = new NUSGUI(new NUSTitle(titleID, key));
|
||||
m.setVisible(true);
|
||||
}
|
||||
}else{
|
||||
titleID = getTitleID().getTitleID();
|
||||
}
|
||||
if(titleID != 0){
|
||||
NUSGUI m = new NUSGUI(new NUSTitle(titleID, key), null);
|
||||
m.setVisible(true);
|
||||
for(NUSTitleInformation nus : getTitleID()){
|
||||
|
||||
final long tID = nus.getTitleID();
|
||||
new Thread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
NUSGUI m = new NUSGUI(new NUSTitle(tID, null));
|
||||
m.setVisible(true);
|
||||
|
||||
}
|
||||
}).start();;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static NUSTitleInformation getTitleID() {
|
||||
private static List<NUSTitleInformation> getTitleID() {
|
||||
List<NUSTitleInformation> updatelist = readUpdateCSV();
|
||||
NUSTitleInformation result = null;
|
||||
List<NUSTitleInformation> result = null;
|
||||
if(updatelist != null){
|
||||
result = new NUSTitleInformation();
|
||||
result = new ArrayList<>();
|
||||
UpdateChooser.createAndShowGUI(updatelist,result);
|
||||
synchronized (result) {
|
||||
try {
|
||||
@ -63,6 +81,9 @@ public class Starter {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}else{
|
||||
Logger.messageBox("Updatefile is missing or not in config?");
|
||||
System.exit(2);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -80,6 +101,7 @@ public class Starter {
|
||||
while((line = in.readLine()) != null){
|
||||
String[] infos = line.split(";");
|
||||
if(infos.length != 7) {
|
||||
Logger.messageBox("Updatelist is broken!");
|
||||
System.out.println("Updatelist is broken!");
|
||||
return null;
|
||||
}
|
||||
@ -96,9 +118,10 @@ public class Starter {
|
||||
in.close();
|
||||
} catch (IOException | NumberFormatException e) {
|
||||
try {
|
||||
in.close();
|
||||
if(in != null)in.close();
|
||||
} catch (IOException e1) {
|
||||
}
|
||||
Logger.messageBox("Updatelist is broken or missing");
|
||||
System.out.println("Updatelist is broken!");
|
||||
return null;
|
||||
}
|
||||
@ -112,6 +135,7 @@ public class Starter {
|
||||
Downloader.URL_BASE = in.readLine();
|
||||
String commonkey = in.readLine();
|
||||
if(commonkey.length() != 32){
|
||||
Logger.messageBox("CommonKey length is wrong");
|
||||
System.out.println("Commonkey length is wrong");
|
||||
System.exit(1);
|
||||
}
|
||||
@ -121,4 +145,35 @@ public class Starter {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void downloadMeta(List<NUSTitleInformation> output_, Progress totalProgress) {
|
||||
ForkJoinPool pool = ForkJoinPool.commonPool();
|
||||
List<ForkJoinTask<Boolean>> list = new ArrayList<>();
|
||||
for(NUSTitleInformation nus : output_){
|
||||
final long tID = nus.getTitleID();
|
||||
list.add(pool.submit(new Callable<Boolean>(){
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
NUSTitle nus = new NUSTitle(tID, null);
|
||||
Progress childProgress = new Progress();
|
||||
totalProgress.add(childProgress);
|
||||
nus.decryptFEntries(nus.getFst().getMetaFolder(),childProgress);
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
}
|
||||
for(ForkJoinTask<Boolean> task : list){
|
||||
try {
|
||||
task.get();
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,13 +18,12 @@ import javax.swing.tree.TreePath;
|
||||
|
||||
import de.mas.jnustool.FEntry;
|
||||
import de.mas.jnustool.NUSTitle;
|
||||
import de.mas.jnustool.util.Settings;
|
||||
|
||||
public class NUSGUI extends JFrame {
|
||||
|
||||
private static final long serialVersionUID = 4648172894076113183L;
|
||||
public static JTextArea output = new JTextArea(1,10);
|
||||
public NUSGUI(NUSTitle nus,Settings mode) {
|
||||
public NUSGUI(NUSTitle nus) {
|
||||
super();
|
||||
this.setResizable(false);
|
||||
setSize(600, 768);
|
||||
@ -64,7 +63,7 @@ public class NUSGUI extends JFrame {
|
||||
}
|
||||
}
|
||||
|
||||
nus.decryptFEntries(list);
|
||||
nus.decryptFEntries(list, null);
|
||||
}}).start();
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,9 @@ import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JTable;
|
||||
@ -25,6 +27,9 @@ import javax.swing.ScrollPaneConstants;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import de.mas.jnustool.Progress;
|
||||
import de.mas.jnustool.ProgressUpdateListener;
|
||||
import de.mas.jnustool.Starter;
|
||||
import de.mas.jnustool.util.NUSTitleInformation;
|
||||
|
||||
public class UpdateChooser extends JPanel {
|
||||
@ -42,7 +47,8 @@ public class UpdateChooser extends JPanel {
|
||||
setSize(800, 600);
|
||||
|
||||
Collections.sort(list_);
|
||||
output_.init(list_.get(0));
|
||||
|
||||
output_.add(list_.get(0));
|
||||
String[] columnNames = { "TitleID", "Region", "Name" };
|
||||
String[][] tableData = new String[list_.size()][];
|
||||
int i = 0;
|
||||
@ -95,7 +101,7 @@ public class UpdateChooser extends JPanel {
|
||||
|
||||
|
||||
listSelectionModel.setSelectionMode(
|
||||
ListSelectionModel.SINGLE_SELECTION);
|
||||
ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
|
||||
//Build output area.
|
||||
output = new JTextArea(1, 10);
|
||||
@ -123,38 +129,75 @@ public class UpdateChooser extends JPanel {
|
||||
splitPane.add(topHalf);
|
||||
JPanel listContainer = new JPanel(new GridLayout(1,1));
|
||||
add(listContainer, BorderLayout.NORTH);
|
||||
JButton btnNewButton = new JButton("Okay");
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
add(panel, BorderLayout.SOUTH);
|
||||
JButton btnNewButton = new JButton("Open FST");
|
||||
panel.add(btnNewButton);
|
||||
JProgressBar progressBar;
|
||||
progressBar = new JProgressBar(0, 100);
|
||||
progressBar.setValue(0);
|
||||
progressBar.setStringPainted(true);
|
||||
|
||||
JButton btnDownloadMeta = new JButton("Download META");
|
||||
JProgressBar progressBar_1 = new JProgressBar();
|
||||
panel.add(progressBar_1);
|
||||
progressBar_1.setValue(0);
|
||||
Progress progress = new Progress();
|
||||
progress.setProgressUpdateListener(new ProgressUpdateListener() {
|
||||
|
||||
@Override
|
||||
public void updatePerformed(Progress p) {
|
||||
progressBar_1.setValue((int)p.statusInPercent());
|
||||
}
|
||||
});
|
||||
|
||||
btnDownloadMeta.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if(progressBar_1.getValue() == 0 || progressBar_1.getValue() == 100){
|
||||
progressBar_1.setValue(1);
|
||||
progress.clear();
|
||||
new Thread(new Runnable(){
|
||||
@Override
|
||||
public void run() {
|
||||
Starter.downloadMeta(output_,progress);
|
||||
JOptionPane.showMessageDialog(window, "Finished");
|
||||
}
|
||||
|
||||
}).start();
|
||||
|
||||
}else{
|
||||
JOptionPane.showMessageDialog(window, "Operation still in progress, please wait");
|
||||
}
|
||||
}
|
||||
});
|
||||
panel.add(btnDownloadMeta);
|
||||
|
||||
|
||||
btnNewButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
System.out.println("lol");
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
synchronized (output_) {
|
||||
window.setVisible(false);
|
||||
output_.notifyAll();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
add(btnNewButton, BorderLayout.SOUTH);
|
||||
|
||||
JPanel bottomHalf = new JPanel(new BorderLayout());
|
||||
bottomHalf.add(controlPane, BorderLayout.PAGE_START);
|
||||
bottomHalf.add(outputPane, BorderLayout.CENTER);
|
||||
//XXX: next line needed if bottomHalf is a scroll pane:
|
||||
//bottomHalf.setMinimumSize(new Dimension(400, 50));
|
||||
|
||||
}
|
||||
|
||||
private static NUSTitleInformation output_;
|
||||
private static List<NUSTitleInformation> output_;
|
||||
static List<NUSTitleInformation> list_;
|
||||
public static void createAndShowGUI(List<NUSTitleInformation> list,NUSTitleInformation output) {
|
||||
public static void createAndShowGUI(List<NUSTitleInformation> list,List<NUSTitleInformation> result) {
|
||||
//Create and set up the window.
|
||||
JFrame frame = new JFrame("Select the title");
|
||||
|
||||
//Create and set up the content pane.
|
||||
list_ = list;
|
||||
output_ =output;
|
||||
output_ =result;
|
||||
UpdateChooser demo = new UpdateChooser(frame);
|
||||
demo.setOpaque(true);
|
||||
frame.setContentPane(demo);
|
||||
@ -178,9 +221,12 @@ public class UpdateChooser extends JPanel {
|
||||
// Find out which indexes are selected.
|
||||
int minIndex = lsm.getMinSelectionIndex();
|
||||
int maxIndex = lsm.getMaxSelectionIndex();
|
||||
output_.clear();
|
||||
for (int i = minIndex; i <= maxIndex; i++) {
|
||||
if (lsm.isSelectedIndex(i)) {
|
||||
output_.init(list_.get(i));
|
||||
if(!output_.contains(list_.get(i))){
|
||||
output_.add(list_.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import de.mas.jnustool.FEntry;
|
||||
import de.mas.jnustool.Progress;
|
||||
import de.mas.jnustool.TIK;
|
||||
|
||||
public class Decryption {
|
||||
@ -171,6 +172,10 @@ public class Decryption {
|
||||
|
||||
boolean first = true;
|
||||
ByteArrayBuffer overflow = new ByteArrayBuffer(BLOCKSIZE);
|
||||
if(progressListener != null){
|
||||
progressListener.setTotal(toDownload.getFileLength());
|
||||
progressListener.setCurrent(0);
|
||||
}
|
||||
do{
|
||||
inBlockBuffer = getChunkFromStream(inputStream,blockBuffer,overflow,BLOCKSIZE);
|
||||
if(first){
|
||||
@ -184,7 +189,9 @@ public class Decryption {
|
||||
if((wrote + inBlockBuffer) > toDownload.getFileLength()){
|
||||
inBlockBuffer = (int) (toDownload.getFileLength()- wrote);
|
||||
}
|
||||
|
||||
if(progressListener != null){
|
||||
progressListener.addCurrent(inBlockBuffer);
|
||||
}
|
||||
wrote += inBlockBuffer;
|
||||
outputStream.write(output, 0, inBlockBuffer);
|
||||
}while(inBlockBuffer == BLOCKSIZE);
|
||||
@ -209,9 +216,16 @@ public class Decryption {
|
||||
|
||||
long wrote = 0;
|
||||
int inBlockBuffer;
|
||||
|
||||
if(progressListener != null){
|
||||
progressListener.setTotal(toDownload.getFileLength()/HASHBLOCKSIZE*BLOCKSIZE);
|
||||
progressListener.setCurrent(0);
|
||||
}
|
||||
do{
|
||||
inBlockBuffer = getChunkFromStream(inputStream,encryptedBlockBuffer,overflow,BLOCKSIZE);
|
||||
|
||||
if(progressListener != null){
|
||||
progressListener.addCurrent(inBlockBuffer);
|
||||
}
|
||||
if( writeSize > size )
|
||||
writeSize = size;
|
||||
|
||||
@ -295,5 +309,12 @@ public class Decryption {
|
||||
return inBlockBuffer;
|
||||
}
|
||||
|
||||
private Progress progressListener = null;
|
||||
|
||||
public void setProgressListener(Progress progressOfFile) {
|
||||
this.progressListener = progressOfFile;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
import de.mas.jnustool.FEntry;
|
||||
import de.mas.jnustool.Progress;
|
||||
|
||||
public class Downloader {
|
||||
private static Downloader instance;
|
||||
@ -22,7 +23,7 @@ public class Downloader {
|
||||
}
|
||||
|
||||
|
||||
public void downloadAndDecrypt(FEntry toDownload) throws IOException{
|
||||
public void downloadAndDecrypt(FEntry toDownload, Progress progressOfFile) throws IOException{
|
||||
String URL = URL_BASE + "/" + String.format("%016X", toDownload.getTitleID()) + "/" + String.format("%08X", toDownload.getNUScontentID());
|
||||
URL url = new URL(URL);
|
||||
String [] path = toDownload.getFullPath().split("/");
|
||||
@ -45,7 +46,7 @@ public class Downloader {
|
||||
connection.connect();
|
||||
|
||||
Decryption decryption = new Decryption(toDownload.getTicket());
|
||||
|
||||
decryption.setProgressListener(progressOfFile);
|
||||
InputStream input = connection.getInputStream();
|
||||
FileOutputStream outputStream = new FileOutputStream(String.format("%016X", toDownload.getTitleID()) +"/" + toDownload.getFullPath().substring(1, toDownload.getFullPath().length()));
|
||||
if(!decryptWithHash){
|
||||
|
@ -12,6 +12,7 @@ public class NUSTitleInformation implements Comparable<NUSTitleInformation>, Ser
|
||||
private String content_platform;
|
||||
private String company_code;
|
||||
private int region;
|
||||
private byte[] key;
|
||||
|
||||
|
||||
public enum Region{
|
||||
@ -123,6 +124,21 @@ public class NUSTitleInformation implements Comparable<NUSTitleInformation>, Ser
|
||||
setID6(n.ID6);
|
||||
setLongnameEN(n.longnameEN);
|
||||
setProduct_code(n.product_code);
|
||||
setKey(n.key);
|
||||
}
|
||||
|
||||
public byte[] getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(byte[] key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o){
|
||||
return titleID == ((NUSTitleInformation)o).titleID;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ public class Util {
|
||||
{
|
||||
StringBuilder hex = new StringBuilder(ba.length * 2);
|
||||
for(byte b : ba){
|
||||
hex.append(String.format("%X", b));
|
||||
hex.append(String.format("%02X", b));
|
||||
}
|
||||
return hex.toString();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user