diff --git a/.gitignore b/.gitignore index 52a1beb..965efbf 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,5 @@ Temporary Items 0* bin /config +/tmp* +UpdateGrabber.java \ No newline at end of file diff --git a/jar/JNUSTool.jar b/jar/JNUSTool.jar index 2aeef33..e58ef4d 100644 Binary files a/jar/JNUSTool.jar and b/jar/JNUSTool.jar differ diff --git a/jar/JNUSTool_Java7.jar b/jar/JNUSTool_Java7.jar deleted file mode 100644 index 4b7917a..0000000 Binary files a/jar/JNUSTool_Java7.jar and /dev/null differ diff --git a/jar/config b/jar/config index 3814033..45dc7a6 100644 --- a/jar/config +++ b/jar/config @@ -1,2 +1,3 @@ http://ccs.cdn.wup.shop.nintendo.net/ccs/download -[COMMONKEY] \ No newline at end of file +[COMMONKEY] +updatetitles.csv \ No newline at end of file diff --git a/jar/updatetitles.csv b/jar/updatetitles.csv new file mode 100644 index 0000000..5a6a2c7 --- /dev/null +++ b/jar/updatetitles.csv @@ -0,0 +1,322 @@ +0005000E-10100600;1;WUP;00AF;WUP-U-AKNJ;AKNJAF;TEKKEN TAG TOURNAMENT 2 Wii U EDITION +0005000E-10101B00;4;WUP;0001;WUP-U-APLP;APLP01;LEGO® CITY UNDERCOVER +0005000E-10101C00;1;WUP;0001;WUP-U-ARPJ;ARPJ01;New SUPER MARIO BROS. U +0005000E-10101D00;2;WUP;0001;WUP-U-ARPE;ARPE01;New SUPER MARIO BROS. U +0005000E-10101E00;4;WUP;0001;WUP-U-ARPP;ARPP01;New SUPER MARIO BROS. U +0005000E-10101F00;1;WUP;0001;WUP-U-ALCJ;ALCJ01;Nintendo Land +0005000E-10102000;2;WUP;0001;WUP-U-ALCE;ALCE01;Nintendo Land +0005000E-10102100;4;WUP;0001;WUP-U-ALCP;ALCP01;Nintendo Land +0005000E-10102200;1;WUP;0001;WUP-U-ASTJ;ASTJ01;Wii Fit U +0005000E-10102300;2;WUP;0001;WUP-U-ASTE;ASTE01;Wii Fit U +0005000E-10102400;4;WUP;0001;WUP-U-ASTP;ASTP01;Wii Fit U +0005000E-10104D00;1;WUP;0008;WUP-U-AHDJ;AHDJ08;MONSTER HUNTER 3(tri-)G HD Ver. +0005000E-10106900;1;WUP;0001;WUP-U-AURJ;AURJ01;Mario & Sonic at the Sochi 2014 Olympic Winter Games +0005000E-10106B00;2;WUP;0041;WUP-U-ASSE;ASSE41;Assassin's Creed® III +0005000E-1010AE00;2;WUP;0041;WUP-U-AJDE;AJDE41;JUST DANCE 4 +0005000E-1010AF00;2;WUP;0041;WUP-U-AMVE;AMVE41;Marvel Avengers™: Battle for Earth +0005000E-1010B000;2;WUP;0041;WUP-U-ARBE;ARBE41;Rabbids Land +0005000E-1010B300;2;WUP;008P;WUP-U-AS2E;AS2E8P;Sonic & All-Stars Racing Transformed +0005000E-1010B400;2;WUP;0041;WUP-U-ASPE;ASPE41;ESPN Sports Connection +0005000E-1010B600;2;WUP;0041;WUP-U-AYSE;AYSE41;Your Shape® Fitness Evolved 2013 +0005000E-1010C700;2;WUP;0001;WUP-U-AURE;AURE01;Mario & Sonic at the Sochi 2014 Olympic Winter Games +0005000E-1010C800;4;WUP;0001;WUP-U-AURP;AURP01;Mario & Sonic at the Sochi 2014 Olympic Winter Games +0005000E-1010CF00;2;WUP;0052;WUP-U-AECE;AECE52;Call of Duty: Black Ops II +0005000E-1010DA00;2;WUP;0054;WUP-U-ANBE;ANBE54;NBA 2K13 +0005000E-1010DC00;2;WUP;0069;WUP-U-AMEE;AMEE69;Mass Effect™ 3 Special Edition +0005000E-1010DD00;2;WUP;0041;WUP-U-AZUE;AZUE41;ZombiU +0005000E-1010E300;2;WUP;0041;WUP-U-AS9E;AS9E41;Splinter Cell Blacklist +0005000E-1010EA00;1;WUP;00C8;WUP-U-AHBJ;AHBJC8;WARRIORS OROCHI 3 Hyper +0005000E-1010EB00;1;WUP;0001;WUP-P-AMKJ;AMKJ01;MARIO KART 8 +0005000E-1010EC00;2;WUP;0001;WUP-P-AMKE;AMKE01;MARIO KART 8 +0005000E-1010ED00;4;WUP;0001;WUP-P-AMKP;AMKP01;MARIO KART 8 +0005000E-1010EE00;4;WUP;0069;WUP-U-AF3P;AF3P69;FIFA 13 +0005000E-1010EF00;4;WUP;0041;WUP-U-AZUP;AZUP41;ZombiU +0005000E-1010F000;4;WUP;0041;WUP-U-AJDP;AJDP41;JUST DANCE 4 +0005000E-1010F500;4;WUP;0069;WUP-U-AMEP;AMEP69;Mass Effect™ 3 Special Edition +0005000E-1010F600;4;WUP;0041;WUP-U-ASSP;ASSP41;Assassin's Creed® III +0005000E-1010F700;4;WUP;0041;WUP-U-AYSP;AYSP41;Your Shape® Fitness Evolved 2013 +0005000E-1010F800;4;WUP;00AF;WUP-U-AKNP;AKNPAF;TEKKEN TAG TOURNAMENT 2 Wii U EDITION +0005000E-1010FB00;4;WUP;00NK;WUP-U-WDLP;WDLPNK;Puddle +0005000E-1010FC00;4;WUP;0041;WUP-U-ARBP;ARBP41;Rabbids Land +0005000E-1010FF00;4;WUP;00WR;WUP-U-AGPP;AGPPWR;Game Party Champions +0005000E-10110000;2;WUP;00AF;WUP-U-AKNE;AKNEAF;TEKKEN TAG TOURNAMENT 2 Wii U EDITION +0005000E-10110100;2;WUP;00JX;WUP-U-WASE;WASEJX;Nano Assault Neo +0005000E-10110200;2;WUP;00C8;WUP-U-AHBE;AHBEC8;WARRIORS OROCHI 3 Hyper(NA) +0005000E-10110600;4;WUP;00JX;WUP-U-WASP;WASPJX;Nano Assault Neo +0005000E-10110800;4;WUP;0041;WUP-U-AMVP;AMVP41;Marvel Avengers™: Battle for Earth +0005000E-10110900;1;WUP;00C8;WUP-U-ANGJ;ANGJC8;NINJA GAIDEN 3: Razor's Edge +0005000E-10110A00;2;WUP;0001;WUP-U-ANGE;ANGE01;NINJA GAIDEN 3: Razor's Edge +0005000E-10110B00;4;WUP;0001;WUP-U-ANGP;ANGP01;NINJA GAIDEN 3: Razor's Edge +0005000E-10110E00;1;WUP;0001;WUP-P-AXFJ;AXFJ01;Super Smash Bros. for Wii U +0005000E-10111700;2;WUP;00WR;WUP-U-AJSE;AJSEWR;Injustice: Gods Among Us +0005000E-10111A00;4;WUP;00WR;WUP-U-AJSP;AJSPWR;Injustice: Gods Among Us +0005000E-10111C00;1;WUP;00C8;WUP-U-AG9J;AG9JC8;Romance of the Three Kingdoms 12 +0005000E-10111D00;4;WUP;0041;WUP-U-ASPP;ASPP41;Sports Connection +0005000E-10111F00;4;WUP;008P;WUP-U-AS2P;AS2P8P;Sonic & All-Stars Racing Transformed +0005000E-10112000;2;WUP;00G9;WUP-U-ACRE;ACREG9;THE CROODS +0005000E-10112100;4;WUP;0041;WUP-U-AKFP;AKFP41;Know Your Friends +0005000E-10112200;4;WUP;00FZ;WUP-U-WBDP;WBDPFZ;Trine 2 Director's Cut +0005000E-10112300;1;WUP;0041;WUP-U-AZUJ;AZUJ41;ZombiU +0005000E-10112400;1;WUP;0041;WUP-U-ASSJ;ASSJ41;Assassin's Creed® III +0005000E-10112500;1;WUP;0041;WUP-U-ASPJ;ASPJ41;Sports Connection +0005000E-10112800;1;WUP;0041;WUP-U-AS9J;AS9J41;Splinter Cell Blacklist +0005000E-10112B00;4;WUP;00C8;WUP-U-AHBP;AHBPC8;WARRIORS OROCHI 3 Hyper(EU) +0005000E-10112F00;4;WUP;0054;WUP-U-ANBP;ANBP54;NBA 2K13 +0005000E-10113000;1;WUP;0013;WUP-U-AMEJ;AMEJ13;Mass Effect™ 3 Special Edition +0005000E-10113100;1;WUP;0008;WUP-U-ABHJ;ABHJ08;BIOHAZARD REVELATIONS Unveiled Edition +0005000E-10113400;4;WUP;0052;WUP-U-AECP;AECP52;Call of Duty: Black Ops II +0005000E-10113500;4;WUP;0052;WUP-U-AECI;AECI52;Call of Duty: Black Ops II +0005000E-10113700;4;WUP;0052;WUP-U-AECD;AECD52;Call of Duty: Black Ops II +0005000E-10113800;4;WUP;00Y4;WUP-U-WBAP;WBAPY4;Zen Pinball 2 +0005000E-10113C00;2;WUP;00GT;WUP-U-AFBE;AFBEGT;Funky Barn +0005000E-10115E00;1;WUP;00GD;WUP-U-ADQJ;ADQJGD;Dragon Quest X +0005000E-10115F00;2;WUP;00Y4;WUP-U-WBAE;WBAEY4;Zen Pinball 2 +0005000E-10116100;1;WUP;0001;WUP-P-AX5J;AX5J01;XenobladeX +0005000E-10116300;1;WUP;0001;WUP-U-ACMJ;ACMJ01;The Wonderful 101 +0005000E-10116500;4;WUP;00TW;WUP-U-WAAP;WAAPTW;Toki Tori 2+ +0005000E-10116600;1;WUP;00C8;WUP-U-AH9J;AH9JC8;Fist of the North Star: Ken's Rage 2 +0005000E-10117200;4;WUP;0008;WUP-U-AHDP;AHDP08;MONSTER HUNTER 3 ULTIMATE +0005000E-10117700;4;WUP;00TJ;WUP-U-WCAP;WCAPTJ;Chasing Aurora +0005000E-10118300;2;WUP;0008;WUP-U-AHDE;AHDE08;MONSTER HUNTER 3 ULTIMATE +0005000E-10118400;4;WUP;00GT;WUP-U-AFBP;AFBPGT;Funky Barn +0005000E-1011A700;4;WUP;0041;WUP-U-AZUD;AZUD41;ZombiU +0005000E-1011AF00;2;WUP;00XY;WUP-U-WBTE;WBTEXY;BIT.TRIP Presents... Runner2: Future Legend of Rhythm Alien +0005000E-1011B300;4;WUP;00TZ;WUP-U-AFBZ;AFBZTZ;Funky Barn (Download Version) +0005000E-1011B400;1;WUP;00GD;WUP-U-AECJ;AECJGD;Call of Duty: Black Ops II +0005000E-1011B600;1;WUP;00GD;WUP-U-AQDJ;AQDJGD;Dragon Quest X Beta test +0005000E-1011B700;4;WUP;0041;WUP-U-WLAP;WLAP41;Uplay +0005000E-1011BA00;2;WUP;0041;WUP-U-WLAE;WLAE41;Uplay +0005000E-1011C000;2;WUP;00TJ;WUP-U-WCAE;WCAETJ;Chasing Aurora +0005000E-10128400;4;WUP;0069;WUP-U-ANSP;ANSP69;Need for Speed™ Most Wanted U +0005000E-10128700;2;WUP;00TW;WUP-U-WAAE;WAAETW;Toki Tori 2+ +0005000E-10128800;2;WUP;0069;WUP-U-ANSE;ANSE69;Need for Speed™ Most Wanted U +0005000E-10128A00;2;WUP;00FZ;WUP-U-WBDE;WBDEFZ;Trine 2 Director's Cut +0005000E-10128F00;2;WUP;008P;WUP-U-ASNE;ASNE8P;SONIC LOST WORLD +0005000E-10129000;2;WUP;0008;WUP-U-WDKE;WDKE08;DuckTales: Remastered +0005000E-10129200;4;WUP;0008;WUP-U-WDKP;WDKP08;DuckTales: Remastered +0005000E-1012AC00;4;WUP;0041;WUP-U-AS9P;AS9P41;Splinter Cell Blacklist +0005000E-1012B100;4;WUP;008P;WUP-U-ASNP;ASNP8P;SONIC LOST WORLD +0005000E-1012B400;4;WUP;0008;WUP-U-ABHP;ABHP08;RESIDENT EVIL REVELATIONS +0005000E-1012B700;1;WUP;0013;WUP-U-ANSJ;ANSJ13;Need for Speed™ Most Wanted U +0005000E-1012BC00;1;WUP;0001;WUP-U-AC3J;AC3J01;PIKMIN 3 +0005000E-1012BD00;2;WUP;0001;WUP-U-AC3E;AC3E01;PIKMIN 3 +0005000E-1012BE00;4;WUP;0001;WUP-U-AC3P;AC3P01;PIKMIN 3 +0005000E-1012C500;4;WUP;00AF;WUP-U-ACRP;ACRPAF;THE CROODS +0005000E-1012CF00;2;WUP;0008;WUP-U-ABHE;ABHE08;RESIDENT EVIL REVELATIONS +0005000E-1012DC00;2;WUP;0001;WUP-U-ACME;ACME01;The Wonderful 101 +0005000E-1012F100;1;WUP;0001;WUP-U-AWSJ;AWSJ01;Wii Sports Club +0005000E-10131D00;1;WUP;0001;WUP-U-ASEJ;ASEJ01;???????? +0005000E-10131F00;1;WUP;0001;WUP-U-AYCJ;AYCJ01;yoshi's woolly world +0005000E-10132400;4;WUP;00WR;WUP-U-ALMP;ALMPWR;LEGO® MARVEL Super Heroes +0005000E-10132500;1;WUP;0001;WUP-U-WB9J;WB9J01;Wii Fit U Quick Check +0005000E-10132600;2;WUP;0001;WUP-U-WB9E;WB9E01;Wii Fit U Quick Check +0005000E-10132700;4;WUP;0001;WUP-U-WB9P;WB9P01;Wii Fit U Quick Check +0005000E-10132800;2;WUP;00UP;WUP-U-WEPE;WEPEUP;Unepic EnjoyUp Games +0005000E-10132900;2;WUP;004Q;WUP-U-ADSE;ADSE4Q;Disney INFINITY +0005000E-10132A00;4;WUP;00Y4;WUP-U-WA2P;WA2PY4;Star Wars Pinball +0005000E-10132B00;2;WUP;00WR;WUP-P-ALME;ALMEWR;LEGO® MARVEL Super Heroes +0005000E-10135200;2;WUP;00Y4;WUP-U-WA2E;WA2EY4;Star Wars Pinball +0005000E-10135300;4;WUP;0001;WUP-U-ACMP;ACMP01;The Wonderful 101 +0005000E-10135700;1;WUP;008P;WUP-U-ASNJ;ASNJ8P;SONIC LOST WORLD +0005000E-10136300;4;WUP;00XY;WUP-U-WBTP;WBTPXY;BIT.TRIP Presents... Runner2: Future Legend of Rhythm Alien +0005000E-10136C00;4;WUP;00WR;WUP-U-AZEP;AZEPWR;Batman™: Arkham Origins +0005000E-10136F00;4;WUP;004Q;WUP-U-ADSP;ADSP4Q;Disney Infinity +0005000E-10137000;4;WUP;004Q;WUP-U-ADSZ;ADSZ4Q;Disney Infinity +0005000E-10137C00;2;WUP;00WR;WUP-U-AZEE;AZEEWR;Batman™: Arkham Origins +0005000E-10137F00;2;WUP;0001;WUP-P-ARKE;ARKE01;Donkey Kong Country Tropical Freeze +0005000E-10138300;4;WUP;0001;WUP-P-ARKP;ARKP01;Donkey Kong Country Tropical Freeze +0005000E-10138700;4;WUP;00YV;WUP-P-WB6P;WB6PYV;Spin the Bottle: Bumpie's Party +0005000E-10138800;4;WUP;0041;WUP-U-ASBP;ASBP41;Assassin's Creed® IV Black Flag +0005000E-10138B00;2;WUP;0041;WUP-U-ASBE;ASBE41;Assassin's Creed® IV Black Flag +0005000E-10138E00;4;WUP;0041;WUP-U-WB7P;WB7P41;Rayman Legends Challenges App +0005000E-10138F00;1;WUP;0001;WUP-U-ADNJ;ADNJ01;Devil's Third +0005000E-10139200;2;WUP;0052;WUP-U-ASFE;ASFE52;Skylanders SWAP Force +0005000E-10139500;2;WUP;0041;WUP-U-WB7E;WB7E41;Rayman Legends Challenges App +0005000E-10139900;2;WUP;0041;WUP-P-AJ5E;AJ5E41;JUST DANCE® 2014 +0005000E-10140400;4;WUP;0052;WUP-U-ASFP;ASFP52;Skylanders SWAP Force +0005000E-10140700;1;WUP;00WR;WUP-U-AJSJ;AJSJWR;Injustice: Gods Among Us +0005000E-10142700;4;WUP;0001;WUP-P-AA9P;AA9P01;Art Academy: SketchPad +0005000E-10142A00;2;WUP;005G;WUP-U-AZBE;AZBE5G;Zumba Fitness World Party +0005000E-10142B00;1;WUP;0001;WUP-P-AA9J;AA9J01;Art Academy: SketchPad +0005000E-10142C00;2;WUP;0001;WUP-P-AA9E;AA9E01;Art Academy: SketchPad +0005000E-10143F00;4;WUP;0041;WUP-P-AJ5P;AJ5P41;JUST DANCE® 2014 +0005000E-10144000;2;WUP;00G9;WUP-U-ADVE;ADVEG9;Adventure Time: Explore the Dungeon Because I Don't Know! +0005000E-10144800;1;WUP;0001;WUP-P-ARKJ;ARKJ01;Donkey Kong Country Tropical Freeze +0005000E-10144D00;2;WUP;0001;WUP-U-AWSE;AWSE01;Wii Sports Club +0005000E-10144E00;4;WUP;0001;WUP-U-AWSP;AWSP01;Wii Sports Club +0005000E-10144F00;2;WUP;0001;WUP-P-AXFE;AXFE01;Super Smash Bros. for Wii U +0005000E-10145000;4;WUP;0001;WUP-P-AXFP;AXFP01;Super Smash Bros. for Wii U +0005000E-10145600;7;WUP;0001;WUP-U-ADBA;ADBA01;Animal Crossing Plaza +0005000E-10145800;4;WUP;00UP;WUP-U-WEPP;WEPPUP;Unepic EnjoyUp Games +0005000E-10145900;4;WUP;00HL;WUP-U-WCDP;WCDPHL;Coaster Crazy Deluxe +0005000E-10145F00;1;WUP;0001;WUP-P-WMGJ;WMGJ01;NES REMIX +0005000E-10146000;2;WUP;0001;WUP-P-WMGE;WMGE01;NES REMIX +0005000E-10146100;4;WUP;0001;WUP-P-WMGP;WMGP01;NES REMIX +0005000E-10146800;2;WUP;0052;WUP-P-ACPE;ACPE52;Call of Duty: Ghosts +0005000E-10147600;4;WUP;00DZ;WUP-P-WEVP;WEVPDZ;EvoFish +0005000E-10147F00;2;WUP;00YV;WUP-P-WB6E;WB6EYV;Spin the Bottle: Bumpie's Party +0005000E-10148000;1;WUP;00AF;WUP-P-AUNJ;AUNJAF;ONE PIECE UNLIMITED WORLD R +0005000E-10148200;2;WUP;00UP;WUP-U-WAEE;WAEEUP;Rock 'N Racing Off Road +0005000E-10148F00;1;WUP;0041;WUP-U-WLAJ;WLAJ41;Uplay +0005000E-10149200;4;WUP;00SS;WUP-U-WDFP;WDFPSS;Spot The Differences: Party! +0005000E-10149500;2;WUP;00CS;WUP-P-WKTE;WKTECS;Scram Kitty and his Buddy on Rails +0005000E-10149700;1;WUP;0001;WUP-P-WAUJ;WAUJ01;?? ?? +0005000E-1014C600;4;WUP;00CX;WUP-U-WGSP;WGSPCX;Giana Sisters Twisted Dreams +0005000E-1014C800;1;WUP;0041;WUP-U-ASBJ;ASBJ41;Assassin's Creed® IV Black Flag +0005000E-1014CB00;2;WUP;00CX;WUP-P-WGSE;WGSECX;Giana Sisters Twisted Dreams +0005000E-1014CF00;2;WUP;00HL;WUP-U-WCDE;WCDEHL;Coaster Crazy Deluxe +0005000E-1014D100;4;WUP;00CS;WUP-U-WKTP;WKTPCS;Scram Kitty and his Buddy on Rails +0005000E-1014D900;1;WUP;008P;WUP-P-APTJ;APTJ8P;PUYOPUYOTETRIS +0005000E-1014DA00;1;WUP;0008;WUP-U-AMFJ;AMFJ08;Monster Hunter Frontier G +0005000E-1014DE00;2;WUP;00WR;WUP-U-ALAE;ALAEWR;The LEGO® Movie Videogame +0005000E-1014E000;4;WUP;00WR;WUP-U-ALAP;ALAPWR;The LEGO® Movie Videogame +0005000E-1014E100;4;WUP;00AF;WUP-U-ADVP;ADVPAF;Adventure Time: Explore the Dungeon Because I Don't Know! +0005000E-1014E300;4;WUP;00GT;WUP-U-AZBP;AZBPGT;Zumba Fitness World Party +0005000E-10154600;1;WUP;00WR;WUP-U-AZEJ;AZEJWR;Batman™: Arkham Origins +0005000E-10154D00;4;WUP;00BU;WUP-U-WC3P;WC3PBU;The Mysterious Cities of Gold: Secret Paths +0005000E-10156100;4;WUP;0052;WUP-P-ACPP;ACPP52;Call of Duty: Ghosts +0005000E-10156500;2;WUP;00BU;WUP-U-WC3E;WC3EBU;The Mysterious Cities of Gold: Secret Paths +0005000E-10157600;4;WUP;0052;WUP-P-ACPI;ACPI52;Call of Duty: Ghosts +0005000E-10157900;1;WUP;00GD;WUP-P-ACPJ;ACPJGD;Call of Duty: Ghosts +0005000E-10159800;1;WUP;0001;WUP-U-AFCJ;AFCJ01;Wii Fit U (Free) +0005000E-10159900;2;WUP;0001;WUP-U-AFCE;AFCE01;Wii Fit U (Free) +0005000E-10159A00;4;WUP;0001;WUP-U-AFCP;AFCP01;Wii Fit U (promo) +0005000E-1015A300;1;WUP;00AF;WUP-U-ADSJ;ADSJAF;Disney INFINITY +0005000E-1015B200;2;WUP;0041;WUP-P-ACLE;ACLE41;CHILD of LIGHT +0005000E-1015D300;2;WUP;00AS;WUP-P-WLCE;WLCEAS;Lucadian Chronicles +0005000E-1015EB00;1;WUP;00R7;WUP-U-WHYJ;WHYJR7;Mighty Switch Force!™ Hyper Drive Edition +0005000E-10161F00;1;WUP;0001;WUP-U-ABAJ;ABAJ01;Mario Party 10 +0005000E-10162300;4;WUP;00YR;WUP-U-WCZP;WCZPYR;Color Zen +0005000E-10162B00;1;WUP;0001;WUP-P-AGMJ;AGMJ01;Splatoon +0005000E-10162D00;2;WUP;0001;WUP-U-ABAE;ABAE01;Mario Party 10 +0005000E-10169600;4;WUP;00UP;WUP-U-WEPS;WEPSUP;Unepic EnjoyUp Games +0005000E-1016A200;4;WUP;00SS;WUP-U-WBXP;WBXPSS;Bombing Bastards +0005000E-1016A400;4;WUP;00WR;WUP-P-BTMP;BTMPWR;LEGO® Batman™ 3 Beyond Gotham +0005000E-1016A600;1;WUP;00TF;WUP-P-WB6J;WB6JTF;?????????????? +0005000E-1016AB00;2;WUP;00SS;WUP-U-WBXE;WBXESS;Bombing Bastards +0005000E-1016AC00;2;WUP;009T;WUP-U-WMLE;WMLE9T;Armillo +0005000E-1016AD00;2;WUP;00WR;WUP-P-BTME;BTMEWR;LEGO® Batman™ 3 Beyond Gotham +0005000E-1016B200;2;WUP;009V;WUP-U-WMRE;WMRE9V;Master Reboot +0005000E-1016C700;4;WUP;009T;WUP-U-WMLP;WMLP9T;Armillo +0005000E-1016CE00;2;WUP;00YR;WUP-U-WCZE;WCZEYR;Color Zen +0005000E-1016D500;4;WUP;009Y;WUP-P-WCTP;WCTP9Y;Super Toy Cars +0005000E-1016D800;1;WUP;0041;WUP-P-ACLJ;ACLJ41;CHILD of LIGHT +0005000E-1016DC00;2;WUP;004Q;WUP-P-ADRE;ADRE4Q;Disney Infinity [2.0] +0005000E-1016DE00;2;WUP;009Y;WUP-P-WCTE;WCTE9Y;Super Toy Cars +0005000E-1016E100;2;WUP;00AY;WUP-P-WKNE;WKNEAY;Shovel Knight +0005000E-1016E300;2;WUP;008S;WUP-P-WGRE;WGRE8S;GravBlocks+ From Nothing Game Studios +0005000E-1016E800;4;WUP;009V;WUP-U-WMRP;WMRP9V;Master Reboot +0005000E-1016EA00;4;WUP;0041;WUP-P-ACLP;ACLP41;CHILD of LIGHT +0005000E-1016FF00;2;WUP;00NT;WUP-P-WFWE;WFWENT;Flowerworks HD Follie's Adventure +0005000E-10170200;2;WUP;007Z;WUP-U-WGAE;WGAE7Z;Pier Solar and the Great Architects +0005000E-10170600;1;WUP;00AF;WUP-U-APWJ;APWJAF;KAMEN RIDER BATTRIDE WAR ? PREMIUM TV&MOVIE SOUND ED. +0005000E-10170700;1;WUP;00AF;WUP-U-ABWJ;ABWJAF;KAMEN RIDER BATTRIDE WAR ? +0005000E-10172A00;2;WUP;009Z;WUP-N-HRLE;HRLE9Z;Crunchyroll +0005000E-10172B00;4;WUP;009Z;WUP-N-HRLP;HRLP9Z;Crunchyroll +0005000E-10173300;4;WUP;00UB;WUP-U-WCGP;WCGPUB;Stealth Inc 2 A Game of Clones +0005000E-10175B00;2;WUP;008P;WUP-P-BSSE;BSSE8P;Sonic Boom: Rise of Lyric +0005000E-10175D00;4;WUP;00AF;WUP-P-AUNP;AUNPAF;ONE PIECE Unlimited World Red +0005000E-10176500;2;WUP;00UB;WUP-U-WCGE;WCGEUB;Stealth Inc 2 A Game of Clones +0005000E-10176900;2;WUP;0001;WUP-P-AGME;AGME01;Splatoon +0005000E-10176A00;4;WUP;0001;WUP-P-AGMP;AGMP01;Splatoon +0005000E-10176F00;4;WUP;0041;WUP-P-BJDP;BJDP41;JUST DANCE® 2015 +0005000E-10177600;2;WUP;0001;WUP-U-ADNE;ADNE01;Devil's Third +0005000E-10177800;4;WUP;008P;WUP-P-BSSP;BSSP8P;Sonic Boom: Rise of Lyric +0005000E-10178F00;4;WUP;00AY;WUP-P-WKNP;WKNPAY;Shovel Knight +0005000E-10179100;2;WUP;0041;WUP-P-BJDE;BJDE41;JUST DANCE® 2015 +0005000E-1017BE00;1;WUP;0001;WUP-U-BXAJ;BXAJ01;Art Academy: Home Studio +0005000E-1017BF00;2;WUP;0001;WUP-U-BXAE;BXAE01;Art Academy: Home Studio +0005000E-1017C600;2;WUP;0052;WUP-P-BK7E;BK7E52;Skylanders Trap Team +0005000E-1017CD00;1;WUP;00C8;WUP-U-BWPJ;BWPJC8;Hyrule Warriors +0005000E-1017D800;2;WUP;0001;WUP-U-BWPE;BWPE01;Hyrule Warriors +0005000E-1017D900;4;WUP;0001;WUP-U-BWPP;BWPP01;Hyrule Warriors +0005000E-1017DA00;2;WUP;011S;WUP-P-ACQE;ACQE1S;Costume Quest 2 +0005000E-1017E000;4;WUP;00XQ;WUP-P-WK8P;WK8PXQ;Turtle Tale +0005000E-10180500;1;WUP;0001;WUP-P-AKBJ;AKBJ01;Captain Toad: Treasure Tracker +0005000E-10180600;2;WUP;0001;WUP-P-AKBE;AKBE01;Captain Toad: Treasure Tracker +0005000E-10180700;4;WUP;0001;WUP-P-AKBP;AKBP01;Captain Toad: Treasure Tracker +0005000E-10181F00;4;WUP;0052;WUP-P-BK7P;BK7P52;Skylanders Trap Team +0005000E-10182C00;4;WUP;00XT;WUP-U-AJTP;AJTPXT;Jett Tailfin +0005000E-10183000;2;WUP;010P;WUP-P-ARNE;ARNE0P;Runbow +0005000E-10183900;2;WUP;00UP;WUP-U-BMVE;BMVEUP;99Moves +0005000E-10184D00;2;WUP;0001;WUP-U-AYCE;AYCE01;Yoshi's Woolly World +0005000E-10187100;4;WUP;00LW;WUP-U-BUGP;BUGPLW;Underground +0005000E-10188B00;1;WUP;0001;WUP-U-AXYJ;AXYJ01;Kirby and the Rainbow Curse +0005000E-10188C00;4;WUP;004Q;WUP-P-ADRP;ADRP4Q;Disney Infinity [2.0] +0005000E-10188D00;4;WUP;004Q;WUP-P-ADRZ;ADRZ4Q;Disney Infinity [2.0] +0005000E-10189200;2;WUP;011C;WUP-P-BSPE;BSPE1C;Sportsball +0005000E-1018C400;1;WUP;00AF;WUP-P-BSFJ;BSFJAF;???F??????????? ????SF??????????? +0005000E-1018DB00;1;WUP;0001;WUP-U-AMAJ;AMAJ01;Super Mario Maker +0005000E-1018DC00;2;WUP;0001;WUP-U-AMAE;AMAE01;Super Mario Maker +0005000E-1018DD00;4;WUP;0001;WUP-U-AMAP;AMAP01;Super Mario Maker +0005000E-1018DE00;4;WUP;00NK;WUP-U-ATCP;ATCPNK;Tetrobot and Co. +0005000E-1018ED00;2;WUP;00NK;WUP-U-ATCE;ATCENK;Tetrobot and Co. +0005000E-10191700;4;WUP;00UP;WUP-U-BMVP;BMVPUP;99Moves +0005000E-10191800;4;WUP;00UP;WUP-U-WAEP;WAEPUP;Rock 'N Racing Off Road +0005000E-10192200;1;WUP;00AF;WUP-P-BRSJ;BRSJAF;KAMEN RIDER SUMMON RIDE! +0005000E-10194200;2;WUP;00WR;WUP-U-APZE;APZEWR;LEGO® DIMENSIONS™ +0005000E-10195D00;4;WUP;00WR;WUP-U-APZP;APZPWR;LEGO® DIMENSIONS™ +0005000E-10197800;4;WUP;011S;WUP-P-ACQP;ACQP1S;Costume Quest 2 +0005000E-10199000;1;WUP;0001;WUP-P-AVXJ;AVXJ01;Mario Tennis: Ultra Smash +0005000E-1019AD00;2;WUP;011A;WUP-P-BEQE;BEQE1A;Elliot Quest +0005000E-101A1B00;2;WUP;00RG;WUP-U-BS2E;BS2ERG;Swords & Soldiers II +0005000E-101A2600;1;WUP;00W4;WUP-U-WKFJ;WKFJW4;Kung Fu Rabbit +0005000E-101A2E00;1;WUP;00TF;WUP-P-WEXJ;WEXJTF;XType+ +0005000E-101A3500;2;WUP;0001;WUP-P-AVXE;AVXE01;Mario Tennis: Ultra Smash +0005000E-101A3600;4;WUP;0001;WUP-P-AVXP;AVXP01;Mario Tennis: Ultra Smash +0005000E-101A3B00;2;WUP;00LY;WUP-P-BLPE;BLPELY;Life of Pixel +0005000E-101A4900;4;WUP;00LY;WUP-U-BLPP;BLPPLY;Life of Pixel +0005000E-101A5C00;4;WUP;00WR;WUP-U-ALJP;ALJPWR;LEGO® Jurassic World™ +0005000E-101A5E00;4;WUP;00UB;WUP-U-ALLP;ALLPUB;OlliOlli +0005000E-101A5F00;2;WUP;00WY;WUP-U-BSXE;BSXEWY;Shantae and the Pirate's Curse +0005000E-101A6200;2;WUP;00WR;WUP-U-ALJE;ALJEWR;LEGO® Jurassic World™ +0005000E-101A6300;4;WUP;00YR;WUP-U-ACUP;ACUPYR;Cube Life: Island Survival +0005000E-101A6400;2;WUP;00YR;WUP-U-ACUE;ACUEYR;Cube Life: Island Survival +0005000E-101A6500;2;WUP;00VZ;WUP-P-BKFE;BKFEVZ;Kung Fu Panda Showdown of Legendary Legends +0005000E-101A6900;2;WUP;00UB;WUP-P-ALLE;ALLEUB;OlliOlli +0005000E-101A9500;4;WUP;00WY;WUP-U-BSXP;BSXPWY;Shantae and the Pirate's Curse +0005000E-101A9F00;2;WUP;0147;WUP-P-BDAE;BDAE47;Dot Arcade +0005000E-101AA500;4;WUP;00VZ;WUP-P-BKFP;BKFPVZ;Kung Fu Panda Showdown of Legendary Legends +0005000E-101ABC00;2;WUP;0001;WUP-U-AXYE;AXYE01;Kirby and the Rainbow Curse +0005000E-101AC700;2;WUP;00VZ;WUP-P-BFNE;BFNEVZ;Adventure Time Finn and Jake Investigations +0005000E-101AC900;2;WUP;004Q;WUP-P-BD3E;BD3E4Q;DISNEY INFINITY 3.0 EDITION +0005000E-101AFE00;4;WUP;00VZ;WUP-P-BFNP;BFNPVZ;Adventure Time Finn and Jake Investigations +0005000E-101B3D00;4;WUP;004Q;WUP-P-BD3P;BD3P4Q;DISNEY INFINITY 3.0: PLAY WITHOUT LIMITS +0005000E-101B3E00;4;WUP;004Q;WUP-P-BD3Z;BD3Z4Q;DISNEY INFINITY 3.0: PLAY WITHOUT LIMITS +0005000E-101B8500;2;WUP;0052;WUP-P-BS5E;BS5E52;Skylanders SuperChargers +0005000E-101B9000;2;WUP;0041;WUP-P-AJ6E;AJ6E41;JUST DANCE® 2016 +0005000E-101B9800;4;WUP;0041;WUP-P-AJ6P;AJ6P41;JUST DANCE® 2016 +0005000E-101BA400;2;WUP;0052;WUP-P-AGNE;AGNE52;Guitar Hero Live +0005000E-101BAA00;2;WUP;010C;WUP-U-ATTE;ATTE0C;Totem Topple +0005000E-101BB300;4;WUP;008V;WUP-P-WLSP;WLSP8V;ZaciSa: Defense of the Crayon Dimension! +0005000E-101BB800;4;WUP;011A;WUP-P-BEQP;BEQP1A;Elliot Quest +0005000E-101BC600;4;WUP;0052;WUP-P-AGNP;AGNP52;Guitar Hero Live +0005000E-101BE900;4;WUP;00WR;WUP-P-ALRP;ALRPWR;LEGO® MARVEL's Avengers +0005000E-101BEF00;2;WUP;00WR;WUP-P-ALRE;ALREWR;LEGO® MARVEL's Avengers +0005000E-101BFC00;4;WUP;0052;WUP-P-BS5P;BS5P52;Skylanders SuperChargers +0005000E-101C0700;4;WUP;00UB;WUP-U-AN3P;AN3PUB;Nova-111 +0005000E-101C0A00;2;WUP;00UB;WUP-U-AN3E;AN3EUB;Nova-111 +0005000E-101C0B00;2;WUP;00UB;WUP-P-BS7E;BS7EUB;The Swindle +0005000E-101C0C00;4;WUP;00UB;WUP-P-BS7P;BS7PUB;The Swindle +0005000E-101C3100;2;WUP;0167;WUP-U-AFEE;AFEE67;Freedom Planet +0005000E-101C3900;4;WUP;015G;WUP-P-AWBP;AWBP5G;Word Search by POWGI +0005000E-101C4C00;4;WUP;0001;WUP-P-AX5D;AX5D01;Xenoblade Chronicles X +0005000E-101C4D00;2;WUP;0001;WUP-P-AX5E;AX5E01;Xenoblade Chronicles X +0005000E-101C6A00;2;WUP;016E;WUP-P-AD5E;AD5E6E;Octodad: Dadliest Catch +0005000E-101C6E00;4;WUP;00RG;WUP-U-BS2P;BS2PRG;Swords & Soldiers II +0005000E-101C8B00;4;WUP;00YT;WUP-P-AWMP;AWMPYT;WICKED MONSTERS BLAST! HD PLUS +0005000E-101CC900;4;WUP;0167;WUP-U-AFEP;AFEP67;Freedom Planet +0005000E-101CE100;2;WUP;0175;WUP-U-ACHE;ACHE75;Canvaleon +0005000E-101D0700;4;WUP;0175;WUP-U-ACHP;ACHP75;Canvaleon +0005000E-101D0900;2;WUP;00FV;WUP-U-AGWE;AGWEFV;Gunman Clive HD Collection +0005000E-101D2C00;1;WUP;00SA;WUP-P-ATXJ;ATXJSA;Bike Rider UltraDX WORLD TOUR +0005000E-101D3900;4;WUP;017D;WUP-P-AQCP;AQCP7D;The Quiet Collection +0005000E-101D4200;2;WUP;00DV;WUP-P-ABPE;ABPEDV;Brunswick Pro Bowling +0005000E-101D6100;4;WUP;00FV;WUP-U-AGWP;AGWPFV;Gunman Clive HD Collection +0005000E-101D6D00;4;WUP;010P;WUP-P-ARNP;ARNP0P;Runbow +0005000E-101D7400;4;WUP;010C;WUP-U-ATTP;ATTP0C;Totem Topple +0005000E-101D7500;4;WUP;00DU;WUP-P-AUMP;AUMPDU;Minecraft: Wii U Edition +0005000E-101D9D00;2;WUP;00DU;WUP-P-AUME;AUMEDU;Minecraft: Wii U Edition +0005000E-101DBE00;1;WUP;0188;WUP-P-AUMJ;AUMJ88;Minecraft: Wii U Edition +0005000E-101DC100;4;WUP;016E;WUP-P-AD5P;AD5P6E;Octodad: Dadliest Catch +0005000E-101DDC00;1;WUP;00AF;WUP-P-BD3J;BD3JAF;????????????3.0 diff --git a/src/de/mas/jnustool/Directory.java b/src/de/mas/jnustool/Directory.java index 75bc4e1..57044b5 100644 --- a/src/de/mas/jnustool/Directory.java +++ b/src/de/mas/jnustool/Directory.java @@ -66,14 +66,15 @@ public class Directory { @Override public String toString(){ - System.out.println(name + ":"); + StringBuilder sb = new StringBuilder(); + sb.append(name + ":" + "\n"); for(Directory d : folder.values()){ - System.out.println(d); + sb.append(d + "\n"); } for(String s : files.keySet()){ - System.out.println(s); + sb.append(s + "\n"); } - return ""; + return sb.toString(); } public DefaultMutableTreeNode getNodes(){ diff --git a/src/de/mas/jnustool/FEntry.java b/src/de/mas/jnustool/FEntry.java index b19b9f5..83fd6d9 100644 --- a/src/de/mas/jnustool/FEntry.java +++ b/src/de/mas/jnustool/FEntry.java @@ -6,7 +6,6 @@ import java.util.List; 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 FEntry { @@ -156,14 +155,13 @@ public class FEntry { return folder; } - public void downloadAndDecrypt() throws ExitException { - + public void downloadAndDecrypt() { createFolder(); long titleID = getTitleID(); File f = new File(String.format("%016X", titleID) +"/" +getFullPath().substring(1, getFullPath().length())); if(f.exists()){ if(f.length() == getFileLength()){ - System.out.println("Skipping: " + String.format("%8.2f MB ",getFileLength()/1024.0/1024.0) + getFullPath()); + Logger.log("Skipping: " + String.format("%8.2f MB ",getFileLength()/1024.0/1024.0) + getFullPath()); return; } } @@ -172,44 +170,45 @@ public class FEntry { f = new File(getContentPath()); if(f.exists()){ if(f.length() == fst.getTmd().contents[this.getContentID()].size){ - System.out.println("Decrypting: " + String.format("%8.2f MB ", getFileLength()/1024.0/1024.0) + getFullPath()); + Logger.log("Decrypting: " + String.format("%8.2f MB ", getFileLength()/1024.0/1024.0) + getFullPath()); Decryption decrypt = new Decryption(fst.getTmd().getNUSTitle().getTicket()); decrypt.decrypt(this,getDownloadPath()); return; }else{ if(!Settings.downloadWhenCachedFilesMissingOrBroken){ - System.out.println("Cached content has the wrong size! Please check your: "+ getContentPath() + " Downloading not allowed"); - if(!Settings.skipBrokenFiles){ - throw new ExitException(""); + Logger.log("Cached content has the wrong size! Please check your: "+ getContentPath() + " Downloading not allowed"); + if(!Settings.skipBrokenFiles){ + System.err.println("File broken!"); + System.exit(2); }else{ - System.out.println("Ignoring the missing file: " + this.getFileName()); + Logger.log("Ignoring the missing file: " + this.getFileName()); } }else{ - System.out.println("Content missing. Downloading the file from the server: " + this.getFileName()); + Logger.log("Content missing. Downloading the file from the server: " + this.getFileName()); } } }else{ if(!Settings.downloadWhenCachedFilesMissingOrBroken){ - System.out.println("Content missing. Downloading not allowed"); + Logger.log("Content missing. Downloading not allowed"); if(!Settings.skipBrokenFiles){ - throw new ExitException(""); + System.err.println("File broken!"); + System.exit(2); }else{ - System.out.println("Ignoring the missing file: " + this.getFileName()); + Logger.log("Ignoring the missing file: " + this.getFileName()); } }else{ - System.out.println("Content missing. Downloading the file from the server: " + this.getFileName()); + Logger.log("Content missing. Downloading the file from the server: " + this.getFileName()); } } } - System.out.println("Downloading: " + String.format("%8.2f MB ", getFileLength()/1024.0/1024.0) + getFullPath()); + Logger.log("Downloading: " + String.format("%8.2f MB ", getFileLength()/1024.0/1024.0) + getFullPath()); Downloader.getInstance().downloadAndDecrypt(this); } catch (IOException e) { - - // TODO Auto-generated catch block e.printStackTrace(); + System.exit(2); } } diff --git a/src/de/mas/jnustool/FST.java b/src/de/mas/jnustool/FST.java index b4887cf..0d82986 100644 --- a/src/de/mas/jnustool/FST.java +++ b/src/de/mas/jnustool/FST.java @@ -18,7 +18,7 @@ public class FST { int totalEntries = 0; int dirEntries = 0; - + public FEntry metaFENtry; private Directory FSTDirectory = new Directory("root"); private Directory contentDirectory = new Directory("root"); @@ -86,13 +86,13 @@ 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"); } this.totalContentCount = Util.getIntFromBytes(decrypteddata, 8); int base_offset = 0x20+totalContentCount*0x20; - this.totalEntries = Util.getIntFromBytes(decrypteddata, base_offset+8); int nameOff = base_offset + totalEntries * 0x10; @@ -138,6 +138,8 @@ public class FST { while(decrypteddata[nameoff_entry + j] != 0){j++;} filename = new String(Arrays.copyOfRange(decrypteddata,nameoff_entry, nameoff_entry + j)); + + //getting offsets. save in two ways offset+=4; fileOffset = (long) Util.getIntFromBytes(decrypteddata, offset); @@ -188,9 +190,8 @@ public class FST { String tmpname = new String(Arrays.copyOfRange(decrypteddata,nameoff_entrypath, nameoff_entrypath + k)); if(!tmpname.equals("")){ pathList.add(tmpname); - } - - + + } sb.append(tmpname); sb.append("/"); @@ -199,8 +200,12 @@ public class FST { } //add this to the List! - fileEntries.add(new FEntry(path,filename,contentID,tmd.contents[contentID].ID,fileOffset,fileLength,dir,in_nus_title,extract_withHash,pathList,this)); - //System.out.println(fileEntries.get(i)); + FEntry tmp = new FEntry(path,filename,contentID,tmd.contents[contentID].ID,fileOffset,fileLength,dir,in_nus_title,extract_withHash,pathList,this); + fileEntries.add(tmp); + if(filename.equals("meta.xml")){ + metaFENtry = tmp; + } + //Logger.log(fileEntries.get(i)); } } diff --git a/src/de/mas/jnustool/Logger.java b/src/de/mas/jnustool/Logger.java new file mode 100644 index 0000000..23fdfa5 --- /dev/null +++ b/src/de/mas/jnustool/Logger.java @@ -0,0 +1,13 @@ +package de.mas.jnustool; + +import de.mas.jnustool.gui.NUSGUI; + +public class Logger { + + public static void log(String string) { + NUSGUI.output.append(string + "\n"); + NUSGUI.output.setCaretPosition(NUSGUI.output.getDocument().getLength()); + + } + +} diff --git a/src/de/mas/jnustool/NUSTitle.java b/src/de/mas/jnustool/NUSTitle.java index a4b97e0..0a7a784 100644 --- a/src/de/mas/jnustool/NUSTitle.java +++ b/src/de/mas/jnustool/NUSTitle.java @@ -5,10 +5,12 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ForkJoinPool; 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 { @@ -16,21 +18,22 @@ public class NUSTitle { private TIK ticket; private FST fst; private long titleID; - public NUSTitle(long titleId,String key) throws ExitException{ + public NUSTitle(long titleId,String key) { setTitleID(titleId); - try { + 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"); + Logger.log("Downloading TMD"); Downloader.getInstance().downloadTMD(titleId,getContentPath()); }else{ - System.out.println("Skipped download of TMD. Already existing"); + Logger.log("Skipped download of TMD. Already existing"); } f = new File(getContentPath() + "/" + "cetk"); if(!(f.exists() && Settings.skipExistingTMDTICKET)){ @@ -39,50 +42,48 @@ public class NUSTitle { Downloader.getInstance().downloadTicket(titleId,getContentPath()); } }else{ - System.out.println("Skipped download of ticket. Already existing"); + Logger.log("Skipped download of ticket. Already existing"); } } if(Settings.useCachedFiles){ File f = new File(getContentPath() + "/" + "tmd"); if(f.exists()){ - System.out.println("Using cached TMD."); + Logger.log("Using cached TMD."); tmd = new TitleMetaData(f); }else{ - System.out.println("No cached TMD found."); + Logger.log("No cached TMD found."); } } - if(tmd == null){ if(Settings.downloadWhenCachedFilesMissingOrBroken){ - if(Settings.useCachedFiles) System.out.println("Getting missing tmd from Server!"); + if(Settings.useCachedFiles) Logger.log("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."); + Logger.log("Downloading of missing files is not enabled. Exiting"); + System.exit(2); } } - if(key != null){ - System.out.println("Using ticket from parameter."); + Logger.log("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."); + Logger.log("Using cached cetk."); ticket = new TIK(f,titleId); }else{ - System.out.println("No cached ticket found."); + Logger.log("No cached ticket found."); } } if(ticket == null){ if(Settings.downloadWhenCachedFilesMissingOrBroken){ - if(Settings.useCachedFiles) System.out.println("getting missing ticket"); + if(Settings.useCachedFiles) Logger.log("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."); + Logger.log("Downloading of missing files is not enabled. Exiting"); + System.exit(2); } } } @@ -90,47 +91,52 @@ public class NUSTitle { 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) + ")"); + Logger.log("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."); + Logger.log("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."); + Logger.log("FST already existing, but broken. No download allowed."); + System.exit(2); } }else{ - System.out.println("Skipped download of FST. Already existing"); + Logger.log("Skipped download of FST. Already existing"); } } } + Decryption decryption = new Decryption(ticket.getDecryptedKey(),0); byte[] encryptedFST = null; if(Settings.useCachedFiles){ + Logger.log(getContentPath()); 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"); + Logger.log("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."); - } + Logger.log("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."); + if(Settings.useCachedFiles)Logger.log("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(""); + Logger.log("Downloading of missing files is not enabled. Exiting"); + System.exit(2); } - } + } + + + decryption.init(ticket.getDecryptedKey(), 0); byte[] decryptedFST = decryption.decrypt(encryptedFST); fst = new FST(decryptedFST,tmd); @@ -140,11 +146,11 @@ public class NUSTitle { 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()); + Logger.log("Total Size of Content Files: " + ((int)((getTotalContentSize()/1024.0/1024.0)*100))/100.0 +" MB"); + Logger.log("Total Size of Decrypted Files: " + ((int)((fst.getTotalContentSizeInNUS()/1024.0/1024.0)*100))/100.0 +" MB"); + Logger.log("Entries: " + fst.getTotalEntries()); + Logger.log("Entries: " + fst.getFileCount()); + Logger.log("Files in NUSTitle: " + fst.getFileCountInNUS()); } catch (IOException e) { // TODO Auto-generated catch block @@ -200,7 +206,7 @@ public class NUSTitle { - private long getTitleID() { + public long getTitleID() { return titleID; } @@ -208,6 +214,19 @@ public class NUSTitle { this.titleID = titleId; } + public void decryptFEntries(List list) { + ForkJoinPool pool = ForkJoinPool.commonPool(); + List dlList = new ArrayList<>(); + for(FEntry f : list){ + if(!f.isDir() && f.isInNUSTitle()){ + dlList.add(new FEntryDownloader(f)); + } + } + + pool.invokeAll(dlList); + Logger.log("Done!"); + } + } diff --git a/src/de/mas/jnustool/Starter.java b/src/de/mas/jnustool/Starter.java index b3f4a54..6947fc3 100644 --- a/src/de/mas/jnustool/Starter.java +++ b/src/de/mas/jnustool/Starter.java @@ -4,49 +4,119 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import de.mas.jnustool.gui.NUSGUI; +import de.mas.jnustool.gui.UpdateChooser; import de.mas.jnustool.util.Downloader; -import de.mas.jnustool.util.ExitException; +import de.mas.jnustool.util.NUSTitleInformation; import de.mas.jnustool.util.Util; public class Starter { - public static void main(String[] args) { - System.out.println("JNUSTool 0.0.2 - pre alpha - by Maschell"); - System.out.println(); + private static String updateCSVPath; + + public static void main(String[] args) { + Logger.log("JNUSTool 0.0.3 - pre alpha - by Maschell"); + Logger.log(""); try { - readConfig(); + readConfig(); + } catch (IOException e) { System.err.println("Error while reading config! Needs to be:"); System.err.println("DOWNLOAD URL BASE"); System.err.println("COMMONKEY"); return; } - if(args.length != 0){ - long titleID = Util.StringToLong(args[0]); - String key = null; + + long titleID = 0; + String key = null; + if(args.length != 0 ){ + titleID = Util.StringToLong(args[0]); if( args.length > 1 && args[1].length() == 32){ key = args[1].substring(0, 32); } - NUSGUI m; - try { - m = new NUSGUI(new NUSTitle(titleID, key), null); - } catch (ExitException e) { - System.out.println("Error: " + e.getMessage()); - return; - } - m.setVisible(true); }else{ - System.out.println("Need parameters: TITLEID [KEY]"); + titleID = getTitleID().getTitleID(); + } + if(titleID != 0){ + NUSGUI m = new NUSGUI(new NUSTitle(titleID, key), null); + m.setVisible(true); } } + + + + private static NUSTitleInformation getTitleID() { + List updatelist = readUpdateCSV(); + NUSTitleInformation result = null; + if(updatelist != null){ + result = new NUSTitleInformation(); + UpdateChooser.createAndShowGUI(updatelist,result); + synchronized (result) { + try { + result.wait(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + return result; + } + + + + @SuppressWarnings("resource") + private static List readUpdateCSV() { + if(updateCSVPath == null) return null; + BufferedReader in = null; + List list = new ArrayList<>(); + try { + in = new BufferedReader(new FileReader(new File(updateCSVPath))); + String line; + while((line = in.readLine()) != null){ + String[] infos = line.split(";"); + if(infos.length != 7) { + System.out.println("Updatelist is broken!"); + return null; + } + long titleID = Util.StringToLong(infos[0].replace("-", "")); + int region = Integer.parseInt(infos[1]); + String content_platform = infos[2]; + String company_code = infos[3]; + String product_code = infos[4]; + String ID6 = infos[5]; + String longnameEN = infos[6]; + NUSTitleInformation info = new NUSTitleInformation(titleID, longnameEN, ID6, product_code, content_platform, company_code, region); + list.add(info); + } + in.close(); + } catch (IOException | NumberFormatException e) { + try { + in.close(); + } catch (IOException e1) { + } + System.out.println("Updatelist is broken!"); + return null; + } + return list; + } + + public static void readConfig() throws IOException { BufferedReader in = new BufferedReader(new FileReader(new File("config"))); - Downloader.URL_BASE = in.readLine(); - Util.commonKey = Util.hexStringToByteArray(in.readLine()); + Downloader.URL_BASE = in.readLine(); + String commonkey = in.readLine(); + if(commonkey.length() != 32){ + System.out.println("Commonkey length is wrong"); + System.exit(1); + } + Util.commonKey = Util.hexStringToByteArray(commonkey); + updateCSVPath = in.readLine(); in.close(); } diff --git a/src/de/mas/jnustool/TitleMetaData.java b/src/de/mas/jnustool/TitleMetaData.java index 908348c..d8320e2 100644 --- a/src/de/mas/jnustool/TitleMetaData.java +++ b/src/de/mas/jnustool/TitleMetaData.java @@ -3,17 +3,9 @@ package de.mas.jnustool; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.RandomAccessFile; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.security.DigestInputStream; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; import de.mas.jnustool.util.Downloader; -import de.mas.jnustool.util.ExitException; import de.mas.jnustool.util.Settings; import de.mas.jnustool.util.Util; @@ -47,9 +39,10 @@ public class TitleMetaData { setTotalContentSize(); } - public TitleMetaData(byte[] downloadTMDToByteArray) throws IOException { - if(downloadTMDToByteArray != null){ - File tempFile = File.createTempFile("bla","blubb"); + public TitleMetaData(byte[] downloadTMDToByteArray) throws IOException { + if(downloadTMDToByteArray != null){ + File tempFile; + tempFile = File.createTempFile("bla","blubb"); FileOutputStream fos = new FileOutputStream(tempFile); fos.write(downloadTMDToByteArray); fos.close(); @@ -62,6 +55,7 @@ public class TitleMetaData { } private void parse(File tmd) throws IOException { + RandomAccessFile f = new RandomAccessFile(tmd, "r"); f.seek(0); this.signatureType = f.readInt(); @@ -163,7 +157,7 @@ public class TitleMetaData { return totalContentSize; } - public void downloadContents() throws IOException, ExitException{ + public void downloadContents() throws IOException{ String tmpPath = getContentPath(); File f = new File(tmpPath); if(!f.exists())f.mkdir(); @@ -173,22 +167,22 @@ public class TitleMetaData { f = new File(tmpPath + "/" + String.format("%08X", c.ID ) + ".app"); if(f.exists()){ if(f.length() == c.size){ - System.out.println("Skipping Content: " + String.format("%08X", c.ID)); + Logger.log("Skipping Content: " + String.format("%08X", c.ID)); }else{ if(Settings.downloadWhenCachedFilesMissingOrBroken){ - System.out.println("Content " +String.format("%08X", c.ID) + " is broken. Downloading it again."); + Logger.log("Content " +String.format("%08X", c.ID) + " is broken. Downloading it again."); Downloader.getInstance().downloadContent(titleID,c.ID,tmpPath); }else{ if(Settings.skipBrokenFiles){ - System.out.println("Content " +String.format("%08X", c.ID) + " is broken. Ignoring it."); + Logger.log("Content " +String.format("%08X", c.ID) + " is broken. Ignoring it."); }else{ - System.out.println("Content " +String.format("%08X", c.ID) + " is broken. Downloading not allowed."); - throw new ExitException("Content missing."); + Logger.log("Content " +String.format("%08X", c.ID) + " is broken. Downloading not allowed."); + System.exit(2); } } } }else{ - System.out.println("Download Content: " + String.format("%08X", c.ID)); + Logger.log("Download Content: " + String.format("%08X", c.ID)); Downloader.getInstance().downloadContent(titleID,c.ID,tmpPath); } } diff --git a/src/de/mas/jnustool/gui/JCheckBoxTree.java b/src/de/mas/jnustool/gui/JCheckBoxTree.java index ac93305..781bc40 100644 --- a/src/de/mas/jnustool/gui/JCheckBoxTree.java +++ b/src/de/mas/jnustool/gui/JCheckBoxTree.java @@ -160,8 +160,6 @@ public class JCheckBoxTree extends JTree { public JCheckBoxTree(NUSTitle nus) { super(); - - setModel(new DefaultTreeModel(nus.getFst().getFSTDirectory().getNodes())); diff --git a/src/de/mas/jnustool/gui/NUSGUI.java b/src/de/mas/jnustool/gui/NUSGUI.java index 5c061f7..af1d2fb 100644 --- a/src/de/mas/jnustool/gui/NUSGUI.java +++ b/src/de/mas/jnustool/gui/NUSGUI.java @@ -5,75 +5,80 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.ForkJoinPool; import javax.swing.JButton; import javax.swing.JFrame; +import javax.swing.JPanel; import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTextArea; +import javax.swing.ScrollPaneConstants; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; import de.mas.jnustool.FEntry; import de.mas.jnustool.NUSTitle; import de.mas.jnustool.util.Settings; -import de.mas.jnustool.FEntryDownloader; 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) { super(); - setSize(800, 600); - getContentPane().setLayout(new BorderLayout(0, 0)); - - final JCheckBoxTree cbt = new JCheckBoxTree(nus); - JScrollPane qPane = new JScrollPane(cbt, - JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, - JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - this.getContentPane().add(qPane); + this.setResizable(false); + setSize(600, 768); + setTitle(String.format("%016X", nus.getTitleID())); + getContentPane().setLayout(null); + JSplitPane splitPane = new JSplitPane(); + splitPane.setBounds(0, 0, 594, 726); + splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT); + getContentPane().add(splitPane, BorderLayout.NORTH); + JScrollPane qPane = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, + JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + + + this.getContentPane().add(splitPane); + final JCheckBoxTree cbt = new JCheckBoxTree(nus); + qPane.setViewportView(cbt); + + JPanel panel = new JPanel(); + panel.setLayout(new BorderLayout(0, 0)); + panel.add(qPane); + splitPane.setLeftComponent(panel); JButton btnNewButton = new JButton("Download"); + panel.add(btnNewButton, BorderLayout.SOUTH); + btnNewButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - new Thread(new Runnable() { public void run() { - ForkJoinPool pool = ForkJoinPool.commonPool(); - List list = new ArrayList<>(); - + new Thread(new Runnable() { public void run() { + List list = new ArrayList<>(); TreePath[] paths = cbt.getCheckedPaths(); for (TreePath tp : paths) { - Object obj = tp.getPath()[tp.getPath().length-1]; if(((DefaultMutableTreeNode)obj).getUserObject() instanceof FEntry){ - FEntry f = (FEntry) ((DefaultMutableTreeNode)obj).getUserObject(); - if(!f.isDir() && f.isInNUSTitle()){ - list.add(new FEntryDownloader(f)); - } - + list.add((FEntry) ((DefaultMutableTreeNode)obj).getUserObject()); } } - pool.invokeAll(list); - System.out.println("Done!"); + + nus.decryptFEntries(list); }}).start(); } }); - getContentPane().add(btnNewButton, BorderLayout.SOUTH); + JScrollPane outputPane = new JScrollPane(output, + ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); - /*cbt.addCheckChangeEventListener(new JCheckBoxTree.CheckChangeEventListener() { - public void checkStateChanged(JCheckBoxTree.CheckChangeEvent event) { - System.out.println("event"); - TreePath[] paths = cbt.getCheckedPaths(); - for (TreePath tp : paths) { - for (Object pathPart : tp.getPath()) { - System.out.print(pathPart + ","); - } - System.out.println(); - } - } - });*/ + splitPane.setRightComponent(outputPane); + + splitPane.setDividerLocation(0.7); + splitPane.setResizeWeight(0.7); + + splitPane.setEnabled(false); this.setDefaultCloseOperation(EXIT_ON_CLOSE); } diff --git a/src/de/mas/jnustool/gui/UpdateChooser.java b/src/de/mas/jnustool/gui/UpdateChooser.java new file mode 100644 index 0000000..7bda788 --- /dev/null +++ b/src/de/mas/jnustool/gui/UpdateChooser.java @@ -0,0 +1,190 @@ +package de.mas.jnustool.gui; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Collections; +import java.util.List; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTable; +import javax.swing.JTextArea; +import javax.swing.ListSelectionModel; +import javax.swing.ScrollPaneConstants; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import de.mas.jnustool.util.NUSTitleInformation; + +public class UpdateChooser extends JPanel { + /** + * + */ + private static final long serialVersionUID = 1L; + JTextArea output; + JList list; + JTable table; + String newline = "\n"; + ListSelectionModel listSelectionModel; + public UpdateChooser(JFrame window) { + super(new BorderLayout()); + setSize(800, 600); + + Collections.sort(list_); + output_.init(list_.get(0)); + String[] columnNames = { "TitleID", "Region", "Name" }; + String[][] tableData = new String[list_.size()][]; + int i = 0; + for(NUSTitleInformation n: list_){ + tableData[i] = new String[3]; + tableData[i][0] = n.getTitleIDAsString(); + tableData[i][1] = n.getRegionAsRegion().toString(); + tableData[i][2] = n.getLongnameEN(); + i++; + } + + + table = new JTable(tableData, columnNames); + + + + //table.setModel(tableModel); + for (int c = 0; c < table.getColumnCount(); c++) + { + Class col_class = table.getColumnClass(c); + table.setDefaultEditor(col_class, null); // remove editor + } + + table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + table.getColumnModel().getColumn(0).setPreferredWidth(150); + table.getColumnModel().getColumn(1).setPreferredWidth(50); + table.getColumnModel().getColumn(2).setPreferredWidth(350); + + listSelectionModel = table.getSelectionModel(); + listSelectionModel.addListSelectionListener(new SharedListSelectionHandler()); + + + + table.setSelectionModel(listSelectionModel); + + table.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + if (me.getClickCount() == 2) { + synchronized (output_) { + window.setVisible(false); + output_.notifyAll(); + } + } + } + }); + + JScrollPane tablePane = new JScrollPane(table); + //Build control area (use default FlowLayout). + JPanel controlPane = new JPanel(); + + + listSelectionModel.setSelectionMode( + ListSelectionModel.SINGLE_SELECTION); + + //Build output area. + output = new JTextArea(1, 10); + output.setEditable(false); + JScrollPane outputPane = new JScrollPane(output, + ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + + //Do the layout. + JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); + add(splitPane, BorderLayout.CENTER); + + JPanel topHalf = new JPanel(); + topHalf.setLayout(new BoxLayout(topHalf, BoxLayout.LINE_AXIS)); + JPanel tableContainer = new JPanel(new GridLayout(1,1)); + tableContainer.setBorder(BorderFactory.createTitledBorder( + "Table")); + tableContainer.add(tablePane); + tablePane.setPreferredSize(new Dimension(420, 130)); + topHalf.setBorder(BorderFactory.createEmptyBorder(5,5,0,5)); + topHalf.add(tableContainer); + + topHalf.setMinimumSize(new Dimension(250, 50)); + topHalf.setPreferredSize(new Dimension(200, 110)); + splitPane.add(topHalf); + JPanel listContainer = new JPanel(new GridLayout(1,1)); + add(listContainer, BorderLayout.NORTH); + JButton btnNewButton = new JButton("Okay"); + btnNewButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + System.out.println("lol"); + 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_; + static List list_; + public static void createAndShowGUI(List list,NUSTitleInformation output) { + //Create and set up the window. + JFrame frame = new JFrame("Select the title"); + + //Create and set up the content pane. + list_ = list; + output_ =output; + UpdateChooser demo = new UpdateChooser(frame); + demo.setOpaque(true); + frame.setContentPane(demo); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + //Display the window. + frame.setSize(610, 600); + + frame.setResizable(false); + frame.setVisible(true); + + } + + class SharedListSelectionHandler implements ListSelectionListener { + public void valueChanged(ListSelectionEvent e) { + ListSelectionModel lsm = (ListSelectionModel)e.getSource(); + + if (lsm.isSelectionEmpty()) { + + } else { + // Find out which indexes are selected. + int minIndex = lsm.getMinSelectionIndex(); + int maxIndex = lsm.getMaxSelectionIndex(); + for (int i = minIndex; i <= maxIndex; i++) { + if (lsm.isSelectedIndex(i)) { + output_.init(list_.get(i)); + } + } + } + + } + } +} diff --git a/src/de/mas/jnustool/util/ByteArrayBuffer.java b/src/de/mas/jnustool/util/ByteArrayBuffer.java new file mode 100644 index 0000000..7799749 --- /dev/null +++ b/src/de/mas/jnustool/util/ByteArrayBuffer.java @@ -0,0 +1,33 @@ +package de.mas.jnustool.util; + +public class ByteArrayBuffer { + public byte[] buffer; + int lengthOfDataInBuffer; + + public ByteArrayBuffer(int length){ + buffer = new byte[(int) length]; + } + + public int getLengthOfDataInBuffer() { + return lengthOfDataInBuffer; + } + + public void setLengthOfDataInBuffer(int lengthOfDataInBuffer) { + this.lengthOfDataInBuffer = lengthOfDataInBuffer; + } + + public int getSpaceLeft() { + return buffer.length - getLengthOfDataInBuffer(); + } + + public void addLengthOfDataInBuffer(int bytesRead) { + lengthOfDataInBuffer += bytesRead; + } + + public void resetLengthOfDataInBuffer() { + setLengthOfDataInBuffer(0); + } + + + +} diff --git a/src/de/mas/jnustool/util/Decryption.java b/src/de/mas/jnustool/util/Decryption.java index dfd59b4..f2ebc43 100644 --- a/src/de/mas/jnustool/util/Decryption.java +++ b/src/de/mas/jnustool/util/Decryption.java @@ -1,12 +1,13 @@ package de.mas.jnustool.util; -import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; @@ -32,19 +33,14 @@ public class Decryption { this(decryptedKey,0); } - public Decryption(byte[] decryptedKey, long titleId) { + public Decryption(byte[] decryptedKey, long titleId) { try { cipher2 = Cipher.getInstance("AES/CBC/NoPadding"); - this.decryptedKey = decryptedKey; - init(titleId); - - } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (NoSuchPaddingException e) { - // TODO Auto-generated catch block + } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { e.printStackTrace(); } + this.decryptedKey = decryptedKey; + init(titleId); } @@ -64,13 +60,13 @@ public class Decryption { } public void init(byte[] decryptedKey,byte[] iv){ + this.decryptedKey = decryptedKey; + SecretKeySpec secretKeySpec = new SecretKeySpec(decryptedKey, "AES"); try { - this.decryptedKey = decryptedKey; - SecretKeySpec secretKeySpec = new SecretKeySpec(decryptedKey, "AES"); - cipher2.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(iv)); - } catch (Exception e) { - // TODO Auto-generated catch block + cipher2.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(iv)); + } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { e.printStackTrace(); + System.exit(2); } } @@ -78,8 +74,8 @@ public class Decryption { try { return cipher2.doFinal(input); } catch (IllegalBlockSizeException | BadPaddingException e) { - // TODO Auto-generated catch block e.printStackTrace(); + System.exit(2); } return input; } @@ -92,8 +88,8 @@ public class Decryption { try { return cipher2.doFinal(input, offset, len); } catch (IllegalBlockSizeException | BadPaddingException e) { - // TODO Auto-generated catch block e.printStackTrace(); + System.exit(2); } return input; } @@ -130,19 +126,16 @@ public class Decryption { byte[] output = decryptFileChunk(blockBuffer,0x400,0xFC00,IV); hash = hash(output); - if(block == 0){ - + if(block == 0) hash[1] ^= contentID; - - } - if(Arrays.equals(hash, h0)){ - //System.out.println("checksum right"); - } - else{ + + if(!Arrays.equals(hash, h0)){ System.out.println("checksum failed"); System.out.println(Util.ByteArrayToString(hash)); System.out.println(Util.ByteArrayToString(h0)); - throw new IllegalArgumentException("checksumfail"); + throw new IllegalArgumentException("checksumfail"); + }else{ + //System.out.println("checksum right!"); } return output; } @@ -151,7 +144,6 @@ public class Decryption { try { byte[] hash = new byte[20]; MessageDigest md = MessageDigest.getInstance("SHA-1"); - hash = md.digest(hashThis); return hash; } catch (NoSuchAlgorithmException nsae) { @@ -162,67 +154,25 @@ public class Decryption { } - public void decryptFile(InputStream inputSteam, OutputStream outputStream,FEntry toDownload) throws IOException{ + public void decryptFile(InputStream inputStream, OutputStream outputStream,FEntry toDownload) throws IOException{ int BLOCKSIZE = 0x8000; long dlFileLength = toDownload.getFileLength(); if(dlFileLength > (dlFileLength/BLOCKSIZE)*BLOCKSIZE){ dlFileLength = ((dlFileLength/BLOCKSIZE)*BLOCKSIZE) +BLOCKSIZE; - } - - int bytesRead = -1; - + } + byte[] IV = new byte[16]; IV[1] = (byte)toDownload.getContentID(); - - byte[] downloadBuffer; - + byte[] blockBuffer = new byte[BLOCKSIZE]; - byte[] overflowBuffer = new byte[BLOCKSIZE]; - int overflowsize = 0; - int inBlockBuffer = 0; - byte[] tmp = new byte[BLOCKSIZE]; - boolean endd = false; - long downloadTotalsize = 0; + int inBlockBuffer; long wrote = 0; boolean first = true; - do{ - downloadBuffer = new byte[BLOCKSIZE-overflowsize]; - - bytesRead = inputSteam.read(downloadBuffer); - downloadTotalsize += bytesRead; - if(bytesRead ==-1){ - endd = true; - } - - if(!endd)System.arraycopy(downloadBuffer, 0, overflowBuffer, overflowsize,bytesRead); - - bytesRead += overflowsize; - - overflowsize = 0; - int oldInThisBlock = inBlockBuffer; - - if(oldInThisBlock + bytesRead > BLOCKSIZE){ - - int tooMuch = (oldInThisBlock + bytesRead) - BLOCKSIZE; - int toRead = BLOCKSIZE - oldInThisBlock; - - System.arraycopy(overflowBuffer, 0, blockBuffer, oldInThisBlock, toRead); - inBlockBuffer += toRead; - - overflowsize = tooMuch; - System.arraycopy(overflowBuffer, toRead, tmp, 0, tooMuch); - - System.arraycopy(tmp, 0, overflowBuffer, 0, tooMuch); - - - }else{ - if(!endd)System.arraycopy(overflowBuffer, 0, blockBuffer, inBlockBuffer, bytesRead); - inBlockBuffer +=bytesRead; - } - - if(inBlockBuffer == BLOCKSIZE || endd){ + ByteArrayBuffer overflow = new ByteArrayBuffer(BLOCKSIZE); + do{ + inBlockBuffer = getChunkFromStream(inputStream,blockBuffer,overflow,BLOCKSIZE); if(first){ first = false; }else{ @@ -237,101 +187,56 @@ public class Decryption { wrote += inBlockBuffer; outputStream.write(output, 0, inBlockBuffer); - - inBlockBuffer = 0; - } - - }while(downloadTotalsize < dlFileLength && !endd); + }while(inBlockBuffer == BLOCKSIZE); outputStream.close(); - inputSteam.close(); + inputStream.close(); } - - public void decryptFileHash(InputStream inputSteam, OutputStream outputStream,FEntry toDownload) throws IOException{ + public void decryptFileHash(InputStream inputStream, OutputStream outputStream,FEntry toDownload) throws IOException{ int BLOCKSIZE = 0x10000; int HASHBLOCKSIZE = 0xFC00; - long writeSize = HASHBLOCKSIZE; // Hash block size - long block = (toDownload.getFileOffset() / HASHBLOCKSIZE) & 0xF; - - long soffset = toDownload.getFileOffset() - (toDownload.getFileOffset() / HASHBLOCKSIZE * HASHBLOCKSIZE); - + long writeSize = HASHBLOCKSIZE; + long block = (toDownload.getFileOffset() / HASHBLOCKSIZE) & 0xF; + long soffset = toDownload.getFileOffset() - (toDownload.getFileOffset() / HASHBLOCKSIZE * HASHBLOCKSIZE); long size = toDownload.getFileLength(); if( soffset+size > writeSize ) writeSize = writeSize - soffset; - - int bytesRead = -1; - byte[] downloadBuffer; byte[] encryptedBlockBuffer = new byte[BLOCKSIZE]; - byte[] buffer = new byte[BLOCKSIZE]; - - int encryptedBytesInBuffer = 0; - int bufferPostion = 0; - - - byte[] tmp = new byte[BLOCKSIZE]; - boolean lastPart = false; + ByteArrayBuffer overflow = new ByteArrayBuffer(BLOCKSIZE); + long wrote = 0; - + int inBlockBuffer; do{ - downloadBuffer = new byte[BLOCKSIZE-bufferPostion]; - bytesRead = inputSteam.read(downloadBuffer); - int bytesInBuffer = bytesRead + bufferPostion; - if(bytesRead ==-1){ - lastPart = true; - }else{ - System.arraycopy(downloadBuffer, 0, buffer, bufferPostion,bytesRead); //copy downloaded stuff in buffer - bufferPostion = 0; - } - - if(encryptedBytesInBuffer + bytesInBuffer > BLOCKSIZE){ - int tooMuch = (encryptedBytesInBuffer + bytesInBuffer) - BLOCKSIZE; - int toRead = BLOCKSIZE - encryptedBytesInBuffer; + inBlockBuffer = getChunkFromStream(inputStream,encryptedBlockBuffer,overflow,BLOCKSIZE); - System.arraycopy(buffer, 0, encryptedBlockBuffer, encryptedBytesInBuffer, toRead); // make buffer with encrypteddata full - encryptedBytesInBuffer += toRead; - - bufferPostion = tooMuch; //set buffer position; - System.arraycopy(buffer, toRead, tmp, 0, tooMuch); - System.arraycopy(tmp, 0, buffer, 0, tooMuch); - - }else{ - if(!lastPart) System.arraycopy(buffer, 0, encryptedBlockBuffer, encryptedBytesInBuffer, bytesInBuffer); //When File if at the end, no more need to copy - encryptedBytesInBuffer +=bytesInBuffer; - } + if( writeSize > size ) + writeSize = size; - //If downloaded BLOCKSIZE, or file at the end: Decrypt! - if(encryptedBytesInBuffer == BLOCKSIZE || lastPart){ - - if( writeSize > size ) - writeSize = size; - - byte[] output = decryptFileChunkHash(encryptedBlockBuffer, BLOCKSIZE, (int) block,toDownload.getContentID()); - - if((wrote + writeSize) > toDownload.getFileLength()){ - writeSize = (int) (toDownload.getFileLength()- wrote); - } - - outputStream.write(output, (int)(0+soffset), (int)writeSize); - wrote +=writeSize; - encryptedBytesInBuffer = 0; - - block++; - if( block >= 16 ) - block = 0; - - if( soffset > 0) - { - writeSize = HASHBLOCKSIZE; - soffset = 0; - } - } - }while(wrote < toDownload.getFileLength() || lastPart); + byte[] output = decryptFileChunkHash(encryptedBlockBuffer, BLOCKSIZE, (int) block,toDownload.getContentID()); + + if((wrote + writeSize) > toDownload.getFileLength()){ + writeSize = (int) (toDownload.getFileLength()- wrote); + } + + outputStream.write(output, (int)(0+soffset), (int)writeSize); + wrote +=writeSize; + + block++; + if( block >= 16 ) + block = 0; + + if( soffset > 0) + { + writeSize = HASHBLOCKSIZE; + soffset = 0; + } + }while(wrote < toDownload.getFileLength() && (inBlockBuffer == BLOCKSIZE)); outputStream.close(); - inputSteam.close(); + inputStream.close(); } @@ -359,12 +264,36 @@ public class Decryption { decryptFile(input, outputStream, fileEntry); }else{ decryptFileHash(input, outputStream, fileEntry); - } - + } } - + private int getChunkFromStream(InputStream inputStream,byte[] output, ByteArrayBuffer overflowbuffer,int BLOCKSIZE) throws IOException { + int bytesRead = -1; + int inBlockBuffer = 0; + do{ + bytesRead = inputStream.read(overflowbuffer.buffer,overflowbuffer.getLengthOfDataInBuffer(),overflowbuffer.getSpaceLeft()); + if(bytesRead <= 0) break; + + overflowbuffer.addLengthOfDataInBuffer(bytesRead); + + if(inBlockBuffer + overflowbuffer.getLengthOfDataInBuffer() > BLOCKSIZE){ + int tooMuch = (inBlockBuffer + bytesRead) - BLOCKSIZE; + int toRead = BLOCKSIZE - inBlockBuffer; + + System.arraycopy(overflowbuffer.buffer, 0, output, inBlockBuffer, toRead); + inBlockBuffer += toRead; + + System.arraycopy(overflowbuffer.buffer, toRead, overflowbuffer.buffer, 0, tooMuch); + overflowbuffer.setLengthOfDataInBuffer(tooMuch); + }else{ + System.arraycopy(overflowbuffer.buffer, 0, output, inBlockBuffer, overflowbuffer.getLengthOfDataInBuffer()); + inBlockBuffer +=overflowbuffer.getLengthOfDataInBuffer(); + overflowbuffer.resetLengthOfDataInBuffer(); + } + }while(inBlockBuffer != BLOCKSIZE); + return inBlockBuffer; + } } diff --git a/src/de/mas/jnustool/util/Downloader.java b/src/de/mas/jnustool/util/Downloader.java index 8c2e503..6989f6b 100644 --- a/src/de/mas/jnustool/util/Downloader.java +++ b/src/de/mas/jnustool/util/Downloader.java @@ -104,8 +104,8 @@ public class Downloader { String URL = URL_BASE + "/" + String.format("%016X", titleID) + "/" + String.format("%08X", contentID); return downloadFileToByteArray(URL); } - public byte[] downloadTMDToByteArray(long titleID) throws IOException { - String URL = URL_BASE + "/" + String.format("%016X", titleID) + "/tmd"; + public byte[] downloadTMDToByteArray(long titleID) throws IOException { + String URL = URL_BASE + "/" + String.format("%016X", titleID) + "/tmd"; return downloadFileToByteArray(URL); } private byte[] downloadFileToByteArray(String fileURL) throws IOException { diff --git a/src/de/mas/jnustool/util/ExitException.java b/src/de/mas/jnustool/util/ExitException.java deleted file mode 100644 index 54eae42..0000000 --- a/src/de/mas/jnustool/util/ExitException.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.mas.jnustool.util; - -public class ExitException extends Exception { - - public ExitException(String string) { - super(string); - } - - /** - * - */ - private static final long serialVersionUID = 1L; - -} diff --git a/src/de/mas/jnustool/util/NUSTitleInformation.java b/src/de/mas/jnustool/util/NUSTitleInformation.java new file mode 100644 index 0000000..b73b418 --- /dev/null +++ b/src/de/mas/jnustool/util/NUSTitleInformation.java @@ -0,0 +1,128 @@ +package de.mas.jnustool.util; + +import java.io.Serializable; + +public class NUSTitleInformation implements Comparable, Serializable{ + private static final long serialVersionUID = 1L; + + private long titleID; + private String longnameEN; + private String ID6; + private String product_code; + private String content_platform; + private String company_code; + private int region; + + + public enum Region{ + EUR, + USA, + JAP, + UKWN + } + + public NUSTitleInformation(long titleID, String longnameEN, String ID6, String product_code,String content_platform,String company_code,int region) { + setTitleID(titleID); + setLongnameEN(longnameEN); + setID6(ID6); + setProduct_code(product_code); + setCompany_code(company_code); + setContent_platform(content_platform); + setRegion(region); + } + + public NUSTitleInformation() { + // TODO Auto-generated constructor stub + } + + public Region getRegionAsRegion() { + switch (region) { + case 1: return Region.JAP; + case 2: return Region.USA; + case 4: return Region.EUR; + default: return Region.UKWN; + } + } + + public String getContent_platform() { + return content_platform; + } + + public void setContent_platform(String content_platform) { + this.content_platform = content_platform; + } + + public String getCompany_code() { + return company_code; + } + + public void setCompany_code(String company_code) { + this.company_code = company_code; + } + + public String getProduct_code() { + return product_code; + } + + public void setProduct_code(String product_code) { + this.product_code = product_code; + } + + public long getTitleID() { + return titleID; + } + + public void setTitleID(long titleID) { + this.titleID = titleID; + } + + public String getLongnameEN() { + return longnameEN; + } + + public void setLongnameEN(String longnameEN) { + this.longnameEN = longnameEN; + } + + public String getID6() { + return ID6; + } + + public void setID6(String iD6) { + ID6 = iD6; + } + + public int getRegion() { + return region; + } + + public void setRegion(int region) { + this.region = region; + } + + public String getTitleIDAsString() { + return String.format("%08X-%08X", titleID>>32,titleID<<32>>32); + + } + + @Override + public String toString(){ + return getTitleIDAsString() + ";" + region +";" + getContent_platform() + ";" + getCompany_code() + ";"+ getProduct_code()+ ";" + getID6() + ";" + getLongnameEN(); + } + + @Override + public int compareTo(NUSTitleInformation o) { + return getLongnameEN().compareTo(o.getLongnameEN()); + } + + public void init(NUSTitleInformation n) { + setTitleID(n.getTitleID()); + setRegion(n.region); + setCompany_code(n.company_code); + setContent_platform(n.content_platform); + setID6(n.ID6); + setLongnameEN(n.longnameEN); + setProduct_code(n.product_code); + } + +} diff --git a/updatetitles.csv b/updatetitles.csv new file mode 100644 index 0000000..5a6a2c7 --- /dev/null +++ b/updatetitles.csv @@ -0,0 +1,322 @@ +0005000E-10100600;1;WUP;00AF;WUP-U-AKNJ;AKNJAF;TEKKEN TAG TOURNAMENT 2 Wii U EDITION +0005000E-10101B00;4;WUP;0001;WUP-U-APLP;APLP01;LEGO® CITY UNDERCOVER +0005000E-10101C00;1;WUP;0001;WUP-U-ARPJ;ARPJ01;New SUPER MARIO BROS. U +0005000E-10101D00;2;WUP;0001;WUP-U-ARPE;ARPE01;New SUPER MARIO BROS. U +0005000E-10101E00;4;WUP;0001;WUP-U-ARPP;ARPP01;New SUPER MARIO BROS. U +0005000E-10101F00;1;WUP;0001;WUP-U-ALCJ;ALCJ01;Nintendo Land +0005000E-10102000;2;WUP;0001;WUP-U-ALCE;ALCE01;Nintendo Land +0005000E-10102100;4;WUP;0001;WUP-U-ALCP;ALCP01;Nintendo Land +0005000E-10102200;1;WUP;0001;WUP-U-ASTJ;ASTJ01;Wii Fit U +0005000E-10102300;2;WUP;0001;WUP-U-ASTE;ASTE01;Wii Fit U +0005000E-10102400;4;WUP;0001;WUP-U-ASTP;ASTP01;Wii Fit U +0005000E-10104D00;1;WUP;0008;WUP-U-AHDJ;AHDJ08;MONSTER HUNTER 3(tri-)G HD Ver. +0005000E-10106900;1;WUP;0001;WUP-U-AURJ;AURJ01;Mario & Sonic at the Sochi 2014 Olympic Winter Games +0005000E-10106B00;2;WUP;0041;WUP-U-ASSE;ASSE41;Assassin's Creed® III +0005000E-1010AE00;2;WUP;0041;WUP-U-AJDE;AJDE41;JUST DANCE 4 +0005000E-1010AF00;2;WUP;0041;WUP-U-AMVE;AMVE41;Marvel Avengers™: Battle for Earth +0005000E-1010B000;2;WUP;0041;WUP-U-ARBE;ARBE41;Rabbids Land +0005000E-1010B300;2;WUP;008P;WUP-U-AS2E;AS2E8P;Sonic & All-Stars Racing Transformed +0005000E-1010B400;2;WUP;0041;WUP-U-ASPE;ASPE41;ESPN Sports Connection +0005000E-1010B600;2;WUP;0041;WUP-U-AYSE;AYSE41;Your Shape® Fitness Evolved 2013 +0005000E-1010C700;2;WUP;0001;WUP-U-AURE;AURE01;Mario & Sonic at the Sochi 2014 Olympic Winter Games +0005000E-1010C800;4;WUP;0001;WUP-U-AURP;AURP01;Mario & Sonic at the Sochi 2014 Olympic Winter Games +0005000E-1010CF00;2;WUP;0052;WUP-U-AECE;AECE52;Call of Duty: Black Ops II +0005000E-1010DA00;2;WUP;0054;WUP-U-ANBE;ANBE54;NBA 2K13 +0005000E-1010DC00;2;WUP;0069;WUP-U-AMEE;AMEE69;Mass Effect™ 3 Special Edition +0005000E-1010DD00;2;WUP;0041;WUP-U-AZUE;AZUE41;ZombiU +0005000E-1010E300;2;WUP;0041;WUP-U-AS9E;AS9E41;Splinter Cell Blacklist +0005000E-1010EA00;1;WUP;00C8;WUP-U-AHBJ;AHBJC8;WARRIORS OROCHI 3 Hyper +0005000E-1010EB00;1;WUP;0001;WUP-P-AMKJ;AMKJ01;MARIO KART 8 +0005000E-1010EC00;2;WUP;0001;WUP-P-AMKE;AMKE01;MARIO KART 8 +0005000E-1010ED00;4;WUP;0001;WUP-P-AMKP;AMKP01;MARIO KART 8 +0005000E-1010EE00;4;WUP;0069;WUP-U-AF3P;AF3P69;FIFA 13 +0005000E-1010EF00;4;WUP;0041;WUP-U-AZUP;AZUP41;ZombiU +0005000E-1010F000;4;WUP;0041;WUP-U-AJDP;AJDP41;JUST DANCE 4 +0005000E-1010F500;4;WUP;0069;WUP-U-AMEP;AMEP69;Mass Effect™ 3 Special Edition +0005000E-1010F600;4;WUP;0041;WUP-U-ASSP;ASSP41;Assassin's Creed® III +0005000E-1010F700;4;WUP;0041;WUP-U-AYSP;AYSP41;Your Shape® Fitness Evolved 2013 +0005000E-1010F800;4;WUP;00AF;WUP-U-AKNP;AKNPAF;TEKKEN TAG TOURNAMENT 2 Wii U EDITION +0005000E-1010FB00;4;WUP;00NK;WUP-U-WDLP;WDLPNK;Puddle +0005000E-1010FC00;4;WUP;0041;WUP-U-ARBP;ARBP41;Rabbids Land +0005000E-1010FF00;4;WUP;00WR;WUP-U-AGPP;AGPPWR;Game Party Champions +0005000E-10110000;2;WUP;00AF;WUP-U-AKNE;AKNEAF;TEKKEN TAG TOURNAMENT 2 Wii U EDITION +0005000E-10110100;2;WUP;00JX;WUP-U-WASE;WASEJX;Nano Assault Neo +0005000E-10110200;2;WUP;00C8;WUP-U-AHBE;AHBEC8;WARRIORS OROCHI 3 Hyper(NA) +0005000E-10110600;4;WUP;00JX;WUP-U-WASP;WASPJX;Nano Assault Neo +0005000E-10110800;4;WUP;0041;WUP-U-AMVP;AMVP41;Marvel Avengers™: Battle for Earth +0005000E-10110900;1;WUP;00C8;WUP-U-ANGJ;ANGJC8;NINJA GAIDEN 3: Razor's Edge +0005000E-10110A00;2;WUP;0001;WUP-U-ANGE;ANGE01;NINJA GAIDEN 3: Razor's Edge +0005000E-10110B00;4;WUP;0001;WUP-U-ANGP;ANGP01;NINJA GAIDEN 3: Razor's Edge +0005000E-10110E00;1;WUP;0001;WUP-P-AXFJ;AXFJ01;Super Smash Bros. for Wii U +0005000E-10111700;2;WUP;00WR;WUP-U-AJSE;AJSEWR;Injustice: Gods Among Us +0005000E-10111A00;4;WUP;00WR;WUP-U-AJSP;AJSPWR;Injustice: Gods Among Us +0005000E-10111C00;1;WUP;00C8;WUP-U-AG9J;AG9JC8;Romance of the Three Kingdoms 12 +0005000E-10111D00;4;WUP;0041;WUP-U-ASPP;ASPP41;Sports Connection +0005000E-10111F00;4;WUP;008P;WUP-U-AS2P;AS2P8P;Sonic & All-Stars Racing Transformed +0005000E-10112000;2;WUP;00G9;WUP-U-ACRE;ACREG9;THE CROODS +0005000E-10112100;4;WUP;0041;WUP-U-AKFP;AKFP41;Know Your Friends +0005000E-10112200;4;WUP;00FZ;WUP-U-WBDP;WBDPFZ;Trine 2 Director's Cut +0005000E-10112300;1;WUP;0041;WUP-U-AZUJ;AZUJ41;ZombiU +0005000E-10112400;1;WUP;0041;WUP-U-ASSJ;ASSJ41;Assassin's Creed® III +0005000E-10112500;1;WUP;0041;WUP-U-ASPJ;ASPJ41;Sports Connection +0005000E-10112800;1;WUP;0041;WUP-U-AS9J;AS9J41;Splinter Cell Blacklist +0005000E-10112B00;4;WUP;00C8;WUP-U-AHBP;AHBPC8;WARRIORS OROCHI 3 Hyper(EU) +0005000E-10112F00;4;WUP;0054;WUP-U-ANBP;ANBP54;NBA 2K13 +0005000E-10113000;1;WUP;0013;WUP-U-AMEJ;AMEJ13;Mass Effect™ 3 Special Edition +0005000E-10113100;1;WUP;0008;WUP-U-ABHJ;ABHJ08;BIOHAZARD REVELATIONS Unveiled Edition +0005000E-10113400;4;WUP;0052;WUP-U-AECP;AECP52;Call of Duty: Black Ops II +0005000E-10113500;4;WUP;0052;WUP-U-AECI;AECI52;Call of Duty: Black Ops II +0005000E-10113700;4;WUP;0052;WUP-U-AECD;AECD52;Call of Duty: Black Ops II +0005000E-10113800;4;WUP;00Y4;WUP-U-WBAP;WBAPY4;Zen Pinball 2 +0005000E-10113C00;2;WUP;00GT;WUP-U-AFBE;AFBEGT;Funky Barn +0005000E-10115E00;1;WUP;00GD;WUP-U-ADQJ;ADQJGD;Dragon Quest X +0005000E-10115F00;2;WUP;00Y4;WUP-U-WBAE;WBAEY4;Zen Pinball 2 +0005000E-10116100;1;WUP;0001;WUP-P-AX5J;AX5J01;XenobladeX +0005000E-10116300;1;WUP;0001;WUP-U-ACMJ;ACMJ01;The Wonderful 101 +0005000E-10116500;4;WUP;00TW;WUP-U-WAAP;WAAPTW;Toki Tori 2+ +0005000E-10116600;1;WUP;00C8;WUP-U-AH9J;AH9JC8;Fist of the North Star: Ken's Rage 2 +0005000E-10117200;4;WUP;0008;WUP-U-AHDP;AHDP08;MONSTER HUNTER 3 ULTIMATE +0005000E-10117700;4;WUP;00TJ;WUP-U-WCAP;WCAPTJ;Chasing Aurora +0005000E-10118300;2;WUP;0008;WUP-U-AHDE;AHDE08;MONSTER HUNTER 3 ULTIMATE +0005000E-10118400;4;WUP;00GT;WUP-U-AFBP;AFBPGT;Funky Barn +0005000E-1011A700;4;WUP;0041;WUP-U-AZUD;AZUD41;ZombiU +0005000E-1011AF00;2;WUP;00XY;WUP-U-WBTE;WBTEXY;BIT.TRIP Presents... Runner2: Future Legend of Rhythm Alien +0005000E-1011B300;4;WUP;00TZ;WUP-U-AFBZ;AFBZTZ;Funky Barn (Download Version) +0005000E-1011B400;1;WUP;00GD;WUP-U-AECJ;AECJGD;Call of Duty: Black Ops II +0005000E-1011B600;1;WUP;00GD;WUP-U-AQDJ;AQDJGD;Dragon Quest X Beta test +0005000E-1011B700;4;WUP;0041;WUP-U-WLAP;WLAP41;Uplay +0005000E-1011BA00;2;WUP;0041;WUP-U-WLAE;WLAE41;Uplay +0005000E-1011C000;2;WUP;00TJ;WUP-U-WCAE;WCAETJ;Chasing Aurora +0005000E-10128400;4;WUP;0069;WUP-U-ANSP;ANSP69;Need for Speed™ Most Wanted U +0005000E-10128700;2;WUP;00TW;WUP-U-WAAE;WAAETW;Toki Tori 2+ +0005000E-10128800;2;WUP;0069;WUP-U-ANSE;ANSE69;Need for Speed™ Most Wanted U +0005000E-10128A00;2;WUP;00FZ;WUP-U-WBDE;WBDEFZ;Trine 2 Director's Cut +0005000E-10128F00;2;WUP;008P;WUP-U-ASNE;ASNE8P;SONIC LOST WORLD +0005000E-10129000;2;WUP;0008;WUP-U-WDKE;WDKE08;DuckTales: Remastered +0005000E-10129200;4;WUP;0008;WUP-U-WDKP;WDKP08;DuckTales: Remastered +0005000E-1012AC00;4;WUP;0041;WUP-U-AS9P;AS9P41;Splinter Cell Blacklist +0005000E-1012B100;4;WUP;008P;WUP-U-ASNP;ASNP8P;SONIC LOST WORLD +0005000E-1012B400;4;WUP;0008;WUP-U-ABHP;ABHP08;RESIDENT EVIL REVELATIONS +0005000E-1012B700;1;WUP;0013;WUP-U-ANSJ;ANSJ13;Need for Speed™ Most Wanted U +0005000E-1012BC00;1;WUP;0001;WUP-U-AC3J;AC3J01;PIKMIN 3 +0005000E-1012BD00;2;WUP;0001;WUP-U-AC3E;AC3E01;PIKMIN 3 +0005000E-1012BE00;4;WUP;0001;WUP-U-AC3P;AC3P01;PIKMIN 3 +0005000E-1012C500;4;WUP;00AF;WUP-U-ACRP;ACRPAF;THE CROODS +0005000E-1012CF00;2;WUP;0008;WUP-U-ABHE;ABHE08;RESIDENT EVIL REVELATIONS +0005000E-1012DC00;2;WUP;0001;WUP-U-ACME;ACME01;The Wonderful 101 +0005000E-1012F100;1;WUP;0001;WUP-U-AWSJ;AWSJ01;Wii Sports Club +0005000E-10131D00;1;WUP;0001;WUP-U-ASEJ;ASEJ01;???????? +0005000E-10131F00;1;WUP;0001;WUP-U-AYCJ;AYCJ01;yoshi's woolly world +0005000E-10132400;4;WUP;00WR;WUP-U-ALMP;ALMPWR;LEGO® MARVEL Super Heroes +0005000E-10132500;1;WUP;0001;WUP-U-WB9J;WB9J01;Wii Fit U Quick Check +0005000E-10132600;2;WUP;0001;WUP-U-WB9E;WB9E01;Wii Fit U Quick Check +0005000E-10132700;4;WUP;0001;WUP-U-WB9P;WB9P01;Wii Fit U Quick Check +0005000E-10132800;2;WUP;00UP;WUP-U-WEPE;WEPEUP;Unepic EnjoyUp Games +0005000E-10132900;2;WUP;004Q;WUP-U-ADSE;ADSE4Q;Disney INFINITY +0005000E-10132A00;4;WUP;00Y4;WUP-U-WA2P;WA2PY4;Star Wars Pinball +0005000E-10132B00;2;WUP;00WR;WUP-P-ALME;ALMEWR;LEGO® MARVEL Super Heroes +0005000E-10135200;2;WUP;00Y4;WUP-U-WA2E;WA2EY4;Star Wars Pinball +0005000E-10135300;4;WUP;0001;WUP-U-ACMP;ACMP01;The Wonderful 101 +0005000E-10135700;1;WUP;008P;WUP-U-ASNJ;ASNJ8P;SONIC LOST WORLD +0005000E-10136300;4;WUP;00XY;WUP-U-WBTP;WBTPXY;BIT.TRIP Presents... Runner2: Future Legend of Rhythm Alien +0005000E-10136C00;4;WUP;00WR;WUP-U-AZEP;AZEPWR;Batman™: Arkham Origins +0005000E-10136F00;4;WUP;004Q;WUP-U-ADSP;ADSP4Q;Disney Infinity +0005000E-10137000;4;WUP;004Q;WUP-U-ADSZ;ADSZ4Q;Disney Infinity +0005000E-10137C00;2;WUP;00WR;WUP-U-AZEE;AZEEWR;Batman™: Arkham Origins +0005000E-10137F00;2;WUP;0001;WUP-P-ARKE;ARKE01;Donkey Kong Country Tropical Freeze +0005000E-10138300;4;WUP;0001;WUP-P-ARKP;ARKP01;Donkey Kong Country Tropical Freeze +0005000E-10138700;4;WUP;00YV;WUP-P-WB6P;WB6PYV;Spin the Bottle: Bumpie's Party +0005000E-10138800;4;WUP;0041;WUP-U-ASBP;ASBP41;Assassin's Creed® IV Black Flag +0005000E-10138B00;2;WUP;0041;WUP-U-ASBE;ASBE41;Assassin's Creed® IV Black Flag +0005000E-10138E00;4;WUP;0041;WUP-U-WB7P;WB7P41;Rayman Legends Challenges App +0005000E-10138F00;1;WUP;0001;WUP-U-ADNJ;ADNJ01;Devil's Third +0005000E-10139200;2;WUP;0052;WUP-U-ASFE;ASFE52;Skylanders SWAP Force +0005000E-10139500;2;WUP;0041;WUP-U-WB7E;WB7E41;Rayman Legends Challenges App +0005000E-10139900;2;WUP;0041;WUP-P-AJ5E;AJ5E41;JUST DANCE® 2014 +0005000E-10140400;4;WUP;0052;WUP-U-ASFP;ASFP52;Skylanders SWAP Force +0005000E-10140700;1;WUP;00WR;WUP-U-AJSJ;AJSJWR;Injustice: Gods Among Us +0005000E-10142700;4;WUP;0001;WUP-P-AA9P;AA9P01;Art Academy: SketchPad +0005000E-10142A00;2;WUP;005G;WUP-U-AZBE;AZBE5G;Zumba Fitness World Party +0005000E-10142B00;1;WUP;0001;WUP-P-AA9J;AA9J01;Art Academy: SketchPad +0005000E-10142C00;2;WUP;0001;WUP-P-AA9E;AA9E01;Art Academy: SketchPad +0005000E-10143F00;4;WUP;0041;WUP-P-AJ5P;AJ5P41;JUST DANCE® 2014 +0005000E-10144000;2;WUP;00G9;WUP-U-ADVE;ADVEG9;Adventure Time: Explore the Dungeon Because I Don't Know! +0005000E-10144800;1;WUP;0001;WUP-P-ARKJ;ARKJ01;Donkey Kong Country Tropical Freeze +0005000E-10144D00;2;WUP;0001;WUP-U-AWSE;AWSE01;Wii Sports Club +0005000E-10144E00;4;WUP;0001;WUP-U-AWSP;AWSP01;Wii Sports Club +0005000E-10144F00;2;WUP;0001;WUP-P-AXFE;AXFE01;Super Smash Bros. for Wii U +0005000E-10145000;4;WUP;0001;WUP-P-AXFP;AXFP01;Super Smash Bros. for Wii U +0005000E-10145600;7;WUP;0001;WUP-U-ADBA;ADBA01;Animal Crossing Plaza +0005000E-10145800;4;WUP;00UP;WUP-U-WEPP;WEPPUP;Unepic EnjoyUp Games +0005000E-10145900;4;WUP;00HL;WUP-U-WCDP;WCDPHL;Coaster Crazy Deluxe +0005000E-10145F00;1;WUP;0001;WUP-P-WMGJ;WMGJ01;NES REMIX +0005000E-10146000;2;WUP;0001;WUP-P-WMGE;WMGE01;NES REMIX +0005000E-10146100;4;WUP;0001;WUP-P-WMGP;WMGP01;NES REMIX +0005000E-10146800;2;WUP;0052;WUP-P-ACPE;ACPE52;Call of Duty: Ghosts +0005000E-10147600;4;WUP;00DZ;WUP-P-WEVP;WEVPDZ;EvoFish +0005000E-10147F00;2;WUP;00YV;WUP-P-WB6E;WB6EYV;Spin the Bottle: Bumpie's Party +0005000E-10148000;1;WUP;00AF;WUP-P-AUNJ;AUNJAF;ONE PIECE UNLIMITED WORLD R +0005000E-10148200;2;WUP;00UP;WUP-U-WAEE;WAEEUP;Rock 'N Racing Off Road +0005000E-10148F00;1;WUP;0041;WUP-U-WLAJ;WLAJ41;Uplay +0005000E-10149200;4;WUP;00SS;WUP-U-WDFP;WDFPSS;Spot The Differences: Party! +0005000E-10149500;2;WUP;00CS;WUP-P-WKTE;WKTECS;Scram Kitty and his Buddy on Rails +0005000E-10149700;1;WUP;0001;WUP-P-WAUJ;WAUJ01;?? ?? +0005000E-1014C600;4;WUP;00CX;WUP-U-WGSP;WGSPCX;Giana Sisters Twisted Dreams +0005000E-1014C800;1;WUP;0041;WUP-U-ASBJ;ASBJ41;Assassin's Creed® IV Black Flag +0005000E-1014CB00;2;WUP;00CX;WUP-P-WGSE;WGSECX;Giana Sisters Twisted Dreams +0005000E-1014CF00;2;WUP;00HL;WUP-U-WCDE;WCDEHL;Coaster Crazy Deluxe +0005000E-1014D100;4;WUP;00CS;WUP-U-WKTP;WKTPCS;Scram Kitty and his Buddy on Rails +0005000E-1014D900;1;WUP;008P;WUP-P-APTJ;APTJ8P;PUYOPUYOTETRIS +0005000E-1014DA00;1;WUP;0008;WUP-U-AMFJ;AMFJ08;Monster Hunter Frontier G +0005000E-1014DE00;2;WUP;00WR;WUP-U-ALAE;ALAEWR;The LEGO® Movie Videogame +0005000E-1014E000;4;WUP;00WR;WUP-U-ALAP;ALAPWR;The LEGO® Movie Videogame +0005000E-1014E100;4;WUP;00AF;WUP-U-ADVP;ADVPAF;Adventure Time: Explore the Dungeon Because I Don't Know! +0005000E-1014E300;4;WUP;00GT;WUP-U-AZBP;AZBPGT;Zumba Fitness World Party +0005000E-10154600;1;WUP;00WR;WUP-U-AZEJ;AZEJWR;Batman™: Arkham Origins +0005000E-10154D00;4;WUP;00BU;WUP-U-WC3P;WC3PBU;The Mysterious Cities of Gold: Secret Paths +0005000E-10156100;4;WUP;0052;WUP-P-ACPP;ACPP52;Call of Duty: Ghosts +0005000E-10156500;2;WUP;00BU;WUP-U-WC3E;WC3EBU;The Mysterious Cities of Gold: Secret Paths +0005000E-10157600;4;WUP;0052;WUP-P-ACPI;ACPI52;Call of Duty: Ghosts +0005000E-10157900;1;WUP;00GD;WUP-P-ACPJ;ACPJGD;Call of Duty: Ghosts +0005000E-10159800;1;WUP;0001;WUP-U-AFCJ;AFCJ01;Wii Fit U (Free) +0005000E-10159900;2;WUP;0001;WUP-U-AFCE;AFCE01;Wii Fit U (Free) +0005000E-10159A00;4;WUP;0001;WUP-U-AFCP;AFCP01;Wii Fit U (promo) +0005000E-1015A300;1;WUP;00AF;WUP-U-ADSJ;ADSJAF;Disney INFINITY +0005000E-1015B200;2;WUP;0041;WUP-P-ACLE;ACLE41;CHILD of LIGHT +0005000E-1015D300;2;WUP;00AS;WUP-P-WLCE;WLCEAS;Lucadian Chronicles +0005000E-1015EB00;1;WUP;00R7;WUP-U-WHYJ;WHYJR7;Mighty Switch Force!™ Hyper Drive Edition +0005000E-10161F00;1;WUP;0001;WUP-U-ABAJ;ABAJ01;Mario Party 10 +0005000E-10162300;4;WUP;00YR;WUP-U-WCZP;WCZPYR;Color Zen +0005000E-10162B00;1;WUP;0001;WUP-P-AGMJ;AGMJ01;Splatoon +0005000E-10162D00;2;WUP;0001;WUP-U-ABAE;ABAE01;Mario Party 10 +0005000E-10169600;4;WUP;00UP;WUP-U-WEPS;WEPSUP;Unepic EnjoyUp Games +0005000E-1016A200;4;WUP;00SS;WUP-U-WBXP;WBXPSS;Bombing Bastards +0005000E-1016A400;4;WUP;00WR;WUP-P-BTMP;BTMPWR;LEGO® Batman™ 3 Beyond Gotham +0005000E-1016A600;1;WUP;00TF;WUP-P-WB6J;WB6JTF;?????????????? +0005000E-1016AB00;2;WUP;00SS;WUP-U-WBXE;WBXESS;Bombing Bastards +0005000E-1016AC00;2;WUP;009T;WUP-U-WMLE;WMLE9T;Armillo +0005000E-1016AD00;2;WUP;00WR;WUP-P-BTME;BTMEWR;LEGO® Batman™ 3 Beyond Gotham +0005000E-1016B200;2;WUP;009V;WUP-U-WMRE;WMRE9V;Master Reboot +0005000E-1016C700;4;WUP;009T;WUP-U-WMLP;WMLP9T;Armillo +0005000E-1016CE00;2;WUP;00YR;WUP-U-WCZE;WCZEYR;Color Zen +0005000E-1016D500;4;WUP;009Y;WUP-P-WCTP;WCTP9Y;Super Toy Cars +0005000E-1016D800;1;WUP;0041;WUP-P-ACLJ;ACLJ41;CHILD of LIGHT +0005000E-1016DC00;2;WUP;004Q;WUP-P-ADRE;ADRE4Q;Disney Infinity [2.0] +0005000E-1016DE00;2;WUP;009Y;WUP-P-WCTE;WCTE9Y;Super Toy Cars +0005000E-1016E100;2;WUP;00AY;WUP-P-WKNE;WKNEAY;Shovel Knight +0005000E-1016E300;2;WUP;008S;WUP-P-WGRE;WGRE8S;GravBlocks+ From Nothing Game Studios +0005000E-1016E800;4;WUP;009V;WUP-U-WMRP;WMRP9V;Master Reboot +0005000E-1016EA00;4;WUP;0041;WUP-P-ACLP;ACLP41;CHILD of LIGHT +0005000E-1016FF00;2;WUP;00NT;WUP-P-WFWE;WFWENT;Flowerworks HD Follie's Adventure +0005000E-10170200;2;WUP;007Z;WUP-U-WGAE;WGAE7Z;Pier Solar and the Great Architects +0005000E-10170600;1;WUP;00AF;WUP-U-APWJ;APWJAF;KAMEN RIDER BATTRIDE WAR ? PREMIUM TV&MOVIE SOUND ED. +0005000E-10170700;1;WUP;00AF;WUP-U-ABWJ;ABWJAF;KAMEN RIDER BATTRIDE WAR ? +0005000E-10172A00;2;WUP;009Z;WUP-N-HRLE;HRLE9Z;Crunchyroll +0005000E-10172B00;4;WUP;009Z;WUP-N-HRLP;HRLP9Z;Crunchyroll +0005000E-10173300;4;WUP;00UB;WUP-U-WCGP;WCGPUB;Stealth Inc 2 A Game of Clones +0005000E-10175B00;2;WUP;008P;WUP-P-BSSE;BSSE8P;Sonic Boom: Rise of Lyric +0005000E-10175D00;4;WUP;00AF;WUP-P-AUNP;AUNPAF;ONE PIECE Unlimited World Red +0005000E-10176500;2;WUP;00UB;WUP-U-WCGE;WCGEUB;Stealth Inc 2 A Game of Clones +0005000E-10176900;2;WUP;0001;WUP-P-AGME;AGME01;Splatoon +0005000E-10176A00;4;WUP;0001;WUP-P-AGMP;AGMP01;Splatoon +0005000E-10176F00;4;WUP;0041;WUP-P-BJDP;BJDP41;JUST DANCE® 2015 +0005000E-10177600;2;WUP;0001;WUP-U-ADNE;ADNE01;Devil's Third +0005000E-10177800;4;WUP;008P;WUP-P-BSSP;BSSP8P;Sonic Boom: Rise of Lyric +0005000E-10178F00;4;WUP;00AY;WUP-P-WKNP;WKNPAY;Shovel Knight +0005000E-10179100;2;WUP;0041;WUP-P-BJDE;BJDE41;JUST DANCE® 2015 +0005000E-1017BE00;1;WUP;0001;WUP-U-BXAJ;BXAJ01;Art Academy: Home Studio +0005000E-1017BF00;2;WUP;0001;WUP-U-BXAE;BXAE01;Art Academy: Home Studio +0005000E-1017C600;2;WUP;0052;WUP-P-BK7E;BK7E52;Skylanders Trap Team +0005000E-1017CD00;1;WUP;00C8;WUP-U-BWPJ;BWPJC8;Hyrule Warriors +0005000E-1017D800;2;WUP;0001;WUP-U-BWPE;BWPE01;Hyrule Warriors +0005000E-1017D900;4;WUP;0001;WUP-U-BWPP;BWPP01;Hyrule Warriors +0005000E-1017DA00;2;WUP;011S;WUP-P-ACQE;ACQE1S;Costume Quest 2 +0005000E-1017E000;4;WUP;00XQ;WUP-P-WK8P;WK8PXQ;Turtle Tale +0005000E-10180500;1;WUP;0001;WUP-P-AKBJ;AKBJ01;Captain Toad: Treasure Tracker +0005000E-10180600;2;WUP;0001;WUP-P-AKBE;AKBE01;Captain Toad: Treasure Tracker +0005000E-10180700;4;WUP;0001;WUP-P-AKBP;AKBP01;Captain Toad: Treasure Tracker +0005000E-10181F00;4;WUP;0052;WUP-P-BK7P;BK7P52;Skylanders Trap Team +0005000E-10182C00;4;WUP;00XT;WUP-U-AJTP;AJTPXT;Jett Tailfin +0005000E-10183000;2;WUP;010P;WUP-P-ARNE;ARNE0P;Runbow +0005000E-10183900;2;WUP;00UP;WUP-U-BMVE;BMVEUP;99Moves +0005000E-10184D00;2;WUP;0001;WUP-U-AYCE;AYCE01;Yoshi's Woolly World +0005000E-10187100;4;WUP;00LW;WUP-U-BUGP;BUGPLW;Underground +0005000E-10188B00;1;WUP;0001;WUP-U-AXYJ;AXYJ01;Kirby and the Rainbow Curse +0005000E-10188C00;4;WUP;004Q;WUP-P-ADRP;ADRP4Q;Disney Infinity [2.0] +0005000E-10188D00;4;WUP;004Q;WUP-P-ADRZ;ADRZ4Q;Disney Infinity [2.0] +0005000E-10189200;2;WUP;011C;WUP-P-BSPE;BSPE1C;Sportsball +0005000E-1018C400;1;WUP;00AF;WUP-P-BSFJ;BSFJAF;???F??????????? ????SF??????????? +0005000E-1018DB00;1;WUP;0001;WUP-U-AMAJ;AMAJ01;Super Mario Maker +0005000E-1018DC00;2;WUP;0001;WUP-U-AMAE;AMAE01;Super Mario Maker +0005000E-1018DD00;4;WUP;0001;WUP-U-AMAP;AMAP01;Super Mario Maker +0005000E-1018DE00;4;WUP;00NK;WUP-U-ATCP;ATCPNK;Tetrobot and Co. +0005000E-1018ED00;2;WUP;00NK;WUP-U-ATCE;ATCENK;Tetrobot and Co. +0005000E-10191700;4;WUP;00UP;WUP-U-BMVP;BMVPUP;99Moves +0005000E-10191800;4;WUP;00UP;WUP-U-WAEP;WAEPUP;Rock 'N Racing Off Road +0005000E-10192200;1;WUP;00AF;WUP-P-BRSJ;BRSJAF;KAMEN RIDER SUMMON RIDE! +0005000E-10194200;2;WUP;00WR;WUP-U-APZE;APZEWR;LEGO® DIMENSIONS™ +0005000E-10195D00;4;WUP;00WR;WUP-U-APZP;APZPWR;LEGO® DIMENSIONS™ +0005000E-10197800;4;WUP;011S;WUP-P-ACQP;ACQP1S;Costume Quest 2 +0005000E-10199000;1;WUP;0001;WUP-P-AVXJ;AVXJ01;Mario Tennis: Ultra Smash +0005000E-1019AD00;2;WUP;011A;WUP-P-BEQE;BEQE1A;Elliot Quest +0005000E-101A1B00;2;WUP;00RG;WUP-U-BS2E;BS2ERG;Swords & Soldiers II +0005000E-101A2600;1;WUP;00W4;WUP-U-WKFJ;WKFJW4;Kung Fu Rabbit +0005000E-101A2E00;1;WUP;00TF;WUP-P-WEXJ;WEXJTF;XType+ +0005000E-101A3500;2;WUP;0001;WUP-P-AVXE;AVXE01;Mario Tennis: Ultra Smash +0005000E-101A3600;4;WUP;0001;WUP-P-AVXP;AVXP01;Mario Tennis: Ultra Smash +0005000E-101A3B00;2;WUP;00LY;WUP-P-BLPE;BLPELY;Life of Pixel +0005000E-101A4900;4;WUP;00LY;WUP-U-BLPP;BLPPLY;Life of Pixel +0005000E-101A5C00;4;WUP;00WR;WUP-U-ALJP;ALJPWR;LEGO® Jurassic World™ +0005000E-101A5E00;4;WUP;00UB;WUP-U-ALLP;ALLPUB;OlliOlli +0005000E-101A5F00;2;WUP;00WY;WUP-U-BSXE;BSXEWY;Shantae and the Pirate's Curse +0005000E-101A6200;2;WUP;00WR;WUP-U-ALJE;ALJEWR;LEGO® Jurassic World™ +0005000E-101A6300;4;WUP;00YR;WUP-U-ACUP;ACUPYR;Cube Life: Island Survival +0005000E-101A6400;2;WUP;00YR;WUP-U-ACUE;ACUEYR;Cube Life: Island Survival +0005000E-101A6500;2;WUP;00VZ;WUP-P-BKFE;BKFEVZ;Kung Fu Panda Showdown of Legendary Legends +0005000E-101A6900;2;WUP;00UB;WUP-P-ALLE;ALLEUB;OlliOlli +0005000E-101A9500;4;WUP;00WY;WUP-U-BSXP;BSXPWY;Shantae and the Pirate's Curse +0005000E-101A9F00;2;WUP;0147;WUP-P-BDAE;BDAE47;Dot Arcade +0005000E-101AA500;4;WUP;00VZ;WUP-P-BKFP;BKFPVZ;Kung Fu Panda Showdown of Legendary Legends +0005000E-101ABC00;2;WUP;0001;WUP-U-AXYE;AXYE01;Kirby and the Rainbow Curse +0005000E-101AC700;2;WUP;00VZ;WUP-P-BFNE;BFNEVZ;Adventure Time Finn and Jake Investigations +0005000E-101AC900;2;WUP;004Q;WUP-P-BD3E;BD3E4Q;DISNEY INFINITY 3.0 EDITION +0005000E-101AFE00;4;WUP;00VZ;WUP-P-BFNP;BFNPVZ;Adventure Time Finn and Jake Investigations +0005000E-101B3D00;4;WUP;004Q;WUP-P-BD3P;BD3P4Q;DISNEY INFINITY 3.0: PLAY WITHOUT LIMITS +0005000E-101B3E00;4;WUP;004Q;WUP-P-BD3Z;BD3Z4Q;DISNEY INFINITY 3.0: PLAY WITHOUT LIMITS +0005000E-101B8500;2;WUP;0052;WUP-P-BS5E;BS5E52;Skylanders SuperChargers +0005000E-101B9000;2;WUP;0041;WUP-P-AJ6E;AJ6E41;JUST DANCE® 2016 +0005000E-101B9800;4;WUP;0041;WUP-P-AJ6P;AJ6P41;JUST DANCE® 2016 +0005000E-101BA400;2;WUP;0052;WUP-P-AGNE;AGNE52;Guitar Hero Live +0005000E-101BAA00;2;WUP;010C;WUP-U-ATTE;ATTE0C;Totem Topple +0005000E-101BB300;4;WUP;008V;WUP-P-WLSP;WLSP8V;ZaciSa: Defense of the Crayon Dimension! +0005000E-101BB800;4;WUP;011A;WUP-P-BEQP;BEQP1A;Elliot Quest +0005000E-101BC600;4;WUP;0052;WUP-P-AGNP;AGNP52;Guitar Hero Live +0005000E-101BE900;4;WUP;00WR;WUP-P-ALRP;ALRPWR;LEGO® MARVEL's Avengers +0005000E-101BEF00;2;WUP;00WR;WUP-P-ALRE;ALREWR;LEGO® MARVEL's Avengers +0005000E-101BFC00;4;WUP;0052;WUP-P-BS5P;BS5P52;Skylanders SuperChargers +0005000E-101C0700;4;WUP;00UB;WUP-U-AN3P;AN3PUB;Nova-111 +0005000E-101C0A00;2;WUP;00UB;WUP-U-AN3E;AN3EUB;Nova-111 +0005000E-101C0B00;2;WUP;00UB;WUP-P-BS7E;BS7EUB;The Swindle +0005000E-101C0C00;4;WUP;00UB;WUP-P-BS7P;BS7PUB;The Swindle +0005000E-101C3100;2;WUP;0167;WUP-U-AFEE;AFEE67;Freedom Planet +0005000E-101C3900;4;WUP;015G;WUP-P-AWBP;AWBP5G;Word Search by POWGI +0005000E-101C4C00;4;WUP;0001;WUP-P-AX5D;AX5D01;Xenoblade Chronicles X +0005000E-101C4D00;2;WUP;0001;WUP-P-AX5E;AX5E01;Xenoblade Chronicles X +0005000E-101C6A00;2;WUP;016E;WUP-P-AD5E;AD5E6E;Octodad: Dadliest Catch +0005000E-101C6E00;4;WUP;00RG;WUP-U-BS2P;BS2PRG;Swords & Soldiers II +0005000E-101C8B00;4;WUP;00YT;WUP-P-AWMP;AWMPYT;WICKED MONSTERS BLAST! HD PLUS +0005000E-101CC900;4;WUP;0167;WUP-U-AFEP;AFEP67;Freedom Planet +0005000E-101CE100;2;WUP;0175;WUP-U-ACHE;ACHE75;Canvaleon +0005000E-101D0700;4;WUP;0175;WUP-U-ACHP;ACHP75;Canvaleon +0005000E-101D0900;2;WUP;00FV;WUP-U-AGWE;AGWEFV;Gunman Clive HD Collection +0005000E-101D2C00;1;WUP;00SA;WUP-P-ATXJ;ATXJSA;Bike Rider UltraDX WORLD TOUR +0005000E-101D3900;4;WUP;017D;WUP-P-AQCP;AQCP7D;The Quiet Collection +0005000E-101D4200;2;WUP;00DV;WUP-P-ABPE;ABPEDV;Brunswick Pro Bowling +0005000E-101D6100;4;WUP;00FV;WUP-U-AGWP;AGWPFV;Gunman Clive HD Collection +0005000E-101D6D00;4;WUP;010P;WUP-P-ARNP;ARNP0P;Runbow +0005000E-101D7400;4;WUP;010C;WUP-U-ATTP;ATTP0C;Totem Topple +0005000E-101D7500;4;WUP;00DU;WUP-P-AUMP;AUMPDU;Minecraft: Wii U Edition +0005000E-101D9D00;2;WUP;00DU;WUP-P-AUME;AUMEDU;Minecraft: Wii U Edition +0005000E-101DBE00;1;WUP;0188;WUP-P-AUMJ;AUMJ88;Minecraft: Wii U Edition +0005000E-101DC100;4;WUP;016E;WUP-P-AD5P;AD5P6E;Octodad: Dadliest Catch +0005000E-101DDC00;1;WUP;00AF;WUP-P-BD3J;BD3JAF;????????????3.0