diff --git a/.gitignore b/.gitignore index 820ffc1..5cadfda 100644 --- a/.gitignore +++ b/.gitignore @@ -51,4 +51,6 @@ bin /tmp* UpdateGrabber.java updatetitles.csv -src/de/mas/jnustool/StarterPRIATE.java \ No newline at end of file +src/de/mas/jnustool/StarterPRIATE.java +jar/tmp* +src/de/mas/jnustool/XMLGEN.java \ No newline at end of file diff --git a/jar/JNUSTool.jar b/jar/JNUSTool.jar index 8e4d0da..501a33d 100644 Binary files a/jar/JNUSTool.jar and b/jar/JNUSTool.jar differ diff --git a/jar/updatetitles.csv b/jar/updatetitles.csv index 5a6a2c7..eabacd7 100644 --- a/jar/updatetitles.csv +++ b/jar/updatetitles.csv @@ -1,322 +1,327 @@ -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 +0005000E-10100600;1;WUP;00AF;WUP-U-AKNJ;AKNJAF;TEKKEN TAG TOURNAMENT 2 Wii U EDITION;16 +0005000E-10101B00;4;WUP;0001;WUP-U-APLP;APLP01;LEGO® CITY UNDERCOVER;16 +0005000E-10101C00;1;WUP;0001;WUP-U-ARPJ;ARPJ01;New SUPER MARIO BROS. U;32,48,65 +0005000E-10101D00;2;WUP;0001;WUP-U-ARPE;ARPE01;New SUPER MARIO BROS. U;32,48,64 +0005000E-10101E00;4;WUP;0001;WUP-U-ARPP;ARPP01;New SUPER MARIO BROS. U;32,48,64,80 +0005000E-10101F00;1;WUP;0001;WUP-U-ALCJ;ALCJ01;Nintendo Land;32 +0005000E-10102000;2;WUP;0001;WUP-U-ALCE;ALCE01;Nintendo Land;32 +0005000E-10102100;4;WUP;0001;WUP-U-ALCP;ALCP01;Nintendo Land;32 +0005000E-10102200;1;WUP;0001;WUP-U-ASTJ;ASTJ01;Wii Fit U;32,48,64,81 +0005000E-10102300;2;WUP;0001;WUP-U-ASTE;ASTE01;Wii Fit U;16,48,64,81 +0005000E-10102400;4;WUP;0001;WUP-U-ASTP;ASTP01;Wii Fit U;16,48,64,81 +0005000E-10104D00;1;WUP;0008;WUP-U-AHDJ;AHDJ08;MONSTER HUNTER 3(tri-)G HD Ver.;16,32,48,65,80,96 +0005000E-10106900;1;WUP;0001;WUP-U-AURJ;AURJ01;Mario & Sonic at the Sochi 2014 Olympic Winter Games;16,32 +0005000E-10106B00;2;WUP;0041;WUP-U-ASSE;ASSE41;Assassin's Creed® III;16,32,48,64,80 +0005000E-1010AE00;2;WUP;0041;WUP-U-AJDE;AJDE41;JUST DANCE 4;16,32 +0005000E-1010AF00;2;WUP;0041;WUP-U-AMVE;AMVE41;Marvel Avengers™: Battle for Earth;16 +0005000E-1010B000;2;WUP;0041;WUP-U-ARBE;ARBE41;Rabbids Land;16 +0005000E-1010B300;2;WUP;008P;WUP-U-AS2E;AS2E8P;Sonic & All-Stars Racing Transformed;16,32,48 +0005000E-1010B400;2;WUP;0041;WUP-U-ASPE;ASPE41;ESPN Sports Connection;16,33 +0005000E-1010B600;2;WUP;0041;WUP-U-AYSE;AYSE41;Your Shape® Fitness Evolved 2013;16,32 +0005000E-1010C700;2;WUP;0001;WUP-U-AURE;AURE01;Mario & Sonic at the Sochi 2014 Olympic Winter Games;16,32 +0005000E-1010C800;4;WUP;0001;WUP-U-AURP;AURP01;Mario & Sonic at the Sochi 2014 Olympic Winter Games;16,32 +0005000E-1010CF00;2;WUP;0052;WUP-U-AECE;AECE52;Call of Duty: Black Ops II;16,32,48,64,80,96,112,128 +0005000E-1010DA00;2;WUP;0054;WUP-U-ANBE;ANBE54;NBA 2K13;16,32 +0005000E-1010DC00;2;WUP;0069;WUP-U-AMEE;AMEE69;Mass Effect™ 3 Special Edition;16 +0005000E-1010DD00;2;WUP;0041;WUP-U-AZUE;AZUE41;ZombiU;16,32 +0005000E-1010E300;2;WUP;0041;WUP-U-AS9E;AS9E41;Splinter Cell Blacklist;16,32,48 +0005000E-1010EA00;1;WUP;00C8;WUP-U-AHBJ;AHBJC8;WARRIORS OROCHI 3 Hyper;16,32,48,64 +0005000E-1010EB00;1;WUP;0001;WUP-P-AMKJ;AMKJ01;MARIO KART 8;17,33,48,64 +0005000E-1010EC00;2;WUP;0001;WUP-P-AMKE;AMKE01;MARIO KART 8;16,32,48,64 +0005000E-1010ED00;4;WUP;0001;WUP-P-AMKP;AMKP01;MARIO KART 8;16,32,48,64 +0005000E-1010EE00;4;WUP;0069;WUP-U-AF3P;AF3P69;FIFA 13 ;16 +0005000E-1010EF00;4;WUP;0041;WUP-U-AZUP;AZUP41;ZombiU;16,32 +0005000E-1010F000;4;WUP;0041;WUP-U-AJDP;AJDP41;JUST DANCE 4;16,32 +0005000E-1010F500;4;WUP;0069;WUP-U-AMEP;AMEP69;Mass Effect™ 3 Special Edition;16 +0005000E-1010F600;4;WUP;0041;WUP-U-ASSP;ASSP41;Assassin's Creed® III;16,48,64,80 +0005000E-1010F700;4;WUP;0041;WUP-U-AYSP;AYSP41;Your Shape® Fitness Evolved 2013;16,33 +0005000E-1010F800;4;WUP;00AF;WUP-U-AKNP;AKNPAF;TEKKEN TAG TOURNAMENT 2 Wii U EDITION;32 +0005000E-1010FB00;4;WUP;00NK;WUP-U-WDLP;WDLPNK;Puddle;16 +0005000E-1010FC00;4;WUP;0041;WUP-U-ARBP;ARBP41;Rabbids Land;16 +0005000E-1010FF00;4;WUP;00WR;WUP-U-AGPP;AGPPWR;Game Party Champions;16 +0005000E-10110000;2;WUP;00AF;WUP-U-AKNE;AKNEAF;TEKKEN TAG TOURNAMENT 2 Wii U EDITION;32 +0005000E-10110100;2;WUP;00JX;WUP-U-WASE;WASEJX;Nano Assault Neo;17 +0005000E-10110200;2;WUP;00C8;WUP-U-AHBE;AHBEC8;WARRIORS OROCHI 3 Hyper(NA);16,32 +0005000E-10110600;4;WUP;00JX;WUP-U-WASP;WASPJX;Nano Assault Neo;17 +0005000E-10110800;4;WUP;0041;WUP-U-AMVP;AMVP41;Marvel Avengers™: Battle for Earth;16 +0005000E-10110900;1;WUP;00C8;WUP-U-ANGJ;ANGJC8;NINJA GAIDEN 3: Razor's Edge;16,32,48,64 +0005000E-10110A00;2;WUP;0001;WUP-U-ANGE;ANGE01;NINJA GAIDEN 3: Razor's Edge;16,32,48,64,80 +0005000E-10110B00;4;WUP;0001;WUP-U-ANGP;ANGP01;NINJA GAIDEN 3: Razor's Edge;17,32,48 +0005000E-10110E00;1;WUP;0001;WUP-P-AXFJ;AXFJ01;Super Smash Bros. for Wii U;16,49,64,80,96,112,128,144,160,176,192,208 +0005000E-10111700;2;WUP;00WR;WUP-U-AJSE;AJSEWR;Injustice: Gods Among Us;16 +0005000E-10111A00;4;WUP;00WR;WUP-U-AJSP;AJSPWR;Injustice: Gods Among Us;16 +0005000E-10111C00;1;WUP;00C8;WUP-U-AG9J;AG9JC8;Romance of the Three Kingdoms 12;16,33 +0005000E-10111D00;4;WUP;0041;WUP-U-ASPP;ASPP41;Sports Connection;16 +0005000E-10111F00;4;WUP;008P;WUP-U-AS2P;AS2P8P;Sonic & All-Stars Racing Transformed;32,48 +0005000E-10112000;2;WUP;00G9;WUP-U-ACRE;ACREG9;THE CROODS;16 +0005000E-10112100;4;WUP;0041;WUP-U-AKFP;AKFP41;Know Your Friends;16 +0005000E-10112200;4;WUP;00FZ;WUP-U-WBDP;WBDPFZ;Trine 2 Director's Cut;16 +0005000E-10112300;1;WUP;0041;WUP-U-AZUJ;AZUJ41;ZombiU;16,32 +0005000E-10112400;1;WUP;0041;WUP-U-ASSJ;ASSJ41;Assassin's Creed® III;16,32,48,64,80 +0005000E-10112500;1;WUP;0041;WUP-U-ASPJ;ASPJ41;Sports Connection;17 +0005000E-10112800;1;WUP;0041;WUP-U-AS9J;AS9J41;Splinter Cell Blacklist;17,32,48 +0005000E-10112B00;4;WUP;00C8;WUP-U-AHBP;AHBPC8;WARRIORS OROCHI 3 Hyper(EU);16,32 +0005000E-10112F00;4;WUP;0054;WUP-U-ANBP;ANBP54;NBA 2K13;32 +0005000E-10113000;1;WUP;0013;WUP-U-AMEJ;AMEJ13;Mass Effect™ 3 Special Edition;16 +0005000E-10113100;1;WUP;0008;WUP-U-ABHJ;ABHJ08;BIOHAZARD REVELATIONS Unveiled Edition;16 +0005000E-10113400;4;WUP;0052;WUP-U-AECP;AECP52;Call of Duty: Black Ops II;16,32,48,64,80,96,112,128 +0005000E-10113500;4;WUP;0052;WUP-U-AECI;AECI52;Call of Duty: Black Ops II;16,32,48,64,80,96,112,144 +0005000E-10113700;4;WUP;0052;WUP-U-AECD;AECD52;Call of Duty: Black Ops II;16,32,48,64,80,96,112,144 +0005000E-10113800;4;WUP;00Y4;WUP-U-WBAP;WBAPY4;Zen Pinball 2;17,32,48,65,80,96 +0005000E-10113C00;2;WUP;00GT;WUP-U-AFBE;AFBEGT;Funky Barn;16 +0005000E-10115E00;1;WUP;00GD;WUP-U-ADQJ;ADQJGD;Dragon Quest X;16,80,128,144,160,192,208,224,240,256,272,288,304,336,368,384,400,416,432,448,464,480,496,512,528,544,560,624,640,656,672,688,704,736,752,784,800,816,832,848,960,976,992,1008,1024,1040,1056,1072,1088,1104,1120,1136,1152,1168,1184,1200,1216,1232,1248,1264,1280,1296,1312,1328,1344,1360,1376,1392,1408,1424,1440,1456,1472,1488,1504,1520,1536,1552,1568,1584,1600,1616,1632,1648,1664,1680,1696,1712,1728,1744,1760,1776,1792,1808,1824,1840,1856,1872,1888,1904,1920,1936,1952,1968,1984,2000,2016,2032,2048,2064,2080,2096,2112,2128,2144,2160,2176,2192,2208,2224,2240,2256,2272,2288,2304,2320 +0005000E-10115F00;2;WUP;00Y4;WUP-U-WBAE;WBAEY4;Zen Pinball 2;16,32,48,65,80,96 +0005000E-10116100;1;WUP;0001;WUP-P-AX5J;AX5J01;XenobladeX;16,32,48 +0005000E-10116300;1;WUP;0001;WUP-U-ACMJ;ACMJ01;The Wonderful 101;16 +0005000E-10116500;4;WUP;00TW;WUP-U-WAAP;WAAPTW;Toki Tori 2+;16,32 +0005000E-10116600;1;WUP;00C8;WUP-U-AH9J;AH9JC8;Fist of the North Star: Ken's Rage 2;17 +0005000E-10117200;4;WUP;0008;WUP-U-AHDP;AHDP08;MONSTER HUNTER 3 ULTIMATE;16,32 +0005000E-10117700;4;WUP;00TJ;WUP-U-WCAP;WCAPTJ;Chasing Aurora;17 +0005000E-10118300;2;WUP;0008;WUP-U-AHDE;AHDE08;MONSTER HUNTER 3 ULTIMATE;16,32 +0005000E-10118400;4;WUP;00GT;WUP-U-AFBP;AFBPGT;Funky Barn;16 +0005000E-1011A700;4;WUP;0041;WUP-U-AZUD;AZUD41;ZombiU;16,32 +0005000E-1011AF00;2;WUP;00XY;WUP-U-WBTE;WBTEXY;BIT.TRIP Presents... Runner2: Future Legend of Rhythm Alien;16,33 +0005000E-1011B300;4;WUP;00TZ;WUP-U-AFBZ;AFBZTZ;Funky Barn (Download Version);16 +0005000E-1011B400;1;WUP;00GD;WUP-U-AECJ;AECJGD;Call of Duty: Black Ops II;16,32,48,64,80,96 +0005000E-1011B600;1;WUP;00GD;WUP-U-AQDJ;AQDJGD;Dragon Quest X Beta test;16,32,48,64,96 +0005000E-1011B700;4;WUP;0041;WUP-U-WLAP;WLAP41;Uplay;16,32,33,48,64 +0005000E-1011BA00;2;WUP;0041;WUP-U-WLAE;WLAE41;Uplay;16,33,48,64 +0005000E-1011C000;2;WUP;00TJ;WUP-U-WCAE;WCAETJ;Chasing Aurora;16 +0005000E-10128400;4;WUP;0069;WUP-U-ANSP;ANSP69;Need for Speed™ Most Wanted U;16,32 +0005000E-10128700;2;WUP;00TW;WUP-U-WAAE;WAAETW;Toki Tori 2+;16,32 +0005000E-10128800;2;WUP;0069;WUP-U-ANSE;ANSE69;Need for Speed™ Most Wanted U;16,32 +0005000E-10128A00;2;WUP;00FZ;WUP-U-WBDE;WBDEFZ;Trine 2 Director's Cut;16 +0005000E-10128F00;2;WUP;008P;WUP-U-ASNE;ASNE8P;SONIC LOST WORLD;16,32,48 +0005000E-10129000;2;WUP;0008;WUP-U-WDKE;WDKE08;DuckTales: Remastered;16,32 +0005000E-10129200;4;WUP;0008;WUP-U-WDKP;WDKP08;DuckTales: Remastered;16,32 +0005000E-1012AC00;4;WUP;0041;WUP-U-AS9P;AS9P41;Splinter Cell Blacklist;16,32,48 +0005000E-1012B100;4;WUP;008P;WUP-U-ASNP;ASNP8P;SONIC LOST WORLD;16,32,48 +0005000E-1012B400;4;WUP;0008;WUP-U-ABHP;ABHP08;RESIDENT EVIL REVELATIONS;16 +0005000E-1012B700;1;WUP;0013;WUP-U-ANSJ;ANSJ13;Need for Speed™ Most Wanted U;16,32 +0005000E-1012BC00;1;WUP;0001;WUP-U-AC3J;AC3J01;PIKMIN 3;17,48,64,80,96 +0005000E-1012BD00;2;WUP;0001;WUP-U-AC3E;AC3E01;PIKMIN 3;33,48,64,80,96 +0005000E-1012BE00;4;WUP;0001;WUP-U-AC3P;AC3P01;PIKMIN 3;17,48,64,80,96 +0005000E-1012C500;4;WUP;00AF;WUP-U-ACRP;ACRPAF;THE CROODS;16 +0005000E-1012CF00;2;WUP;0008;WUP-U-ABHE;ABHE08;RESIDENT EVIL REVELATIONS;16 +0005000E-1012DC00;2;WUP;0001;WUP-U-ACME;ACME01;The Wonderful 101;16 +0005000E-1012F100;1;WUP;0001;WUP-U-AWSJ;AWSJ01;Wii Sports Club;16,32,48,64,80,96,112 +0005000E-10131D00;1;WUP;0001;WUP-P-ASEJ;ASEJ01;????????;17,32 +0005000E-10131F00;1;WUP;0001;WUP-U-AYCJ;AYCJ01;yoshi's woolly world;32 +0005000E-10132400;4;WUP;00WR;WUP-U-ALMP;ALMPWR;LEGO® MARVEL Super Heroes;16,32,48 +0005000E-10132500;1;WUP;0001;WUP-U-WB9J;WB9J01;Wii Fit U Quick Check;16,64,81 +0005000E-10132600;2;WUP;0001;WUP-U-WB9E;WB9E01;Wii Fit U Quick Check;16,64,81 +0005000E-10132700;4;WUP;0001;WUP-U-WB9P;WB9P01;Wii Fit U Quick Check;16,64,81 +0005000E-10132800;2;WUP;00UP;WUP-U-WEPE;WEPEUP;Unepic EnjoyUp Games;16,32 +0005000E-10132900;2;WUP;004Q;WUP-U-ADSE;ADSE4Q;Disney INFINITY;16,32,49 +0005000E-10132A00;4;WUP;00Y4;WUP-U-WA2P;WA2PY4;Star Wars Pinball;17,32,48 +0005000E-10132B00;2;WUP;00WR;WUP-P-ALME;ALMEWR;LEGO® MARVEL Super Heroes;16,32 +0005000E-10135200;2;WUP;00Y4;WUP-U-WA2E;WA2EY4;Star Wars Pinball;16,33,48 +0005000E-10135300;4;WUP;0001;WUP-U-ACMP;ACMP01;The Wonderful 101;16 +0005000E-10135700;1;WUP;008P;WUP-U-ASNJ;ASNJ8P;SONIC LOST WORLD;16,32,48 +0005000E-10136300;4;WUP;00XY;WUP-U-WBTP;WBTPXY;BIT.TRIP Presents... Runner2: Future Legend of Rhythm Alien;17 +0005000E-10136C00;4;WUP;00WR;WUP-U-AZEP;AZEPWR;Batman™: Arkham Origins;16 +0005000E-10136F00;4;WUP;004Q;WUP-U-ADSP;ADSP4Q;Disney Infinity;16,32,49 +0005000E-10137000;4;WUP;004Q;WUP-U-ADSZ;ADSZ4Q;Disney Infinity;16,32,49 +0005000E-10137C00;2;WUP;00WR;WUP-U-AZEE;AZEEWR;Batman™: Arkham Origins;16 +0005000E-10137F00;2;WUP;0001;WUP-P-ARKE;ARKE01;Donkey Kong Country Tropical Freeze;16 +0005000E-10138300;4;WUP;0001;WUP-P-ARKP;ARKP01;Donkey Kong Country Tropical Freeze;17 +0005000E-10138700;4;WUP;00YV;WUP-P-WB6P;WB6PYV;Spin the Bottle: Bumpie's Party;16,33 +0005000E-10138800;4;WUP;0041;WUP-U-ASBP;ASBP41;Assassin's Creed® IV Black Flag;16,32 +0005000E-10138B00;2;WUP;0041;WUP-U-ASBE;ASBE41;Assassin's Creed® IV Black Flag;16,32 +0005000E-10138E00;4;WUP;0041;WUP-U-WB7P;WB7P41;Rayman Legends Challenges App;16 +0005000E-10138F00;1;WUP;0001;WUP-U-ADNJ;ADNJ01;Devil's Third;16 +0005000E-10139200;2;WUP;0052;WUP-U-ASFE;ASFE52;Skylanders SWAP Force;16 +0005000E-10139500;2;WUP;0041;WUP-U-WB7E;WB7E41;Rayman Legends Challenges App;16 +0005000E-10139900;2;WUP;0041;WUP-P-AJ5E;AJ5E41;JUST DANCE® 2014;16 +0005000E-10140400;4;WUP;0052;WUP-U-ASFP;ASFP52;Skylanders SWAP Force;16 +0005000E-10140700;1;WUP;00WR;WUP-U-AJSJ;AJSJWR;Injustice: Gods Among Us;16 +0005000E-10142700;4;WUP;0001;WUP-P-AA9P;AA9P01;Art Academy: SketchPad;16 +0005000E-10142A00;2;WUP;005G;WUP-U-AZBE;AZBE5G;Zumba Fitness World Party;16 +0005000E-10142B00;1;WUP;0001;WUP-P-AA9J;AA9J01;Art Academy: SketchPad;16 +0005000E-10142C00;2;WUP;0001;WUP-P-AA9E;AA9E01;Art Academy: SketchPad;16 +0005000E-10143F00;4;WUP;0041;WUP-P-AJ5P;AJ5P41;JUST DANCE® 2014;16 +0005000E-10144000;2;WUP;00G9;WUP-U-ADVE;ADVEG9;Adventure Time: Explore the Dungeon Because I Don't Know!;16 +0005000E-10144800;1;WUP;0001;WUP-P-ARKJ;ARKJ01;Donkey Kong Country Tropical Freeze;17 +0005000E-10144D00;2;WUP;0001;WUP-U-AWSE;AWSE01;Wii Sports Club;16,33,48,64,80,96,112 +0005000E-10144E00;4;WUP;0001;WUP-U-AWSP;AWSP01;Wii Sports Club;16,33,48,64,80,96,112 +0005000E-10144F00;2;WUP;0001;WUP-P-AXFE;AXFE01;Super Smash Bros. for Wii U;32,48,64,80,96,112,128,144,160,176,192,208 +0005000E-10145000;4;WUP;0001;WUP-P-AXFP;AXFP01;Super Smash Bros. for Wii U;32,48,64,80,96,112,128,144,160,176,192,208 +0005000E-10145600;7;WUP;0001;WUP-U-ADBA;ADBA01;Animal Crossing Plaza;16 +0005000E-10145800;4;WUP;00UP;WUP-U-WEPP;WEPPUP;Unepic EnjoyUp Games;16,32 +0005000E-10145900;4;WUP;00HL;WUP-U-WCDP;WCDPHL;Coaster Crazy Deluxe;16 +0005000E-10145F00;1;WUP;0001;WUP-P-WMGJ;WMGJ01;NES REMIX;16 +0005000E-10146000;2;WUP;0001;WUP-P-WMGE;WMGE01;NES REMIX;16 +0005000E-10146100;4;WUP;0001;WUP-P-WMGP;WMGP01;NES REMIX;16 +0005000E-10146800;2;WUP;0052;WUP-P-ACPE;ACPE52;Call of Duty: Ghosts;16,32,48,64,80,96,112 +0005000E-10147600;4;WUP;00DZ;WUP-P-WEVP;WEVPDZ;EvoFish;17 +0005000E-10147F00;2;WUP;00YV;WUP-P-WB6E;WB6EYV;Spin the Bottle: Bumpie's Party;16,32 +0005000E-10148000;1;WUP;00AF;WUP-P-AUNJ;AUNJAF;ONE PIECE UNLIMITED WORLD R;16 +0005000E-10148200;2;WUP;00UP;WUP-U-WAEE;WAEEUP;Rock 'N Racing Off Road;16 +0005000E-10148F00;1;WUP;0041;WUP-U-WLAJ;WLAJ41;Uplay;16 +0005000E-10149200;4;WUP;00SS;WUP-U-WDFP;WDFPSS;Spot The Differences: Party!;16,32 +0005000E-10149500;2;WUP;00CS;WUP-P-WKTE;WKTECS;Scram Kitty and his Buddy on Rails;16,32 +0005000E-10149700;1;WUP;0001;WUP-P-WAUJ;WAUJ01;?? ??;34,48 +0005000E-1014C600;4;WUP;00CX;WUP-U-WGSP;WGSPCX;Giana Sisters Twisted Dreams;16 +0005000E-1014C800;1;WUP;0041;WUP-U-ASBJ;ASBJ41;Assassin's Creed® IV Black Flag;16 +0005000E-1014CB00;2;WUP;00CX;WUP-P-WGSE;WGSECX;Giana Sisters Twisted Dreams;16 +0005000E-1014CF00;2;WUP;00HL;WUP-U-WCDE;WCDEHL;Coaster Crazy Deluxe;16,32 +0005000E-1014D100;4;WUP;00CS;WUP-U-WKTP;WKTPCS;Scram Kitty and his Buddy on Rails;17,32 +0005000E-1014D900;1;WUP;008P;WUP-P-APTJ;APTJ8P;PUYOPUYOTETRIS;16,32 +0005000E-1014DA00;1;WUP;0008;WUP-U-AMFJ;AMFJ08;Monster Hunter Frontier G;80,96,112,128,144,160,176,192,208,224,240,256,288,304,320,336,352,368,400,432,448,464,480,496,512,528,544,560,576,592,608,624,640,656,672,688,704,720,736,752,768,784,800,816,832,848,864,880,896,912,928,944,960,976,992,1008,1024,1040,1056,1072,1088,1104,1120,1136,1152,1168,1184,1200,1216,1232,1248,1264,1280,1296,1312,1328,1344,1360,1376 +0005000E-1014DE00;2;WUP;00WR;WUP-U-ALAE;ALAEWR;The LEGO® Movie Videogame;16 +0005000E-1014E000;4;WUP;00WR;WUP-U-ALAP;ALAPWR;The LEGO® Movie Videogame;18 +0005000E-1014E100;4;WUP;00AF;WUP-U-ADVP;ADVPAF;Adventure Time: Explore the Dungeon Because I Don't Know!;16 +0005000E-1014E300;4;WUP;00GT;WUP-U-AZBP;AZBPGT;Zumba Fitness World Party;16 +0005000E-10154600;1;WUP;00WR;WUP-U-AZEJ;AZEJWR;Batman™: Arkham Origins;16 +0005000E-10154D00;4;WUP;00BU;WUP-U-WC3P;WC3PBU;The Mysterious Cities of Gold: Secret Paths;16 +0005000E-10156100;4;WUP;0052;WUP-P-ACPP;ACPP52;Call of Duty: Ghosts;16,32,48,64,80,96,112 +0005000E-10156500;2;WUP;00BU;WUP-U-WC3E;WC3EBU;The Mysterious Cities of Gold: Secret Paths;16 +0005000E-10157600;4;WUP;0052;WUP-P-ACPI;ACPI52;Call of Duty: Ghosts;16,32,48,64,80,96,112 +0005000E-10157900;1;WUP;00GD;WUP-P-ACPJ;ACPJGD;Call of Duty: Ghosts;16,32,48,64,80,97,112 +0005000E-10159800;1;WUP;0001;WUP-U-AFCJ;AFCJ01;Wii Fit U (Free);48,64,81 +0005000E-10159900;2;WUP;0001;WUP-U-AFCE;AFCE01;Wii Fit U (Free);48,64,81 +0005000E-10159A00;4;WUP;0001;WUP-U-AFCP;AFCP01;Wii Fit U (promo);48,64,81 +0005000E-1015A300;1;WUP;00AF;WUP-U-ADSJ;ADSJAF;Disney INFINITY;17 +0005000E-1015B200;2;WUP;0041;WUP-P-ACLE;ACLE41;CHILD of LIGHT;16 +0005000E-1015D300;2;WUP;00AS;WUP-P-WLCE;WLCEAS;Lucadian Chronicles;32 +0005000E-1015EB00;1;WUP;00R7;WUP-U-WHYJ;WHYJR7;Mighty Switch Force!™ Hyper Drive Edition;18 +0005000E-10161F00;1;WUP;0001;WUP-U-ABAJ;ABAJ01;Mario Party 10;16 +0005000E-10162300;4;WUP;00YR;WUP-U-WCZP;WCZPYR;Color Zen;17 +0005000E-10162B00;1;WUP;0001;WUP-P-AGMJ;AGMJ01;Splatoon;16,32,48,64,80,96,112,128,144,160 +0005000E-10162D00;2;WUP;0001;WUP-U-ABAE;ABAE01;Mario Party 10;16 +0005000E-10169600;4;WUP;00UP;WUP-U-WEPS;WEPSUP;Unepic EnjoyUp Games;16,32 +0005000E-1016A200;4;WUP;00SS;WUP-U-WBXP;WBXPSS;Bombing Bastards;16 +0005000E-1016A400;4;WUP;00WR;WUP-P-BTMP;BTMPWR;LEGO® Batman™ 3 Beyond Gotham;16,32,48 +0005000E-1016A600;1;WUP;00TF;WUP-P-WB6J;WB6JTF;??????????????;17 +0005000E-1016AB00;2;WUP;00SS;WUP-U-WBXE;WBXESS;Bombing Bastards;16 +0005000E-1016AC00;2;WUP;009T;WUP-U-WMLE;WMLE9T;Armillo;16 +0005000E-1016AD00;2;WUP;00WR;WUP-P-BTME;BTMEWR;LEGO® Batman™ 3 Beyond Gotham;16,32,48 +0005000E-1016B200;2;WUP;009V;WUP-U-WMRE;WMRE9V;Master Reboot;16 +0005000E-1016C700;4;WUP;009T;WUP-U-WMLP;WMLP9T;Armillo;16 +0005000E-1016CE00;2;WUP;00YR;WUP-U-WCZE;WCZEYR;Color Zen;16 +0005000E-1016D500;4;WUP;009Y;WUP-P-WCTP;WCTP9Y;Super Toy Cars;22 +0005000E-1016D800;1;WUP;0041;WUP-P-ACLJ;ACLJ41;CHILD of LIGHT;16 +0005000E-1016DC00;2;WUP;004Q;WUP-P-ADRE;ADRE4Q;Disney Infinity [2.0];16,32,64,80 +0005000E-1016DE00;2;WUP;009Y;WUP-P-WCTE;WCTE9Y;Super Toy Cars;16 +0005000E-1016E100;2;WUP;00AY;WUP-P-WKNE;WKNEAY;Shovel Knight;16,32,48,64,80 +0005000E-1016E300;2;WUP;008S;WUP-P-WGRE;WGRE8S;GravBlocks+ From Nothing Game Studios;16 +0005000E-1016E800;4;WUP;009V;WUP-U-WMRP;WMRP9V;Master Reboot;16 +0005000E-1016EA00;4;WUP;0041;WUP-P-ACLP;ACLP41;CHILD of LIGHT;16 +0005000E-1016FF00;2;WUP;00NT;WUP-P-WFWE;WFWENT;Flowerworks HD Follie's Adventure;16 +0005000E-10170200;2;WUP;007Z;WUP-U-WGAE;WGAE7Z;Pier Solar and the Great Architects;16,33 +0005000E-10170600;1;WUP;00AF;WUP-U-APWJ;APWJAF;KAMEN RIDER BATTRIDE WAR ? PREMIUM TV&MOVIE SOUND ED.;16 +0005000E-10170700;1;WUP;00AF;WUP-U-ABWJ;ABWJAF;KAMEN RIDER BATTRIDE WAR ?;17 +0005000E-10172A00;2;WUP;009Z;WUP-N-HRLE;HRLE9Z;Crunchyroll;16 +0005000E-10172B00;4;WUP;009Z;WUP-N-HRLP;HRLP9Z;Crunchyroll;17 +0005000E-10173300;4;WUP;00UB;WUP-U-WCGP;WCGPUB;Stealth Inc 2 A Game of Clones;16,32 +0005000E-10175B00;2;WUP;008P;WUP-P-BSSE;BSSE8P;Sonic Boom: Rise of Lyric;16 +0005000E-10175D00;4;WUP;00AF;WUP-P-AUNP;AUNPAF;ONE PIECE Unlimited World Red;16 +0005000E-10176500;2;WUP;00UB;WUP-U-WCGE;WCGEUB;Stealth Inc 2 A Game of Clones;16 +0005000E-10176900;2;WUP;0001;WUP-P-AGME;AGME01;Splatoon;16,32,48,64,80,96,128,144,160 +0005000E-10176A00;4;WUP;0001;WUP-P-AGMP;AGMP01;Splatoon;32,48,64,80,96,112,128,144,160 +0005000E-10176F00;4;WUP;0041;WUP-P-BJDP;BJDP41;JUST DANCE® 2015;16 +0005000E-10177600;2;WUP;0001;WUP-U-ADNE;ADNE01;Devil's Third;16 +0005000E-10177800;4;WUP;008P;WUP-P-BSSP;BSSP8P;Sonic Boom: Rise of Lyric;16 +0005000E-10178F00;4;WUP;00AY;WUP-P-WKNP;WKNPAY;Shovel Knight;16,32,48 +0005000E-10179100;2;WUP;0041;WUP-P-BJDE;BJDE41;JUST DANCE® 2015;16 +0005000E-1017BE00;1;WUP;0001;WUP-U-BXAJ;BXAJ01;Art Academy: Home Studio;48 +0005000E-1017BF00;2;WUP;0001;WUP-U-BXAE;BXAE01;Art Academy: Home Studio;17 +0005000E-1017C600;2;WUP;0052;WUP-P-BK7E;BK7E52;Skylanders Trap Team;16 +0005000E-1017CD00;1;WUP;00C8;WUP-U-BWPJ;BWPJC8;Hyrule Warriors;32,49,64,80,98,112,113,128,144,160,176,192,208 +0005000E-1017D800;2;WUP;0001;WUP-U-BWPE;BWPE01;Hyrule Warriors;16,32,48,64,80,96,112,128 +0005000E-1017D900;4;WUP;0001;WUP-U-BWPP;BWPP01;Hyrule Warriors;16,33,48,64,80,96,112,128 +0005000E-1017DA00;2;WUP;011S;WUP-P-ACQE;ACQE1S;Costume Quest 2;16 +0005000E-1017E000;4;WUP;00XQ;WUP-P-WK8P;WK8PXQ;Turtle Tale;16 +0005000E-10180500;1;WUP;0001;WUP-P-AKBJ;AKBJ01;Captain Toad: Treasure Tracker;16 +0005000E-10180600;2;WUP;0001;WUP-P-AKBE;AKBE01;Captain Toad: Treasure Tracker;16 +0005000E-10180700;4;WUP;0001;WUP-P-AKBP;AKBP01;Captain Toad: Treasure Tracker;16 +0005000E-10181F00;4;WUP;0052;WUP-P-BK7P;BK7P52;Skylanders Trap Team;16 +0005000E-10182C00;4;WUP;00XT;WUP-U-AJTP;AJTPXT;Jett Tailfin;16 +0005000E-10183000;2;WUP;010P;WUP-P-ARNE;ARNE0P;Runbow;16,33,49 +0005000E-10183900;2;WUP;00UP;WUP-U-BMVE;BMVEUP;99Moves;16,32 +0005000E-10184D00;2;WUP;0001;WUP-U-AYCE;AYCE01;Yoshi's Woolly World;17 +0005000E-10187100;4;WUP;00LW;WUP-U-BUGP;BUGPLW;Underground;16,32 +0005000E-10188B00;1;WUP;0001;WUP-U-AXYJ;AXYJ01;Kirby and the Rainbow Curse;16 +0005000E-10188C00;4;WUP;004Q;WUP-P-ADRP;ADRP4Q;Disney Infinity [2.0];16,32,64,80 +0005000E-10188D00;4;WUP;004Q;WUP-P-ADRZ;ADRZ4Q;Disney Infinity [2.0];16,32,64,80 +0005000E-10189200;2;WUP;011C;WUP-P-BSPE;BSPE1C;Sportsball;16 +0005000E-1018C400;1;WUP;00AF;WUP-P-BSFJ;BSFJAF;???F??????????? ????SF???????????;16 +0005000E-1018D900;1;WUP;00AF;WUP-P-APHJ;APHJAF;LOST REAVERS;17 +0005000E-1018DB00;1;WUP;0001;WUP-U-AMAJ;AMAJ01;Super Mario Maker;16,32,48,64,80,96,113,128 +0005000E-1018DC00;2;WUP;0001;WUP-U-AMAE;AMAE01;Super Mario Maker;16,32,48,64,80,96,113,128 +0005000E-1018DD00;4;WUP;0001;WUP-U-AMAP;AMAP01;Super Mario Maker;32,48,64,80,96,113,128 +0005000E-1018DE00;4;WUP;00NK;WUP-U-ATCP;ATCPNK;Tetrobot and Co.;16 +0005000E-1018ED00;2;WUP;00NK;WUP-U-ATCE;ATCENK;Tetrobot and Co.;16 +0005000E-10191700;4;WUP;00UP;WUP-U-BMVP;BMVPUP;99Moves;16,32 +0005000E-10191800;4;WUP;00UP;WUP-U-WAEP;WAEPUP;Rock 'N Racing Off Road;16 +0005000E-10192200;1;WUP;00AF;WUP-P-BRSJ;BRSJAF;KAMEN RIDER SUMMON RIDE!;16,33,48,64,80 +0005000E-10194200;2;WUP;00WR;WUP-U-APZE;APZEWR;LEGO® DIMENSIONS™;16,32,48,64,80 +0005000E-10195D00;4;WUP;00WR;WUP-U-APZP;APZPWR;LEGO® DIMENSIONS™;32,48,64,80,96 +0005000E-10197800;4;WUP;011S;WUP-P-ACQP;ACQP1S;Costume Quest 2;16 +0005000E-10199000;1;WUP;0001;WUP-P-AVXJ;AVXJ01;Mario Tennis: Ultra Smash;16,32 +0005000E-1019AD00;2;WUP;011A;WUP-P-BEQE;BEQE1A;Elliot Quest;16,32,48,64,80,96 +0005000E-101A1B00;2;WUP;00RG;WUP-U-BS2E;BS2ERG;Swords & Soldiers II;16 +0005000E-101A2600;1;WUP;00W4;WUP-U-WKFJ;WKFJW4;Kung Fu Rabbit;16 +0005000E-101A2E00;1;WUP;00TF;WUP-P-WEXJ;WEXJTF;XType+;16 +0005000E-101A3500;2;WUP;0001;WUP-P-AVXE;AVXE01;Mario Tennis: Ultra Smash;16,32 +0005000E-101A3600;4;WUP;0001;WUP-P-AVXP;AVXP01;Mario Tennis: Ultra Smash;32 +0005000E-101A3B00;2;WUP;00LY;WUP-P-BLPE;BLPELY;Life of Pixel;16 +0005000E-101A4900;4;WUP;00LY;WUP-U-BLPP;BLPPLY;Life of Pixel;16 +0005000E-101A5C00;4;WUP;00WR;WUP-U-ALJP;ALJPWR;LEGO® Jurassic World™;16 +0005000E-101A5E00;4;WUP;00UB;WUP-U-ALLP;ALLPUB;OlliOlli;16 +0005000E-101A5F00;2;WUP;00WY;WUP-U-BSXE;BSXEWY;Shantae and the Pirate's Curse;16 +0005000E-101A6200;2;WUP;00WR;WUP-U-ALJE;ALJEWR;LEGO® Jurassic World™;16 +0005000E-101A6300;4;WUP;00YR;WUP-U-ACUP;ACUPYR;Cube Life: Island Survival;16 +0005000E-101A6400;2;WUP;00YR;WUP-U-ACUE;ACUEYR;Cube Life: Island Survival;16 +0005000E-101A6500;2;WUP;00VZ;WUP-P-BKFE;BKFEVZ;Kung Fu Panda Showdown of Legendary Legends;16 +0005000E-101A6900;2;WUP;00UB;WUP-P-ALLE;ALLEUB;OlliOlli;17 +0005000E-101A9500;4;WUP;00WY;WUP-U-BSXP;BSXPWY;Shantae and the Pirate's Curse;16 +0005000E-101A9F00;2;WUP;0147;WUP-P-BDAE;BDAE47;Dot Arcade;16 +0005000E-101AA200;2;WUP;014K;WUP-U-APJE;APJE4K;Vector Assault;18 +0005000E-101AA500;4;WUP;00VZ;WUP-P-BKFP;BKFPVZ;Kung Fu Panda Showdown of Legendary Legends;16,32 +0005000E-101ABC00;2;WUP;0001;WUP-U-AXYE;AXYE01;Kirby and the Rainbow Curse;16 +0005000E-101AC700;2;WUP;00VZ;WUP-P-BFNE;BFNEVZ;Adventure Time Finn and Jake Investigations;16 +0005000E-101AC900;2;WUP;004Q;WUP-P-BD3E;BD3E4Q;DISNEY INFINITY 3.0 EDITION;16,32,49 +0005000E-101AFE00;4;WUP;00VZ;WUP-P-BFNP;BFNPVZ;Adventure Time Finn and Jake Investigations;16 +0005000E-101B3D00;4;WUP;004Q;WUP-P-BD3P;BD3P4Q;DISNEY INFINITY 3.0: PLAY WITHOUT LIMITS;16,32,49 +0005000E-101B3E00;4;WUP;004Q;WUP-P-BD3Z;BD3Z4Q;DISNEY INFINITY 3.0: PLAY WITHOUT LIMITS;16,32,49 +0005000E-101B8500;2;WUP;0052;WUP-P-BS5E;BS5E52;Skylanders SuperChargers;16,32,64,80,96 +0005000E-101B9000;2;WUP;0041;WUP-P-AJ6E;AJ6E41;JUST DANCE® 2016;16,32 +0005000E-101B9800;4;WUP;0041;WUP-P-AJ6P;AJ6P41;JUST DANCE® 2016;16,32 +0005000E-101BA400;2;WUP;0052;WUP-P-AGNE;AGNE52;Guitar Hero Live;16,32,48,64 +0005000E-101BAA00;2;WUP;010C;WUP-U-ATTE;ATTE0C;Totem Topple;16 +0005000E-101BB300;4;WUP;008V;WUP-P-WLSP;WLSP8V;ZaciSa: Defense of the Crayon Dimension!;16 +0005000E-101BB800;4;WUP;011A;WUP-P-BEQP;BEQP1A;Elliot Quest;16,32,48,64,80 +0005000E-101BC600;4;WUP;0052;WUP-P-AGNP;AGNP52;Guitar Hero Live;18,32,48,64 +0005000E-101BE900;4;WUP;00WR;WUP-P-ALRP;ALRPWR;LEGO® MARVEL's Avengers;16 +0005000E-101BEF00;2;WUP;00WR;WUP-P-ALRE;ALREWR;LEGO® MARVEL's Avengers;16 +0005000E-101BFC00;4;WUP;0052;WUP-P-BS5P;BS5P52;Skylanders SuperChargers;32,48,64,80,97 +0005000E-101C0700;4;WUP;00UB;WUP-U-AN3P;AN3PUB;Nova-111;16 +0005000E-101C0A00;2;WUP;00UB;WUP-U-AN3E;AN3EUB;Nova-111;16 +0005000E-101C0B00;2;WUP;00UB;WUP-P-BS7E;BS7EUB;The Swindle;16 +0005000E-101C0C00;4;WUP;00UB;WUP-P-BS7P;BS7PUB;The Swindle;16 +0005000E-101C3100;2;WUP;0167;WUP-U-AFEE;AFEE67;Freedom Planet;17 +0005000E-101C3900;4;WUP;015G;WUP-P-AWBP;AWBP5G;Word Search by POWGI;16 +0005000E-101C4C00;4;WUP;0001;WUP-P-AX5D;AX5D01;Xenoblade Chronicles X;16 +0005000E-101C4D00;2;WUP;0001;WUP-P-AX5E;AX5E01;Xenoblade Chronicles X;16,32,48 +0005000E-101C6A00;2;WUP;016E;WUP-P-AD5E;AD5E6E;Octodad: Dadliest Catch;16 +0005000E-101C6E00;4;WUP;00RG;WUP-U-BS2P;BS2PRG;Swords & Soldiers II;16 +0005000E-101C8B00;4;WUP;00YT;WUP-P-AWMP;AWMPYT;WICKED MONSTERS BLAST! HD PLUS;16 +0005000E-101CC900;4;WUP;0167;WUP-U-AFEP;AFEP67;Freedom Planet;16 +0005000E-101CE100;2;WUP;0175;WUP-U-ACHE;ACHE75;Canvaleon;16,32 +0005000E-101D0700;4;WUP;0175;WUP-U-ACHP;ACHP75;Canvaleon;16,32 +0005000E-101D0900;2;WUP;00FV;WUP-U-AGWE;AGWEFV;Gunman Clive HD Collection;16 +0005000E-101D2C00;1;WUP;00SA;WUP-P-ATXJ;ATXJSA;Bike Rider UltraDX WORLD TOUR;16,32 +0005000E-101D3000;1;WUP;00AF;WUP-P-BT3J;BT3JAF;Taiko no Tatsujin Atsumete? TomodachiDaisakusen!;16 +0005000E-101D3900;4;WUP;017D;WUP-P-AQCP;AQCP7D;The Quiet Collection;16 +0005000E-101D4200;2;WUP;00DV;WUP-P-ABPE;ABPEDV;Brunswick Pro Bowling;16 +0005000E-101D6100;4;WUP;00FV;WUP-U-AGWP;AGWPFV;Gunman Clive HD Collection;16 +0005000E-101D6D00;4;WUP;010P;WUP-P-ARNP;ARNP0P;Runbow;17,33 +0005000E-101D7400;4;WUP;010C;WUP-U-ATTP;ATTP0C;Totem Topple;16 +0005000E-101D7500;4;WUP;00DU;WUP-P-AUMP;AUMPDU;Minecraft: Wii U Edition;16,32,48 +0005000E-101D8300;4;WUP;00TJ;WUP-U-AEJP;AEJPTJ;Electronic Super Joy;16 +0005000E-101D9D00;2;WUP;00DU;WUP-P-AUME;AUMEDU;Minecraft: Wii U Edition;16,32,48 +0005000E-101DBE00;1;WUP;0188;WUP-P-AUMJ;AUMJ88;Minecraft: Wii U Edition;16,32,48 +0005000E-101DC100;4;WUP;016E;WUP-P-AD5P;AD5P6E;Octodad: Dadliest Catch;16 +0005000E-101DD700;1;WUP;013P;WUP-P-ARNJ;ARNJ3P;Runbow;16,17 +0005000E-101DDC00;1;WUP;00AF;WUP-P-BD3J;BD3JAF;????????????3.0;17,33 diff --git a/src/de/mas/jnustool/Content.java b/src/de/mas/jnustool/Content.java index 8fd28ca..414b6c9 100644 --- a/src/de/mas/jnustool/Content.java +++ b/src/de/mas/jnustool/Content.java @@ -1,5 +1,11 @@ package de.mas.jnustool; +import java.io.File; +import java.io.IOException; +import java.util.concurrent.atomic.AtomicInteger; + +import de.mas.jnustool.util.Downloader; +import de.mas.jnustool.util.Settings; import de.mas.jnustool.util.Util; public class Content { @@ -9,17 +15,50 @@ public class Content { short type; // 6 0xB0A long size; // 8 0xB0C byte[] SHA2 = new byte[32]; // 16 0xB14 + TitleMetaData tmd; + AtomicInteger error_output_done = new AtomicInteger(0);// 16 0xB14 - public Content(int ID, short index, short type, long size, byte[] SHA2) { + public Content(int ID, short index, short type, long size, byte[] SHA2,TitleMetaData tmd) { this.ID = ID; this.index = index; this.type = type; this.size = size; this.SHA2 = SHA2; + this.tmd = tmd; } @Override public String toString(){ return "ID: " + ID +" index: " + index + " type: " + type + " size: " + size + " SHA2: " + Util.ByteArrayToString(SHA2); } + + public void download(Progress progress) throws IOException{ + String tmpPath = tmd.getContentPath(); + if ((type & 0x02) == 0x02){ + Downloader.getInstance().downloadContentH3(tmd.titleID,ID,tmpPath,null); + } + File f = new File(tmpPath + "/" + String.format("%08X", ID ) + ".app"); + if(f.exists()){ + if(f.length() == size){ + Logger.log("Skipping Content: " + String.format("%08X", ID)); + progress.addCurrent((int) size); + }else{ + if(Settings.downloadWhenCachedFilesMissingOrBroken){ + Logger.log("Content " +String.format("%08X", ID) + " is broken. Downloading it again."); + Downloader.getInstance().downloadContent(tmd.titleID,ID,tmpPath,progress); + }else{ + if(Settings.skipBrokenFiles){ + Logger.log("Content " +String.format("%08X", ID) + " is broken. Ignoring it."); + }else{ + Logger.log("Content " +String.format("%08X", ID) + " is broken. Downloading not allowed."); + System.exit(2); + } + } + } + }else{ + Logger.log("Download Content: " + String.format("%08X", ID)); + Downloader.getInstance().downloadContent(tmd.titleID,ID,tmpPath,progress); + } + + } } diff --git a/src/de/mas/jnustool/ContentDownloader.java b/src/de/mas/jnustool/ContentDownloader.java new file mode 100644 index 0000000..7f36a3b --- /dev/null +++ b/src/de/mas/jnustool/ContentDownloader.java @@ -0,0 +1,32 @@ +package de.mas.jnustool; + +import java.util.concurrent.Callable; + +public class ContentDownloader implements Callable +{ + Content c; + Progress progress = null; + public void setContent(Content c){ + this.c = c; + } + public ContentDownloader(Content f,Progress fatherProgress){ + setContent(f); + createProgress(fatherProgress); + } + + private void createProgress(Progress fatherProgress) { + if(fatherProgress != null){ + progress = new Progress(); + fatherProgress.add(progress); + progress.addTotal(c.size); + + } + } + + @Override + public Integer call() throws Exception { + c.download(progress); + return null; + } + +} diff --git a/src/de/mas/jnustool/FEntry.java b/src/de/mas/jnustool/FEntry.java index 3c8fe49..0637fd9 100644 --- a/src/de/mas/jnustool/FEntry.java +++ b/src/de/mas/jnustool/FEntry.java @@ -7,6 +7,7 @@ import java.util.List; import de.mas.jnustool.util.Decryption; import de.mas.jnustool.util.Downloader; import de.mas.jnustool.util.Settings; +import de.mas.jnustool.util.Util; public class FEntry { private FST fst; @@ -125,28 +126,11 @@ public class FEntry { NUScontentID = nUScontentID; } - private void createFolder() { - long titleID = getTitleID(); - String [] path = getFullPath().split("/"); - File f = new File (String.format("%016X", titleID)); - if(!f.exists())f.mkdir(); - - String folder = String.format("%016X", titleID) +"/"; - File folder_ = null; - for(int i = 0;i private void createProgressListener(Progress fatherProgress) { if(fatherProgress != null){ progress = new Progress(); - progress.setTotal(f.getFileLength()); - fatherProgress.add(progress); + fatherProgress.add(progress); + progress.addTotal(f.getFileLength()); + } } @Override diff --git a/src/de/mas/jnustool/FST.java b/src/de/mas/jnustool/FST.java index 5fb7b89..969ae95 100644 --- a/src/de/mas/jnustool/FST.java +++ b/src/de/mas/jnustool/FST.java @@ -30,8 +30,7 @@ public class FST { buildDirectories(); } - private void buildDirectories() { - + private void buildDirectories() { String contentfolder = ""; Directory curContent = contentDirectory; for(FEntry f : getFileEntries()){ @@ -60,8 +59,7 @@ public class FST { } if(i==f.getPathList().size()){ curContent.addFile(f); - } - + } //FST if(current.containsFolder(s)){ @@ -77,12 +75,7 @@ public class FST { } } } - - - } - - private void parse(byte[] decrypteddata, TitleMetaData tmd) throws IOException { @@ -120,8 +113,7 @@ public class FST { { level--; } - } - + } int offset = base_offset + i*0x10; @@ -216,64 +208,52 @@ public class FST { //Logger.log(fileEntries.get(i)); } - } - - + } public long getTotalContentSize() { return totalContentSize; } - public void setTotalContentSize(long totalContentSize) { this.totalContentSize = totalContentSize; } - public long getTotalContentSizeInNUS() { return totalContentSizeInNUS; } - public void setTotalContentSizeInNUS(long totalContentSizeInNUS) { this.totalContentSizeInNUS = totalContentSizeInNUS; } public List getMetaFolder() { return metaFolder; - } - + } public List getFileEntries() { return fileEntries; } - public void setFileEntries(List fileEntries) { this.fileEntries = fileEntries; } - public int getTotalContentCount() { return totalContentCount; } - public void setTotalContentCount(int totalContentCount) { this.totalContentCount = totalContentCount; } - public int getTotalEntries() { return totalEntries; } - public void setTotalEntries(int totalEntries) { this.totalEntries = totalEntries; } - public int getDirEntries() { return dirEntries; } @@ -283,13 +263,11 @@ public class FST { this.dirEntries = dirEntries; } - @Override public String toString(){ return "entryCount: " + totalContentCount+ " entries: " + totalEntries; } - public int getFileCount() { int i = 0; for(FEntry f: getFileEntries()){ @@ -315,8 +293,6 @@ public class FST { public Directory getContentDirectory() { return contentDirectory; } - - public TitleMetaData getTmd() { return tmd; diff --git a/src/de/mas/jnustool/Logger.java b/src/de/mas/jnustool/Logger.java index d0046f9..324cc0b 100644 --- a/src/de/mas/jnustool/Logger.java +++ b/src/de/mas/jnustool/Logger.java @@ -10,7 +10,7 @@ public class Logger { public static void log(String string) { NUSGUI.output.append(string + "\n"); NUSGUI.output.setCaretPosition(NUSGUI.output.getDocument().getLength()); - //System.out.println(string); + System.out.println(string); } diff --git a/src/de/mas/jnustool/NUSTitle.java b/src/de/mas/jnustool/NUSTitle.java index f66e8a7..bedca66 100644 --- a/src/de/mas/jnustool/NUSTitle.java +++ b/src/de/mas/jnustool/NUSTitle.java @@ -1,7 +1,10 @@ package de.mas.jnustool; +import java.io.ByteArrayInputStream; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -9,18 +12,39 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.ForkJoinPool; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + import de.mas.jnustool.util.Decryption; import de.mas.jnustool.util.Downloader; +import de.mas.jnustool.util.NUSTitleInformation; import de.mas.jnustool.util.Settings; +import de.mas.jnustool.util.Util; public class NUSTitle { private TitleMetaData tmd; private TIK ticket; private FST fst; private long titleID; - public NUSTitle(long titleId,String key) { + private String targetPath = new String(); + private String longNameFolder = new String(); + private int version = -1; + + private String getTMDName(){ + String result = "title.tmd"; + + return result; + } + + public NUSTitle(long titleId,int version, String key) { + setVersion(version); setTitleID(titleId); - try { + try { + /* if(Settings.downloadContent){ File f = new File(getContentPath()); if(!f.exists())f.mkdir(); @@ -28,26 +52,27 @@ public class NUSTitle { if(Settings.downloadContent){ - File f = new File(getContentPath() + "/" + "tmd"); + File f = new File(getContentPath() + "/" + getTMDName()); if(!(f.exists() && Settings.skipExistingTMDTICKET)){ Logger.log("Downloading TMD"); Downloader.getInstance().downloadTMD(titleId,getContentPath()); }else{ Logger.log("Skipped download of TMD. Already existing"); } + f = new File(getContentPath() + "/" + "cetk"); if(!(f.exists() && Settings.skipExistingTMDTICKET)){ if(key == null){ - System.out.print("Downloading Ticket"); + Logger.log("Downloading Ticket"); Downloader.getInstance().downloadTicket(titleId,getContentPath()); } }else{ Logger.log("Skipped download of ticket. Already existing"); } - } + }*/ if(Settings.useCachedFiles){ - File f = new File(getContentPath() + "/" + "tmd"); + File f = new File(getContentPath() + "/" + getTMDName()); if(f.exists()){ Logger.log("Using cached TMD."); tmd = new TitleMetaData(f); @@ -58,7 +83,7 @@ public class NUSTitle { if(tmd == null){ if(Settings.downloadWhenCachedFilesMissingOrBroken){ if(Settings.useCachedFiles) Logger.log("Getting missing tmd from Server!"); - tmd = new TitleMetaData(Downloader.getInstance().downloadTMDToByteArray(titleId)); + tmd = new TitleMetaData(Downloader.getInstance().downloadTMDToByteArray(titleId,this.version)); }else{ Logger.log("Downloading of missing files is not enabled. Exiting"); System.exit(2); @@ -69,7 +94,7 @@ public class NUSTitle { ticket = new TIK(key,titleId); }else{ if(Settings.useCachedFiles){ - File f = new File(getContentPath() + "/" + "cetk"); + File f = new File(getContentPath() + "/" + "title.tik"); if(f.exists()){ Logger.log("Using cached cetk."); ticket = new TIK(f,titleId); @@ -88,27 +113,25 @@ public class NUSTitle { } } - if(Settings.downloadContent){ + /*if(Settings.downloadContent){ File f = new File(getContentPath() + "/" + String.format("%08x", tmd.contents[0].ID) + ".app"); if(!(f.exists() && Settings.skipExistingFiles)){ Logger.log("Downloading FST (" + String.format("%08x", tmd.contents[0].ID) + ")"); - Downloader.getInstance().downloadContent(titleId,tmd.contents[0].ID,getContentPath()); + Downloader.getInstance().downloadContent(titleId,tmd.contents[0].ID,getContentPath(),null); }else{ if(f.length() != tmd.contents[0].size){ if(Settings.downloadWhenCachedFilesMissingOrBroken){ Logger.log("FST already existing, but broken. Downloading it again."); - Downloader.getInstance().downloadContent(titleId,tmd.contents[0].ID,getContentPath()); + Downloader.getInstance().downloadContent(titleId,tmd.contents[0].ID,getContentPath(),null); }else{ Logger.log("FST already existing, but broken. No download allowed."); System.exit(2); } }else{ Logger.log("Skipped download of FST. Already existing"); - } - + } } - - } + }*/ Decryption decryption = new Decryption(ticket.getDecryptedKey(),0); @@ -140,16 +163,33 @@ public class NUSTitle { byte[] decryptedFST = decryption.decrypt(encryptedFST); fst = new FST(decryptedFST,tmd); + tmd.setNUSTitle(this); - if(Settings.downloadContent){ - tmd.downloadContents(); + setTargetPath(String.format("%016X", getTitleID())); + + setLongNameFolder(String.format("%016X", getTitleID())); + + if(tmd.isUpdate()){ + byte[] metaxml = fst.metaFENtry.downloadAsByteArray(); + if(metaxml != null){ + InputStream bis = new ByteArrayInputStream(metaxml); + NUSTitleInformation nusinfo = readMeta(bis); + String folder = nusinfo.getLongnameEN() + " [" + nusinfo.getID6() + "]"; + String subfolder = "/" + "updates" + "/" + "v" + tmd.titleVersion; + setTargetPath(folder + subfolder); + setLongNameFolder(folder); + } + } + + if(Settings.downloadContent){ + downloadEncryptedFiles(null); } 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: " + fst.getFileCount()); Logger.log("Files in NUSTitle: " + fst.getFileCountInNUS()); } catch (IOException e) { @@ -157,11 +197,52 @@ public class NUSTitle { e.printStackTrace(); } } - - - - + public void downloadEncryptedFiles(Progress progress) throws IOException { + Util.createSubfolder(getContentPath()); + + Downloader.getInstance().downloadTMD(titleID,version,getContentPath()); + Downloader.getInstance().downloadTicket(titleID,getContentPath()); + + tmd.downloadContents(progress); + + FileOutputStream fos = new FileOutputStream(getContentPath() +"/title.cert"); + fos.write(ticket.cert0); + fos.write(tmd.cert); + fos.write(ticket.cert1); + fos.close(); + } + + NUSTitleInformation readMeta(InputStream bis) { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder; + + String ID6 = null; + try { + builder = factory.newDocumentBuilder(); + Document document = builder.parse(bis); + String proc = document.getElementsByTagName("product_code").item(0).getTextContent().toString(); + String comp = document.getElementsByTagName("company_code").item(0).getTextContent().toString(); + String title_id = document.getElementsByTagName("title_id").item(0).getTextContent().toString(); + + String longname = document.getElementsByTagName("longname_en").item(0).getTextContent().toString(); + longname = longname.replace("\n", " "); + String id = proc.substring(proc.length()-4, proc.length()); + comp = comp.substring(comp.length()-2, comp.length()); + ID6 = id+comp; + String company_code = document.getElementsByTagName("company_code").item(0).getTextContent().toString(); + String content_platform = document.getElementsByTagName("content_platform").item(0).getTextContent().toString(); + String region = document.getElementsByTagName("region").item(0).getTextContent().toString(); + NUSTitleInformation nusinfo = new NUSTitleInformation(Util.StringToLong(title_id),longname,ID6,proc,content_platform,company_code,Integer.parseInt(region),new String[1]); + return nusinfo; + + } catch (ParserConfigurationException | SAXException | IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + + } public FST getFst() { return fst; @@ -170,7 +251,6 @@ public class NUSTitle { public void setFst(FST fst) { this.fst = fst; } - public TitleMetaData getTmd() { return tmd; @@ -184,8 +264,6 @@ public class NUSTitle { return ticket; } - - public void setTicket(TIK ticket) { this.ticket = ticket; } @@ -194,18 +272,18 @@ public class NUSTitle { return tmd.getTotalContentSize(); } - - public String getContentPath() { - return getContentPathPrefix() + String.format("%016X", getTitleID()); + String result = getContentPathPrefix() + String.format("%016X", getTitleID()); + if(version > 0){ + result += "_v" + version; + } + return result; } public String getContentPathPrefix() { return "tmp_"; } - - public long getTitleID() { return titleID; } @@ -215,6 +293,8 @@ public class NUSTitle { } public void decryptFEntries(List list,Progress progress) { + Util.createSubfolder(getTargetPath()); + //progress = null; ForkJoinPool pool = ForkJoinPool.commonPool(); List dlList = new ArrayList<>(); for(FEntry f : list){ @@ -225,6 +305,32 @@ public class NUSTitle { pool.invokeAll(dlList); Logger.log("Done!"); } + + public void setTargetPath(String path){ + path = path.replaceAll("[:\\\\*?|<>]", ""); + this.targetPath = path; + } + + public String getTargetPath() { + return this.targetPath; + } + + public String getLongNameFolder() { + return longNameFolder; + } + + public void setLongNameFolder(String path) { + path = path.replaceAll("[:\\\\*?|<>]", ""); + longNameFolder = path; + } + + public int getVersion() { + return version; + } + + public void setVersion(int version) { + this.version = version; + } diff --git a/src/de/mas/jnustool/Progress.java b/src/de/mas/jnustool/Progress.java index 0ff2f98..d840660 100644 --- a/src/de/mas/jnustool/Progress.java +++ b/src/de/mas/jnustool/Progress.java @@ -2,42 +2,63 @@ package de.mas.jnustool; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.atomic.AtomicLong; public class Progress { - private long total; - private long current; + private AtomicLong total = new AtomicLong(); + private AtomicLong current = new AtomicLong(); private ProgressUpdateListener progressUpdateListener = null; List children = new ArrayList<>(); Progress father = null; + private AtomicLong totalChildren = new AtomicLong(); + private AtomicLong currentChildren = new AtomicLong(); public long getTotalOfSingle() { - return total; + return total.get(); } - - public void setTotal(long total) { - this.total = total; + + private void setTotalOfSingle(long total) { + this.total.set(total); } public long getCurrentOfSingle() { - return current; + return current.get(); } - public void setCurrent(long current) { - this.current = current; + private void setCurrent(long current) { + this.current.set(current); update(); } - - public void addCurrent(int i) { - if(this.current + i > getTotalOfSingle()){ - setCurrent(getTotalOfSingle()); - }else{ - setCurrent(getCurrent() + i); - } + + public void addTotal(long i) { + setTotalOfSingle(getTotalOfSingle() + i); + if(father != null) father.addTotalChildren(i); + } + + private void addCurrentChildren(long i) { + if(father != null) father.addCurrentChildren(i); + this.currentChildren.addAndGet(i); } + private void addTotalChildren(long i) { + if(father != null){ + father.addTotalChildren(i); + } + this.totalChildren.addAndGet(i); + } + + public void addCurrent(int i) { + if(this.current.get() + i > getTotalOfSingle()){ + setCurrent(getTotalOfSingle()); + }else{ + setCurrent(getCurrentOfSingle() + i); + if(father != null) father.addCurrentChildren(i); + } + } + private void update() { if(father != null) father.update(); @@ -48,40 +69,47 @@ public class Progress { public void add(Progress progress) { progress.setFather(this); + addChildrenTotal(progress.getTotalOfSingle()); children.add(progress); } + private void addChildrenTotal(long totalOfSingle) { + this.totalChildren.addAndGet(totalOfSingle); + } + private void setFather(Progress progressListener) { this.father = progressListener; } public long getCurrent() { - long tmp = getCurrentOfSingle(); - for(Progress p : children){ - tmp +=p.getCurrent(); - } - return tmp; + return this.currentChildren.get() + this.current.get(); } - public long getTotal() { - long tmp = getTotalOfSingle(); - for(Progress p : children){ - tmp +=p.getTotal(); - } - return tmp; + + public long getTotal() { + return this.totalChildren.get() + this.total.get(); } + + public void setTotal(long total) { + this.total.set(total); + } + + public void setProgressUpdateListener(ProgressUpdateListener progressUpdateListener) { this.progressUpdateListener = progressUpdateListener; } public void clear() { - setCurrent(0); - setTotal(0); + current.set(0); + currentChildren.set(0); + total.set(0); + totalChildren.set(0); + father = null; children = new ArrayList<>(); } - public int statusInPercent() { + public int statusInPercent() { return (int) ((getCurrent()*1.0)/(getTotal()*1.0)*100); } @@ -101,5 +129,11 @@ public class Progress { public boolean isInProgress(){ return inprogress; } + + public void resetCurrent() { + while(getCurrentOfSingle() > 0){ + addCurrent((int)getCurrentOfSingle() * (-1)); + } + } } diff --git a/src/de/mas/jnustool/Starter.java b/src/de/mas/jnustool/Starter.java index dacd427..7bf3686 100644 --- a/src/de/mas/jnustool/Starter.java +++ b/src/de/mas/jnustool/Starter.java @@ -21,12 +21,12 @@ public class Starter { private static String updateCSVPath; - public static void main(String[] args) { - Logger.log("JNUSTool 0.0.4 - pre alpha - by Maschell"); + public static void main(String[] args) { + + Logger.log("JNUSTool 0.0.5 - alpha - by Maschell"); Logger.log(""); try { readConfig(); - } catch (IOException e) { System.err.println("Error while reading config! Needs to be:"); System.err.println("DOWNLOAD URL BASE"); @@ -42,7 +42,7 @@ public class Starter { key = args[1].substring(0, 32); } if(titleID != 0){ - NUSGUI m = new NUSGUI(new NUSTitle(titleID, key)); + NUSGUI m = new NUSGUI(new NUSTitle(titleID,-1, key)); m.setVisible(true); } }else{ @@ -53,16 +53,12 @@ public class Starter { @Override public void run() { - NUSGUI m = new NUSGUI(new NUSTitle(tID, null)); - m.setVisible(true); - + NUSGUI m = new NUSGUI(new NUSTitle(tID,nus.getSelectedVersion(), null)); + m.setVisible(true); } }).start();; - } - + } } - - } @@ -100,9 +96,9 @@ public class Starter { String line; while((line = in.readLine()) != null){ String[] infos = line.split(";"); - if(infos.length != 7) { + if(infos.length != 8) { Logger.messageBox("Updatelist is broken!"); - System.out.println("Updatelist is broken!"); + Logger.log("Updatelist is broken!"); return null; } long titleID = Util.StringToLong(infos[0].replace("-", "")); @@ -112,7 +108,9 @@ public class Starter { 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); + String[] versions = infos[7].split(","); + NUSTitleInformation info = new NUSTitleInformation(titleID, longnameEN, ID6, product_code, content_platform, company_code, region,versions); + list.add(info); } in.close(); @@ -122,7 +120,7 @@ public class Starter { } catch (IOException e1) { } Logger.messageBox("Updatelist is broken or missing"); - System.out.println("Updatelist is broken!"); + Logger.log("Updatelist is broken!"); return null; } return list; @@ -136,7 +134,7 @@ public class Starter { String commonkey = in.readLine(); if(commonkey.length() != 32){ Logger.messageBox("CommonKey length is wrong"); - System.out.println("Commonkey length is wrong"); + Logger.log("Commonkey length is wrong"); System.exit(1); } Util.commonKey = Util.hexStringToByteArray(commonkey); @@ -145,20 +143,37 @@ public class Starter { } - + public static boolean deleteFolder(File element) { + if (element.isDirectory()) { + for (File sub : element.listFiles()) { + if(sub.isFile()){ + return false; + } + } + for (File sub : element.listFiles()) { + if(!deleteFolder(sub)) return false; + } + } + element.delete(); + return true; + } public static void downloadMeta(List output_, Progress totalProgress) { ForkJoinPool pool = ForkJoinPool.commonPool(); List> list = new ArrayList<>(); + for(NUSTitleInformation nus : output_){ final long tID = nus.getTitleID(); list.add(pool.submit(new Callable(){ @Override - public Boolean call() throws Exception { - NUSTitle nus = new NUSTitle(tID, null); + public Boolean call() throws Exception { + NUSTitle nusa = new NUSTitle(tID,nus.getSelectedVersion(),Util.ByteArrayToString(nus.getKey())); Progress childProgress = new Progress(); + totalProgress.add(childProgress); - nus.decryptFEntries(nus.getFst().getMetaFolder(),childProgress); + deleteFolder(new File(nusa.getLongNameFolder() + "/updates")); + nusa.setTargetPath(nusa.getLongNameFolder()); + nusa.decryptFEntries(nusa.getFst().getMetaFolder(),childProgress); return true; } })); @@ -176,4 +191,36 @@ public class Starter { } } + public static void downloadEncrypted(List output_, Progress progress) { + ForkJoinPool pool = ForkJoinPool.commonPool(); + List> list = new ArrayList<>(); + + for(NUSTitleInformation nus : output_){ + final long tID = nus.getTitleID(); + list.add(pool.submit(new Callable(){ + @Override + public Boolean call() throws Exception { + NUSTitle nusa = new NUSTitle(tID,nus.getSelectedVersion(), Util.ByteArrayToString(nus.getKey())); + Progress childProgress = new Progress(); + progress.add(childProgress); + nusa.downloadEncryptedFiles(progress); + + return true; + } + })); + } + for(ForkJoinTask task : list){ + try { + task.get(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + } + } diff --git a/src/de/mas/jnustool/TIK.java b/src/de/mas/jnustool/TIK.java index 76c0aed..c51b95a 100644 --- a/src/de/mas/jnustool/TIK.java +++ b/src/de/mas/jnustool/TIK.java @@ -3,6 +3,7 @@ package de.mas.jnustool; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; +import java.util.Arrays; import de.mas.jnustool.util.Decryption; import de.mas.jnustool.util.Util; @@ -12,6 +13,9 @@ public class TIK { private byte[] encryptedKey = new byte[16]; private byte[] decryptedKey = new byte[16]; + public byte[] cert0 = new byte[0x400]; + public byte[] cert1 = new byte[0x300]; + public TIK(File cetk,long titleid) throws IOException{ parse(cetk); calculateDecryptedKey(titleid); @@ -33,14 +37,29 @@ public class TIK { decryptedKey = decryption.decrypt(encryptedKey); } - private void parse(byte[] cetk) throws IOException { - System.arraycopy(cetk, 0x1bf, this.encryptedKey, 0,16); + private void parse(byte[] cetk) throws IOException { + if(cetk != null){ + System.arraycopy(cetk, 0x1bf, this.encryptedKey, 0,16); + if(cetk.length >= 0x650 + 0x400){ + cert0 = Arrays.copyOfRange(cetk, 0x650, 0x650 + 0x400); + cert1 = Arrays.copyOfRange(cetk, 0x350, 0x350 + 0x300); + }else{ + Logger.log("No certs for TIK found. File too short!"); + } + } + } private void parse(File cetk) throws IOException { RandomAccessFile f = new RandomAccessFile(cetk, "r"); f.seek(0x1bf); - f.read(this.encryptedKey, 0, 16); + f.read(this.encryptedKey, 0, 16); + + f.seek(0x650); + f.read(cert0, 0, 0x400); + f.seek(0x350); + f.read(cert1, 0, 0x300); + f.close(); } @@ -66,6 +85,9 @@ public class TIK { @Override public String toString(){ - return "encrypted key: " + Util.ByteArrayToString(encryptedKey)+ " decrypted key: " + Util.ByteArrayToString(decryptedKey); + String result = "Encrypted key: " + Util.ByteArrayToString(encryptedKey)+ " Decrypted key: " + Util.ByteArrayToString(decryptedKey) + "\n"; + result += "cert0:" + Util.ByteArrayToString(cert0) + "\n"; + result += "cert1:" + Util.ByteArrayToString(cert1) + "\n"; + return result; } } diff --git a/src/de/mas/jnustool/TitleMetaData.java b/src/de/mas/jnustool/TitleMetaData.java index d8320e2..e38c9d6 100644 --- a/src/de/mas/jnustool/TitleMetaData.java +++ b/src/de/mas/jnustool/TitleMetaData.java @@ -4,9 +4,10 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ForkJoinPool; -import de.mas.jnustool.util.Downloader; -import de.mas.jnustool.util.Settings; import de.mas.jnustool.util.Util; public class TitleMetaData { @@ -28,8 +29,8 @@ public class TitleMetaData { byte[] SHA2 = new byte[32]; // 0x1E4 ContentInfo[] contentInfos = new ContentInfo[64]; // 0x1E4 Content[] contents; // 0x1E4 - - + byte[] cert = new byte[0x300]; + private NUSTitle nus; private long totalContentSize; @@ -112,8 +113,12 @@ public class TitleMetaData { byte[] buffer = new byte[0x20]; // 16 0xB14 f.read(buffer,0, 0x20); - this.contents[i] = new Content(ID,index,type,size,buffer); - } + this.contents[i] = new Content(ID,index,type,size,buffer,this); + } + + if(f.read(cert,0, 0x300) != 0x300){ + Logger.log("Error reading TMD cert"); + } f.close(); } @@ -136,6 +141,7 @@ public class TitleMetaData { sb.append("contentCount: " + contentCount +"\n"); sb.append("bootIndex: " + bootIndex +"\n"); sb.append("SHA2: " + Util.ByteArrayToString(SHA2) +"\n"); + sb.append("cert: " + Util.ByteArrayToString(cert) +"\n"); sb.append("contentInfos: \n"); for(int i = 0; i dlList = new ArrayList<>(); for(Content c : contents){ - if(c != contents[0]){ - f = new File(tmpPath + "/" + String.format("%08X", c.ID ) + ".app"); - if(f.exists()){ - if(f.length() == c.size){ - Logger.log("Skipping Content: " + String.format("%08X", c.ID)); - }else{ - if(Settings.downloadWhenCachedFilesMissingOrBroken){ - Logger.log("Content " +String.format("%08X", c.ID) + " is broken. Downloading it again."); - Downloader.getInstance().downloadContent(titleID,c.ID,tmpPath); - }else{ - if(Settings.skipBrokenFiles){ - Logger.log("Content " +String.format("%08X", c.ID) + " is broken. Ignoring it."); - }else{ - Logger.log("Content " +String.format("%08X", c.ID) + " is broken. Downloading not allowed."); - System.exit(2); - } - } - } - }else{ - Logger.log("Download Content: " + String.format("%08X", c.ID)); - Downloader.getInstance().downloadContent(titleID,c.ID,tmpPath); - } - } + dlList.add(new ContentDownloader(c,progress)); } + pool.invokeAll(dlList); + Logger.log("Done!"); } diff --git a/src/de/mas/jnustool/gui/NUSGUI.java b/src/de/mas/jnustool/gui/NUSGUI.java index e82b319..2334f77 100644 --- a/src/de/mas/jnustool/gui/NUSGUI.java +++ b/src/de/mas/jnustool/gui/NUSGUI.java @@ -9,6 +9,7 @@ import java.util.List; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; +import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTextArea; @@ -22,8 +23,6 @@ import de.mas.jnustool.NUSTitle; import de.mas.jnustool.Progress; import de.mas.jnustool.ProgressUpdateListener; -import javax.swing.JProgressBar; - public class NUSGUI extends JFrame { private static final long serialVersionUID = 4648172894076113183L; diff --git a/src/de/mas/jnustool/gui/UpdateChooser.java b/src/de/mas/jnustool/gui/UpdateChooser.java index 9f063ae..1b2b3df 100644 --- a/src/de/mas/jnustool/gui/UpdateChooser.java +++ b/src/de/mas/jnustool/gui/UpdateChooser.java @@ -1,31 +1,42 @@ package de.mas.jnustool.gui; import java.awt.BorderLayout; +import java.awt.Component; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Collections; +import java.util.EventObject; +import java.util.HashMap; +import java.util.Hashtable; import java.util.List; +import java.util.Map.Entry; import javax.swing.BorderFactory; import javax.swing.BoxLayout; +import javax.swing.DefaultCellEditor; import javax.swing.JButton; +import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JList; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTable; import javax.swing.JTextArea; +import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.ScrollPaneConstants; +import javax.swing.event.CellEditorListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; +import javax.swing.table.TableCellEditor; import de.mas.jnustool.Logger; import de.mas.jnustool.Progress; @@ -45,25 +56,50 @@ public class UpdateChooser extends JPanel { ListSelectionModel listSelectionModel; public UpdateChooser(JFrame window) { super(new BorderLayout()); - setSize(800, 600); + setSize(800, 650); Collections.sort(list_); output_.add(list_.get(0)); - String[] columnNames = { "TitleID", "Region", "Name" }; + String[] columnNames = { "TitleID", "Region", "Name","version"}; String[][] tableData = new String[list_.size()][]; int i = 0; + HashMap> comboboxes = new HashMap<>(); for(NUSTitleInformation n: list_){ - tableData[i] = new String[3]; + tableData[i] = new String[4]; tableData[i][0] = n.getTitleIDAsString(); tableData[i][1] = n.getRegionAsRegion().toString(); tableData[i][2] = n.getLongnameEN(); - i++; + tableData[i][3] = n.getLatestVersion(); + + JComboBox comboBox = new JComboBox<>(); + for(String v : n.getAllVersions()){ + comboBox.addItem(v); + } + final int position = i; + comboBox.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + list_.get(position).setSelectedVersion((String) e.getItem()); + } + }); + comboboxes.put(i,comboBox); + + i++; } table = new JTable(tableData, columnNames); + + EachRowEditor rowEditor = new EachRowEditor(table); + + for (Entry> entry : comboboxes.entrySet()) + { + rowEditor.setEditorAt(entry.getKey(), new DefaultCellEditor(entry.getValue())); + } + + + table.getColumn("version").setCellEditor(rowEditor); //table.setModel(tableModel); @@ -85,16 +121,7 @@ public class UpdateChooser extends JPanel { 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). @@ -141,6 +168,7 @@ public class UpdateChooser extends JPanel { progressBar.setStringPainted(true); JButton btnDownloadMeta = new JButton("Download META"); + JButton btnDownloadEncrypted = new JButton("Download Enctrypted"); JProgressBar progressBar_1 = new JProgressBar(); panel.add(progressBar_1); progressBar_1.setValue(0); @@ -153,6 +181,7 @@ public class UpdateChooser extends JPanel { } }); + btnDownloadMeta.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if(!progress.isInProgress()){ @@ -161,6 +190,8 @@ public class UpdateChooser extends JPanel { new Thread(new Runnable(){ @Override public void run() { + progressBar_1.setValue(0); + progress.clear(); Starter.downloadMeta(output_,progress); progress.operationFinish(); Logger.messageBox("Finished"); @@ -175,15 +206,54 @@ public class UpdateChooser extends JPanel { }); panel.add(btnDownloadMeta); - - btnNewButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - synchronized (output_) { - window.setVisible(false); - output_.notifyAll(); - } + btnDownloadEncrypted.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(!progress.isInProgress()){ + progress.clear(); + progress.operationStart(); + new Thread(new Runnable(){ + @Override + public void run() { + progressBar_1.setValue(0); + progress.clear(); + Starter.downloadEncrypted(output_,progress); + progress.operationFinish(); + Logger.messageBox("Finished"); + } + + }).start(); + + }else{ + Logger.messageBox("Operation still in progress, please wait"); + } } }); + panel.add(btnDownloadEncrypted); + + + btnNewButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(!progress.isInProgress()){ + synchronized (output_) { + window.setVisible(false); + output_.notifyAll(); + } + } + } + }); + + table.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + if(!progress.isInProgress()){ + if (me.getClickCount() == 2) { + synchronized (output_) { + window.setVisible(false); + output_.notifyAll(); + } + } + } + } + }); JPanel bottomHalf = new JPanel(new BorderLayout()); bottomHalf.add(controlPane, BorderLayout.PAGE_START); @@ -206,7 +276,7 @@ public class UpdateChooser extends JPanel { frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Display the window. - frame.setSize(610, 600); + frame.setSize(672, 600); frame.setResizable(false); frame.setVisible(true); @@ -235,4 +305,93 @@ public class UpdateChooser extends JPanel { } } + /** + * each row TableCellEditor + * + * @version 1.1 09/09/99 + * @author Nobuo Tamemasa + */ + + class EachRowEditor implements TableCellEditor { + protected Hashtable editors; + + protected TableCellEditor editor, defaultEditor; + + JTable table; + + /** + * Constructs a EachRowEditor. create default editor + * + * @see TableCellEditor + * @see DefaultCellEditor + */ + public EachRowEditor(JTable table) { + this.table = table; + editors = new Hashtable(); + defaultEditor = new DefaultCellEditor(new JTextField()); + } + + /** + * @param row + * table row + * @param editor + * table cell editor + */ + public void setEditorAt(int row, TableCellEditor editor) { + editors.put(new Integer(row), editor); + } + + public Component getTableCellEditorComponent(JTable table, Object value, + boolean isSelected, int row, int column) { + //editor = (TableCellEditor)editors.get(new Integer(row)); + //if (editor == null) { + // editor = defaultEditor; + //} + return editor.getTableCellEditorComponent(table, value, isSelected, + row, column); + } + + public Object getCellEditorValue() { + return editor.getCellEditorValue(); + } + + public boolean stopCellEditing() { + return editor.stopCellEditing(); + } + + public void cancelCellEditing() { + editor.cancelCellEditing(); + } + + public boolean isCellEditable(EventObject anEvent) { + selectEditor((MouseEvent) anEvent); + return editor.isCellEditable(anEvent); + } + + public void addCellEditorListener(CellEditorListener l) { + editor.addCellEditorListener(l); + } + + public void removeCellEditorListener(CellEditorListener l) { + editor.removeCellEditorListener(l); + } + + public boolean shouldSelectCell(EventObject anEvent) { + selectEditor((MouseEvent) anEvent); + return editor.shouldSelectCell(anEvent); + } + + protected void selectEditor(MouseEvent e) { + int row; + if (e == null) { + row = table.getSelectionModel().getAnchorSelectionIndex(); + } else { + row = table.rowAtPoint(e.getPoint()); + } + editor = (TableCellEditor) editors.get(new Integer(row)); + if (editor == null) { + editor = defaultEditor; + } + } + } } diff --git a/src/de/mas/jnustool/util/Decryption.java b/src/de/mas/jnustool/util/Decryption.java index cfe0467..771c55d 100644 --- a/src/de/mas/jnustool/util/Decryption.java +++ b/src/de/mas/jnustool/util/Decryption.java @@ -174,7 +174,7 @@ public class Decryption { ByteArrayBuffer overflow = new ByteArrayBuffer(BLOCKSIZE); if(progressListener != null){ progressListener.setTotal(toDownload.getFileLength()); - progressListener.setCurrent(0); + progressListener.resetCurrent(); } do{ inBlockBuffer = getChunkFromStream(inputStream,blockBuffer,overflow,BLOCKSIZE); @@ -219,7 +219,7 @@ public class Decryption { if(progressListener != null){ progressListener.setTotal(toDownload.getFileLength()/HASHBLOCKSIZE*BLOCKSIZE); - progressListener.setCurrent(0); + progressListener.resetCurrent(); } do{ inBlockBuffer = getChunkFromStream(inputStream,encryptedBlockBuffer,overflow,BLOCKSIZE); diff --git a/src/de/mas/jnustool/util/Downloader.java b/src/de/mas/jnustool/util/Downloader.java index 41a26fc..3819a1b 100644 --- a/src/de/mas/jnustool/util/Downloader.java +++ b/src/de/mas/jnustool/util/Downloader.java @@ -1,8 +1,10 @@ package de.mas.jnustool.util; +import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; @@ -23,7 +25,7 @@ public class Downloader { } - public void downloadAndDecrypt(FEntry toDownload, Progress progressOfFile) throws IOException{ + public byte[] downloadAndDecrypt(FEntry toDownload, Progress progressOfFile, boolean asByteArray) throws IOException{ String URL = URL_BASE + "/" + String.format("%016X", toDownload.getTitleID()) + "/" + String.format("%08X", toDownload.getNUScontentID()); URL url = new URL(URL); String [] path = toDownload.getFullPath().split("/"); @@ -38,36 +40,50 @@ public class Downloader { int BLOCKSIZE = 0x10000; int HASHBLOCKSIZE = 0xFC00; fileOffset = ((toDownload.getFileOffset() / HASHBLOCKSIZE) * BLOCKSIZE); - } connection.setRequestProperty("Range", "bytes=" + fileOffset +"-"); - - connection.connect(); + try{ + connection.connect(); + }catch(Exception e){ + + } Decryption decryption = new Decryption(toDownload.getTicket()); decryption.setProgressListener(progressOfFile); InputStream input = connection.getInputStream(); - FileOutputStream outputStream = new FileOutputStream(String.format("%016X", toDownload.getTitleID()) +"/" + toDownload.getFullPath().substring(1, toDownload.getFullPath().length())); - if(!decryptWithHash){ + OutputStream outputStream; + + if(!asByteArray){ + outputStream = new FileOutputStream(toDownload.getTargetPath() +"/" + toDownload.getFullPath().substring(1, toDownload.getFullPath().length())); + }else{ + outputStream = new ByteArrayOutputStream((int) toDownload.getFileLength()); + } + + if(!decryptWithHash){ decryption.decryptFile(input, outputStream, toDownload); }else{ decryption.decryptFileHash(input, outputStream, toDownload); - } - + } connection.disconnect(); + if(asByteArray){ + return ((ByteArrayOutputStream)outputStream).toByteArray(); + }else{ + return null; + } } public static String URL_BASE = ""; public void downloadTMD(long titleID,int version,String path) throws IOException { - downloadTMD(titleID,path); + String version_suf = ""; + if(version > 0) version_suf = "." + version; + String URL = URL_BASE + "/" + String.format("%016X", titleID) + "/tmd" + version_suf; + System.out.println(URL); + downloadFile(URL, "title.tmd",path,null); } - public void downloadTMD(long titleID,String path) throws IOException { - String URL = URL_BASE + "/" + String.format("%016X", titleID) + "/tmd"; - downloadFile(URL, "tmd",path); - } - public void downloadFile(String fileURL,String filename,String tmpPath) throws IOException{ + + public void downloadFile(String fileURL,String filename,String tmpPath, Progress progress) throws IOException{ int BUFFER_SIZE = 0x800; URL url = new URL(fileURL); HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); @@ -78,11 +94,16 @@ public class Downloader { } FileOutputStream outputStream = new FileOutputStream(filename); - + if(progress != null){ + progress.resetCurrent(); + } int bytesRead = -1; byte[] buffer = new byte[BUFFER_SIZE]; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); + if(progress != null){ + progress.addCurrent(bytesRead); + } } outputStream.close(); @@ -92,26 +113,29 @@ public class Downloader { } public void downloadFile(String fileURL,String filename) throws IOException{ - downloadFile(fileURL, filename,null); + downloadFile(fileURL, filename,null,null); } public void downloadTicket(long titleID,String path) throws IOException { String URL = URL_BASE + "/" + String.format("%016X", titleID) + "/cetk"; - downloadFile(URL, "cetk",path); + downloadFile(URL, "title.tik",path,null); } - public void downloadContent(long titleID,int contentID) throws IOException { - downloadContent(titleID,contentID, null); + public void downloadContent(long titleID,int contentID,Progress progress) throws IOException { + downloadContent(titleID,contentID, null,progress); } public byte[] downloadContentToByteArray(long titleID,int contentID) throws IOException { 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, int version) throws IOException { + String version_suf = ""; + if(version > 0) version_suf = "." + version; + String URL = URL_BASE + "/" + String.format("%016X", titleID) + "/tmd" +version_suf; + System.out.println(URL); return downloadFileToByteArray(URL); } private byte[] downloadFileToByteArray(String fileURL) throws IOException { - int BUFFER_SIZE = 0x800; + int BUFFER_SIZE = 0x800; URL url = new URL(fileURL); HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); int responseCode = httpConn.getResponseCode(); @@ -141,17 +165,23 @@ public class Downloader { } httpConn.disconnect(); return file; - } + + + public byte[] downloadTicketToByteArray(long titleID) throws IOException { String URL = URL_BASE + "/" + String.format("%016X", titleID) + "/cetk"; return downloadFileToByteArray(URL); } - public void downloadContent(long titleID,int contentID, String tmpPath) throws IOException { + public void downloadContent(long titleID,int contentID, String tmpPath, Progress progress) throws IOException { String URL = URL_BASE + "/" + String.format("%016X", titleID) + "/" + String.format("%08X", contentID); - downloadFile(URL, String.format("%08X", contentID) +".app",tmpPath); + downloadFile(URL, String.format("%08x", contentID) +".app",tmpPath,progress); } + public void downloadContentH3(long titleID, int contentID, String tmpPath, Progress progress) throws IOException { + String URL = URL_BASE + "/" + String.format("%016X", titleID) + "/" + String.format("%08X", contentID) + ".h3"; + downloadFile(URL, String.format("%08X", contentID) +".h3",tmpPath,progress); + } } diff --git a/src/de/mas/jnustool/util/NUSTitleInformation.java b/src/de/mas/jnustool/util/NUSTitleInformation.java index 2083050..a1582e3 100644 --- a/src/de/mas/jnustool/util/NUSTitleInformation.java +++ b/src/de/mas/jnustool/util/NUSTitleInformation.java @@ -1,6 +1,8 @@ package de.mas.jnustool.util; import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; public class NUSTitleInformation implements Comparable, Serializable{ private static final long serialVersionUID = 1L; @@ -13,7 +15,9 @@ public class NUSTitleInformation implements Comparable, Ser private String company_code; private int region; private byte[] key; + private ArrayList versions = new ArrayList<>(); + private String selectedVersion = "latest"; public enum Region{ EUR, @@ -22,7 +26,7 @@ public class NUSTitleInformation implements Comparable, Ser UKWN } - public NUSTitleInformation(long titleID, String longnameEN, String ID6, String product_code,String content_platform,String company_code,int region) { + public NUSTitleInformation(long titleID, String longnameEN, String ID6, String product_code,String content_platform,String company_code,int region, String[] versions) { setTitleID(titleID); setLongnameEN(longnameEN); setID6(ID6); @@ -30,12 +34,21 @@ public class NUSTitleInformation implements Comparable, Ser setCompany_code(company_code); setContent_platform(content_platform); setRegion(region); + for(String s : versions){ + if(s != null){ + this.versions.add(Integer.parseInt(s)); + } + } } public NUSTitleInformation() { // TODO Auto-generated constructor stub } + public NUSTitleInformation(long titleID, String longnameEN, String ID6, String product_code,String content_platform,String company_code,int region) { + this(titleID, longnameEN, ID6, product_code,content_platform,company_code,region,new String[1]); + } + public Region getRegionAsRegion() { switch (region) { case 1: return Region.JAP; @@ -108,7 +121,12 @@ public class NUSTitleInformation implements Comparable, Ser @Override public String toString(){ - return getTitleIDAsString() + ";" + region +";" + getContent_platform() + ";" + getCompany_code() + ";"+ getProduct_code()+ ";" + getID6() + ";" + getLongnameEN(); + String result = getTitleIDAsString() + ";" + region +";" + getContent_platform() + ";" + getCompany_code() + ";"+ getProduct_code()+ ";" + getID6() + ";" + getLongnameEN(); + for(Integer i :versions){ + result += ";" + i; + } + result += ";" + getSelectedVersion(); + return result; } @Override @@ -139,6 +157,41 @@ public class NUSTitleInformation implements Comparable, Ser public boolean equals(Object o){ return titleID == ((NUSTitleInformation)o).titleID; } - + public String getLatestVersion() { + String result = "latest"; + if(versions != null && !versions.isEmpty()){ + result = versions.get(versions.size()-1) + ""; + } + return result; + } + + public List getAllVersions() { + List list = new ArrayList<>(); + if(versions != null && !versions.isEmpty()){ + for(Integer v: versions){ + list.add(v + ""); + } + } + list.add("latest"); + return list; + } + + public void setSelectedVersion(String string) { + this.selectedVersion = string; + } + + public int getSelectedVersion() { + int version = -1; + if(this.selectedVersion == "latest"){ + version = -1; + }else{ + try{ + version = Integer.parseInt(this.selectedVersion); + }catch(Exception e){ + + } + } + return version; + } } diff --git a/src/de/mas/jnustool/util/Settings.java b/src/de/mas/jnustool/util/Settings.java index c2f1fdf..ec1373d 100644 --- a/src/de/mas/jnustool/util/Settings.java +++ b/src/de/mas/jnustool/util/Settings.java @@ -3,7 +3,7 @@ package de.mas.jnustool.util; public class Settings { public static boolean downloadContent = false; - public static boolean useCachedFiles = false; + public static boolean useCachedFiles = true; public static boolean downloadWhenCachedFilesMissingOrBroken = true; public static boolean skipBrokenFiles = false; public static boolean skipExistingFiles = true; diff --git a/src/de/mas/jnustool/util/Util.java b/src/de/mas/jnustool/util/Util.java index c7eff97..9f446be 100644 --- a/src/de/mas/jnustool/util/Util.java +++ b/src/de/mas/jnustool/util/Util.java @@ -1,5 +1,6 @@ package de.mas.jnustool.util; +import java.io.File; import java.math.BigInteger; import java.nio.ByteBuffer; import java.util.Arrays; @@ -21,6 +22,7 @@ public class Util { public static String ByteArrayToString(byte[] ba) { + if(ba == null) return null; StringBuilder hex = new StringBuilder(ba.length * 2); for(byte b : ba){ hex.append(String.format("%02X", b)); @@ -59,4 +61,26 @@ public class Util { return 0L; } } + + public static void createSubfolder(String folder){ + + String [] path = folder.split("/"); + File folder_ = null; + String foldername = new String(); + if(path.length == 1){ + folder_ = new File(folder); + if(!folder_.exists()){ + folder_.mkdir(); + } + } + for(int i = 0;i